How to fix mysql connectivity issues on bosh-lite for a cf.org sample spring boot app? - spring-boot

I am trying to cf push this code from this github repo after running mvn package, but I get a failed app deployment.
I have created a user defined service for mysql since cleardb is not available on my bosh-lite local vm. I created the mysql service and named it as 'mysql' as well as guided by this.
The application.yml in this spring boot app points to localhost. That doesn't work even for a local (non cf) build without corrrecting the jdbc url. Here is the stack trace from the bosh-lite vm when I try to cf push this app and read the logs using cf logs springpong --recent.
Also, why do we need both, the manifest.yml and the application.yml providing database details ?
vagrant#vagrant-ubuntu-trusty-64:~$ cat pong_matcher_spring/src/main/resources/application.yml
---
spring:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost/pong_matcher_spring_development
username: springpong
password: springpong
jpa:
hibernate.ddl-auto: none
show_sql: false
vagrant#vagrant-ubuntu-trusty-64:~$ cat pong_matcher_spring/manifest.yml
---
applications:
- name: springpong
buildpack: java_buildpack
path: target/pong-matcher-spring-1.0.0.BUILD-SNAPSHOT.jar
services:
- mysql
vagrant#vagrant-ubuntu-trusty-64:~$
Can someone help me fix this ?
TIA

This was happening as the security groups were not setup to allow for network access. A sample gist of commands can be seen here -> https://gist.github.com/menicosia/2e9c414430138064f945
Caveat: This is only for bosh-lite and development purposes.

Related

How to build a Docker image for client service of Spring Cloud Config Server

I have built a Docker image for cloud config service. I have another service employee for which I want to build a Docker image. This client service will read data source configuration properties from the config server
I am able to connect the employee service successfully with config service on localhost without Docker. The problem is only that I am not able to build a Docker image for the employee service.
On running mvn package dockerfile:build command for the employee service I get the following error
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Below is the bootstrap.yml file located at src/main/resources directory
spring:
application:
name: employee
profiles:
active: dev
cloud:
config:
uri: http://configserver:8071
Config service's bootstrap.yml file
spring:
application:
name: config-server
profiles:
active: native,dev
cloud:
config:
server:
#Local configuration: This locations can either of classpath or locations in the filesystem.
native:
#Reads from a specific filesystem folder
search-locations: classpath:/config
server:
port: 8071
employee.properties file in config directory
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
employee-dev.properties file
spring.datasource.url=jdbc:mysql://db:3306/employee?allowPublicKeyRetrieval=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
This is probably because the container of config server with hostname configserver is not up. I am not sure what hostname I should provide. Even if I want to build the image of employee service by starting the container of config server, it won't be on configserver host but on localhost. This is probably why the build is failing?
I want to build the Docker image of employee service so that its container can be fired up using the docker-compose up command
Edit: This question is similar but I already have the spring-cloud-starter-config dependency added in my client service and it still gives me the same error on build
Edit 2
You don't have to separately build a Docker image for the client service at all!
When I ran docker-compose up command I noticed the following line in output
c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://configserver:8071
But I was still not sure if it was actually reading the data from the config server. So I purposely added incorrect database credentials in config server properties file for my service and the service startup failed! Now I am sure that my employee service is reading the data from the config server
I am still not sure how can I achieve creating a new Docker image for my employee service.
Did you try changing the URL param db to actual host of vhostname ?
db =change it to IP addess or accessable load balancer URL
spring.datasource.url=jdbc:mysql://db:3306/employee?allowPublicKeyRetrieval=true&useSSL=false

Profile based Spring Cloud Config Server client with optional local developer properties

