Currently the scenario is I am trying to implement
I used Jhipster Registry app directly from git-hub to use it as Eureka registry and Spring-Cloud-Config server(be default feature though).
I need to centralize the configurations of micro-service-apps' configurations files in Jhipster registry.
All these we have to do without using Docker as current project doesn't uses Docker. To do that I made changes to bootstrap.yml file as shown below( to run as composite profile though native type with local file system as we don't have access to production git repository. So chose file-system only with dev /composite profile only. Currently my boostrap.yml looks as below
spring:
application:
name: jhipster-registry
profiles:
active: dev
include: composite
cloud:
config:
server:
bootstrap: true
composite:
- type: native #git
search-locations: file:/C:/Jhipster_Eureka/jhipster-registry-master/central-config/
prefix: /config
fail-fast: true
name: jhipster-registry
profile: composite
I have also created a gateway.yml file under central-config folder( gateway is one of micro-service sample app whose configuration I am trying to centralize, be it eureka client, data-source everything which comes under by default to application-dev.yml in the Jhipster micro-service gateway app I generated.) by stating all configuration like below gateway.yml
server:
port: 8888
management:
health:
diskspace:
enabled: false
# ===================================================================
# JHipster Sample Spring Cloud Config.
# ===================================================================
# Property used on app startup to check the config server status
configserver:
name: JHipster Registry config server
status: Connected to the JHipster Registry config server!
# Default JWT secret token (to be changed in production!)
jhipster:
security:
authentication:
jwt:
# It is recommended to encrypt the secret key in Base64, using the `base64-secret` property.
# For compabitibily issues with applications generated with older JHipster releases,
# we use the non Base64-encoded `secret` property here.
# secret: my-secret-key-which-should-be-changed-in-production-and-be-base64-encoded
# The `base64-secret` property is recommended if you use JHipster v5.3.0+
# (you can type `echo 'secret-key'|base64` on your command line)
base64-secret: bXktc2VjcmV0LWtleS13aGljaC1zaG91bGQtYmUtY2hhbmdlZC1pbi1wcm9kdWN0aW9uLWFuZC1iZS1iYXNlNjQtZW5jb2RlZAo=
spring:
profiles:
active: dev
include:
- swagger
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://admin:admin@localhost:8761/eureka/
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://localhost:3306/conference?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true
username: root
password: root
hikari:
poolName: Hikari
auto-commit: false
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
jpa:
show-sql: true
liquibase:
# Remove 'faker' if you do not want the sample data to be loaded automatically
contexts: dev
Issue#1 If I run my registry it's coming up properly without any issue. If I try to run "gateway" micro-service app without defining data-source definitions mentioned in it's own configuration file(application-dev.yml) it's failing at runtime.
Exception Stack trace during runtime
2020-08-06 21:45:58.301 WARN 28804 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'servletEndpointRegistrar' defined in class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration$WebMvcServletEndpointManagementContextConfiguration.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar]: Factory method 'servletEndpointRegistrar' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthEndpoint' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Unsatisfied dependency expressed through method 'healthEndpoint' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'healthContributorRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.health.HealthContributorRegistry]: Factory method 'healthContributorRegistry' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthContributorAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
I am surprised how eureka instance it picked up from that gateway.yml file but not the data source, so what went wrong here?
Issue#2
In the gateway.app yml server.port:8888
is mentioned, but would it be spring-cloud-config-server's port or the micro-service app port e.g., 8083
.
I observed if i try to alter that port from 8888 to 8083 it's giving error at runtime not able to find discovery client, what's the issue or am i still missing something configuration-wise?
Please let me know if the query is detailed enough now to respond.
Docker is absolutely NOT required for JHipster micro services architecture using jhipster-registry, your use case is well supported and the issues you encountered are only due to your configuration errors.
gateway.yml
is not indented correctly so property names for datasource
do not match and this is why you get this error about being unable to find JDBC driver.
The eureka
block in the middle of the spring
block completely broke it and anyway eureka config is shared by all apps so it should be placed in application-dev.yml
and application-prod.yml
.
gateway.yml
as any other files that are in environment repository (central-config
folder when using native) must be exactly the same format as your local application.yml files.
If you are not comfortable with YAML files you could switch to normal properties.
About file naming in native repository, Spring Cloud Config Server doc says:
If the repository is file-based, the server creates an Environment from application.yml (shared between all clients) and foo.yml (with foo.yml taking precedence). If the YAML files have documents inside them that point to Spring profiles, those are applied with higher precedence (in order of the profiles listed). If there are profile-specific YAML (or properties) files, these are also applied with higher precedence than the defaults.
So basically it means that in your central-config
folder you should have these files:
application.yml
: all properties common to all apps when no profile is setapplication-dev.yml
: all properties common to all apps when dev profile is set. This is where you will put the JWT secret for dev, the url for dev Eureka server (often localhost)application-prod.yml
: all properties common to all apps when prod profile is set. This is where you will put the JWT secret for prod, the url for prod Eureka servergateway.yml
: all properties of gateway app when no profile is setgateway-dev.yml
: all properties of gateway app when dev profile is set. This is where you will put dev datasourcegateway-prod.yml
: all properties of gateway app when prod profile is set. This is where you will put prod datasourceSo when your gateway bootstraps with dev profile, it will gets a combination of application.yml, application-dev.yml, gateway.yml and gateway-dev.yml
This mechanism can work only if you follow the naming convention {app name}-{profile}.yml
So, having named a file application-dev-gateway.yml
just meant properties common to all apps with dev-gateway
profile which is probably not what you meant.