Spring Boot and Spring Cloud AWS Data source pool configuration - spring-boot

I have an application on EC2 instance that connect to RDS (MySQL), after 8 hours the DB connection gets closed from MySQL and when the application tries to read/write data I get the below Exception
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed;
nested exception is org.springframework.dao.DataAccessResourceFailureException: could not extract ResultSet;
nested exception is org.hibernate.exception.JDBCConnectionException: could not extract ResultSet] with root cause
java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
also this Exception:
Request processing failed; nested exception is
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction;
nested exception is javax.persistence.PersistenceException: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionEx
ception: No operations allowed after connection closed.] with root cause
java.net.SocketException: Connection timed out (Write failed)
this happens after 8 hours when the application is running.
my config file (YAML):
management:
security:
enabled: false
spring:
profiles: prod
datasource:
tomcat:
max-active: 20
max-idle: 10
min-idle: 5
initial-size: 5
test-while-idle: true
test-on-borrow: true
test-on-return: true
validation-query: select 2 from dual
validation-interval: 3600
time-between-eviction-runs-millis: 5000
jpa:
database: MYSQL
generate-ddl: false
show-sql: true
properties:
globally_quoted_identifiers: true
hibernate:
ddl-auto: none
cloud:
aws:
stack:
auto: false
region:
static: *****
credentials:
instanceProfile: true
rds:
dev-db:
databaseName: dev-db
username: ******
password: ******
I'm using:
Java 1.8
Spring boot 1.5.4.RELEASE (JAR deployment)
Spring Cloud AWS JDBC and AWS autoconfigure, 1.1.3.RELEASE
My POM is:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-aws-autoconfigure</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>io.spring.repo.maven.release</id>
<url>http://repo.spring.io/release/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
My Question is:
How can I configure Data source pool in Spring Boot for AWS (Amazon)? I Logged the DataSource configuration once the App is deployed on EC2, and it not configured to with test-while-idle and other configurations, here is the logs from EC2:
Data source Class Impl: class org.apache.tomcat.jdbc.pool.DataSource
TimeBetweenEvictionRunsMillis: 5000
ValidationInterval: 3000
isTestOnBorrow: false
isTestOnBorrow: false
isTestOnBorrow: false
I checked this Page but cannot find a way to configure the pool from properties file (yaml in my case)...

I found below workaround, but it would be better to support it through same spring AWS-JDBC auto-config properties.. I added the below (from spring cloud aws)
#Configuration
#EnableRdsInstance(dbInstanceIdentifier = "test",password = "secret")
public class ApplicationConfiguration {
#Bean
public RdsInstanceConfigurer instanceConfigurer() {
return new RdsInstanceConfigurer() {
#Override
public DataSourceFactory getDataSourceFactory() {
TomcatJdbcDataSourceFactory dataSourceFactory = new TomcatJdbcDataSourceFactory();
dataSourceFactory.setInitialSize(10);
dataSourceFactory.setValidationQuery("SELECT 1 FROM DUAL");
dataSourceFactory.setValidationInterval(10000);
dataSourceFactory.setTimeBetweenEvictionRunsMillis(20000);
return dataSourceFactory;
}
};
}
}

Related

Spring Boot JASYPT Failure Failed to bind properties under 'spring.datasource.password'