My Goal:
Having the Spring Cloud Config Server import active and provide a way for developers to have an optional property file on their machine.
My Config Server is up and running using org.springframework.cloud:spring-cloud-config-server:3.1.3 and #EnableConfigServer on the main class. Http requests to the concrete endpoint yield the expected result. This server should provide important environment configurations for a developer for his/her local setup.
$ curl http://localhost:8888/test-application/dev
{"name":"test-application","profiles":["dev"],"label":null,"version":null,"state":null,"propertySources":[{"name":"classpath:/cfg/test-application/application-dev.yml","source":{"server.port":1111}},{"name":"classpath:/cfg/test-application/application.yml","source":{"server.port":8000}}]}
Where localhost:8888 is my Config Server and test-application ist the name of the client application (defined via spring.application.name). The provided dev is the currently active profile on the client (The dev profile indicates a locally running software, there is no dev environment).
Clients configuration:
application.yml
spring:
application:
name: test-application
config:
import:
- configserver:http://localhost:8888 # <- pull the configuration from the configserver
- optional:file:/absolute/path/to/the/project/root/ # <- if there are any additional configuration files, use them
The client uses the following dependencies:
org.springframework.boot:spring-boot-starter-web:2.7.0
org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.3
org.springframework.cloud:spring-cloud-starter:3.1.3
org.springframework.cloud:spring-cloud-starter-config:3.1.3
As shown above, the "base" application.yml configured server.port=8000 where the profile specific is set to server.port=1111. When reading the documentation this behaviour is correct. But my local developer configuration contains server.port=2222. This was ignored.
Here comes the problem:
When starting the client application, i can see the following log statements:
Fetching config from server at : http://localhost:8888
Located environment: name=test-application, profiles=[default], label=null, version=null, state=null
Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-classpath:/cfg/test-application/application-dev.yml'}, BootstrapPropertySource {name='bootstrapProperties-classpath:/cfg/test-application/application.yml'}]
The following 1 profile is active: "dev"
Tomcat initialized with port(s): 1111 (http)
Initializing Spring embedded WebApplicationContext
Tomcat started on port(s): 1111 (http) with context path ''
Started TestApplicationKt in 2.234 seconds (JVM running for 2.762)
The configuration evaluation result from spring was to choose port 1111 instead of the wanted 2222 within the application-dev.yml located in the project root (developer config).
Wrapped up:
Three config files:
config server application.yml (port: 8000)
config server application-dev.yml (port: 1111)
project root developer config application-dev.yml (port: 2222) <- I want this file to have precedence over the other two.
When running the debugger, i see these found property sources within the injected Environment bean. The wanted developer file is within this list and the property source content is correct (server.port=2222).
Does anyone have an idea how to solve this problem?
I have created a project that reproduces this exact behaviour. Link to GitHub.
Thanks in advance!
Is the dev profile active when application is running in dev environment or it's also active when running locally?
Ideally you should have 2 different profiles for dev and local and you can enable config server only when dev profile is active.
You can rename your local property file as application-local.yml and disable spring cloud config when profile local is active.
You can put below code in bootstrap.yml(create new file beside application.yml) and remove config server configurations from application.yml
---
spring:
application:
name: test-application
config:
activate:
on-profile: dev
import:
- configserver:http://localhost:8888 # <- pull the configuration from the configserver
- optional:file:/absolute/path/to/the/project/root/ # <- if there are any additional configuration files, use them
---
spring:
application:
name: test-application
config:
activate:
on-profile: local
cloud:
config:
enabled: false
EDIT: Actual fix
Thanks for sharing reproducible example.
All you need to do is remove local application-dev.yml location reference from client application.yml and add it to configServer application.yml as shown in belolow screenshots.
/client/src/main/resources/application.yml
And put it in configServer application.yml at the end of search-locations. Order matters so please make sure you put overriding location/s at the end.
/configServer/src/main/resources/application.yml
Build and start both the applications and you will see client application server started on port 2222

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Fa

