Find out which endpoint sent a REST call - java

I'm trying to create a visualisation of REST calls among several internal and external services/servers. I'd like to know which endpoint called which other endpoint. I figured that the only way to do this is to do this on the caller side, because the receiver does not have any information about the caller endpoint.
Here's my thinking:
I create an object like RestTemplate and call the method.
I create an Interceptor or something like that, which will extract the information from the RestTemplate.
My problem is that I'm not sure how to find out which REST endpoint called the RestTemplate method. The RestTemplate (or other similar object) call could be called in nested methods, so for example the endpoint could invoke a private method, which then calls the external service itself.
Is there any way how to get this information? Or am I maybe just thinking too hard and there is an easier way to do this?
Example:
#GetMapping("/hello")
public String hello() {
methodThatCallsOtherEndpoint("something.com/weather"); // this method inside itself calls an endpoint
logRestCall("localhost:8000/hello", "something.com/weather"); // how do I do this automatically without having to type it myself?
return "hello";
}
Thanks for any help.

If these services/servers have a static IP you can possibly, tag them by their IP address?

You can use Spring Sleuth to trace the relationship between different REST calls.

Related

Micronaut: how to set an HttpClient URL after injection

I have the following method:
public HttpResponse<String> sendMessage(#NonNull String url, #NonNull String message) {
try (HttpClient client = HttpClient.create(new URL(url))) { ... }
}
Basically, what I want to achieve is to create the HttpClient with a URL that comes as a parameter to the method. It cannot be a property in a config file since it depends on some external conditions.
If I check the docs for the HttpClient.create() method it says that it should not be used within a Micronaut environment, and that the client should be injected instead. However, the problem is that if it's injected I cannot initialize it with my custom URL.
Another problem is that if I keep it with the HttpClient.create() method, if I want to unit test the class, I cannot mock the HttpClient. The best option would be to inject it via constructor to be able to create the tests.
What options do I have? I haven't been able to find this type of initialization. It looks like everyone uses a fix URL? 😅
Thanks!
I'll answer it myself. Apparently, you can specify in the request passed to the HttpClient methods (retrieve, exchange, etc.) both the relative and full URLs. So it doesn't matter what you put when you inject, instantiate the client.

Used a token to secure API without authentification

Objective
When a person creates a resource (no need to connect), she receives a unique token, which she must then transmit to each request she sends for information about her resource.
Question
There is a simple way to do that with Spring? Indeed, all tuto I found and read used an authentification with username and password.
Already tried
My first idea was to create a token at the end of POST methods (store it into database), put it into each GET requests and check if requestToken == databaseToken.
However, I don't think that's the best way to do it.
So, can you help me and advise me to solve the problem?
Thanks a lot!
There are multiple ways.
Using the #SessionAttributes annotation:
The first time our controller is accessed, Spring will instantiate an instance and place it in the Model. Since we also declare the bean in #SessionAttributes, Spring will store the instance.
You will get it inside controller's handler method thru #ModelAttribute.
Or, you can try this route:
#RequestMapping(value = "/test")
public String handler(HttpSession httpSession) {
httpSession.getId(); //this will give you unique identifier that you can set back to object that you send to front end and can share the same ID between requests.
}
https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSession.html#getId--

Testing Rest Api methods

