Accessing User defined service in spring boot - java

I am working on spring boot application which uses REST webservices. Till now , all the database paaswords i used to store in my application.properties class and am using HICKARI CP also to manage the connection pooling.
But now , i have created the user services in Cloud foundry and have included the script of CF in my build.gradle file too.
But i do not have any idea as to how shall i access these services within my code and how can i autowire thise datasources. Please advice any solution.

Use Spring cloud service connector. This is sub project of Springs cloud.
http://cloud.spring.io/spring-cloud-connectors/spring-cloud-spring-service-connector.html#_relational_database_db2_mysql_oracle_postgresql_sql_server
you can create a mysql service inside your cloud foundry space. And the bind the same to your app. This can be done as defining services inside your manifest.yml or using bind-service command in cf cli.
You can add spring cloud service connector dependencies in your gradle build and add datasource configuration bean.
#Bean
public DataSource dataSource() {
return connectionFactory().dataSource("your-mysql-service-name");
}
This creates a datasource of the mysql service in your application, and registers as a bean in spring context. That can be autowired where ever needed.
Alternatively, cloud foundry exposes the details about every service that application is binded to, in VCAP_SERVICES env variable. Once your application is binded to service, you can find your mysql service username, password, connection url, db name etc in this variable. You can read this variable and parse the values and build a datasource of your own.
Using service connectors are preferred approach as the infrastructure code is handled by springs.

Related

How to handle configuration When Spring Boot config server itself is down?

I'm new to the spring cloud config server. Consider a scenario where we have 10 spring boot microservice fetching configurations from the Spring Boot Cloud Config. I was wondering How the 10 spring boot microservices will work when the Spring Boot Cloud Config itself is down?
Can someone answer to below queries:
If the config server is down, Will there be downtime for all the microservice connected to it?
Let's say we have a config file application.properties in GitHub and Spring boot config refers to the application.properties file in GitHub What if the username and password to access the application.properties file itself will change?
In terms of Disaster recovery, Do we need any backup of the config server? If yes, How can we achieve the same?
If the config server is down, Will there be downtime for all the microservice connected to it?
In real world application, there will be multiple instances of your config server deployed across multiple availability zones, fronted by load balancer or API gateway, or even you can register your multiple instance with eureka server so that there is No single point of failure.
So how the configuration will look like is instance 1 is in us-east-1
instance 2 in us-west-2, so even if one AZ is down it will not impact your services.
As far as GitHub or external repo is concerned, you can configure config server to read properties natively but that not something I will suggest !!
Let's say we have a config file application.properties in GitHub and Spring boot config refers to the application.properties file in GitHub What if the username and password to access the application.properties file itself will change?
First of all you should not commit password in Github for public repo, secondly password should be dynamically fetched from Idvault, or AWS secret Manager or other services whichever you prefer. So that even if you change password it will not affect any services.
In terms of Disaster recovery, Do we need any backup of the config server? If yes, How can we achieve the same?
Config server is just reading properties/config from repo that you provide,so repository where your code is hosted is of importance to you. Github can take care of that for you !!

Spring Boot: use database config from WildFly's standalone.xml

I'm currently developing an REST app whith Spring boot. For development, I hardcode my database configuration in application.properties. However, this app is going to be deployed on different WildFly servers, each of them defining their DB config (user credentials) in standalone.xml.
As I'm a newbe to Spring/Java, here is my question: How can I use the DB config from standalone for my spring app?
I already did some research. What I got is to define Services with an #PersistenceContext annotated entity manager. But how can I use it without defining new services, just by using plain JpaRepositories?
In Wildfly you will have a datasource configured with at JNDI name.
Instead of configuring url, username and password you have to configure this JNDI name:
spring.datasource.jndi-name=java:jboss/datasources/myGreatDS
That's all.

After deployed the App in Elastic Beanstalk end point of app throws 404 not found in SpringBoot+MySql+Angular app with maven

is literally my first time on AWS deployments , and doing it by myself is harder the task.
After having created my app in Elastic Beans and its respective RDS database with its instance , i created a Snapshot (jar) on my Springboot app which was also implemented in the deployment process of the AWS application.
Also several items were configured in its Software Category referring the RDS database endpoint, server ports, user-name of database , etc...
.
Then after all that process , got the app deployed with a url.
But when i apply that url with the endpoints my springboot controllers have , i receive as error a 404 Not Found; but if i decide to work on local requesting only the RDS database created by the application in Elastic Bean the endpoints shows data and the app works
Literally on my Spring Boot App i declared in the app. properties the connection to that database in AWS
spring.datasource.url=jdbc:mysql://aat54g98qswmf3.clnhc7kmwszz.us-west-2.rds.amazonaws.com:3306/ebdb?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=xxxx
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
logging.level.org.hibernate.SQL=debug
thus my controllers in the spring working in local don't have any problem
#RequestMapping(path = "/restaurant-booking/version1")
public class RestaurantController {
#Autowired
RestaurantService restaurantService;
#ResponseStatus(HttpStatus.OK)
#RequestMapping(value = "/restaurant/all", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
some code.........
};
then on my browser:
But if i switch to the url facilitated by the deployed EB app in AWS, and the use the same endpoint
Any help guys would be amazing , cause honestly can't find the problem or where to look at!
Thanks in advance!!!
The whitelabel error page is the default error page in spring when you have not defined your own. This means your application is deployed and running. You either messed up your request mapping or your url.
If we look at your mappings we see the url should be .../restaurant-booking/version1/restaurant/all
Request mappings get nested when they are on the class and method level.
You actually used the correct url locally but not on your deployed version.
The problem might be arising due to the connectivity with the RDS and the correct Environment configuration for your Spring Boot Application.
I would suggest that prior to continuing with the environment creation (or even after), make sure you connect the RDS properly. For the configuration part:-
you can make use of application-prod.properties file and specify an environment variable and value for software configuration labelled SPRING_PROFILES_ACTIVE and set its value to prod.
The application-prod properties consist of:-
server.port=5000
spring.datasource.url=jdbc:mysql://${RDS_HOSTNAME}:${RDS_PORT}/${RDS_DB_NAME}
spring.datasource.username=${RDS_USERNAME}
spring.datasource.password=${RDS_PASSWORD}
spring.jpa.hibernate.ddl-auto=create
Select a suitable RDS before or after creating the environment.
You need to configure the inbound and outbound rules for security group encompassing the RDS manually to allow access for creating, delete, update, etc.
And then finally upload the jar file in the environment. Worked for me.