I am developing a web application by using the Spring Boot, Spring Cloud Config and Docker. There are 3 projects. One is springboot web, Spring Cloud Config Server and MySql Database. I have use the Spring Boot Web with Themeleaf. It's basically perform a CRUD operation. In the development phase it's working fine. But when I deploy it in the Docker
Spring-Boot webapp container(springboot-thymeleaf-web-crud) is giving me the following error--
APPLICATION FAILED TO START
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
I have created 3 container on Docker Compose file.
version: '3'
services:
springboot-thymeleaf-web-crud:
image: numery/springboot-thymeleaf-web-crud:latest
networks:
- employee-network
ports:
- 8080:8080
depends_on:
- employee-database
- spring-cloud-config-server-employee
spring-cloud-config-server-employee:
image: numery/spring-cloud-config-server-employee:latest
networks:
- employee-network
ports:
- 8888:8888
employee-database:
image: mysql:5
networks:
- employee-network
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=employee_directory
volumes:
- /home/numery/Docker-Database/employee_directory:/var/lib/mysql
networks:
employee-network:
SpringBoot Web Application.properties is given below
spring.application.name=employee-service-mysql
server.port=8080
spring.cloud.config.uri=http://spring-cloud-config-server-
employee:8888
spring.profiles.active=dev
SpringBoot Config Server is providing the following properties--
spring.datasource.url: jdbc:mysql://employee-
database:3306/employee_directory?
useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username: root
spring.datasource.password: rootpassword
spring.datasource.validationQuery: SELECT 1
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.tomcat.max-wait: 20000
spring.tomcat.max-active: 50
spring.tomcat.max-idle: 20
spring.tomcat.min-idle: 15
spring.jpa.properties.hibernate.dialect:
org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql: true
spring.jpa.format-sql: true
spring.jpa.database: MYSQL
spring.jpa.hibernate.ddl-auto: create
Out of these 3 containers Mysql and Spring Cloud Config container is working fine. But for the Spring Boot Webapp(springboot-thymeleaf-web-crud) is exiting by giving the error above.
Note: I use the same datasouce(Spring Data JPA) configuration on some other SpringBoot Rest API. Which are working fine. But this is the first time I am using SpringBoot Web. Do I need to explicitly define any configuration on the data-source.
Please help!!
The datasource URL, that is spring.datasource.url: jdbc:mysql://employee- may be wrong.
OR Should add your datasource url to your Application.properties file
The url should be in the format jdbc:oracle:thin:#hostname:portNumber/schemaName
For further details and clarification, Not using the hostname and port in jdbc url
I perform the following task to solve the problem--
1) We should have up and running the mysql
container.
2) Inspect mysql container which ip running--
docker inspect mysqlcontainer | grep IP
3) Add the IP of that mysql container to my
springboot web app--
"spring.datasource.url:
jdbc:mysql://172.20.0.2:3306/employee_directory?
useSSL=false&serverTimezone
=UTC&useLegacyDatetimeCode=false"
4) run mvn clean, mvn install and build the
SpringBoot Web image.
5) If we down the container we need to perform the
same task again. Because each time Mysql
container obtain the different ip.

How to create Spring Cloud Config Client with env specific configuration?

