How can spring boot application instances be packaged in testcontainers - spring-boot

there are several instances of applications that interact with each other (microservices)
There are docker images of these spring boot apps
Is it possible to use these docker images in test container to deploy in tests and how is it possible to do this
There is no need to take into account the time to work and initialization of such tests, this is not the main thing in this situation.

Testcontainers offers GenericContainer which allow you to use images in the registry. For example, let's say you have a image for your service called myorganization/greetings-service:2.0.0 which listen request in the port 8080. Then you can use:
GenericContainer container = new GenericContainer("myorganization/greetings-service:2.0.0")
.withExposedPort(8080)
.waitingFor(Wait.forHttp("/"));
and later you can get the host and port using container.getHost() and container.getMappedPort(8080).
Hope this can help you

Related

Deploy spring boot microservices on AWS Appmesh with EC2

I am trying to deploy Spring Boot microservices using Docker using Appmesh and EC2. I have deployed two sample microservices (https://github.com/amitgct/appmesh-hello) namely: caller-service and called-service using docker on a single EC2 instance and configured appmesh accordingly by following guide https://docs.aws.amazon.com/app-mesh/latest/userguide/getting-started-ec2.html. Currently, my applications are running on ec2 but they cannot communicate with each other and getting error on calling called-service from caller-service i.e. Unknown host. Can anyone tell me how can I specify hostname and register service with that host on EC2 and App mesh. (Note: I don't want to use kubernetes, ECS, AWS cloud map, AWS Route53) . If can provide example also then very thankful to you. Please help.
https://www.appmeshworkshop.com/servicediscovery/
here's a step by step process shown, and this is for http protocol...
but if you change the listeners section in virtual routes to tcp then it should work for TCP messages as well - for those systems which works on tcp protocol - example Akka Clusters

How PCF works internally when deploying Spring boot project

Will PCF run the Tomcat embedded in Spring boot jar or it runs its own tomcat. In PCF we never mention the port number. In the classic approach, we start 3 Tomcat instances in different port number and have apache server before that. Does PCF work the same way.
This is a pretty broad question, so I'm going to answer with a pretty broad response but link you to where you can find more details, if you are inclined to dig in more.
How PCF works internally when deploying Spring boot project
Will PCF run the Tomcat embedded in Spring boot jar or it runs its own tomcat.
When you run cf push -p my/cool/file.jar (or even file.war), the cf cli extracts everything from that archive and pushes it up to CF. CF stores your app files & then your app is staged.
During staging, the Java build pack runs. It looks at all the files that were pushed & tries to determine what to do with them. It knows how to handle several different types of apps [1], including both standard WAR files & Spring Boot apps. The build pack will check your app to see if its one of the supported types in order [2] and will select the first match.
After selecting the type of app, it runs through and installs what is necessary to run your app. For a Spring Boot app, that's basically just the JVM. For a WAR file, it installs Tomcat & a JVM. In addition, it writes out the configuration & start up commands necessary for CF to launch your app.
At this point staging is complete and you have what is called a "droplet". If you have any additional questions on the staging workflow, read here for more details [3].
At this point, the app would be started. The platform takes the droplet that was created and executes the command specified by the build pack to start the app [4]. If all goes well, your app will then be up and running on CF.
In PCF we never mention the port number.
Correct. The platform will tell you the port on which your application should listen. For Java apps, you don't have to do anything. The Java buildpack will handle configuring Spring Boot or Tomcat to start and listen on the correct port.
For Spring Boot apps, you can look at the start up command to see how it's doing this. For Tomcat, it happens in the server.xml that's generated by the Java buildpack [5].
In the classic approach, we start 3 Tomcat instances in different port number and have apache server before that. Does PCF work the same way.
Yes and no. Each application you run can have multiple instances. If you scaled your app to have three instances, that would be roughly like having 3 Tomcat instances in your classic approach.
The main difference is that there would be no Apache Web Server in front. On Cloud Foundry, this is not necessary because it has it's own load balancer called Gorouter [6] which handles proxying traffic to your app and load balancing across available app instances.
This is a classic mistake that people new to CF make. They try to replicate classic architectures and shoehorn a reverse proxy into their app when it's not necessary. This is one of the benefits of CF. It handles routing traffic to your app in a scalable way, freeing you up to focus more on your app.
[1] See "Standard Containers -> https://github.com/cloudfoundry/java-buildpack#additional-documentation
[2] https://github.com/cloudfoundry/java-buildpack/blob/master/config/components.yml#L18
[3] https://docs.cloudfoundry.org/concepts/how-applications-are-staged.html
[4] https://docs.cloudfoundry.org/concepts/overview.html#apps-anywhere
[5] https://github.com/cloudfoundry/java-buildpack/blob/master/resources/tomcat/conf/server.xml#L21
[6] https://docs.cloudfoundry.org/concepts/architecture/#routing
No. The simple answer is each instance of ur application jar is running in its own container within PCF. So there is no clash of using the same port numbers.

Sidecar doesn't support multiple instances of one NON-JVM app

I was able to register the single nodejs app instance using the netflix sidecar app successfully. Both nodejs and sidecar bridge app are running in Cloud foundry.
Result:
SAMPLE-NODEJS n/a (1) (1) UP (1)
When i scale the nodeJS app to 3 instances, could not see the scaled instances in Eureka service registry. It still shows 1 instance.
Can some one help me to do this....
I want to register all the instances of Nodejs app with Eureka service registry with Sidecar bridge app.
Pls.. help.
Regards
Purandhar
Sidecar, like the eureka java client is built to register only one application with the eureka server at a time. It is not a eureka proxy for multiple applications. I built a proof of concept proxy that will do what you want.
This happens because it's not your node application, which is registering to eureka, but your sidecar, which still runs in one instance.
simple solution
you scale your sidecars with your node apps. This is quite straight forward, in particular when using container based deployment. You just can craft a docker container starting both, a node instance and a sidecar.
load balancing
you can extend your sidecar application to load balance traffic to your sidecars. Then your node apps will still be shown as a single instance, but still have load balancing to scaled node instances

How to run Spring Cloud Config server in Fault Tolerance mode?

In my project we have a requirement to run two instances of spring cloud config server so if one instance goes down, other will take care the config server responsibilities.
Currently, you would need to put config server behind a load balancer. It is stateless, so that wouldn't hurt. There is an open issue to configure multiple config server url's in the client, so it could do failover there.
If you are running multiple instances of the config server, you can have them all register themselves in Eureka, and maybe do a lookup to the config server with it's application name via Eureka in all the other microservices. This way, Zuul (and Ribbon) will take care of the load balancing.
Edit:
I guess spencergibb is right. It's best to use a load balancer, for eg: ELB, if you're going to deploy on AWS.
Consider multiple spring-cloud-config-uris for high availability

Can I use Distributed OSGi and ConfigurationAdmin together?

If:
I have a bundle I wish to run on n OSGi containers exporting some service;
I am using DS to register the modified method for when configuration changes, so I can update the service via ConfigurationAdmin, and to export the interfaces remotely as per RFC119;
I am using Discovery to call those services from other bundles on other boxes,
is it possible to have a central configuration for this service using ConfigurationAdmin, so that I can publish a configuration change via the Configuration Admin and it is received by all instances of the service running?
It seems from everything that I have read that ConfigurationAdmin is not network aware, and is local to each OSGi container?
Thanks for your insight in advance :)
So your bundle runs on N containers, exports its service to that local container only, and it exports ManagedService using remote services to publish it to some "central" container that has ConfigurationAdmin running?
You are right that ConfigurationAdmin is not network aware, but if the bundle remotely publishes its ManagedService to that container running Configuration Admin it should work. The only caveat is that each ManagedService must have a unique service PID so you cannot simply publish the same bundle in N containers unless you ensure that each instance ends up using a unique PID.
You should probably check out Karaf Cellar. It provides cluster support for OSGi applications and synchronizes configuration changes across nodes.

Resources