Spring Coud Sleuth causing ActiveMQ/JMS message headers to be lost - spring

Versions:
SpringBoot: 2.3.12.RELEASE
SpringCloud: Hoxton.SR12
SpringCloud Starter Sleuth: 3.0.3
Camel: 3.4.6
I want to add Sleuth to a pre-exisitng project that now makes use of ActiveMQ, previosuly it was jusing JMS. When I do, values from the ActiceMQ message get blocked/removed and (one being "filename" which is the key value for S2 requests). Other JMS values still seem to come through OK.
I need to understand why the non-JMS values are getting blocked/removed (I cannot find any information on what would be causing that to happen) to prevent the errors.
I know I can disbale Sleuth for JMS with spring.sleuth.messaging.jms.enabled=true but moving forwards I'd like to be able to trace the ActiveMQ/JMS code, so that workaround isn't particularly attractive.
As this is pre-exiting code, I'd also like to avoid having to re-write it if at all possible.
Has anyone gotten SPring Cloud Sleuth to work with ActiveMQ/JMS and can maybe point out where things are going wrong?
Edit:
Based on the initial response from Marcin, we found that the following version compile & execute, although significant problems do remain:
SpringBoot: 2.4.8
SpringCloud: 2020.0.3
Camel: 3.7.5
Without Sleuth
ActiveMQ message details:
Log message ("filename", "CamelAwsS3Etag" etc present):
2021-08-16 10:10:37.889 INFO [MyApp,,] 28775 --- [umer[taskQueue]] taskQueueConsumer: ***HEADERS IN***: {CamelAwsS3ETag=39d029a87fa4c6aaee5f1de643d9f3f6, Content-Type=application/json, filename=_bl001/group0/_bl001-group0-1629104686042.zip, JMSCorrelationID=null, JMSCorrelationIDAsBytes=null, JMSDeliveryMode=2, JMSDestination=queue://taskQueue, JMSExpiration=0, JMSMessageID=ID:server-44053-1629104652998-1:3:1:1:1, JMSPriority=4, JMSRedelivered=false, JMSReplyTo=null, JMSTimestamp=1629104686350, JMSType=null, JMSXGroupID=_bl001-group0, JMSXGroupSeq=0, JMSXUserID=null}
With Sleuth
ActiveMQ message details:
Log message ("filename", "CamelAwsS3Etag" etc are missing):
2021-08-16 10:24:33.821 INFO [MyApp,,] 31553 --- [umer[taskQueue]] taskQueueConsumer: ***HEADERS IN***: {JMSCorrelationID=null, JMSCorrelationIDAsBytes=null, JMSDeliveryMode=2, JMSDestination=queue://taskQueue, JMSExpiration=0, JMSMessageID=ID:server-42561-1629105658959-1:3:1:1:1, JMSPriority=4, JMSRedelivered=false, JMSReplyTo=null, JMSTimestamp=1629105675306, JMSType=null, JMSXGroupID=_bl000-group1, JMSXGroupSeq=0, JMSXUserID=null}
Sample Java code
#Component
public class MyAppCoreRouter extends RouteBuilder {
/* Other code */
#Override
public void configure() {
from("activemq:queue:taskQueue?concurrentConsumers=" + taskNumberOfConcurrentConsumers)
.log("***HEADERS IN***: ${headers}")
.routeId("taskQueueConsumer")
.threads(taskNumberOfConcurrentConsumers)
.pollEnrich().simple("aws-s3://myapp-task?amazonS3Client=#amazonS3Client&fileName=${header.filename}&operation=getObject")
.choice()
.when(header(S3Constants.KEY).endsWith(".zip"))
.to("file://" + taskLocalUnCompressedEndpoint + "?fileName=${header.CamelAwsS3ETag}/${header.CamelAwsS3Key}")
.process(exchange -> {
String camelAwsS3ETag = exchange.getIn().getHeader("CamelAwsS3ETag", String.class);
String camelAwsS3Key = exchange.getIn().getHeader("CamelAwsS3Key", String.class);
File uniqueDir = new File(taskLocalUnCompressedEndpoint, camelAwsS3ETag);
File taskZip = new File(uniqueDir, camelAwsS3Key);
new ZipFile(taskZip).extractAll(uniqueDir.getAbsolutePath());
})
.setHeader("resourceDirectory", simple(taskLocalUnCompressedEndpoint + "/${header.CamelAwsS3ETag}")).setHeader("schedule.time", simple("${date:now}"))
.removeHeader("CamelAwsS3Headers")
.log(LoggingLevel.DEBUG, "Processing batch job ${headers}")
.to("spring-batch:importMyAppRecordJob")
.endChoice()
.otherwise()
.log(LoggingLevel.WARN, "Unexpected file type, filtering file name ${header.CamelAwsS3Key} ")
.end();
/* Other code */
}
}

You're using wrong versions of Boot, Cloud and Sleuth. To use Sleuth 3.0.x you need to use Cloud 2020.0.x and Boot 2.4.x or 2.5.x.

Related

Flux not returning any response SPRING BOOT / MONGO

I am doing the typical chat application with mongodb and spring boot, I declared a tailable cursor and all that stuff, I followed this tutorial https://jskim1991.medium.com/spring-boot-making-a-chat-application-with-webflux-and-mongodb-part-1-5ad09c88f2ce
but the problem is that my controller is not showing any response
Status is 200 but nothing there even if I add another message, I can't get it meanwhile I can see it on the console
this is my code
#GetMapping(value = "/chat/id/{chatId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Chat> getMessages(#PathVariable Integer chatId) {
return chatRepository.findByChatId(chatId).doOnNext(System.out::println)
.subscribeOn(Schedulers.boundedElastic());
}
Does anyone have a clue on what is going on ?

Spring webClient getResponseBodyAsString() is empty(over spring 5.3.13)

I'm using spring webClient for call some Rest API.
try {
webClient.post().uri("apiUrl")
.bodyValue(someParams)
.retrive()
.awaitBody<SomeResponseClass>()
} catch (ex: WebCleintResponseException) {
ex.reponseBodyAsString
}
This is work right on under spring 5.3.12.
I can take response body in ex.
but over spring 5.3.13. is not work.
resposeBody is empty.
webClient.post().uri("apiUrl")
.bodyValue(someParams)
.awaitExchange { response: ClientResponse ->
if (response.satusCode().is2xxSuccessful)
response.awatieBody<SomeResponseClass>
else if (response.statusCodes().isError)
response.awatieBody<SomeResponseClass>
else throw response.createExceptionAndAwaite
}
This working one over spring 5.3.13.
So...What is different from this? I don't find anything on release note.
https://github.com/spring-projects/spring-framework/releases/tag/v5.3.13
I want to know what is changed.
Thanks guys.
Updated
I found this commit on github.
https://github.com/spring-projects/spring-framework/commit/9197f15a306a497b3aa10c6ed48c581b3e938f58

spring boot rsocket with "message was successfully sent"

I have a client that needs to receive an Exception from the server
client:
rSocketRequester
.route("v1.data")
.data(data)
.sendAndAwait()
server:
return Mono.error(RuntimeException("test excep"))
In docs say: https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#rsocket-requester-requests "For Fire-and-Forget use the send() method that returns Mono. Note that the Mono indicates only that the message was successfully sent, and not that it was handled."
How do i get message was complete or the exception data?
Switch to a Request-Response operation instead of Fire-and-Forget, you may want to assume the result is a lightweight result object, or empty byte.
https://github.com/spring-projects/spring-framework/blob/3ed8813bbfc1678de73529a882ce535e2636519c/src/docs/asciidoc/rsocket.adoc
Java
Mono<AirportLocation> location = requester.route("find.radar.EWR"))
.retrieveMono(AirportLocation.class);
Kotlin
import org.springframework.messaging.rsocket.retrieveAndAwait
val location = requester.route("find.radar.EWR")
.retrieveAndAwait<AirportLocation>()