We currently have JASYPT running in boot 2.2.4, jasypt 3.0.2 with not issues. Only exception is the jasypt passphrase is obtained from a DB from a postProcessEnvironment event.
The new Spring Boot 2.3.2, Jaspt 3.0.2 throws the following on startup.
13:27:42.380 [restartedMain] ERROR o.s.b.w.e.tomcat.TomcatStarter onStartup - Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'h2Console' defined in class path resource [org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'h2Console' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Unsatisfied dependency expressed through method 'dataSource' parameter 0; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Could not bind properties to 'DataSourceProperties' : prefix=spring.datasource, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.datasource.password' to java.lang.String
13:27:42.471 [restartedMain] ERROR o.s.b.d.LoggingFailureAnalysisReporter report -
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<jacoco-maven-plugin.ver>0.8.2</jacoco-maven-plugin.ver>
<jasypt.spring.boot.starter.ver>3.0.3</jasypt.spring.boot.starter.ver>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<!-- JASYPT Encryption -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>${jasypt.spring.boot.starter.ver}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
.....
jasypt:
encryptor:
password: fubar
#iv-generator-classname: org.jasypt.RandomIvGenerator
#iv-generator-classname: org.jasypt.NoIvGenerator
spring:
datasource:
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://myDb;databaseName=BAR;sendStringParametersAsUnicode=false
username: Bullwincle
password: ENC(dX8PMJjtC04JBzjSMllTop6s2/seBDHo)
hikari:
connection-timeout: 60000
maximum-pool-size: 5
jpa:
database-platform: org.hibernate.dialect.SQLServerDialect
show-sql: false
generate-ddl: false
hibernate:
ddl-auto: none
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
properties:
hibernate:
jdbc:
time_zone: UTC
#SpringBootApplication
#EnableEncryptableProperties
public class MyApplication {
I do not have a custom Encryptor bean
Application starts with non-encrypted password.
TRIED:
iv-generator-classname: org.jasypt.NoIvGenerator
iv-generator-classname: org.jasypt.RandomIvGenerator
If I down grade JASYPT to 2.1.2 the application starts.
According to their release notes default encryption algorithm has been changed in 3.0.0 so what they suggest is to set these:
jasypt:
encryptor:
algorithm: PBEWithMD5AndDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
This answer is irrelavant of version, if your jasypt.encryptor.password is not the password that you used to encrypt your passwords, then it would fail also because it cant decrypt.

/graphql endpoint returns 404 error during integration test of spring cloud app but not by running the app with mvn spring-boot:run

spring-cloud.version:Greenwich.SR2, spring boot 2.1.7
mvn spring-boot:run makes the endpoint /graphql accessible but not mvn clean verify
I included graphql-java-servlet, javax.servlet-api, graphql-spring-boot-starter-test and graphql-spring-boot-starter, but it stills does not work
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<!-- graphql -->
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>13.0</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-extended-scalars</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>java-dataloader</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>5.10.0</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>5.0.2</version>
</dependency>
<!-- Apache CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>spring-mock-mvc</artifactId>
<version>3.3.0</version>
<scope>test</scope>
</dependency>
Here is my simple test which returns 404:
#Test
public void persons() throws Exception {
Map<String, Object> variables = new HashMap<String, Object>();
GraphQLRequest request = new GraphQLRequest(
"query persons{persons"
+ "{"
+ " id"
+ "}}",
variables,
null);
// SUT
given()
.contentType(ContentType.JSON)
.body(request)
.get(GRAPHQL_PATH)
.then()
.log().body()
.statusCode(200);
}
The test class is annotated with :
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
#TestPropertySource(locations = "classpath:bootstrap-test.yml")
Here is my bootstrap.yml:
spring:
application:
name: crm-service
cloud:
config:
uri: http://localhost:8081
fail-fast: false
password: configPassword
username: user
main:
allow-bean-definition-overriding: true #i dont remember why but i think there is a bug with spring cloud and OAuth2ClientContext
acls-management:
permissions-config-path: permissions-config.json
acl-rules-path: acl-rules.json
eureka:
client:
register-with-eureka: false
fetch-registry: false
graphql:
servlet:
mapping: /graphql
enabled: true

Spring Cloud Config client not loading the value from config server

I am facing below issue while I try to run my Spring Cloud Config Client:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'DATABASE_NAME' in string value "${DATABASE_NAME}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:204
My dependencies in POM.xml are as below:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config</artifactId>
<version>1.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
The bootstrap.yml
spring:
application:
name: my-config-client
cloud:
services:
registrationMethod: route
config:
enabled: true
uri: http://localhost:${config.port:8888}
The application.yml is as below:
# HTTP Server
server:
port: 2222
# Spring properties
spring:
profiles:
active: dev
#Disable HTTP Basic Authentication
security:
basic:
enabled: false
The class where I am trying to access the property is as below:
#RefreshScope
#Component
public class MyProperty {
#Value("${DATABASE_NAME}")
private String databaseName;
public String getDatabaseName() {
return databaseName;
}
}
My config server is running fine. When I use this url on browser http://localhost:8888/configserver/dev, It gives the below result:
{
"name":"configserver",
"profiles":[
"dev"
],
"label":"master",
"version":"c991526a93fb776e37e18e138c7485d894d6ea4f",
"propertySources":[
{
"name":"https://onestash.abc.com/scm/kapmol/microservice-config-repo.git/configserver.properties",
"source":{
"DATABASE_NAME":"ABC",
"CONVERT_USERS":"Y",
"LRDS_JNDI_NAME":"jdbc/tds_new"
}
}
]
}
I tried with all the posts who were facing this issue. But, it is not working for me. May be, I am missing some points. If anybody can provide help, it would be great.
Thanks
There are some breaking changes with the new spring cloud module read more: here.
Bootstrap, provided by spring-cloud-commons, is no longer enabled by
default. If your project requires it, it can be re-enabled by
properties or by a new starter.
To re-enable by properties set spring.cloud.bootstrap.enabled=true or spring.config.use-legacy-processing=true. These need to be set as
an environment variable, java system property or a command line
argument.
The other option is to include the new spring-cloud-starter-bootstrap
It worked for me by adding these dependencies:
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>2020.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
I referred this post answered by 'spencergibb' and able to resolve the issue. I added "spring.config.name" in my bootstrap.yml file of client application and resolved the issue. Now, my bootstrap.yml look like as below:
spring:
application:
name: my-config-client
cloud:
services:
registrationMethod: route
config:
name: configserver
enabled: true
uri: http://localhost:${config.port:8888}

spring boot with spring-data-jpa and full tomcat-jdbc config throws java.lang.ClassNotFoundException for ResetAbandonedTimer

I'm using spring boot 1.3.0.RELEASE with the following pom dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I am trying to get JPA working and it all works fine with the following in my application.properties
# Connection url for the database
spring.datasource.url = jdbc:oracle:thin:#**********
# Username and password
spring.datasource.username = **********
spring.datasource.password = *********
when I switch to full blown dbcp config for tomcat-jdbc as below:
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:#**********
spring.datasource.username=*****
spring.datasource.password=*****
spring.datasource.initial-size=0
spring.datasource.max-active=10
spring.datasource.default-auto-commit=true
spring.datasource.default-transaction-isolation=2
spring.datasource.fair-queue=false
spring.datasource.jdbc-interceptors=ConnectionState;StatementFinalizer;ResetAbandonedTimer"
spring.datasource.jmx-enabled=true
spring.datasource.log-abandoned=true
spring.datasource.max-idle=1
spring.datasource.max-wait=30000
spring.datasource.min-evictable-idle-time-millis=60000
spring.datasource.min-idle=1
spring.datasource.remove-abandoned=true
spring.datasource.remove-abandoned-timeout=300
spring.datasource.test-on-borrow=true
spring.datasource.test-on-return=false
spring.datasource.test-while-idle=false
spring.datasource.time-between-eviction-runs-millis=10000
spring.datasource.use-equals=false
spring.datasource.validation-interval=60000
spring.datasource.validation-query=SELECT 2+2 FROM DUAL
I get the following stack trace
2015-11-20 16:58:18.788 ERROR 48307 --- [nio-8080-exec-1] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to inform interceptor of pool start.
java.lang.ClassNotFoundException: Unable to load class: org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer" from ClassLoader:java.net.URLClassLoader#5bbcaf22;ClassLoader:TomcatEmbeddedWebappClassLoader
context: ROOT
delegate: true
----------> Parent Classloader:
java.net.URLClassLoader#5bbcaf22
at org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:56) ~[tomcat-jdbc-8.0.28.jar:na]
at org.apache.tomcat.jdbc.pool.PoolProperties$InterceptorDefinition.getInterceptorClass(PoolProperties.java:964) ~[tomcat-jdbc-8.0.28.jar:na]\
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:447) [tomcat-jdbc-8.0.28.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:141) [tomcat-jdbc-8.0.28.jar:na]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:115) [tomcat-jdbc-8.0.28.jar:na]
......
......
......
Caused by: java.lang.ClassNotFoundException: org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader.loadClass(TomcatEmbeddedWebappClassLoader.java:74) ~[spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at java.lang.Class.forName0(Native Method) ~[na:1.8.0_20]
at java.lang.Class.forName(Class.java:340) ~[na:1.8.0_20]
at org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:38) ~[tomcat-jdbc-8.0.28.jar:na]
... 147 common frames omitted
This seems to be the case even with different spring boot versions....
Is my config (taken from a spring datasource bean we already use fine) not what boot expects?
cheers
Typo.
Remove " from spring.datasource.jdbc-interceptors=ConnectionState;StatementFinalizer;ResetAbandonedTimer" at the end there.

