I have two apps. First of them executes some business logics and than calls other app with POST or DELETE
from("direct:firstapp").routeId("rst_firstapp").streamCaching()
//data preparation was here
.setHeader(Exchange.CONTENT_TYPE, simple(MediaType.APPLICATION_JSON_VALUE))
.convertBodyTo(MyRequest.class)
.choice().id("rst_req_lockCardChoice")
.when().simple("${mycondition} == '1'")
.setHeader(Exchange.HTTP_METHOD, simple("POST"))
.log(LoggingLevel.INFO, "Call post")
.when().simple("${mycondition} == '0'")
.setHeader(Exchange.HTTP_METHOD, simple("DELETE"))
.log(LoggingLevel.INFO, "Call delete")
.end()
.marshal(new JsonDataFormat(JsonLibrary.Jackson))
.log(LoggingLevel.INFO, " Call to service ${body}")
.to('myadress/mypath').id("rt_call_service")
.log(LoggingLevel.INFO, " Response from service ${body}");
Logs for line: .log(LoggingLevel.INFO, " Call to service ${body}")
print that body exists in both cases.
The second app receives this requests and does some other business logics.
rest().post("/mypath")
.consumes(MediaType.APPLICATION_JSON_VALUE)
.produces(MediaType.APPLICATION_JSON_VALUE)
.type(MyRequest.class)
.responseMessage().code("200").message("Success").endResponseMessage()
.route().routeId("rst_postrecieve")
.log(LoggingLevel.INFO, "Recieved request ${body}")
.id("rst_rst_post_recieved")
.to("direct:drt_rst_postbranch")
.endRest();
rest().delete("/mypath")
.consumes(MediaType.APPLICATION_JSON_VALUE)
.produces(MediaType.APPLICATION_JSON_VALUE)
.type(MyRequest.class)
.responseMessage().code("200").message("Success").endResponseMessage()
.route().routeId("rst_deleterecive")
.log(LoggingLevel.INFO, "Received request ${body}")
.id("rst_rst_delete_recieved")
.to("direct:drt_rst_deletebrach")
.endRest();
POST request works fine.
First app sends body. Second recieves it.
DELETE doesn't.
First app cuts the body out. Line .log(LoggingLevel.INFO, " Call to service ${body}") prints the body. But the reciever gets a DELETE request with empty body. I have sniffed the Http-request with Wireshark: the body is empty.
However, I'm perfectly able to send a DELETE request with body using any other tool like Swagger-ui, Postman, Soap-UI etc. The second app will recieve body and proccess it correctly.
Why does Camel forbid to send a DELETE body, while it allows to recieve it? I expected the behaviour to be the same.
What is the workaround? I can't change request type, it's a customer requirement.
Camel version: 2.21.0.000033-fuse-000001-redhat-1
P.S. I know that Http standards state that no body is expected for DELETE, however all the tools & frameworks I faced allowed to send and receive it. Including Spring, for example.
Most probably Delete method will ignore body while processing. This is no problem with your code, it was because of HTTP implementation.
If a DELETE request includes an entity body, the body is ignored [...]
If you still need to send some data from one app to another to Delete method. I suggest you can try with path param. So than you can get as parameter in second app and do you process.
Related
I'm having an issue on route configuration with Apache Camel.
For some reason, after falling into an exception, I'm loosing the ${body}, it's just simply wiping out. Is there any way to keep what I have on ${body} if my request fail?
This is the chunk of code:
.to(pricingDomainUrl + "?bridgeEndpoint=true").process(PRICING_DOMAIN_RESPONSE_PROCESSOR)
.doCatch(Exception.class)
.doTry()
.setProperty("exception", simple("true"))
.log(LoggingLevel.INFO, logger, "BODY ON TRY: ${body}")<- prints an empty body
.log(LoggingLevel.WARN, "First call failed, trying cleaning headers")
.process(PRICING_DOMAIN_REQUEST_PROCESSOR)
.doCatch(Exception.class)
.process(EXCEPTION_PROCESSOR);
I receive a Request from the Client which returns a SendRequest-Object that has a HttpMethod, a path and data to send.
Now I would like to send the Request depending on the object I get to the API.
After sending I will get a Response.
The problem now is how can I send the payload and receive the response.
#Bean
public IntegrationFlow httpPostSendRawData() {
return IntegrationFlows.from(
Http.inboundGateway("/api/data/send")
.requestMapping(r -> r.methods(HttpMethod.POST))
.statusCodeExpression(dataParser().parseExpression("T(org.springframework.http.HttpStatus).BAD_REQUEST"))
.requestPayloadType(ResolvableType.forClass(DataSend.class))
.crossOrigin(cors -> cors.origin("*"))
.headerMapper(dataHeaderMapper())
)
.channel("http.data.send.channel")
.handle("rawDataEndpoint", "send")
.transform(/* here i have some transformations*/)
.handle(Http.outboundGateway((Message<SendRequest> r)->r.getPayload().getPath())
.httpMethod(/* Here I would like to get the Method of SendRequest*/)
//add payload
.extractPayload(true))
.get();
It's not clear what is your SendRequest, but the idea for the method is exactly the same what you have done for the url:
.httpMethodFunction((Message<SendRequest> r)->r.getPayload().getMethod())
Although, since you want to have some extraction for the request body, you need to do that in advance in the transform() and move values for url and method to the headers.
There is just no any payload extraction in the Http.outboundGateway: it deals with the whole request payload as an entity for HTTP request body.
I'm using Apache Camel 2.19.2 DSL and trying to consume a soap service hosted in a different server. My camel code is -
SoapJaxbDataFormat soap = new SoapJaxbDataFormat("<Service Class Package Path>");
soap.setContextPath("Root element package path");
soap.setVersion("1.1");
from("direct:invokeSOAPService")
.process(new Processor1()) //Constructs the main message body that will be set as body of the soap-Envelope
.removeHeaders("*")
.setHeader(Exchange.SOAP_ACTION, simple("Soap Action of the service from ASDL"))
.setHeader(Exchange.HTTP_METHOD, simple("POST"))
.setHeader(Exchange.CONTENT_TYPE, constant("text/xml"))
.marshal(soap)
.log(LoggingLevel.DEBUG, LOG, "Request xml===========>${body}")
.log(LoggingLevel.DEBUG, LOG, "Posting request to server url")
.to("cxf://http://<ip>:<port>/<wsdl server location without ?wsdl>?serviceClass=<qualified service class name without .class extension>&dataFormat=MESSAGE&synchronous=true&continuationTimeout=100000&serviceName={<target-name-space-name>}<service-name>&endpointName={<target-name-space-name>}<service port name>")
.log(LoggingLevel.DEBUG, LOG, "Posted request successfully to server url")
.log(LoggingLevel.DEBUG, LOG, "Received response from server ==========>${body}")
.end();
Application is able to generate the soap-request and able to post the same to the server and server is sending back the soap response (as confirmed by the owner of the soap server) but I can't see the response at my application end.
it is printing the request xml using below log:
Request xml===========> <soap request xml>
Posting request to server url
**org.apache.camel.component.cxf.feature.AbstractDataFormatFeature.removeInterceptors><removing the interceptor org.apache.cxf.interceptor.ClientFaultConverter#58811c5b
org.apache.camel.component.cxf.feature.AbstractDataFormatFeature.removeInterceptors><removing the interceptor org.apache.cxf.jaxws.interceptors.WrapperClassInInterceptor#1d25437
org.apache.camel.component.cxf.feature.AbstractDataFormatFeature.removeInterceptors><removing the interceptor org.apache.cxf.jaxws.interceptors.HolderInInterceptor#4451805d
org.apache.camel.component.cxf.feature.AbstractDataFormatFeature.removeInterceptors><removing the interceptor org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor#2514dd3d
org.apache.camel.component.cxf.feature.AbstractDataFormatFeature.removeInterceptors><removing the interceptor org.apache.cxf.jaxws.interceptors.HolderOutInterceptor#75a76e00**
Posted request successfully to server url
Received response from server ==========> **PRINTING THE REQUEST XML**
Could you please help me to understand the issue, why camel is not able to capture the response! It is because of those camel internal remove methods?
Could you please help me to capture the response.
Would you please advise how to configure RestAssured to wait until complete response data is returned.
I am trying to validate a data feed using http get as shown below.
given()
.relaxedHTTPSValidation()
.header("Content-Type", "application/json")
.when()
.get("/API/data/")
.then()
.statusCode(200)
.log().all();
In this context, Rest Assured logging only few lines of data, does not seem to wait until complete response data is returned .
This works ok when data response is small.
In this case, it seems to log only data that's available when http status code is returned.
Consequently I am seeing the following error message: Premature end of Content-Length delimited message body (expected: 1486; received: 1088)
Thx
If you want to check the status code you should use the expect().statusCode(x).
Anyway the tool waits until the whole response is returned from the server and only logs it out after that. So it shouldn't be a problem with big JSON/XML responses either.
I have a camel route configured for reading from a JMS queue and POST it to a service.
My route is :
from("jms:queue")
.marshal()
.json(JsonLibrary.GSON)
.setHeader(Exchange.CONTENT_TYPE,constant("application/json"))
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.process(new Processor1())
.to("https4:xxxxxx?throwExceptionOnFailure=false")
.process(new MyProcessor())
My Configuration :
HttpComponent httpc = getContext().getComponent("http4",HttpComponent.class);
httpc.setHttpConfiguaration(customHttpConfig())
and in customHttpConfig i set my auth details.
I am getting a 400 error from the server. But i am able to hit the server from Postman api and get successfull response.
In my Processor1 class ( before making the request), i am able to print the body of the message, which contains a json representation of my object.
But in the processor after the POST request, i am doing this and getting below responses:
Message in = exchange.getIn();
in.getBody(String.class); // print the error code 400
HttpServletRequest request = in.getBody(HttpServletRequest.class)// This is null.
Anything i am doing wrong? Do i need to set the message Content to the body of my Post Request?
It will not be String.class:
in.getBody(String.class);
First check the type of server response, then try to print or log exchange body.
It should be HttpServletResponse:
HttpServletRequest request = in.getBody(HttpServletRequest.class)