I'm using Spring Integration 4. I was hoping to define a contract for various integrations whereby an integration needs to implement a generic interface like:
public interface Integration {
Object execute(Map<String, Object> inputs);
}
Then to define an integration you define a gateway:
<int:gateway service-interface="com.whatever.Integration" ... >
I've got this working but am stuck trying to understand how to handle the execute method's return value. The first integration I built sends an email and so doesn't really have a return value, i.e. the last element of the workflow is a non-MessageProducer mail sender: <int-mail:outbound-channel-adapter ... >.
If I change the execute method's return type to void the integration runs fine, but as soon as I change it to Object, the integration runs but never returns. I assume this is because it's waiting for something on the reply channel.
For these type of non-result-producing integrations, is there a way to force a true value to be returned or something? I was thinking of trying something like <int:transformer expression="true"> but I can't put this in my chain after the <int-mail:outbound-channel-adapter> because the later doesn't produce a value and so can't precede anything in the chain.
Thus, I'm a bit confused on how to handle non-MessageProducer elements in general. Any help is much appreciated.
p.s. If anybody has feedback on the integration architecture proposed above, feel free to chime in on that in the comments too.
TBH your client should know if a reply is expected. In which case, add a second method that returns void.
Or add reply-timeout=0 to the gw and you'll get null returned.
The problem with the latter is you can't tell if a reply producer timed out with requires-reply=false or the ultimate consumer would never return a reply.
Related
I am using the io.lettuce.core library and I am having trouble subscribing to a channel using the RedisPubSubReactiveCommands interface.
I have a StatefulRedisPubSubConnection and an active redis cluster which I am attempting to subscribe to.
connection.sync().subscribe("channel") works fine, as does connection.async().subscribe("channel"). However, when I use the reactive 'hot observable' interface provided by lettuce like so:
connection.reactive().subscribe(channels).subscribe();
connection.reactive().observeChannels().doOnNext(this::notifyObservers).subscribe();
It will not register as a subscription action on redis. I feel like I'm following the example given in the lettuce documentation closely.
I'm programming for an interface that accepts a hot Flux Observable and I'm getting close to wrapping the sync or async connection interfaces with my own reactive wrapper and throwing them in the pipe. What am I doing wrong here?
In case anyone else runs into this same problem, it turns out I was passing in a Set<String> Object into a function that accepts a varargs Object... and didn't realize it was treating the entire collection as a single element instead of parsing it as a varargs array.
I'll leave this up for others to learn from my dumb mistake.
I am bit confused, whether I should validate the data returned from the remote call to another Microserivce Or should I rely on the contract between these Microservice.
I know putting extra checks will not hurt anyone but I would like to know what's the right approach?
in theory, you don't even know how the data you get back from a microservices is created since you only know the interface (API) and what it is returning.
By that, you should take the data response of this API as given.
Sure, additional validation may not harm in the first place.
But consider a case where some business-logic got changed which lead to a change in one of the services. Could be a simple thing like adapting the definition of a KPI leading to a different response (datawise, not structurewise) from the microservice.
Your validation would fail too as false-positive. You would need to adapt your validation for basically nothing.
So we are using the nice #RabbitHandler annotation in spring-amqp to create endpoints that resemble the coding style of RestControllers but work with Rabbit under the hood. Its all very nice and neat and it works great especially with dynamic resolution of method handlers based on signatures. However we are facing a bit of a controversy here.
So imagine the following method
#RabbitHandler
public void handleEmailDto(EmailDto message) {
System.out.println(message);
}
This will get handled by fromMessage method on the MessagingMessageConverter.java class. At a certain point down the chain the type information of the message will be required in order for the handler resolver to determine which method to call with the payload of the message, and what class to serialise the payload to. The thing is we are using MappingJackson2MessageConverter. Nevertheless, we need a populated ____TypeId____ prop of the message with the fully qualified name of the type of the class. Thats not a problem either. very well engineered and thought out.
The problem comes when this class is not on the classpath. This is actually a huge pain for us as we are working in a microservices environment and some of our services are completely decoupled. That is.. we do not want to have "common" artefact which holds our data domain, just so we can use it at runtime in both the sender and receiver of the message. I have traced through the code, and I see how this hole type situation has been handled and why it is done the way it is.
However from architectural perspective, this is quite limiting... Does that mean that we definitely need to share code between microservices that are quite decoupled otherwise just to satisfy serialization/deserialization/method resolution logic ?
Maybe I am missing something or overlooking another way of doing it. If that is the case, I am certainly opened to suggestions. Thanks in advance for the help.
1.6 has a new feature where the argument type of the #RabbitListener is supplied to the JSON message converter which it can use instead of type id headers.
Unfortunately, this mechanism doesn't work with #RabbitHandlers because the hander method is (has to be) determined after the payload has been converted.
You don't need the source type on the class path, you can configure the converter to use a different type; see this test case for an example where we send a Foo1 and receive a Foo2.
The listener is here and the listener factory configuration with customized converter is here. See how the idClassMapping is set up to convert to the Foo2 type.
Obviously the type has to be compatible with the source type, but it doesn't have to be the same class.
I am fairly new to many of the concepts and technologies being used in this question so I would appreciate a little understanding and help for a beginner from the community. I am using the Play Framework version 2.1.3 and I need to POST data to a RESTful web service so that it can be inserted into a remote database. An XML response will be returned indicating either success or failure.
I am sure you are aware that the documentation for the Play Framework is quite lacking and is in no way helpful to beginners, therefore I am unsure of how to accomplish this task with best practices in mind. I am looking for a Java solution to this problem, I do not have the time at present to learn the Scala language. My experience with Web Services is fairly limited, normally I would implement a DAO design pattern (or use one of the many available ORM libraries depending on needs) within my application and use JDBC to connect directly to the database. That is not an option here.
My first question would have to be, is there a recommended design pattern for accessing web services? Then, considering the Play MVC framework, how would one best implement such a design pattern, package the data (assuming the application has already captured and validated data from the user), send it off and process the responses back to the user?
I know it is a fairly lengthy question however my intention behind this is to create a knowledge base of sorts for beginners who can easily come in with limited experience, read, understand and replicate what they find here to produce a working solution. Having searched the web quite extensively, I have found a few disjointed snippets but nothing concrete involving these technologies and no up-to-date tutorials. Thank you for your time.
Creating requests is straight-forward. First you provide a URL. There are various methods to add content types, query parameters, timeouts, etc. to the request. Then you choose a request type and optionally add some content to send. Examples:
WSRequestHolder request = WS.url("http://example.com");
request.setQueryParameter("page", "1");
Promise<Response> promise = request.get();
Promise<Response> promise = WS.url("http://example.com").post(content);
The complicated part is to send it and use the response of the request. I assume you have a controller that should return a Result to the user, based on the web service's response. The result is usually a rendered template or maybe just a status code.
Play avoids blocking by using Futures and Promises. The controller's async method takes a Promise<Result> and returns a result (the future value) at some point later. A simple to use promise is provided by the get and post methods shown above. You don't need to care about their implementation, you just need to know that they promise to provide a Response once the request is complete.
Notice the problem here: When creating a request with WS.url("...").get() it will give you a Promise<Response> even though async takes a Promise<Result>. Here you have to implement another promise yourself, which will convert the response to a result using the map method. If you follow the Play documentation, this will look a bit confusing, because Java doesn't has closures (yet) and everything has to be wrapped in a class. You don't have to use anonymous classes inside the method call though. If you prefer more clean code, you also can do it like this:
return async(
request
.get() // returns a `Promise<Response>`
.map(resultFromResponse) // map takes a `Function<Response, Result>` and
// returns the `Promise<Result>` we need
);
The object resultFromResponse may look like follows. It's actually just like a cumbersome definition of some kind of callback method that takes a Response as only argument and returns a Result.
Function<Response, List<T>> resultFromResponse =
new Function<Response /* 1st parameter type */, Result /* return type */>() {
#Override
public Result apply(Response response) {
// example: read some json from the response
String message = response.asJson().get("message");
Result result = ok(message);
return result;
}
};
As #itsjeyd pointed out in the comments, when calling webservices in Play 2.2.x you don't wrap the call in async any more. You simply return the Promise<Result>:
public static Promise<Result> index() {
return request.get().map(resultFromResponse);
}
Although I have tagged this as a java/spring question it can be easily asked of any mvc framework with stateless controllers. I know rails uses simple stateless controllers for instance so perhaps you guys know how to best solve this problem. I can best describe the problem with java/spring mvc which is the implementation - forgive the java jargon.
The issue
We are having trouble coming up with a satisfactory way of performing stateless-to-stateful handover in spring mvc.
In essence given a structure like:
Model: Unit
With the states: withdrawn, available, unavailable
And the operations: getOutline() and getHelp()
Controller: UnitController
with operations: displayOutline() and displayHelp()
We need a way to check the state of the unit before we execute the operation displayOutline() (because the unit itself may be withdrawn and so the user should be forwarded to a withdrawn page).
We have tried to do this a number of ways including:
The dead simple way (any language)
All methods in the controller that require an ‘available’ state unit call a method isAvailable() in the first line of its implementation. Obviously there lots of replication here, it reeks.
The AOP way (Java specific)
An #Around advice can be created called UnitAccess which does the check and reroutes the control flow (i.e. instead of calling proceed() which would invoke the underlying method it calls another method on the controller). This seems like a hack and not really what AOP if for, it does remove the replication but adds complexity and reduces transparency.
An Interceptor (Provided by servlet architecture but probably doable in other frameworks)
Which checks the unit state and essentially changes the actual URL call. Again this does not seem right. We don’t like the idea of invoking model logic before getting to a controller.
We have thought about
Command Pattern
Creating a command pattern structure which (with the use of inheritance) can return a withdrawn view or valid displayOutline view. As the execute method will perform the checks in a super()call and the specific logic inside the concrete commands. Ie creating a object structure like
DisplayOutlineCommand extends UnitCommand
public void execute(){
super();
// must be ok, perform getOutline()
}
And finally, using a custom Exception
Calling getAvailableUnit() on a service level object which will do the checks for availability, etc before returning the unit. If the unit is withdrawn then it will throw a UnitWithdrawnException which could be caught by the servlet and handled by returning an appropriate view. Were still not convinced. We are also not hot on the idea of using an exception for normal flow control.
Are we missing something? Is there an easy way to do this under spring/another stateless controller framework?
Maybe I'm missing the point, but why should a user come to the controller if the Unit is withdrawn?
I would argue it is best to ensure that normally pages don't link to a controller that require the Unit to be 'OK', if that Unit is not 'OK'.
If the state of the Unit changes between the time the referring page is rendered and the actual call comes in to the controller (it is not longer 'OK'), then the use of an exception to handle that event seems perfectly fine to me (like having an exception when an optimistic locking error occurs).
Perhaps you haven't described the whole problem, but why not put the check in displayOutline() itself? perhaps route to a displayOutlineOrHelp() method, which looks essentially like
ModelAndView displayOutlineOrHelp(...) {
Unit unit = ... //code to get the unit the request refers to
return unit.isAvailable() ? displayOutline(...) : displayHelp(...);
}