Im using header enricher which uses existing headers to set a value of new header. However existing header information is lost and only 3 header remain ie request-id,timestamp and raw-body.
public String vipul(Message<String> message) {
MessageHeaders messageHeaders =message.getHeaders();
if (messageHeaders.containsKey("x-death")) {
List<HashMap<String, Object>> deathList = (List<HashMap<String, Object>>) messageHeaders
.get("x-death");
//logger.debug(message.get("messageId")+" "+deathList);
if (deathList.size() > 0) {
HashMap<String, Object> death = deathList.get(0);
if (death.containsKey("original-expiration")) {
return (String) death.get("original-expiration");
//logger.info(messageHeaders.get("messageId")+" original-expiration = "+death.get("original-expiration"));
}
}
} else {
return null;
}
return "";
}
In this messageHeaders map has only has 3 keys and not all the header keys which are normally there. I need to make a retry system using original expiration .
MY spring integration xml has following snippet :
<int:header-enricher input-channel="fromPushAppointmentErrorHandler1"
output-channel="fromPushAppointmentErrorHandler">
<int:header name="original_expiration" method="vipul" ref="errorhelper"/>
</int:header-enricher>
First of all it looks like you also need an overwrite="true" for that <int:header name="original_expiration"> since the logic in your vipul() is about to produce a new value for existing header and that is not going to happen since the value is already there in headers.
The fact that you are missing some headers in this your logic might be dictated by some upstream <transformer> which returns the whole Message without copying request headers.
Related
I have RouteBuilder as below.
from("seda:requestQueue").routeId("service_request").log(LoggingLevel.INFO, "Processing STARTED, {body = ${body}")
.setBody(body())
.to("select * from SERVICE_REQUEST WHERE requestType=:#TYPE AND requestDate=:#date AND owner=:#OWNER)
.split(body()).streaming().process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
Map<String, Object> row = exchange.getIn().getBody(Map.class);
if (row == null) {
LOGGER.info("Request is new. No records found.");
return;
}
//Duplicate request. Q(Not sure how to terminate the process with exception)
}
})
.log(LoggingLevel.INFO, "Processing CONTINUE, {body = ${body}")
.setBody(body())
.to("insert into SERVICE_REQUEST (ID,....) ").log(LoggingLevel.INFO, "Processing COMPLETED").end();
I would like to achieve
Whenever request is submitted (for now via SEDA), first check whether the same request has been available in database or not.
If it is not available then only insert into database (new row)
Question:
1. How can I set original request body to insertQuery? As per the above code, body received at seda:requestQueue is not available to to("insert into SERVICE..).
Your splitter will send out messages with a new body (based on the SQL). So, the body itself cannot be used.
Instead, before calling the splitter, set the body to a property of the Exchange. Then, when you need to use it, read the value of the property.
.setProperty("mySampleProperty", simple("${body}")
If you need it back as the body, then -- at that point -- set the body to the value that you previously stored in the Exchange property.
Here's a similar question: Apache Camel: how store variable for later use
I am trying to use Firebase Cloud Messaging by Google with the help of Jetty HTTP client:
public static final String FCM_URL = "https://fcm.googleapis.com/fcm/send";
public static final String FCM_KEY = "key=AAAA....";
private final HttpClient mHttpClient = new HttpClient();
private final CompleteListener mFcmListener = new CompleteListener() {
#Override
public void onComplete(Result result) {
if (result.isFailed()) {
// TODO delete FCM token in database for certain responses
}
}
};
mHttpClient.start();
mHttpClient.POST(FCM_URL)
.header(HttpHeader.AUTHORIZATION, FCM_KEY)
.content(new StringContentProvider(notificationStr), "application/json")
.send(mFcmListener);
My question is very simple, but I couldn't find the answer myself yet by looking at the StringContentProvider and its base classes -
If I need to set the request HTTP header for FCM:
Content-Type: application/json
then do I have to add the line:
.header(HttpHeader.CONTENT_TYPE, "application/json")
or will that class already do it for me?
A couple of points:
Yes, if you don't set content type header explicitly, it would be auto set based on the selected Content Provider.
By default, the StringContentProvider sets Content-Type to text/plain. To override, you need to use another constructor -
new StringContentProvider("application/json", content, StandardCharsets.UTF_8);
Request #setContent method auto sets Content-Type header to the provided value. Hence, you need not make any change to the code.
I am trying to use TikaJAXRS and add headers for setting PDFParser properties. Specifially the ocrStrategy property. However, when I add the header using X-Tika-PDFocrStrategy, I get an error stating that it is an invalid X-Tika-OCR header.
After looking into the source code, I believe the issue might be with the 'fillParseContext' method in the TikaResource.java file.
public static void fillParseContext(ParseContext parseContext, MultivaluedMap<String, String> httpHeaders,
Parser embeddedParser) {
TesseractOCRConfig ocrConfig = new TesseractOCRConfig();
PDFParserConfig pdfParserConfig = new PDFParserConfig();
for (String key : httpHeaders.keySet()) {
if (StringUtils.startsWith(key, X_TIKA_OCR_HEADER_PREFIX)) {
processHeaderConfig(httpHeaders, ocrConfig, key, X_TIKA_OCR_HEADER_PREFIX);
} else if (StringUtils.startsWith(key, X_TIKA_PDF_HEADER_PREFIX)) {
processHeaderConfig(httpHeaders, pdfParserConfig, key, X_TIKA_PDF_HEADER_PREFIX);
}
}
parseContext.set(TesseractOCRConfig.class, ocrConfig);
parseContext.set(PDFParserConfig.class, pdfParserConfig);
if (embeddedParser != null) {
parseContext.set(Parser.class, embeddedParser);
}
}
The if statement first looks for a key that starts with the OCR header prefix, and since the PDFParser's property name contains 'ocr', it is trying to find a property named 'ocrStrategy' in the OCRParser class, which doesn't exist.
Can anyone verify this, or tell me how I could set that property via the restful service?
Side note, I am using Tika as a service via a docker container and calling it from a python app.
I'm trying to extract a value from org.restlet.http.headers header collection in a Camel route.
My incoming POST has a http header property called IncomingRequestType: ABCD.
Camel moves this inside the exchange headers collection, but it is buried inside org.restlet.http.headers which is in-itself a collection of headers.
I can extract the value in a process using the code below:
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
org.restlet.util.Series<Header> httpHeaders = null;
httpHeaders = (Series<Header>) exchange.getIn().getHeader("org.restlet.http.headers");
String reqType = httpHeaders.getValues("IncomingRequestType").toString();
}})
Outside of a process I need to access the IncomingRequestType inside a .choice().when()
e.g. i want to be able to do:
.choice()
.when(header("org.restlet.http.headers")["IncomingRequestType"]).isEqualTo("ABCD"))
Any suggestions on how this can be done. I've tried creating predicates but cannot get a suitable solution.
This can be done in the simple language:
.choice()
.when(simple("${in.header.org.restlet.http.headers[IncomingRequestType]} == 'ABCD'"))
I have a problem in my Camel Route when I try to check the value of a header.
So what is happening is that I go to a processor, do my stuff, then I create 2 different message that I put inside the body.
After that I go back on my route, I split my body so I can route the 2 differents messages, and there I use a .choice().when() on the header CamelFileName to check if it contains some value.
It doesn't find the value and then doesn't go inside the .when()
Here is the source code to make it more clear :
// My route
from("myQuartz")
.routeId("myId")
.bean(myProcessor.class)
.split(body())
.to("log:test?showAll=true&multiline=true")
.log('[${header.CamelFileName}]')
.choice()
.when(header('CamelFileName').contains('myString1'))
// do my stuff
.endChoice()
.when(header('CamelFileName').contains('myString2'))
// do my other stuff
.endChoice()
.otherwise()
.log("It did not go inside the when")
.to("log:test?showAll=true&multiline=true")
.endChoice()
.end()
So here I am simply trying to check if the CamelFileName header contains a string (it's not a variable), but it keep going inside the otherwise.
The log just after the split show me that the CamelFileName header is correct and do contains the string I am looking for.
I tried different ways of checking the value inside the when() such as using a simple(), but it doesn't work.
My file is a groovy file.
Thanks for your help.
EDIT :
So to explain what is inside my body I will show you the processor source code.
I create two DefaultMessage,
I set them a body and a CamelFileName header,
I put them into a list and then I put that list into my exchange body.
After that I go back to the route and I split the body so it will separate the two messages and route them.
Here is what's happening in my processor :
// Message 1
DefaultMessage message1 = new DefaultMessage()
message1.setBody(bodyContent)
def fileName1 = "myString1_blablabla.txt"
message1.setHeader("CamelFileName",fileName1)
listMessages.add(message1)
// Message 2
DefaultMessage message2 = new DefaultMessage()
message2.setBody(bodyContent)
def fileName2 = "myString2_blablabla.txt"
message2.setHeader("CamelFileName",fileName2)
listMessages.add(message2)
exchange.in.setBody(listMessages)
I've setup a simpler test for your route. It routes data to the proper when clause. When you split(), the headers get copied for each exchange, so I'm not sure why you would expect (given your route) why the elements of the list would have different header values.
public class SampleTest extends CamelTestSupport{
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:start")
.setHeader("CamelFileName", simple("myString1"))
.split(body())
.choice()
.when(header("CamelFileName").contains("myString1"))
.to("mock:myString1")
.endChoice()
.when(header("CamelFileName").contains("myString2"))
.to("mock:myString2")
.endChoice()
.otherwise()
.to("mock:otherwise")
.endChoice()
.end();
}
};
}
#Test
public void test() throws Exception {
//Setup mock body
java.util.List<String> myList = new java.util.ArrayList<String>();
myList.add("1");
myList.add("2");
MockEndpoint mock1 = getMockEndpoint("mock:myString1");
MockEndpoint mock2 = getMockEndpoint("mock:myString2");
MockEndpoint mockOtherwise = getMockEndpoint("mock:otherwise");
mock1.expectedMessageCount(myList.size());
mock2.expectedMessageCount(0);
mockOtherwise.expectedMessageCount(0);
template.sendBody("direct:start", myList);
assertMockEndpointsSatisfied();
}
}