Apache Camel HTTP display request and response

I am using Apache Camel to load data from CSV file to a webservice. Is there anyway I can display request and response. Below is the route configuration..
I split and aggregate 100 items from array to be sent as POST body.
from(fileLocation)
.unmarshal().csv().bean(new CSVConverter(), "process")
.split(body())
.aggregate(constant(true), new GroupedBodyAggregationStrategy())
.completionSize(100)
.completionTimeout(1000)
.marshal().json(JsonLibrary.Jackson)
.setHeader("Authorization", simple(apiKEY))
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setHeader(Exchange.HTTP_URI, simple(apiURL))
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.to("https://serivceurl.com/abc");
Please let me know how can I display request and response with above route?
You can use camel log component to log headers; properties and body
ex:
.to("log:DEBUG?showBody=true&showHeaders=true")
.to("https://serivceurl.com/abc");
.to("log:DEBUG?showBody=true&showHeaders=true")
For more options pl refer: https://camel.apache.org/log.html
If you are planning to use CXF to invoke web service, out of the box logging feature can be used as below,
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
If you take a look into the org.apache.camel.component.http.HttpProducer class you'll see that there is some logging implemented.
try {
if (LOG.isDebugEnabled()) {
LOG.debug("Executing http {} method: {}", method.getName(), method.getURI());
}
int responseCode = executeMethod(method);
LOG.debug("Http responseCode: {}", responseCode);
So if you configure your logging framework (like logback) to the correct LoggingLevel you'll see what the HTTP-Component exactly does.
If you want to log it yourself you can try with the log component or the log dsl like mentioned in the other answer.

Multiple headers message using Spring Integration

How to create a instance of Message with multiple headers using Spring Integration MessageBuilder class
Found the below information but it is only for single header
http://docs.spring.io/autorepo/docs/spring-integration/3.0.0.M3/reference/html/messaging-construction-chapter.html
Please use the current documentation - your link is not even to a released version, but a milestone of the 3.0.0 release. The current version is 4.2.0.RELEASE.
You can add as many headers as you want...
Message<String> message4 = MessageBuilder.withPayload("test4")
.setHeader("foo", 123)
.setHeader("bar", 456)
.build();
You can also use createMessage method. Pass MessageHeaders as second argument.
Map<String,Object> headers = new HashMap<>();
headers.put("foo", 123);
headers.put("bar", 456);
MessageBuilder.createMessage(payload, new MessageHeaders(headers));

Resources