Communicate between microservices on the same machine without exposing a public API - java

I am relatively new to Camel and Spring, and I am making a service to predict stock prices using a neural network to practise using Camel, Spring and also DL4J.
My service is divided into 5 microservices (Gateway, H2 SQL Database, Admin Console, Data Fetcher, DL4J Handler) which will each run in their own Java application. Each one has a REST API.
How can I prevent an external computer from connecting to 4 of the services, while leaving the gateway open and connectable?
To clarify:
All 5 services have a REST endpoint, and they are all visible to each other because they are all running on the same machine and can connect with localhost:port. I'd like to know how I can prevent an external computer from connecting to 4 of the services, whilst leaving 1 (the gateway) still connectable.

There's nothing unique about Spring or Camel here.
Each one has an REST API, meaning there's an HTTP endpoint, meaning each service has bound its server port on localhost, and so can reach each other via http://localhost:<port>, assuming nothing is running in a VM or Docker container
You should also be able to use the gateway on localhost

Related

spring boot Enterprise application with eureka and zuul

I am in charge of designing a new enterprise application that should handle tons of clients and should be completely fault free.
In order to to that I'm thinking about implementing different microservices that are going to be replicated so eureka server / client solution is perfect for this.
Then since the eureka server could be the single point of failure I found that is possible to have it replicated in multiple instances and it is perfect.
In order to not expose every service I'm going to put as a gateway zuul that will use the eureka server in order to find the perfect instance of the backend serivice that will handle the requests.
Since now zuul is the single point of faiulre I found that it is possible to replicate also this component so if one of them fails I still have the others.
At this point I need to find the way to create a load balancer between the client application (android and ios app) and the zuul stack but a server side load balancer will be the single point of failure so it is useless.
I would like to ask if there is a way to make our tons of clients connect to an healty instance of zuul application without having any single point of failure. Maybe by implementing ribbon on the mobile application that will choose a proper healty instance of zuul.
Unfortunatly everything will be deployed on a "private" cluster so I can not use amazon elastic load balancer or any other different propietary solution
Thanks

How do I communicate between/connect two tomcat servers

I am working on a project where I have two servers (tomcat), Server A gives initial snapshot of information from DB(MySQL) to the frontend. Server B to serve updates to server A, both servers need to communicate. How do I connect them? Thank you very much for your help.
There are many ways two Tomcat instances running on the same host could be set up to communicate with each other. It's quite common to implement a REST service in the "server" Tomcat instance and have the "client" Tomcat instance send the REST request to the other instance. It's common to use either the Jersey or CXF framework to implement a JAX-RS REST service, or you could use the Spring framework to implement a more general web request handler.
Tomcat typically accepts HTTP/S requests. So you could program your own servlets in Tomcat A (and publish them as URIs) to accept data which shall be updated to the DB. Then, Server B must act as a client to server A, initiating communication whenever it wants, and sending the data to Server A as HTTP requests.
Taking security into account, I'd also suggest that Server A should forbid any requests to the updating URIs which do not come from Server B. For instance, securizing the updating URIs through standard JEE security.

Microservices : Without Service Discovery With Spring API Gateway

I'm having a really tough time with this one. We want to move our legacy app to Microservice application(Spring-boot, Java 8) .
As per Architect, we do-not need Service Disvovery and API Gateway is enough for the doing Service Discovery and Routing.
Note that currently , deployments are On premise server and we will have fixed number of nodes and F5/load balancer will be able to route the request to API gateway and then to the microservices.
Can we survive with Spring Cloud API Gateway and no Service Discovery?
A short answer Yes, you can survive with Spring Cloud API Gateway and no Service Discovery.
But it's really dependent on the size of your application and the amount of traffic it will be handling.
You can start migration to microservices without Service discovery.
For internal service-to-service communication just use real hardcoded IP addresses and ports.
Regarding to the API Gateway doing Service Discovery. I can be wrong, but you won't be able to communicate through Api Gateway because it also has no clue about the location of the targets (services locations have to be hardcoded as well).
Once you begin feeling that you need scaling out you won't avoid using Service Registry tool. If you start considering which one to take I can suggest using HashiCorp Consul.
Anyway, it's most likely that you finally will have to inject Service discovery mechanism to your infrastructure. You can either do it from the beginning or take care of it later if the new architecture will be beneficial to you and there will be a plan of extending it further.
If you have plans of migration to the clouds then you can think about Kubernetes for your infrastructure in advance. It provides you with Service discovery mechanism out of the box.
Kubernetes is a great platform for this, if you can opt.
It can handle parts ranging from service discovery to deployment.
You just need to make a cloud ready docker image (preferably) and deploy it to kubernetes, Kubernetes will map an internal endpoint to this, based on your configuration and your services will be registered with it ( if I talk in terms of spring-cloud and eureka server).
If there is no Service-Registry-backed DiscoveryClient then you can configure spring.cloud.discovery.client.simple.instances.userservice[0].uri=http://s11:8080
You can host this userservice on kubernetes cluster .For further details go to this docs
https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/
Like wise to have communcation between sevices ,suppose userservice wants to communicate to password service easily configure via ribbon
passwordservice.ribbon.listOfServers:${PASSWORDSERIVCE}:http://localhost:8081
I do not see any problem with this strcuture .

