Spring Cloud Stream router app - spring

I've been playing with the router sink in the Spring Cloud Stream App Starters, and I have a question about content type.
I'm sending a JSON string to the router, and I would like to write a SpEL expression to determine the routing. However, even when I run this by modifying the JUnit test cases in the project, the "payload" shows up as a string, not parsed JSON. When running JUnit test case for the filter processor, also in the Spring Cloud Stream App Starters, all I need to do is pass valid JSON in a string, and the payload is a LinkedHashMap. (A regular string, like "Hello, world!" makes the payload show up as a String type.)
I really want my router to have a HashMap payload as well. Otherwise, I can't figure out how to write my SpEL expression. I learned earlier how to set a content type on Spring Cloud Stream, and so when I deploy the router in Spring Cloud Dataflow, I try to set it via:
stream deploy --name router-flow --properties "app.router.spring.cloud.stream.bindings.input.content-type=application/json"
However, the payload stills shows up a string. Where am I going wrong?

You can use the #jsonPath() SpEL function - it's automatically registered for use by Stream apps.

Related

how to use httpclient processor in Spring cloud Dataflow

I am trying out spring cloud dataflow. My specific usecase is to dump the response from a GET request to a log. I am trying to use the httpclient processor for this. But i dont understand how come it is a processor, and not a source. If it a processor, what should be the input source to it. Any example would do great.
It requires an incoming Message to trigger the http request. The message may specify the URL, HTTP Method, etc. using SpEL expressions but these may also be statically configured as well. For example, you can use the time source to trigger a request every second.

Is it possible to get exactly once processing with Spring Cloud Stream?

Currently I'm using SCS with almost default configuration for sending and receiving message between microservices.
Somehow I've read this
https://www.confluent.io/blog/enabling-exactly-kafka-streams
and wonder that it is gonna works or not if we just put the property called "processing.guarantee" with value "exactly-once" there through properties in Spring boot application ?
In the context of your question you should look at Spring Cloud Stream as just a delegate between target system (e.g., Kafka) and your code. The binders that enable such delegation are usually implemented in such way that they propagate whatever functionality supported by the target system.

Spring integration : handle a File given in arguments

I have an existing Spring Integration app, which handle files coming from FTP with InboundChannelAdapter. I want to plug Spring boot to this app to use it now like this :
java -jar app.jar <filetohandlepath>
So, the application start with this command, and stop at the end of the treatment. But my question is how can I run my existing channels (ServiceActivator) to give this file to handle ?
I can use an InboundChannelAdapter, but I think the poller can be a problem
Maybe a Gateway ? But I don't think this can be a solution
Or I need to build and send a Message manually ?
What about Spring Boot, to handle the argument ? I need to build the message into the main method, or in an other class with a scan ?
I just need to know the best way to design my app.
Your FTP Inbound Channel Adapter polls remote file to local files and sends them as payload of messages into some channel for the mentioned Service Activator. Of course you can send message manually to the same channel with the payload accepted by that Service Activator subscriber. Yes, you can use #MessagingGateway to separate Messaging concern from your code. Or you can just rely on the MessagingTemplate and its convertAndSend() API. Any convenient way for you is acceptable: https://docs.spring.io/spring-integration/docs/5.0.4.RELEASE/reference/html/messaging-endpoints-chapter.html#gateway
As for Spring Boot and command line arguments, you definitely can take a look into the CommandLineRunner: https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#boot-features-command-line-runner

Camel routes from activemq to rest endpoint

I am trying to use Spring Boot 1.5.2.RELEASE + Camel (Spring Boot starter) 2.19.2 to listen to ActiveMQ queue and then post the message to a rest endpoint URL (POST method) as its body. What would be the best possible way to achieve this?
I have gathered pieces of information and am trying to tie it all together but getting a bit confused.
Here is what I have gathered for Camel Rest DSL, I am not too sure if camel below is creating these rest services via this or is it just an already exposed endpoint, in my case it is an already exposed endpoint
rest("/basePath")
post("/someEndpoint").to("direct:restEndpoint")
Using the above is what I have gathered for ActiveMQ which I am not too sure is correct
from("activemq:queue:<queue_name>").to("direct:restEndpoint")
But again, I am not too sure how to listen to the ActiveMQ queue for new messages or is it something that Camel would do by default always? Additionally, I need to pass the message as a post body to my rest endpoint. I also saw some references to camel-http4 and camel-http as well and I am completely confused.
Any assistance would be greatly appreciated.
Some confusion is common when starting to use Camel, but your final solution will look something like:
from("activemq:queue:my-route")
.process(/* change the in/out messages if you need to */)
.to("http4://your-endpoint.com");
Don't try to simply copy/paste this code until it works. My Camel rule of thumb is: always read the component documentation and try playing with it using it in your software. In your case I suggest:
Read ActiveMQ component docs and try reading from ActiveMQ / writing to a Log;
Generate some input from a Timer and send to your Rest endpoint using HTTP4 Component;
Your first routes will take some time for simple things but you will get on flow quickly.

Spring XD stream that responds to an HTTP POST

I would like to create a stream in Spring XD that starting with an HTTP source would use the result of the stream execution as the body of the response.
In the following example, I would like to know if there is anything I could use as sink after I upper case in the transformer so that the body of the response of the original http post is that upper cased entity.
stream create --name httptest --definition "http | transform --expression=payload.toUpperCase() | ??" --deploy
Currently, when I use it, putting the log module as the sink, the returned body is null.
Thanks,
David
No; that is not currently supported; the stream is a one-way street.
You can use a stand-alone Spring Integration, or Spring Integration Java DSL app (perhaps a Spring Boot app which provides a fast on-ramp with the web and integration starters) to provide that functionality.

Resources