2012-09-25 17 views
6

Me gustaría procesar los mensajes de solicitud y respuesta al final de mi ruta. Sin embargo, no veo una forma de acceder al mensaje de solicitud original.Apache Camel: acceda al mensaje de solicitud y respuesta al final de la ruta

Tengo la terrible sensación de que estoy luchando con un concepto básico.

Aquí es un simple ejemplo de ruta en DSL para delinear mi problema (streamCaching está habilitado para todo el contexto):

from("activemq:queue:myQueue") 
.to("log:" + getClass().getName() + "?showOut=true") 
.to("http://localhost:8080/someBackend") 
.log("Now in.Body returns this: ${in.body} and out.Body this: ${out.body}") 
.to("log:" + getClass().getName() + "?showOut=true"); 

He aquí un extracto de acuerdo a los registros de mi (saltos de línea editado para una mejor lectura) . Como se puede ver, el mensaje SOAP original se pierde una vez que el servidor HTTP responde, y el objeto de respuesta SOAP se almacena en el cuerpo del mensaje.

2012-09-25 17:28:08,312 local.bar.foo.MyRouteBuilder INFO - 
    Exchange[ExchangePattern:InOut, BodyType:byte[], 
    Body:<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Header /><env:Body><urn:someRequest xmlns:urn="http://foo.bar.local/ns"></urn:someRequest></env:Body></env:Envelope>, 
    Out: null] 
2012-09-25 17:28:08,398 org.apache.camel.component.http.HttpProducer DEBUG - 
    Executing http POST method: http://localhost:8080/someBackend 
2012-09-25 17:28:09,389 org.apache.camel.component.http.HttpProducer DEBUG - 
    Http responseCode: 200 
2012-09-25 17:28:09,392 route2 INFO - 
    Now in.Body returns this: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:someResponse xmlns:ns2="http://foo.bar.local/ns"</ns2:someResponse></soap:Body></soap:Envelope> 
    and out.Body this: 
2012-09-25 17:28:09,392 local.bar.foo.MyRouteBuilder INFO - 
    Exchange[ExchangePattern:InOut, 
    BodyType:org.apache.camel.converter.stream.InputStreamCache, 
    Body:[Body is instance of org.apache.camel.StreamCache], 
    Out: null] 

Hubiera esperado que se guardaran in.body y out.body durante toda la ruta?

Las soluciones alternativas que estoy considerando: el uso

  • Hacer del patrón Correlation Identifier para correlacionar ambas petición y respuesta. Pero, ¿esto preservaría los cuerpos del mensaje también? Además, mis mensajes de solicitud/respuesta no tienen identificadores únicos para la correlación.
  • Escribir un grano de costumbre, que realiza la llamada al back-end http, el procesamiento tanto de petición y respuesta objetos (pero esto es básicamente una solución sin camello, reinventar la rueda y por lo tanto no se prefiere)

Ya enfoques fallidos:

que intentó acceder el mensaje de solicitud original usando un procesador como esto al final de mi ruta, sin éxito:

process(new Processor() { 
    @Override 
    public void process(Exchange exchange) throws Exception { 
     Message originalInMessage = exchange.getUnitOfWork().getOriginalInMessage(); 
     logger.debug(originalInMessage.getBody(String.class)); 
     logger.debug(exchange.getIn().getBody(String.class)); 
    } 
}); 

Gracias por cualquier ayuda

+1

Me enfrenté a una situación similar, resuelto como: String payload = new String ((byte []) exchange.getUnitOfWork(). GetOriginalInMessage(). GetBody()) – dkb

Respuesta

14

almacenar simplemente el cuerpo original de la en el mensaje en un encabezado o una propiedad y recuperarlo al final:

from("activemq:queue:myQueue") 
.setProperty("origInBody", body()) 
.to("http://localhost:8080/someBackend") 

Después la llamada http puede acceder a la propiedad origInBody.

12

En primer lugar, este artículo muestra muy bien cómo y trabajos en camello: http://camel.apache.org/using-getin-or-getout-methods-on-exchange.html

Típicamente, el mensaje no siempre se utiliza, sino que copian de la transmisión del mensaje en cada paso .

En su caso, si desea que el mensaje original permanezca hasta el final de la ruta, puede continuar con Enrichment EIP. http://camel.apache.org/content-enricher.html

La ruta sería algo como esto:

public class MyAggregationStrategy implements AggregationStrategy { 
    public Exchange aggregate(Exchange orig, Exchange httpExchange){ 
    // if you want to check something with the Http request, you better do that here 
    if(httpExchange is not correct in some way) 
     throw new RuntimeException("Something went wrong"); 

    return orig; 
    } 
} 

AggregationStrategy aggStrategy = new MyAggregationStrategy(); 

from("activemq:queue:myQueue") 
    .enrich("http://localhost:8080/someBackend",aggStrategy) 
    .//keep processing the original request here if you like, in the "in" message 
+0

Muchas gracias por esto. Utilicé la solución provista por "Christian Schneider" ya que soluciona mi caso de uso.Sin embargo, para escenarios más complejos, creo que AggregationStrategy es el camino a seguir. Muchas gracias también por el enlace en las entradas de preguntas frecuentes, me llamó la atención. (No se pudo votar porque no tengo suficientes puntos, lo siento por esto) – user1627943

Cuestiones relacionadas