Micro-services: Zuul & consul in Spring cloud application

I'm trying to create a Spring cloud microservice application using Zuul and Consul.
I have 2 components in my project:
api-gateway microservice using Zuul
Hello world microservice (a simple hello world Rest Webservice)
Here is the code of The api-gateway:
#SpringBootApplication
#EnableZuulProxy
#EnableDiscoveryClient
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
The pom.xml
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M3</version>
</parent>
<properties>
<java.version>1.8</java.version>
<spring.cloud.consul.version>1.0.0.M4</spring.cloud.consul.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<!-- Setup Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<!-- Setup Spring MVC & REST, use Embedded Tomcat -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<!-- Spring Cloud starter -->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-all</artifactId>
<version>${spring.cloud.consul.version}</version>
</dependency>
</dependencies>
application.yml
zuul:
routes:
hello1:
path: /hello1/**
serviceId: microservice-example
logging:
level:
org.springframework: INFO
com.netflix: DEBUG
bootstrap.yml
spring:
application:
name: edge-server
cloud:
consul:
config:
enabled: true
host: localhost
port: 8500
Here is the code of hello microservice:
#SpringBootApplication
#EnableConfigServer
#EnableDiscoveryClient
#RestController
public class Application {
#RequestMapping(value="/hello1",method = RequestMethod.GET)
public String hello() {
System.out.print("hello1");
return "Hello1";
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
bootstrap.yml:
spring:
application:
name: microservice-example
profiles:
active: native
cloud:
consul:
config:
enabled: true
host: localhost
port: 8500
But, when I start the api-gateway I got the following exception:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.netflix.zuul.filters.RouteLocator]: Factory method 'routeLocator' threw exception; nested exception is java.lang.IllegalStateException: Unable to locate service in consul agent: edge-server
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 69 common frames omitted
Caused by: java.lang.IllegalStateException: Unable to locate service in consul agent: edge-server
at org.springframework.cloud.consul.discovery.ConsulDiscoveryClient.getLocalServiceInstance(ConsulDiscoveryClient.java:66) ~[spring-cloud-consul-discovery-1.0.0.M4.jar:1.0.0.M4]
This issue is fixed in Brixton.M3 (1.0.0.M5). As mentioned above this was an issue with spring-cloud-consul. The new version is working fine

Resources