Best Architecture for implementing a WebService that takes requests from one side, save and enhance that and then call another service with new parameters.
is there any special Design Pattern for this?
There's not a lot to go on, but from what you've said it sounds like a job for "pipes and filters"!
To get a more precise answer, you might want to ask yourself some more detailed questions:
If you need to do any validation or transformation of the incoming message? Will you want to handle all requests the same way, or are there different types? Are the external services likely to change, and if so, will they do this frequently? What do you want to do if the final web service call fails (should you rollback the database record?)? How do you want to report failures/responses - do you need to report these back? Do you need a mechanism to track the progress of a particular request?
Since you are looking for a design pattern, I think you might want to compare the pros and cons of using microservices orchestration vs choreography in the context of your project.
If you do not need an immediate response to the calling system I would suggest to you to use event-driven approach if that's feasible. So instead of REST services, you will have a message broker and your services will be subscribed for certain events. This will hide your consumers behind the message broker which will make your system less coupled.
This can be implemented via Spring Cloud Stream, where you will have a Sink (microservice producing events, transformer - microservice that makes intermediate transformations possible and a source - microservice that receives a final result for further processing).
Another possible case could be Camel. It has basically all the integration patterns built in, so it should not be a problem to implement the solution either based on REST APIs or events.
Related
To understand if the spring events fits the task im working on I need to understand how they work, where are they stored?
as I can guess they are stored in a spring application context and disappears if the application crashes, is my guess correct?
Spring events are intended to use when calling methods directly would create too much coupling. If you need to track events for auditing or replay purposes you have to save the events yourself. Based on your comments, there are many ways to achieve this, based on the topology and purpose of the application (list not complete):
Model entities that represent the events and store them in a repository
Incorporate a message broker such as Kafka that support message persistence
Install an in-memory cache such as Hazelcast
Use a cloud message service such as AWS SQS
Lastly, please make sure that you carefully evaluate which options suits your needs best. Options 2 to 4 all introduce heavy complexity and distributed applications can bring sorrow and misery to your life. Go for the simplest option if you can and only resort the other options if absolutely necessary.
I'd like to trace my async application with some key checkpoint.
Is there any popular framework I can use?
For example, I may choose to use vert.x or any other java async framework. For each request/response cycle, I'd make some checkpoint to log something while these points might happen in different threads.
I'd like to see an aggregated view of 1 request to see what's going on. Supporting distributed case would be better but single JVM is good to go.
What you are looking for is OpenTracing. It's an API that allows you to have distributed tracing features in a way that is vendor agnostic.
For your specific case, you'd have to handle the context propagation yourself, as there's no other (reliable) way to do that on OpenTracing yet for teh async case. For other cases (sync JAX-RS, Servlets, Spring Boot, ...), it would be safe to use the native framework integration and/or the Java agent rules.
For Vert.x, you'll need to inject the span context into Vert.x' message, and extract this context later on.
There's an example of OpenTracing + Vert.x on the Hawkular APM example directory, that might help you get started. Note, however, that you might want to use another backend should you decide to move forward, as we (Hawkular APM team) decided to join forces with Jaeger for the OpenTracing backend.
I am building a web service in java. The business logic has no concurrency requirements. It is a simple rest call where an input json is expected and after some processing an output json is thrown back. However the request can be in millions where I am planning to bring in a load balancer.
My question is I have read a few articles which say that using akka will make the development faster and give a performance boost as well. Is this true in case of an application which has no concurrency requirement?
Thanks in advance.
Even without concurrency requirements, Akka is a great framework to use. You can use actors to encapsulate single responsibilities, send them messages to react on it and respond with another message.
This has the benefit that you can model errors inside your domain, which means, sending an Message with the error back to the sender, which can then decide how to deal with it, e.g. retrying n times. So you get a good exception modelling with Akka.
Even better, whenever an Actor fails with an Exception, the parent Actor can than decide, what to do, e.g. restart the actor, propagate the error even higher in the hierarchy etc.
So in conclusion, Akka helps you to develop a solid reactive domain based on messages. It also makes it easy for you to make it concurrent later, or to pass messages to other actors as well, when you logic changes.
In my environment I need to schedule long-running task. I have application A which just shows to the client the list of currently running tasks and allows to schedule new ones. There is also application B which does the actual hard work.
So app A needs to schedule a task in app B. The only thing they have in common is the database. The simplest thing to do seems to be adding a table with a list of tasks and having app B query that table every once in a while and execute newly scheduled tasks.
Yet, it doesn't seem to be the proper way of doing it. At first glance it seems that the tool for the job in an enterprise environment is a message queue. App A sends a message with task description to the queue, app B reads a message from the queue and executes the task. Is it possible in such case for app A to get the status of all the tasks scheduled (persistent queue?) without creating a table like the one mentioned above to which app B would write the status of completed tasks? Note also that there may be multiple instances of app A and each of them needs to know about all tasks of all instances.
The disadvantage of the 'table approach' is that I need to have DB polling.
The disadvantage of the 'message queue approach' is that I'm introducing a new communication channel into the infrastructure (yet another thing that can fail).
What do you think? Any other ideas?
Thank you in advance for any advice :)
========== UPDATE ==========
Eventually I decided on the following approach: there are two sides of this problem: one is communication between A and B. The other is getting information about the tasks.
For communication the right tool for the job is JMS. For getting data the right tool is the database.
So I'll have app A add a new row to the 'tasks' table descibing a task (I can query this table later on to get list of all tasks). Then A will send a message to B via JMS just to say 'you have work to do'. B will do the work and update task status in the table.
Thank you for all responses!
You need to think about your deployment environment both now and likely changes in the future.
You're effectively looking at two problems, both which can be solved in several ways, depending on how much infrastructure you able to obtain and are also willing to introduce, but it's also important to "right size" your design for your problems.
Whilst you're correct to think about the use of both databases and messaging, you need to consider whether these items are overkill for your domain and only you and others who know your domain can really answer that.
My advice would be to look at what is already in use in your area. If you already have database infrastructure that you can build into, then monitoring task activity and scheduling jobs in a database are not a bad idea. However, if you would have to run your own database, get new hardware, don't have sufficient support resources then introduction of a database may not be a sensible option and you could look at a simpler, but potentially more fragile approach of having your processes write files to schedule jobs and report tasks.
At the same time, don't look at the introduction of a DB or JMS as inherently error prone. Correctly implemented they are stable and proven technologies that will make your system scalable and manageable.
As #kan says, use exposing an web service interface is also a useful option.
Another option is to make the B as a service, e.g. expose control and status interfaces as REST or SOAP interfaces. In this case the A will just be as a client application of the B. The B stores its state in the database. The A is a stateless application which just communicates with B.
BTW, using Spring Remote you could expose an interface and use any of JMS, REST, SOAP or RMI as a transport layer which could be changed later if necessary.
You have messages (JMS) in enterprise architecture. Use these, they are available in Java EE containers like Glassfish. Messages can be serialized to be sure they will be delivered even if the server reboots while they are in the queue. And you even do not need to care how all this is implemented.
There can be couple of approaches here. First, as #kan suggested to have app B expose some web service for the interactions. This will heterogenous clients to communicate with app B. Seems a good approach. App B can internally use whatever persistent store it deems fit.
Alternatively, you can have app B expose some management interface via JMX and have applications like app A talk to app B through this management interface. Implementing the task submission and retrieving the statistics etc. would be simpler. Additionally, you can also leverage JMX notifications for real time updates on task submissions and accomplishments etc. Downside to this is that this would be a Java specific solution and hence supporting heterogenous clients will be distant dream.
I have to develop a web service that looks like this: I make a get call, including a string in the url, and I need to receive another string based on the initial string from the query.
I might have to make this call even for a thousands times a minute. Do you think that the server will be able to handle so much HTTP communication? Is a RPC approach better?
Any suggestion is welcomed, I am just starting to work on web services and I have no clue about the performance.
Thanks.
Thousands calls per minute means hundreds per second. I believe that modern computers can do more. I do not think that you will have serious performance limitations. But before you are starting check how long will it take to deal with the request. If this will take time I'd recommend you to decouple the HTTP WEB front end and business logic, i.e. process the request asynchronously. You can easily achieve this using JMS.
SOAP or REST? I personally prefer REST. It is simpler, it is faster. And it seems that you have only 2 String parameters, so SOAP does not give you any advantages.
IMHO, the main difference between SOAP and REST is that the former inserts an additional overhead (both processing and data) since it's data has to follow a somewhat strict structure. REST is simpler and leaner because it doesn't require you to explicitly define a message format, leaving this task to the software that will handle the message instead of the transport infrastructure.
So:
Do you want to enforce a message structure at the cost of additional overhead? Use SOAP;
You want a more lightweight option, at the cost of having senders and receivers piece together the messages into meaningful data? Use REST;
One of the key advantages of a REST web service is that its responses can be cached. In this way, the intermediate HTTP cache chain between your service and its clients bears a huge part of the total workload, so your web service can scale up. REST can be far more scalable than SOAP or RPC.
You may also want to check out Jersey at http://jersey.java.net/ as an alternative to Restlet.