I'have to test the functions in rest api class that i created, I'm unable to get the functions of the created api class inside the test class, I haven't do the testing coding before. I need some guides to follow .
#POST
#Produces("text/plain")
#Path("/notifications/login/")
#HeaderParam("encoded")
Response login(#HeaderParam("encoded") String encoded, #QueryParam("tenantId") String tenantId) throws NotificationManagementException;
Its a function that i created, im not giving whole function body here, i need to know how to test this function. I'm giving a request call in javascript.
Unless there is some reason why you really don't want to, you could make the method public, and then you would be able to see it inside the test class.
i.e.
public Response login(...)
In the test you can then make a new instance of the class and call the method normally.
e.g.
#Test
public void shouldDoSomething(){
SomeClass someClass = new SomeClass();
someClass.login(...);
//some assertions or verifications
}
Two ways:
Use Postman to send post request.
Follow Spring-rest-client to create a rest client for test.
You can test with Postman a great chrome extension tool for REST based APIs. Run your server and hit the request from Postman. The image shows how to make a request.

Spring RestController - Intercept method invocation

I have a Spring RestController with an endpoint consuming JSON. It converts the JSON to an object, and validates the fields (using bean validation):
#RequestMapping(method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<?> myMethod(#Valid #RequestBody MyEntity e) {
...
}
I'd like to intercept the invocation of this method only after the conversion and validation has taken place to have access to MyEntity and possibly abort execution.
Using Spring interceptors, I can only intercept the request before it reaches the method - so I don't have access to the validated bean. I can use Spring AOP and add a pointcut, but is there a way of aborting the execution nicely – ideally without throwing an exception?
This functionality is outside of the business logic of this method, and is temporary – so I want to separate it.
A possible solution is to create a bean proxy between the Spring's proxy object and an object of your original class. To do that you need:
Implement your own BeanPostProcessor.
Spring will call its postProcessBeforeInitialization() method right after it has instantiated an object of your class, but before wrapping and initialising it. In this method, identify which beans must be provided with your functionality. It's often done by means of your custom annotations on methods or classes.
Create your own proxy for the beans from step 2. You can use cglib or something more modern for that. Your proxy will make all the checks you need and then call the parent's method if everything is ok, or just silently return from the method if something is wrong.
Return your proxy from postProcessBeforeInitialization(), it will instruct Spring to use it instead of the original bean.
As the result, Spring will create proxy of your proxy, not of the original object. When a request arrives, Spring will do the validation and send it to your proxy. Your proxy will make all your custom checks and decide on whether to send it further to your original class or to return immediately.

Interfere in Jersey REST life cycle

I have variant resources that all extend BaseResource<T>
#Component
#Path("/businesses")
public class BusinessResource extends BaseResource<Business>{
#GET
#Path({businessId}/)
public Business getBusiness(#PathParam("businessId") Integer businessId){..}
}
#Component
#Path("/clients")
public class ClientResource extends BaseResource<Client>{
#GET
#Path({clientId}/)
public Client getClient(#PathParam("clientId") Integer clientId){..}
}
I would like, that when there is a call to
/businesses/3, it will first go through a method that I will write which validates the T object and if everything is ok I will tell jersey to continue handling the resource.
Same goes for Client.
I can't use a regular servlet/filter - since it's being called BEFORE jersey servlet and I wouldn't know which resource is being called.
What is the best way to do it in Jersey?
Is there a place to interfere between knowing the method that jersey will invoke and the invokation?
There are 4 basic http methods in REST, namly GET, PUT, POST, DELETE.
Your annotation tells Jersey what method to call when a http request occurs. Jersey looks up the target URI in the request and matches it against your model. If the request is a http get it will execute the method annotiated with #Get from the class with the correct #Path annotiaton.
Usually you dont want to grant access to your resources in this annotated method directly. A common (may not perfect) way is to implement a DAO class that handles access to your resources, and of course does the validation before it returns the resource back to the #Get annotated method, which will itself only pass the resource to the client. So you will get another layer in your application between persisting (SQL, etc) and the client interface (Jersey).
You can use jersey 2.x ContainerRequestFilters with NameBinding. After having matched the resource, the bound filter will be executed prior to executing the method itself.
You can see the Jersey user guide, which states that it is possible:
Chapter 9.2.1.1 explains about PreMatching and PostMatching filters and chapter 9.4 chapter shows the execution order of jersey filters.
See my post for the implementation where I had the problem to make the filters with jersey 2 work.

Categories

Resources