Pregunta

Todavía estoy luchando con la integración de Spring; este es mi escenario:

  1. Un servicio web recibe una solicitud del cliente A.
  2. El servicio web pone la solicitud en una cola.
  3. Un consumidor de cola procesa los mensajes FIFO y envía una respuesta que se enruta de regreso al servicio web.
  4. Los servicios web envían la respuesta al cliente A

Habrá varios servicios web que alimentarán mensajes en esta cola y debo asegurarme de que realmente se procesen en el orden en que se reciben.

¿Qué piezas de Spring Integration necesito conectar?

¿Fue útil?

Solución

No puedo ayudarte con la integración de primavera, pero tal vez debas pensar en tu arquitectura. En los sistemas ESB, generalmente coloca un mensaje en una cola, cuando sabe que el procesamiento del mensaje tomará un tiempo considerable o si no está seguro de que el extremo remoto esté listo (otra razón es cerrar componentes incompatibles). Cuando agrega el mensaje a la cola, regresa inmediatamente al solicitante que indica que el mensaje se recibe, pero no proporciona el resultado de la operación. El solicitante necesitaría sondear para obtener el resultado o, alternativamente, podría proporcionar algún tipo de funcionalidad de "empujar".

Entonces, si el procesamiento de los mensajes en la cola lleva mucho tiempo, recomiendo modificar su arquitectura. No es común que un cliente web espere largos tiempos para la respuesta y muchas solicitudes también podrían tiempo de espera.

Si, por otro lado, el procesamiento de los mensajes es rápido y confiable, entonces no es necesario usar canales de cola. Haga que todos sus mensajes se comuniquen con un componente central (Java EE Session Bean, Spring Bean, Web Service) e implementen un mecanismo de cola usted mismo. Ya son respuestas que cubren cómo podrías hacer esto.

Otros consejos

Basado en el javadoc para el Queuechannel Aquí está mi intento por eso. Esto no aborda la configuración del servicio web, solo el código que iría en la implementación de Back End del servicio web.

Este es el código que agregaría algo a una cola (su servicio web).

public class TheWebService {

  // Could also use QueueChannel, or PollableChannel here instead
  // just picked the most general one
  private org.springframework.integration.channel.MessageChannel queue;

  public void yourWebServiceMethod(SomeArg arg) {
     SomeObjectToPassThatExtendsMessage passed = someInitialProcessing(arg);
     queue.send(passed);
  }
}

Este es el código que iría en su clase de receptor/procesador/dequeue

public class TheProcessor {

  // Could also use QueueChannel here instead
  // just picked the most general one
  private org.springframework.integration.channel.PollableChannel queue;

  // This method needs to be setup to be called by a separate thread.
  // See http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/scheduling/package-summary.html
  // and it's sub-packages.
  public void someProcessingPoller() {
     SomeObjectToPassThatExtendsMessage passed = queue.receive();
     // Do some processing with the passed object.
  }

}

La configuración de primavera para esto se vería algo así como

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans">

  <bean id="webService" class="mypackage.TheWebService">
      <property name="queue" ref="queue" />
  </bean>

  <bean id="processor" class="mypackage.TheProcessor ">
      <property name="queue" ref="queue" />
  </bean>

  <bean id="queue" class="org.springframework.integration.channel.QueueChannel"/>
</beans>

Tenga en cuenta que Spring Integration, pero Java 5 tiene una serie de Bloquingqueues que pueden manejar FIFO.

Deberías mirar los elementos "inbound-gateway" http (para REST) ​​o ws (para POX/SOAP) en Spring Integration.Cualquiera de los dos puede conectarse a un canal compartido respaldado por cola a través del atributo "canal de solicitud" (el enrutamiento de una respuesta a través de la misma puerta de enlace se puede manejar detrás de escena).Recomendaría comenzar explorando las muestras.Este blog debería ayudarle a ponerse en marcha: http://blog.springsource.com/2010/09/29/new-spring-integration-samples/

Espero que ayude.-Marca

El problema no es la primavera. Creo que necesitará una cola con elementos que contengan la solicitud y ofrecen una respuesta. Pero la respuesta debe bloquear hasta que el elemento se descifra y procese. Entonces el elemento de la cola se ve como:

public class BlockingPair {
  private final RequestBodyType request;
  private ResponseBodyType response;

  public BlockingPair(RequestBodyType request) {
    this.request = request;
  }

  public RequestBodyType getRequest() {
    return request;
  }

  public ResponseBodyType getResponse() {
    while (response == null) {
      Thread.currentThread().sleep(10);
    }
    return response;
  }

  public void setResponse(ResponseBodyType response) {
    this.response = response;
  }
}

WebService Enqueing crea el blockingpair con su cuerpo de solicitud. Que empuja el elemento BLOCKINGPAIR a la cola. Luego crea la respuesta que obtiene el cuerpo de respuesta del blockingpair, pero bloquea.

El consumidor Deques se bloquea y establece el cuerpo de respuesta. A partir de ahí, el servicio web continúa escribiendo la respuesta.

Necesita tres frijoles: servicio web, una cola de bloqueo y el consumidor. Tanto el servicio web como el consumidor necesitan la cola como propiedad de bean.

La cola y los frijoles del consumidor deben ser planificados en el contexto de la aplicación (como se inicia el ContextLoaderListener). La cola necesita una identificación de frijoles para ser referencias del servicio web (que tiene su propio contexto, pero el contexto de la aplicación como padre, por lo que se puede hacer referencia a la referencia de la cola):

Parte de web.xml:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
  <servlet-name>service</servlet-name>
  <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>service</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

los applicationContext.xml Contiene dos frijoles:

<bean id="queue" class="java.util.concurrent.LinkedBlockingQueue"/>

<bean id="consumer" class="...">
  <property name="queue" ref="queue"/>
</bean>

El servicio web tiene su propia definición de contexto, aquí service-servlet.xml:

<bean id="endpoint" class="org.springframework.ws.server.endpoint....PayloadEndpoint">
  <property name="queue" ref="queue"/>
</bean>

Para obtener más información sobre cómo definir un punto final de primavera WS, consulte el tutorial de primavera.

El consumidor debe ser una tarea de fondo, por lo que preferiría cuarzo, para la integración de primavera ver aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top