I have a bunch of microservices written using Java and Spring Boot 2.
generation-service, creates an object with a bunch of info and sends it to the next service (in the body of a request pointing to the next service endpoint) that we'll call receiver-service.
Now, I want to test the object generated by generation-service.
Is there any way that I can intercept the request created by generation service and redirect it to a test object? (Spawning a service and pointing generation-service to this endpoint is not an option as I cannot spawn new services.)
Please notice that the post "How to mock RestTemplate in Java Spring?" doesn't solve my problem as I am not interested in testing the response, but the request to the next service. With Rest template I can instead check just the feed that is just OK/FAILED.
Related
Let's say we have three applications called A,B and C B is an email sending application,and it has a method to send an email like sendEmail(String email) now I need to call that function from A through the rest API of C(Here A and B are rest consumers who can use C as a Common API).Can I do something like that?. I mean you can see there is no any direct communication between A and B so I am simply asking can I use rest API as the one who links them ?I know there is rest template and other rest consuming technologies available to do the consuming tasks,but in all those scenarios there is only two way data exchanging ,which is most probably with a client and a server(Rest service provider and consumer) and there won't be something like server is calling the client,because in every time client is calling the server methods(Get,post,put,delete) .but here you can see we need some kind of a method to call the sendEmail(String email) function of email sending application through the server so basically to do so server(Rest services provider) needs to have an object of that email sending application.How is this possible?
If you doesn't understand the scenario please tell me at-least is it possible to invoke a method of a rest consumer from rest API(rest server)? , because normally we call the methods of rest API from rest consumer [I am using spring boot]
In any case you need to invoke REST method to invoke your sendEmail method because you client is also a REST client and it can communicate with REST method
If you need A to call B directly, you need to have B expose the email sending capability as a REST Endpoint if it doesn't already exist.
Then you can use the Spring Rest Template capability to call application B from A. Make changes to A to use Spring Rest Template and then make the relevant call.
I want to call a service to Validate(Validation service) before routing the actual request to desired service.
Lets consider two different scenarios:
If the Validation service returns Valid, then call respective service (In this case service A).
If Validation service returns Invalid, then return response bad request to user (No need to call service A)
Please help me finding correct configuration (or coding in which filter) to be done, to call validation service for every request.
I am confused about how an infinite loop of feign calls might behave.
An example:
Assume I have 2 APIs, A & B.
if I call API A, which in turn calls API B via a feign HTTP call, which in turn calls API A again via feign, will it recognize this and break the call chain?
Quick flowchart of calls:
A -> B -> A -> B ... Repeat infinitely?
I have not tried this code, it is just an idea。
But I am assuming that spring-cloud-starter-feign will provide some methods to resolve this problem? Is this assumption correct?
#PostMapping(RestJsonPath.API_A)
ResponseEntity<byte[]> apiA();
#PostMapping(RestJsonPath.API_B)
ResponseEntity<byte[]> apiB();
Will it execute until it times out or hystrix will stop it?
TL;DR:
Feign will keep the connection open on the initial request from A to B until the pre-configured timeout kicks in. At this point, Feign will time out the request and if you have specified a Hystrix fallback, Spring will use your Hystrix fallback as the response.
Explanation:
spring-boot-starter-feign provides an abstraction layer for writing the HTTP request code. It will not handle potential loops or cycles in your code.
Here is an example spring boot feign client from their tutorials website for demonstration:
#FeignClient(value = "jplaceholder",
url = "https://jsonplaceholder.typicode.com/",
configuration = ClientConfiguration.class,
fallback = JSONPlaceHolderFallback.class)
public interface JSONPlaceHolderClient {
#RequestMapping(method = RequestMethod.GET, value = "/posts")
List<Post> getPosts();
#RequestMapping(method = RequestMethod.GET, value = "/posts/{postId}", produces = "application/json")
Post getPostById(#PathVariable("postId") Long postId);
}
Notice first that this is an interface - all the code is auto generated by Spring at startup time, and that code will make RESTful requests to the urls configured via the annotations. For instance, the 2nd request allows us to pass in a path variable, which Spring will ensure makes it on the URL path of the outbound request.
The important thing to stress here is that this interface is only responsible for the HTTP calls, not any potential loops. Logic using this interface (which I can inject to any other Spring Bean as I would any other Spring Bean), is up to you the developer.
Github repo where this example came from.
Spring Boot Docs on spring-boot-starter-openfeign.
Hope this helps you understand the purpose of the openfeign project, and helps you understand that it's up to you to deal with cycles and infinite loops in your application code.
As for Hystrix, that framework comes in to play (if it is enabled) only if one of these generated HTTP requests fails, whether it's a timeout, 4xx error, 5xx error, or a response deserialization error. You configure Hystrix, as a sensible default or fallback for when the HTTP request fails.
This is a decent tutorial on Hystrix.
Some points to call out is that a Hystrix fallback must implement your Feign client interface, and you must specify this class as your Hysterix fallback in the #FeignClient annotation. Spring and Hystrix will call your Hystrix class automatically if a Feign request fails.
UPDATE: I upgraded the code to Java 8 without too much of a hassle. So I would like answers tied to Spring 4/Java 8.
I am working on a task to fix performance issues (Tomcat max thread count of 200 reached at a request rate of just 400/s, request latencies building up periodically, etc) in a Tomcat/Spring 4.2.4/Java 8 web mvc application.
It is a typical web application which looks up Mysql via Hibernate for small but frequent things like user info per request, then does actual data POST/GET to another web service via RestTemplate.
The code is in Java 7 style as I just migrated to Java 8, but no new code has been written in that style yet. (I am also back using Spring after ages, so not sure what would be best).
As expected in a normal such application, the Service layer calls other services for info, and then also passes that along to a call to the DAO. So I have some dependent callbacks here.
Setup
#EnableAsync is set
The flow of our Http requests goes from Controller -> Service -> DAO -> REST or Hibernate
Sample flow
Say Controller receives POST request R and expects a DeferredResult
Controller calls entityXService.save()
EntityXService calls userService.findUser(id)
UserService calls UserDAO.findUser(id) which in turn talks to Hibernate
UserService returns a Spring ListenableFuture to the caller
EntityXService awaits the user info (using callback) in and calls EntityXDAO.save(user, R)
EntityXDAO calls AsyncRestTemplate.postForEntity(user, R)
EntityXDAO receives DeferredResult> which is our data abstraction for the response.
EntityXDAO processes the response and converts to EntityXDTO
Eventually somehow the DeferredResult is sent back through the same chain as a response.
I am getting lost at how in step 3, EntityXService asynchronously calls UserService.findUser(id) with an onSuccess callback to EntityXDAO.save(user, R). However, EntityXDAO.save(user, R) also now returns a DeferredResult from the AsyncRestTemplate.
Questions:
Is using DeferredResult a good way to get concurrency going in this application?
Is using Guava's ListenableFuture or Java 8 CompletableFuture going to help make it better in anyway, rather than using DeferredResult?
My BIGGEST question and confusion is how to arrange the DeferredResult from one service lookup to be used by another, and then finally set a DeferredResult of a completely different return type for the final response?
Is there an example of how to chain such callbacks and what is the recommended way to build such a flow? If this sounds completely wrong, is Java 7 going to be the right choice for this?
Thanks in advance!
I am using jersey client to send POST requests to a third party webservice. Since creating jersey clients is expensive, I am doing this inside the constructor of a service client class which is Spring managed. My thinking is that when my server starts up, Spring will create my service client bean, which in turn will cause the constructor to be invoked and so my jersey client will be created once. As long as the server is up, this jersey client will be responsible for sending out the requests and no further client initializations are required. However, I will be creating a new webresource for each call as creating jersey webresources is much cheaper.
package com.mypackage;
//Bunch of imports
class MyWebserviceClient {
//jersey client member variable
private Client jClient;
public MyWebserviceClient(){
//Create jersey client
jClient = Client.create();
//Other stuff
}
public void sendRequest(){
WebResource wr = jClient.resource(someUrl);
//Use the webresource to make webservice call
}
}
MyWebserviceClient is spring managed as such in the Spring config xml:
<bean id="myClient" class="com.mypackage,MyWebserviceClient"></bean>
The bean myClient will then be injected into the appropriate place where the service call needs to be made.
My questions
1) If my application is dealing with thousands of requests per hour is it efficient enough to handle all the requests with just one jersey client.
2) Do I need some kind of jersey client pool so that a large number of requests are taken care of more efficiently. If so, is there a way to do it?
3) I would like to know in general how multiple requests coming in from the end users are handled on the server side. Each request is a separate thread of execution on the server and all of them have access to the same jersey client object. If the jersey client object is busy with one such request, are the other requests from different end users going to wait till a response is received for the ongoing request?
4) Any better alternative to the one I am using.
Your thinking is right on track.
1 - Yes, and it is recommended to reuse a client instance:
from https://jersey.java.net/documentation/1.18/client-api.html#d4e623:
Client instances are expensive resources. It is recommended a configured instance is reused for the creation of Web resources. The creation of Web resources, the building of requests and receiving of responses are guaranteed to be thread safe. Thus a Client instance and WebResource instances may be shared between multiple threads.
2 - No need, the client itself can handle the requests. In the case of asynchronous requests, it internally uses a thread pool that is configurable.
3 - The Jersey client is thread safe, so threads will not block each other
4 - You can also consider providing the client as a dependency to MyWebserviceClient, and possibly reuse the same client between multiple classes