I have facing an issue with Spring Cloud Config Server and Eureka Server Profiling.
Let's say I have 3 services with their name ("spring.application.name") as :
myapp-svc
myapp-spring-cloud-config-svc
myapp-spring-eureka-svc
I want to deploy each service in 2 regions ( dev and prod ). In Dev region, each service will run on localhost and in prod it will have some different url. 'myapp-spring-cloud-config-svc' in dev region will point to local git repo, while in prod region it will point to remote git repo.I can have 2 configurations:
1) When I start 'myapp-svc' service in local, it should connect to 'myapp-spring-cloud-config-svc' in dev.
I can do this by setting spring.cloud.config.uri = .
But the issue with this set up is that the property needs to be defined in bootstrap.properties.
So, If deploy 'myapp-svc' to prod, I will have to change config uri there to point it to prod config service which in turn would need another build creation.
This doesn't seem like a good solution, what if I have 50 app related services, I can't change this property in each one of them before prod deployment.
I tried setting spring.cloud.config.uri in application-dev.properties of 'myapp-svc' but it doesn't work. As per docs, it must be changed in bootstrap.
So, how do I implement this without having to create new build for prod ?
2) I can first call eureka and then using eureka I can call config service here.
The problem here is also same.
If I use eureka to look up config then "eureka.client.serviceUrl.defaultZone" must be defined in "bootstrap.yml".
See this:https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_client.html
So, in this case too, I need to change eureka url before deploying this service to prod.
Please help me on this...!!
Here is how, the properties, yml looks like for each of the above mentioned services:
1) myapp-svc:
1.1)bootstrap.yml
spring:
application:
name: myapp-svc
cloud:
config:
discovery:
enabled: true
serviceId: myapp-spring-cloud-config-svc
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8762/eureka/
server:
port: 8082
2) myapp-spring-cloud-config-svc:
2.1)application-dev.properties:
spring.cloud.config.server.git.uri=file:///C:/config-repo
eureka.client.serviceUrl.defaultZone=http://localhost:8762/eureka
2.2)application-prod.properties:
spring.cloud.config.server.git.uri=https://github.com/<mygit Repo>
2.3)bootstrap.proerties:
spring.application.name=myapp-spring-cloud-config-svc
server.port=8888
3) myapp-spring-eureka-svc
3.1)bootstrap.proerties
spring.application.name=myapp-spring-eureka-svc
server.port=8762
1) You can have profile specific bootstrap-<profile>.properties (like for application-<profile>.properties) for each supported profile to avoid rebuilding your application for each env. Then just pass application profile using to your application during start-up. Spring will load correct bootstrap-<profile>.properties and will connect to proper configuration server (or eureka, etc). Example:
java -jar your-app.jar --spring.profiles.active=dev
2) You can pass your URLs externally as custom properties (same as with profile above) and have smth like this in bootstrap.properties. Example:
spring.cloud.config.uri=${config.server.url}
then pass --config.server.url= ... during start-up.
3) You can pass Spring properties in the same way during start-up. Example:
java -jar your-app.jar --spring.cloud.config.uri= ...
4) You can use system env variables. Example:
spring.cloud.config.uri=${SYSTEM_ENV_CLOUD_CONFIG_URI}

How to ask Spring Cloud Config server to checkout configuration from specific branch?

I have following Spring cloud config application.yml:
spring:
application:
name: configserver
cloud:
config:
server:
git:
uri: https://xyz#bitbucket.org/xyz/microservices-configs.git
username: xyz
password: xyz
basedir: target/configs
server:
port: 8881
Following is my bootstrap.yml of user microservice:
spring:
application:
name: userservice
cloud:
config:
uri: http://localhost:8881/
Scenario - 1
When I hit config server in browser like this:
http://localhost:8881/development/userservice-development.yml
It serves file properly. and when I look at basedir i.e. target/config, I see:
- userservice.yml
- gateway.yml
Exactly what I wanted, Since I added this two files only in development branch.
Scenario - 2
When I run my userservice microservice project using following command:
mvn clean spring-boot:run -Dspring.profiles.active=development
It fetches the right file from git, but it checkout from master branch ! but not from the development branch as I am expecting. am I expecting right ? (FYI I have both development and production yml in master branch)
So the question is, how do we go for using config server ? Is there any configuration which we can set to fetch yml from that particular branch only ? I believe we need to set some label, because as per documentation, default label is master. Can anyone let me know how do we go for setting label in above scenario ?
According to the documentation, the configuration you want to set in your config client is:
spring.cloud.config.label=mybranch
Where mybranch is an existing branch in your git repo.
You can specify the default branch (more generally, Git label) that a config server uses if a client does not specify the label, via property spring.cloud.config.server.git.default-label, perhaps this is what you are after? Certainly solves the issue for me!
If only use the branch in a yml file just configure:
spring:
cloud:
config:
server:
git:
uri: https://gitlab.com/somerepo.git
username: someuser
password: somepass
default-label: branchname
Config server designed to use profile to separate environment.
Example:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
The branching make configuration inconsistency.
Concept of config server is based on 12-factor config (http://12factor.net/config ) .
Check it out for detail reason.

Resources