Multiple property files for same Spring Boot Application based on request

I have a Spring Boot application for UI test automation using Cucumber and Selenium.
The application is expected to test multiple environments.
To begin with I have created json files with required properties like URLs, credentials etc. and load it(pass the file path as a property and use it) while triggering the test (mvn test -DconfigFile=config/env1_config.json).
I see that using profiles while running test is an option-Dspring.profiles.active=client1 but as i will configure multiple pipelines in Jenkins for testing multiple environments to use same project with different configuration files, it will clone the entire project and run tests in workspace corresponding to the pipeline. To avoid keeping multiple copies of the project, i am planning to use Rest API to trigger Selenium tests and have configuration files in Git.
Is it possible to create multiple application properties files with custom properties, place them in Git and use required property file in a Spring Boot application(inside a Rest API impl) based on a property or RequestParam using Spring Cloud Config or something?
you can use spring boot profiles and pass it as maven argument
just pass -Dspring.profiles.active=test1 as command line argument
you can read more here
You can do it by setting spring.profiles.active environment variable. Like if you are using property file for every environment by convention application-dev.properties, application-qa.properties. You can define you spring.profiles.active as dev and qa.
You can refer to the below link for more in site on same.
https://stackabuse.com/spring-boot-configuring-properties/
You can use Spring cloud server and client.
Make A project With Dependency Spring cloud server and make config file(appilcation.properties) there. For use that config file in other microservice
just add spring cloud cilent dependency in other projects and add this line in application.properties
spring.cloud.config.uri:[your spring cloud server project url]
refrence:-
spring cloud server:-
https://www.youtube.com/watch?v=gb1i4WyWNK4&list=PLqq-6Pq4lTTaoaVoQVfRJPqvNTCjcTvJB&index=11
spring cloud client:- https://www.youtube.com/watch?v=E2HkL766VHs&list=PLqq-6Pq4lTTaoaVoQVfRJPqvNTCjcTvJB&index=12
Sharing the approach I ended up with as it might help someone someday.
As i wanted to create a Rest API and use properties from different config files in API implementation, based on the api request,
I created a Spring Cloud Config Server application that connects to application properties repo in git and I consumed Rest APIs exposed by Spring Cloud Config Server (host:port/app/profile) in the service layer of my Rest API implementation.

How to load changed environment variable in spring boot application running in PCF without restarting application?

We have a spring boot application running in PCF and it reads the PCF environment variables(CF_INSTANCE_INDEX, CF_INSTANCE_ADDR,..) from an application. Based on those variables, we are trying to implement the logic for a scheduler. While running this scheduler, these variables' values could have changed. Is there a way to refresh/reload bean that have env values during runtime?
we used #RefreshScope annotation on config properties bean.
#Configuration
#RefreshScope
public class PcfEnvProperties{
#Value("${CF_INSTANCE_INDEX}")
private int intanceIndex;
#Value("${CF_INSTANCE_ADDR}")
private String intanceAddr;
...
}
and refresh using
context.getBean(RefreshScope.class).refresh("PcfEnvProperties");
PcfEnvProperties pcfEnv = context.getBean(PcfEnvProperties.class);
But It is not loading the recently changed env variable into running application. Any ideas on how to accomplish this?
You can use Spring Cloud Config Server in combination with Spring Actuator to expose an endpoint in your service that will refresh the application's properties on the fly. You could set up your scheduler to hit this endpoint on a timer or as needed.
Here is one tutorial I found that seems pretty straightforward: https://jeroenbellen.com/manage-and-reload-spring-application-properties-on-the-fly/
You may have to play with the setup depending on how your platform is configured, but I believe it should do what you're wanting. We have deployed many java web services on our PCF platform using this actuator/config server approach, and we can just make a call to the refresh endpoint and it successfully pulls in (and overwrites when necessary) the new properties and values from the config server. Also you can pull out a list of the property names and values that changed from the response.
I'm not familiar with the specific property values you mentioned, but as long as they are normally a part of Spring's ApplicationContext (where properties usually are found) then you should be able to pull in changed values using this approach with Spring's cloud config server and actuator libraries.
Hope this helps

Categories

Resources