I am presently working on an application which has an external dependency on micro-services, there are around 25 microservices, which are administrated via a eureka instance, every microservice has around 3-4 controllers.
This is an external dependency for me and blocks my work if it goes down, also I am unaware of the code ad logics for these microservices.
Currently, I am looking for a solution which can act as a simulator for these services in there absence, some application which can intercept and log, all the request and response to/from the external services, and in absence of these services it can match the last response to a requests from log and provide that response.
you should check mockito or any other mock framework
just record and serialize the result e.g. with xstream and respond with the deserialized xstream result and modify it slightly by your needs.
This is the quickest solution for mocking remote services.
Related
So I've been working on a microservice-based architecture in Spring and my prototype uses Spring's WebClient to explicitly send a request to a different service and await a response. Recently I've tried to migrate the project to some RPC-based service remoting technology, and I figured out that all the technologies that just work out of the box (Hessian, RMI, HTTP Method Invoker) are deprecated, and the ones that Spring encourages to use (JAX WS and Spring WS) require to learn multiple additional DSLs and spend a week trying to deeply understand their principles just to export a service to the web. Also, just using WebClient feels far more flexible and seems to leave a lot of room for further improvements. Will creating my own REST-like APIs for each of the microservices and then explicitly using WebClient to call them turn my code into instant legacy spaghetti mess or is it a normal thing to do?
P.S. By "more flexible" I mean, for example, an ability to set up a reverse proxy load balancer with caching and different actions for different methods in between the actual microservice nodes and the requesting service, etc.
I would like to know if it's possible to create a spring boot microservice between an old java 1.8 monolithic API and a Spring Boot Backend (React for the front but it doesn't matter).
Here is the idea:
RestController inside the monolithic API ---> Microservice (Springboot) ---> Back API (Springboot)
For the use case:
Click on the button of API A
Binding data to the RestController of the API B
Send the same data to an API C
I don't think it's possible through a RestController due to the Cross Origin but it could be great to find a solution.
What do you think?
TL;DR Assuming these are all synchronous remoting calls I think this should not pose too many problems, apart from maybe latency if that's an issue and possibly authentication.
The RestController in your Monolith A can call the REST API implemented by your Microservice B as long as it can reach that endpoint, and knows how to map/aggregate the data for it. The Microservice B can in turn call your Back API C.
I assume the calls will all be blocking, meaning each thread processing a request will be paused until a response is received. This means that the call to A will have to wait until B and C are all done with their processing and have sent their responses. This can add up (especially if these are all network hops to different servers). If this is a temporary set up to apply the strangler pattern to part of the monolith then the latency might not be an issue for the period in which calls are still routed through the monolith.
Cross origin resource sharing (CORS) is only a concern when retrieving content from a browser window as far as I know. In the described situation this should not be an issue. Any client calling Monolith A will not be aware of the components behind it. If one or more oof the three components are not under your control, or not managed/authenticated in the same way then you might run into some authentication challenges. For instance, the Microservice might require a JWT token which the Monolight might not yet provide. This would mean some tinkering to get the components to become friends in this respect.
Strangler pattern
I am using TestNG to write test cases.
I want to write a test case for my Rest API, and my server is not up. It means no one is giving me a response.
I have URL which I can hit. I know the response also what should come as a response when I hit the URL.
It is possible using directly hit the API, fetch the response and then from the response fetch the body and check it whether it is true or not?
I don't want that way means my server is not.
Is this any way to mock the Rest Service and implement that?
There are numerous ways how to approach your issue. Whether they would be easy or complicated depends on what was the way your service under test was implemented.
You can configure the required mock using Soap UI for example or WireMock. Unlike the previous ways you can build your mocks automatically if the developers used frameworks like Swagger (Swagger mock server) to describe the REST service.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
What is the best way to test REST services in Java? What approaches and tool set do developers usually take?
Also if you are writing rest clients that call into third party REST services. What is the best way to test REST clients. Do you have JUnit tests that communicate with a third party REST service. You could run into the risk of service not being available/or production REST service cannot be access without certain credentials.
I suggest that you take a look at REST Assured for automated testing of REST services. The following example is copied from it's web page:
For example if your HTTP server returns the following JSON at “http://localhost:8080/lotto/{id}”:
{
"lotto":{
"lottoId":5,
"winning-numbers":[2,45,34,23,7,5,3],
"winners":[
{
"winnerId":23,
"numbers":[2,45,34,23,3,5]
},
{
"winnerId":54,
"numbers":[52,3,12,11,18,22]
}
]
}
}
You can easily use REST Assured to validate interesting things from response:
#Test public void
lotto_resource_returns_200_with_expected_id_and_winners() {
when().
get("/lotto/{id}", 5).
then().
statusCode(200).
body("lotto.lottoId", equalTo(5),
"lotto.winners.winnerId", containsOnly(23, 54));
}
See the getting started and usage guides for more information.
If you have implemented your server app using Spring Boot, you may also find the blog post about Integrating Testing a Spring Boot Application that I wrote a couple of years ago interesting. It shows how Spring Boot test support starts an embedded web server and deploys the application to it before executing REST Assured based tests against the REST API. In other words, neither do you have to manually start a web server, nor do you need to re-deploy the app between tests. As a matter of fact, you do not even have to create a .war or .jar file between your code changes in order to validate REST API changes.
1. What is the best way to test REST services in Java? What approaches and tool set do developers usually take?
You can test your rest services by first testing the actual code and functionality of the service itself and make sure it is functioning properly using any unit testing library applicable to your project.
Next, you would publish the REST service and try accessing the RESTful methods using a http client of some sort.
Generally, the easiest way is just a plain old browser. Type in the url and information if it is a GET or PUT based request. If it is a post, you can use browser plugins or dev tools to help add data to the body of the request or header as needed and validate you are getting the response you expect. If it works in a browser, it should perform similarly with any HTTP capable client you choose.
2. Also if you are writing rest clients that call into third party REST services. What is the best way to test REST clients. Do you have JUnit tests that communicate with a third party REST service. You could run into the risk of service not being available/or production REST service cannot be access without certain credentials.
You can generally use any sort of Http Client library you wish based on the language you are using. The main pitfall to look out for with testing of a REST client is to make sure you are capturing the Response returned by the REST service and checking the status. If it is good, you will get a 200, server error 500, etc. etc.
I recommend taking a look at W3C or Wikipedia status code information https://en.wikipedia.org/wiki/List_of_HTTP_status_codes or https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
Further, you should understand the types of responses that are possible to be returned from the particular service. This should be available in the api documentation for the service. The api should also explain any sort of credentials or requirements that need to be passed through the header or as a parameter to the REST call.
Understanding how REST works and HTTP in general would be good starting points.
There are several ways to test REST API, depends on your needs:
Jersey Test - you can execute and test REST API calls with in-memory HTTP server. You'll need to mock your code - use Mockito (Jersey 1.19 Test configuration - mock classes) or in-memory testing database.
Rest Assured - the main drawback is that you need to run REST API project separately/individually from tests (RestAssured testing without running Tomcat)
Tools with UI - SOAP UI or Postman
Swagger - generates interactive documentation - web page where you execute REST methods with prepared data according annotated methods in a code.
Use Spring Boot for developing REST services. It has various tools for testing which you can use out of the box without excessive configuration.
You can create a REST Service mock using SoapUI. Also, if you needed to run this test through maven, you can use soapui-maven-plugin to instanciate do soapui service automatically
For part 2 in your question, the correct answer depends on various factors. You would want to consider both the resolution of the mocking and the time spent writing and maintaining the tests.
Client library
The choice of HTTP-client will affect your options - some klients (like Spring RestTemplate) offer built-in mocking support. If you have a service definition like a swagger or RAML file, you'd want to generate the client.
Project configuration
The most thorough way is to actually let the application make HTTP calls to real endpoints, involving the full stack. If so, configure your project so that the client URLs are injected in a per-environment (or profile) fashion.
Mock endpoints
You want mocking per unit test. No 'deployable mocks' which serve multiple unit-tests. Services are mocked on a localhost port - preferably randomly selected so that parallell testing is possible (i.e. on jenkins).
Mock data
To save time, for deep data structures, it is very desirable that mock data is read from a file, rather than constructed programmatically. Files are much easier to work with, especially if you enable request/response logging, fixing bugs and so is faster.
Mocking
Some frameworks are loosely coupled to the service, as in they are strictly not aware of the nature of the service. Typically you'd mock a respons at some path which is coded in the unit test. This is like Wiremock and most of the test frameworks I've seen.
Whereas other tools work directly on class service definitions, basically you'd use a tool like Mockito to mock an object directly (but wrapped in a real endpoint). This should be less error prone, but requires the classes to be present (as test dependencies). I've written a tool like that, for comparison.
I'd like to synchronize the state to all the clients interested in particular entity changes. So I'd like to achieve something like:
exposing CRUD API on entity (via HTTP/REST and websockets)
and routing the response (of the modifying calls) to websockets topic
So technically, I'd be interested in ideas to mix spring-data-rest with spring websockets implementation to achieve something like spring-data-websocket.
There are a two solutions coming to my mind, and in fact both would be:
spring-data-rest to expose my entities via REST/HTTP API
websocket controllers (used for the modification calls on entities)
The websocket controllers would look like this:
#Controller
public class EntityAWebSocketController {
#MessageMapping("/EntityA/update")
#SendTo("/topic/EntityA/update")
public EntityA update(EntityA entityA) throws Exception {
// persist,....
return entityA;
}
}
Scenario 1: Websocket API called from REST/HTTP API
Rules:
client request is always REST/HTTP API
response is REST/HTTP API for all the operations
moreover for modifying operations the websocket message comes as well
Technically, could be achieved, by:
calling the websocket controllers from the spring-rest-data events (namely in the AfterCreateEvent, AfterSaveEvent, AfterLinkSaveEvent, AfterDeleteEvent)
Still the solution seems quite sick to me, as I'd need to go for:
client A --HTTP request--> Server (spring-data-rest controller)
Server (AfterXXXEvent in the spring-data-rest controller) --websocket message--> Spring websocket controller
Spring websocket controller --websocket message via topic--> all Clients interested in the topic
Server (spring-data-rest controller) --HTTP response--> client A
Scenario 2: Websocket API independent from REST API
Rules:
client request is REST/HTTP API for non-modifying operations only
response is REST/HTTP API for non-modifying operations only
client sends websocket message for all the modifying operations
websocket message is sent to client for all the modifying operations only
Well, if no other ideas come up, I'd go for the later one, but still, it would be great if I could have somehow generated C(R)UD methods exposed via websockets as well, something like spring-data-websockets and handle only the routes in my implementation.
As I feel like I'd have to manually expose (via *WebSocketControllers) all the CUD methods for all my entities. And I might be too lazy for that.
Ideas?
Scenario 2 talks about, in the last step, a single client.But I thought your requirement was for a topic since you wanted multiple clients.
If I wanted to complete 2 for your stated requirement, then you might want to maintain a list of clients and implement your own queue or use a ForkJoinPool to message all your clients listening in on your WebSockets. Having said that, A topic is definitely more elegant here but overall looks too complicated with different interfaces
For all messages from client to server, just go with a simple wire protocol and use a collection to parameterize, it could be
RParam1.......
At the server, you need a controller to map these to different requests(and operations). Somehow does not look like too much work.
Hope this helps.
The same architecture has bugged my mind for a while now and it will be a long story if I want to mention all the drawbacks and advantages of it so let me jump into the implementation.
The second scenario is valid, but as you mentioned its better to perform the crud actions on same websocket session. This shall remove the need for HTTP handshakes on every request, and reduces the body size of messages, therefore you will have better latency. Meanwhile, you already have a persisting connection to a server, so why not make good use out of it?
I searched around for a while and after 6 years from your question, I still couldn't find any websocket protocols that can make this happen, so I decided to work on that by myself cause I needed it for another dummy project.
Another advantage of such protocol could be that it doesn't require much changes to your already written controllers. So it should be able to support Spring Framework (for example) annotations and make websocket endpoints out of it.
The hard part about implementing such protocol in another framework like spring is that as its not nice to create ServletRequest and ServletResponse and convert them to your own websocket protocol, you loose some advantages. For example, any http filter you have written in your application till that moment, will be meaningless because its not really easy to pass your websocket messages through those filters.
About the protocol itself: I decided everything to be passed through json format, alongside a unique id for each request so we can map callbacks on client side to the request id. And of course there is a filter chain to add your filters to it.
Another hard to deal thing here is Spring Security as that too works like http filters in some cases. In my own lib I could finally handle annotations like #PreAuthorize but if you are using antMatchers in your HTTP Security Config, it would be a problem.
Therefore, creating websocket adapter to call http controllers will have many drawbacks.
You can check out the project here: Rest Over Websocket. Its written for Spring Boot.