TestContainers - create GenericContainer and get the uri/path - spring

I'am trying to create isolated test env using TestContainers (for database - postgresql and external services - for example authorising service). My question is, how can i set path in application.yml/application.properties to these external services? With db is easy i just need to use "jdbc:tc:postgresql:14.5:///dbtests", to create containers with my services i use GenericContainer<?> and ports are different every start. TestContainers (except db) are initialized in external class.

You always have to think about how you can inject the dynamic connections URLs into your system-under-test. How you can do is very specific to your application. If you create objects yourself, you can simply to construction dependency injection, like in this example.
For frameworks, there is generally a framework-specific approach. As EddĂș already mentioned in the comments, Spring-Boot allows the usage of DynamicPropertySource.

Related

Can you use Testcontainers to manage service dependencies, like a database, during local development?

Testcontainers can manage dockerized service dependencies, like a database, Kafka, Elasticsearch, and so on for integration testing.
Can I configure my Spring Boot application to manage these service dependencies during local development?
For example, my Spring Boot application needs a MySQL database.
I would like to integrate it with Testcontainers to provide a Docker container with MySQL not only during the tests execution, but at application startup during local development too.
Testcontainers provides an API to manage applications and services in Docker containers. It's incredibly useful for integration testing, where having a programmatically configured, isolated, repeatable environments is an essential requirement for trustworthy tests.
Because of that Testcontainers has integrations with the frameworks like Spring and Quarkus, and tes frameworks like JUnit, Spock, etc to automatically tie the lifecycle of your containerized dependencies to the lifecycle of the tests.
However, Testcontainers API is generic and doesn't have to run during the tests. For example, Quarkus has a feature called Dev Services which automatically creates a container for your database (or other service dependencies, for example Kafka, Redis, etc) when your application tries to access the database, but the configuration is not present.
You can think about it like this, if you have the data access repository classes initialized and wired, but no datasource.url in the config -- it'll spin up the database using testcontainers and configure the app to use it (just like it would happen during tests, but instead used for local development).
Spring Boot doesn't have an automated feature like that currently, there's an open issue to investigate these local development setups with Testcontainers.
If you're open to manually add a feature for your particular application, you can look at the prototype linked from that issue here: https://github.com/joshlong/testcontainers-auto-services-prototype
It's a bit more involved because it integrates with the Spring DevTools, but here are the essential parts that need to be taken care of:
Check that you need to use the database (in your application it can be a given).
Verify the configuration to use the database is absent (if the database is already configured you don't need to spin up a new one)
Create a container using Testcontainers API, either using an appropriate module or the GenericContainer with any Docker image.
Provide the configuration back to the application. For the database that would be the jdbcUrl, username, password, database name, r2dbcUrl and any other relevant properties.
You can take a look at the video with Josh Long where this concept was tried: https://www.youtube.com/watch?v=1PUshxvTbAc&t=2450s
It would also work in the production environments, but the usefulness of the ephemeral Databases, might be limited.

Managing database content on jhipster server

How would one go about managing the data in their PostgreSQL database on their JHipster generated server? My goal is to be able to periodically check the items in the database and perform certain tasks based on the database contents.
I'm new to using JHipster and I'm not sure how I'd go about adding or removing entities as well as adding items to entities on the server. I understand that services facilitate doing these operations for the client-side, but I can't see how I would use the same approach to do what I need on the server (if this is even the correct approach).
To schedule a task on backend you can annotate a public method of a service with #Scheduled, you can find an example in the code generated by JHipster in UserService class look at the removeNotActivatedUsers() method.

Asynchronous task execution using Spring in container managed environment

I want to run few tasks asynchronously in a web application. My question is which Spring implementation of task executors i should use in a Container managed environment.
I refereed to this chapter in Spring documentation and found few options.
One option I considered is WorkManagerTaskExecutor. This is very simple and works seamlessly with the IBM Websepher server which I'm currently using but this is very specific to IBM Websphere and Oracle Weblogic servers. I don't want to tie my code specifically to one particular implementation as in some test and local regions we are using Jetty container & this implementation creates problems to run the code in Jetty.
Other options like SimpleThreadPoolTaskExecutor does not seem to be best fit to leverage thread pooling in container managed environment and I don't want to create new thread myself.
Could you pleas suggest how do I go about this. Any pointers to a sample implementation will be great help.
As usual, it depends. If you rely on the container's thread management and want to be able to set thread pools on its admin interface or if you're application is not the only app inside the container or you use specific features like setting thread pool priorities for EJB or JMS you should add support for the WorkManagerTaskExecutor and make it configurable. If not, you can use whatever you want cause in the end threads are just threads. Since Spring is an IOC container you can do it. To use the same app everywhere I wouldn't suggest to change the XML config per app version. Rather
use profiles with configuration to set the executor type and inside your java config return the proper bean type. If you use Jetty you should have a configuration for the thread pool sizes to to be able to tune it.
use spring boot like auto configuration which usually rely on available classes on classpath (#ConditionalOnClass). If your weblogic or websphere specific classes are available or any other container specific thing like env variables you can create the WorkManagerTaskExecutor
With both of these you can deploy the same war everywhere.

Can I duplicate a web service for testing?

I have a REST web service exposed at http://server:8080/my-production-ws by JBoss (7). My spring (3.2) configuration has a datasource which points to a my-production-db database. So far so good.
I want to test that web service from the client side, including PUT/POST operations but I obviously don't want my tests to affect the production database.
Is there an easy way to have spring auto-magically create another web service entry point at http://server:8080/my-test-ws or maybe http://server:8080/my-production-ws/test that will have the exact same semantics as the production web service but will use a my-test-db database as a data source instead of my-production-db?
If this is not possible, what is the standard approach to integration testing in that situation?
I'd rather not duplicate every single method in my controllers.
Check the spring Profiles functionality, this should solve the problem. With it its possible to create two datasources with the same bean name in different profiles and then activate only one depending on a parameter passed to the the JVM.

Storing spring integration routes in mongo for dynamism

I have a mongo repository with connectivity between multiple components. I have a traditional java application which reads the mongo repository and performs the routing, transformation by calling appropriate java classes dynamically. I am planning to move this to spring but do not want to statically declare routes as this is highly inflexible. Is there any possibility to make sure that spring can refer routes and transformations from mongo and performs the routing.
It's not entirely clear what you are looking for but, yes, it's easy to create custom routers, transformers and/or other components.

Resources