Best practice to map webservice endpoint in client

this question is more of a design/architecture question. Let's say I have a server application that provides Spring-based webservices and a client application. So currently I have a few Java classes on the client side where the endpoint of the service is hardcoded (e.g. http://myserver/some/webservice).
What is a good way to map the client side properly with the webservice? Just off the top of my head: is there a library that helps evaluate URLs with parameters and maps them to the properties of a POJO using reflection?
As I understand your question, 2 options pop into my head:
1) Eureka- Service Discovery for Spring Cloud.
It can help you by giving your client the Eureka URL and the Eureka will supply the client with the desired service URL. so if there the server is going down Eureka can point the client to a back up server (it will be seamless to the client) or even different URL's to different services on the same server.
2) Spring Cloud Config
A configuration service that contains the URL's in the DB, the client will pull those URLs from there and will make the calls to a configurable URI's.
Spring allow you to update those URL's in the DB and it will use spring cloud config to push the new URL's down to the clients without any downtime... (might fit you better if you are not interested in load balancing and other features provided by Eureka)

Web Service vs TCP/IP Sockets (Java) + SQL Connections

We are currently are at a stage in our product lifecycle where we are thinking about moving to Web Services. Our system is written in Java which consists of a number of client and server applications which talk to one another over TCP Sockets and also has in-line SQL to perform data retrieval and updates (yuk! I know) which uses our own SQL Connection class which then uses the java.sql.Connection to connect to a SQL Server database using the Microsoft JDBC driver.
The applications bind to one another using TCP sockets. They request data from and push data to one another. Which works perfectly fine.
Thought
So we are looking at converting all data access and TCP communication to a web service.
The web service would be designed to run on a companies secure internet site. The idea would be that users could connect their clients to the web service from home - when they are not on the company network - or at work, when they are.
The client applications would send/recieve the messages to/from the server side applications using the web service.
The client applications would retrieve and update data in the database using the web service.
Question
I would just like to know what peoples experience is of doing anything with 2 way communication (request and push) over a web service (if possible) and what the thoughts are about doing this.
Converting the data access to a web service seems straight forward enough - I can forsee some issues with performance where large data sets are retrieved in some parts of the system.
I am looking through various reading materials on the matter as it is a while since I have touched web services (using C# and ASP.NET). Currently reading "Building Web Services with Java™: Making Sense of XML, SOAP, WSDL, and UDDI". I must admit I thought web services were always stateless but have just read that they are not!
Thanks,
Andez
It helps to think of WebServices as being the same as any other web application on the transport layer. It uses HTTP/HTTPS protocols in the same way, it's just that instead of sending HTML, it sends XML according to a predefined format (SOAP). As such:
It's Request/response oriented
Can be stateful in the same way as a web-page can be stateful, using sessions (assuming you have a web-service client that supports maintaining session cookies across requests)
All requests eventually boil down to good old-fashioned servlet endpoints in the server
Keeping these limitations and features in mind, think about your requirements and how they map against each other. If you need true two-way communication (push), then web services are not ideal. They are client/server, request/response oriented. The achieve push, you would have to poll from the client. A possible alternative could be to let both the "server" and the "client" act as web service "servers". That would mean bundling some light-weight servlet engine with the client (like jetty) so the "server" could make web service calls TO the "client". Another way is to look at two-way RMI/IOOP.
Yet another way would be to keep the communication layer as you have it today. There is no inherent gain in refactoring to Web Services just for the sake of using web services. If they don't add any benefit, it's just waste. As you already mentioned yourself, Web Service comes with a load of additional overhead (verbose protocol, servlet engine etc), so it really needs to balance the extra cost and development time with a clear benefit. As the saying goes "if it's not broken, don't fix it". As you say the current solution "works perfectly fine", I would probably not change it. That's just me though.

Categories