Hi I am haveing a spring boot rest based application . I have added a couple of properties related to elastic search in my application-dev.yml and application-prod.yml file . These properties are injected into my PerformanceReportingRepository class . however they are set to null .
so following is my yml definition .
# ===================================================================
# Standard Spring Boot properties.
# Full reference is available at:
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
# ===================================================================
logging:
level:
ROOT: TRACE
com.openmind.primecast: DEBUG
io.github.jhipster: TRACE
spring:
profiles:
active: dev
include: swagger
devtools:
restart:
enabled: true
livereload:
enabled: false # we use gulp + BrowserSync for livereload
jackson:
serialization.indent_output: true
data:
cassandra:
contactPoints: localhost
protocolVersion: V4
compression: LZ4
keyspaceName: Openmind
mail:
host: localhost
port: 25
username:
password:
properties:
mail:
smtp:
auth: true
starttls.enable: true
messages:
cache-seconds: 1
thymeleaf:
cache: false
http:
multipart:
maxFileSize: 150MB
maxRequestSize: 150MB
# ===================================================================
# To enable SSL, generate a certificate using:
# keytool -genkey -alias primecast -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
#
# You can also use Let's Encrypt:
# https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
#
# Then, modify the server.ssl properties so your "server" configuration looks like:
#
# server:
# port: 8443
# ssl:
# key-store: keystore.p12
# key-store-password: <your-password>
# key-store-type: PKCS12
# key-alias: primecast
# ===================================================================
server:
port: 8080
# ===================================================================
# JHipster specific properties
#
# Full reference is available at: http://www.jhipster.tech/common-application-properties/
# ===================================================================
jhipster:
http:
version: V_1_1 # To use HTTP/2 you will need SSL support (see above the "server.ssl" configuration)
cache: # Cache configuration
hazelcast: # Hazelcast distributed cache
time-to-live-seconds: 3600
backup-count: 1
management-center: # Full reference is available at: http://docs.hazelcast.org/docs/management-center/3.9/manual/html/Deploying_and_Starting.html
enabled: false
update-interval: 3
url: http://localhost:8180/mancenter
# CORS is only enabled by default with the "dev" profile, so BrowserSync can access the API
cors:
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
exposed-headers: "Authorization,Link,X-Total-Count"
allow-credentials: true
max-age: 1800
security:
authentication:
jwt:
secret: my-secret-token-to-change-in-production
# Token is valid 24 hours
token-validity-in-seconds: 86400
token-validity-in-seconds-for-remember-me: 2592000
mail: # specific JHipster mail property, for standard properties see MailProperties
from: primecast#localhost
base-url: http://127.0.0.1:8080
metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
jmx.enabled: true
graphite: # Use the "graphite" Maven profile to have the Graphite dependencies
enabled: false
host: localhost
port: 2003
prefix: primecast
prometheus: # Use the "prometheus" Maven profile to have the Prometheus dependencies
enabled: false
endpoint: /prometheusMetrics
logs: # Reports Dropwizard metrics in the logs
enabled: false
report-frequency: 60 # in seconds
logging:
logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
enabled: false
host: localhost
port: 5000
queue-size: 512
google:
accessToken: AIzaSyBasWNyK7ELbLlopD3anXrJCgtXUPRZYN8
endpoint: https://www.googleapis.com/urlshortener/v1/url
urlshortener:
is.gd:
endpoint: https://is.gd
http:
proxyEnabled: false
proxyHost:
proxyPort:
password:
expiryInDays: 90
historyCount: 3
expiryEmailAlertInDays: 3
policy: '^(?!.*(.)\1\1)(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!#$%^&*-]).{8,}.*$'
file:
size: 5242880
elasticsearch:
host: localhost
port: 9200
and my repository class is
#Repository
public class PerformanceReportingRepository {
#Value("${elasticsearch.host}")
private String host;
#Value("${elasticsearch.port}")
private Integer port;
#Value("${file.size}")
private long fileUploadSizeLimit;
private RestHighLevelClient elasticSearchClient;
public PerformanceReportingRepository() {
System.out.println(this.fileUploadSizeLimit);
this.elasticSearchClient = new RestHighLevelClient(RestClient.builder(new HttpHost(host, port)));
}
public void setElasticSearchClient(RestHighLevelClient elasticSearchClient) {
this.elasticSearchClient = elasticSearchClient;
}
}
However the bean creation fails because host and port are not resolved from the yaml file.
I am sharing the project in https://github.com/prasanthmp500/mep.git
please checkout the branch ENG-170-performance-reports
appreciate any help
thanks a lot
Related
I am trying to setup a openapi specification and publish the API with Apache Camel and Spring. I tried using restConfiguration, adding the property in the application.yaml, and using the #OpenApiProperty on the app. Everytime the generated yaml reads:
- servers
- url: ""
platform:
# not used
urlrewrite:
enabled: false
token: ${LOCAL_TOKEN:}
apim:
token_ep: ${x/token}
client:
username: ${apim_client_username:}
password: ${apim_client_password:}
consumerKey: ${apim_client_id:}
consumerSecret: ${apim_client_secret:}
endpointsOrchestrated:
server: myServer
emr-endpoint: xxxxxxxx
triggerName: ${PLATFORM_MODULE_ID}
env: dev
domain: ${PLATFORM_MODULE_DOMAIN}
openapi:
title: My Sample api
version: 1.0.0
camel:
dataformat:
jackson:
auto-discover-object-mapper: true
springboot:
tracing: false
rest:
host: myhost.com
port: 8080
spring:
application:
name: aaa
profiles:
active: ${ENV:local}
server:
servlet:
context-path: /
port: ${TOMCAT_PORT:8080}
host: localhost
# MAX HTTP THREADS
tomcat:
threads:
max: ${MAIN_HTTP_THREADS:200}
I have searched over stackoverflow & tried alot of solutions but with no result.
I have 2 containers one is for eureka server and another one for spring cloud gateway.
I'm running these 2 containers with docker-compose but spring-cloud-gateway didn't register to eureka server.
I'm using https. On localhost everything is working as expected but when I jumped to containers this is the problem of unregistered clients.
eureka.server.yml:
eureka:
client:
fetch-registry: false
register-with-eureka: false
instance:
secure-port-enabled: true
non-secure-port-enabled: false
server:
port: 8761
ssl:
enabled: true
key-alias: statement
key-store: classpath:statement-keystore.p12
key-store-password: secret
key-store-type: PKCS12
spring:
application:
name: netflix-eureka
spring.cloud.gateway.yml:
eureka:
instance:
nonSecurePortEnabled: false
securePortEnabled: true
securePort: 8765
prefer-ip-address: true
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: https://localhost:8761/eureka
level:
org:
springframework:
cloud:
gateway: DEBUG
reactor:
netty:
http:
client: DEBUG
server:
port: 8765
ssl:
enabled: true
key-alias: statement
key-store: classpath:statement-keystore.p12
key-store-password: secret
key-store-type: PKCS12
spring:
application:
name: api-gateway
cloud:
config:
enabled: false
gateway:
discovery:
locator:
enabled: true
httpclient:
wiretap: true
httpserver:
wiretap: true
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "https://localhost:4200"
allowedHeaders: "*"
allowedMethods:
- GET
- POST
- PUT
- DELETE
spring.cloud.gateway.Dockerfile:
FROM openjdk:11-jre-slim
LABEL Description="SPring cloud gateway" Version="0.0.1"
ARG VERSION=0.0.1
VOLUME /tmp
ADD target/api-gateway-${VERSION}-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
eureka.server.Dockerfile:
FROM openjdk:11-jre-slim
LABEL Description="Eureka Server" Version="1.0"
ARG VERSION=1.0
VOLUME /tmp
ADD target/eureka-server-${VERSION}-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
docker-compose.yml:
version: '3.7'
services:
netflix-eureka:
image: abraham/netflix-eureka
container_name: "netflix-eureka"
ports:
- "8761:8761"
networks:
- statement-network
api-gateway:
image: abraham/api-gateway
container_name: "api-gateway"
ports:
- "8765:8765"
networks:
- statement-network
environment:
eureka.client.service-url.default-zone: https://netflix-eureka:8761/eureka
depends_on:
- netflix-eureka
links:
- netflix-eureka
networks:
abraham-network:
I have a springboot based microservice application.
id 'org.springframework.boot' version '2.5.4'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id "com.palantir.docker" version "0.26.0"
id "com.palantir.docker-run" version "0.26.0"
id 'pl.allegro.tech.build.axion-release' version '1.13.2'
Database is mysql5.7 aurora rds
'mysql', name: 'mysql-connector-java', version: '8.0.28'
hikaricp - 4.0.3
I am witnessing one strange surge in cpu utilisation stats on RDS performance insight dashboard is that even when there are no requests on my app server, mysql still shows high cpu utilization.
Here are the screen shots:
we can observe from the logs that there are no requests on server but when the connection passes its max life, surge in cpu utilization on RDS aurora mysql:
"connection has passed maxLifetime" -> and the top sql shows set autocommit = 0 is the highest number of queries being fired.
Here are my configurations:
application.yml
spring:
application:
name: catalogue
profiles:
# The commented value for `active` can be replaced with valid Spring profiles to load.
# Otherwise, it will be filled in by gradle when building the JAR file
# Either way, it can be overridden by `--spring.profiles.active` value passed in the commandline or `-Dspring.profiles.active` set in `JAVA_OPTS`
active: dev
group:
dev:
- dev
- api-docs
# Uncomment to activate TLS for the dev profile
#- tls
prod:
- prod
- api-docs
# Uncomment to activate TLS for the dev profile
#- tls
stage:
- stage
jmx:
enabled: false
data:
web:
pageable:
default-page-size: 20
max-page-size: 20
jpa:
repositories:
bootstrap-mode: deferred
jpa:
open-in-view: false
properties:
hibernate.jdbc.time_zone: UTC
hibernate.id.new_generator_mappings: true
hibernate.connection.provider_disables_autocommit: true #https://vladmihalcea.com/why-you-should-always-use-hibernate-connection-provider_disables_autocommit-for-resource-local-jpa-transactions/
hibernate.cache.use_second_level_cache: true
hibernate.cache.region.factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory
hibernate.cache.use_query_cache: false
hibernate.javax.cache.missing_cache_strategy: create
# modify batch size as necessary
hibernate.jdbc.batch_size: 20
hibernate.order_inserts: true
hibernate.order_updates: true
hibernate.batch_versioned_data: true
hibernate.query.fail_on_pagination_over_collection_fetch: true
hibernate.query.in_clause_parameter_padding: true
hibernate.dialect: org.hibernate.dialect.MySQL5InnoDBDialect
javax.persistent.sharedCache.mode: ENABLE_SELECTIVE
hibernate:
ddl-auto: none
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
messages:
basename: i18n/messages
main:
allow-bean-definition-overriding: true
task:
execution:
thread-name-prefix: catalogue-task-
pool:
core-size: 2
max-size: 50
queue-capacity: 10000
scheduling:
thread-name-prefix: catalogue-scheduling-
pool:
size: 2
thymeleaf:
mode: HTML
output:
ansi:
console-available: true
server:
servlet:
session:
cookie:
http-only: true
tomcat:
mbeanregistry:
enabled: true
threads:
max: 100
compression:
enabled: true
mime-types: "text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json"
min-response-size: 1024
port: 8080
# Properties to be exposed on the /info management endpoint
info:
# Comma separated list of profiles that will trigger the ribbon to show
display-ribbon-on-profiles: 'dev'
management:
endpoints:
web:
exposure:
include: "health,info,metrics,prometheus"
endpoint:
health:
probes:
enabled: true
show-details: always
show-components: always
application-prod.yml
logging:
level:
ROOT: ERROR
org.hibernate.SQL: ERROR
com.pitstop.catalogue: ERROR
com.zaxxer.hikari: ERROR
config: classpath:logback-prod.xml
spring:
devtools:
restart:
enabled: true
additional-exclude: static/**
jackson:
serialization:
indent-output: true
datasource:
auto-commit: false
type: com.zaxxer.hikari.HikariDataSource
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
hikari:
poolName: CatalogJPAHikariCP
minimumIdle: 10
maximumPoolSize: 120
connectionTimeout: 30000
idleTimeout: 300000
maxLifetime: 600000
auto-commit: false
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
useLocalSessionState: true
rewriteBatchedStatements: true
cacheResultSetMetadata: true
cacheServerConfiguration: true
maintainTimeStats: true
servlet:
multipart:
location: /data/tmp
jpa:
hibernate:
ddl-auto: none
properties:
spring.jpa.show-sql: true
hibernate.generate_statistics: true
liquibase:
contexts: prod
messages:
cache-duration: PT1S # 1 second, see the ISO 8601 standard
thymeleaf:
cache: false
sleuth:
sampler:
probability: 1 # report 100% of traces
Well, a have tried ALL tutorials, ALL answer on Stackoverflow. But I still face the same error:
On Heroku, Eureka Clients are receiving random ports that I don't know where they come from.
And these random ports are different from Heroku Environment variable $PORT. I know that $PORT is the container Dyno port, not the host port xxxxx.herokuapp.com that the out side world can access. Again, I don't know where these ports come from!!!
The link clients in the Eureka Dashboard stay like this:
hdfb2324-8jfw-83ud-dkdf-9ej90jefj201.qwer.dyno.rt.heroku.com:inight-ws-gateway:${RANDOM PORT}
When I click, go to https://inight-ws-gateway.herokuapp.com:${RANDOM PORT}/actuator/info. I take the Timeout because the correct port is 443, Https default.
I have 3 applications, 1 Eureka Server and 2 Eureka Clients (Zuul Gateway and a trivial Rest API).
Every works ok when I run in my localhost, but when I deploy in Heroku, it's happen.
Eureka Server application.yaml:
server:
port: ${PORT}
spring:
application:
name: '#project.artifactId#' # inight-ws-discovery
version: '#project.version#'
eureka:
client:
fetch-registry: false
register-with-eureka: false
management:
endpoints:
enabled-by-default: false
web:
exposure:
include:
- health
- info
endpoint:
health:
enabled: true
info:
enabled: true
Eureka Client (Zuul gateway) application.yaml:
server:
port: ${PORT}
spring:
application:
name: '#project.artifactId#' # inight-ws-gateway
version: '#project.version#'
eureka:
instance:
hostname: ${INIGHT_EUREKA_INSTANCE_HOSTNAME} # inight-ws-gateway.herokuapp.com
client:
enabled: true
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: ${INIGHT_EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE} # https://inight-ws-discovery.herokuapp.com/eureka/
healthcheck:
enabled: true
zuul:
sensitive-headers:
- Cookie
management:
endpoints:
enabled-by-default: false
web:
exposure:
include:
- health
- info
- routes
endpoint:
health:
enabled: true
info:
enabled: true
routes:
enabled: true
jwt:
config:
privateKey: ${INIGHT_JWT_CONFIG_PRIVATEKEY}
Eureka Client (Rest API) application.yaml:
server:
port: ${PORT}
spring:
application:
name: '#project.artifactId#' # inight-ws-auth
version: '#project.version#'
datasource:
hikari:
schema: inight
jdbc-url: ${INIGHT_DATASOURCE_JDBC_URL}
username: ${INIGHT_DATASOURCE_USERNAME}
password: ${INIGHT_DATASOURCE_PASSWORD}
driver-class-name: ${INIGHT_DATASOURCE_DRIVER_CLASS_NAME}
jpa:
show-sql: ${INIGHT_JPA_SHOW_SQL}
hibernate:
ddl-auto: ${INIGHT_JPA_HIBERNATE_DDL_AUTO}
eureka:
instance:
hostname: ${INIGHT_EUREKA_INSTANCE_HOSTNAME} inight-ws-auth.herokuapp.com
client:
enabled: true
service-url:
defaultZone: ${INIGHT_EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE} https://inight-ws-discovery.herokuapp.com/eureka/
healthcheck:
enabled: true
management:
endpoints:
enabled-by-default: false
web:
exposure:
include:
- health
- info
endpoint:
health:
enabled: true
info:
enabled: true
jwt:
config:
privateKey: ${INIGHT_JWT_CONFIG_PRIVATEKEY}
swagger.basePackage: br.com.bz.inight.auth.controller
my fault!!!!!
I have a couple of microservices on Heroku:
Eureka Server
Zuul Gateway
Some app services
The link on Eureka Server Dashboard, doesn't matter. Whats matter is the https://GATEWAY.herokuapp.com/actuator/routes and the <port enabled="true">80</port> on https://EUREKA_SERVER.herokuapp.com/eureka/apps.
But for this happen (<port enabled="true">80</port> on app services) you MUST ,EXPLICITLY, declare in application.yaml
eureka:
instance:
non-secure-port: 80
hostname: ${EUREKA_CLIENT_INSTANCE_HOSTNAME} # herokuapp_name.herokuapp.com
If you read the documentation, you will see that the property eureka.instance.non-secure-port has the default value 80. I don't know why, but, if you don't declare it, the <port enabled="true">80</port> are not set up on microservices applications on Eureka Server.
Check the tutorial https://blog.heroku.com/managing_your_microservices_on_heroku_with_netflix_s_eureka.
Well, these are my architecture application.yaml:
coffee-eureka-server application.yaml
spring:
application:
name: '#project.artifactId#'
server:
port: ${PORT}
eureka:
instance:
hostname: ${EUREKA_CLIENT_INSTANCE_HOSTNAME} # herokuapp_name.herokuapp.com
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: ${EUREKA_SERVER_URI}/eureka/ # in this case, same value of eureka.instance.hostname, but with https:// prefix, of course
coffee-zuul-gateway application.yaml
spring:
application:
name: '#project.artifactId#'
server:
port: ${PORT}
eureka:
instance:
hostname: ${EUREKA_CLIENT_INSTANCE_HOSTNAME} # herokuapp_name.herokuapp.com
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: ${EUREKA_SERVER_URI}/eureka/
management:
endpoints:
enabled-by-default: true
web:
exposure:
include:
- routes
- info
- health
coffee-simple-ms application.yaml
spring:
application:
name: '#project.artifactId#'
server:
port: ${PORT}
eureka:
instance:
non-secure-port: 80 # <<<<<<<<< HERE
hostname: ${EUREKA_CLIENT_INSTANCE_HOSTNAME} # herokuapp_name.herokuapp.com
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: ${EUREKA_SERVER_URI}/eureka/
When I click, go to https://inight-ws-gateway.herokuapp.com:${RANDOM PORT}/actuator/info. I take the Timeout because the correct port is
443, Https default.
When you are hosting on localhost the link would be: http://localhost:${PORT}/actuator/info
On Heroku this link is: https://inight-ws-gateway.herokuapp.com/actuator/info
The difference:
It is using http secure, https
The port number is "gone"
The hostname inight-ws-gateway.herokuapp.com is automatically translated into a ${IP_ADDRESS}:${PORT}.
You will need to adjust your source code for the https URL generation.
Your web application will run on a port different from the usual http/https port. It does not have to be 80, 8080 or 443. It can be any port. And that port is specified by Heroku through $PORT.
We are using Spring Cloud Gateway before multiple microservices with consul as service discovery. There are several microservices developed in different languages.
Please find build.gradle for the application
buildscript {
ext {
springBootVersion = '2.1.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
ext {
set('springCloudVersion', 'Greenwich.RELEASE')
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-consul-config'
implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.boot:spring-boot-starter-security'
// https://mvnrepository.com/artifact/io.netty/netty-tcnative-boringssl-static
compile group: 'io.netty', name: 'netty-tcnative-boringssl-static', version: '2.0.20.Final'
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
compileOnly 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
Below is the example of API gateway configuration
application.yaml
server:
port: 10000
http:
port: 9000
# enable HTTP2
http2:
enabled: true
# enable compression
compression:
enabled: true
mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
ssl:
enabled: true
key-store: /var/.conf/self-signed.p12
key-store-type: PKCS12
key-store-password: "something"
key-alias: athenasowl
trust-store: /var/.conf/self-signe.p12
trust-store-password: "something"
spring:
application:
name: api-gateway
cloud:
gateway:
discovery:
locator:
enabled: true
predicates:
- Path="'/api/' + serviceId + '/**'"
filters:
- RewritePath="'/api/' + serviceId + '/(?<remaining>.*)'", "serviceId + '/${remaining}'"
management:
security:
enabled: false
server:
port: 10001
ssl:
enabled: false
endpoint:
gateway:
enabled: true
endpoints:
web:
exposure:
include: "*"
health:
sensitive: false
logging:
level:
root: DEBUG
org:
springframework:
web: INFO
pattern:
console: "%-5level %d{dd-MM-yyyy HH:mm:ss,SSS} [%F:%L] VTC : %msg%n"
file: "%-5level %d{dd-MM-yyyy HH:mm:ss,SSS} [%F:%L] VTC : %msg%n"
file: /tmp/log_files/apigateway.log
security:
basic:
enabled: false
There are a few configuration issues which we are facing, they are listed below:
Rewrite URL prefixed with /api/ to respective serviceId registered on consul: We tried to configure predicate to get path prefixed with api to rewrite path and remove api, but still it's not working. So there is another service /hello-service/ registered with consul server, but we want to do API call with /api/hello-service/
Redirect unmatched request to default path: We want to redirect all unmatched request to UI.
Redirecting HTTP to HTTPS on spring cloud gateway: We want to force all request coming to spring gateway to be https
Forwarding HTTPS request to HTTP serviceId registered with consul: Services registered with consul are on HTTP except for the API gateway, we want to be able to send HTTPS request to HTTP backend i.e. terminating HTTPS at API Gateway only.
Any help in solving the above issue would be good
Edit 1:
After some help from #spencergibb, we had setup the spring cloud gateway with https. But There are some additional issues which we faced
If HTTPS is enabled on both API gateway and service both, we received below error
javax.net.ssl.SSLException: handshake timed out at
io.netty.handler.ssl.SslHandler.handshake(...)(Unknown Source)
~[netty-handler-4.1.31.Final.jar:4.1.31.
If HTTPS is enabled on only API gateway, we received below error
There was an unexpected error (type=Not Found, status=404).
org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND
and received
for path https://localhost:8443/api/hello-service/hello/message
Unable to Connect
for path http://localhost:8080/hello-service/hello/message
Please find the link for the sample applications
Instructions:
navigate to consul directory and Start consul server using command ./consul agent -dev
run api-gateway spring boot gradle project
run rest-demo spring boot gradle project
Edit 2
Thank You #spencergibb, We were able to successfully apply ssl on gateway and call the registered services on HTTP. Since Spring Webflux with Netty does not support listening on two ports, we created an additional tcp server bind to http port based on this answer.
There is still some issue we are facing with RewritePath for /api/ rule
predicates:
- name: Path
args:
pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
below is the complete trace for the request
DEBUG 13-02-2019 03:32:01 [FilteringWebHandler.java:86] VTC : Sorted
gatewayFilterFactories:
[OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter#257505fd},
order=-2147482648},
OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.GatewayMetricsFilter#400caab4},
order=-2147473648},
OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyWriteResponseFilter#36e2c50b},
order=-1},
OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardPathFilter#66f0c66d}, order=0},
OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda$360/1720581802#5821f2e6,
order=0},
OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter#27119239},
order=10000},
OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.LoadBalancerClientFilter#568a9d8f},
order=10100},
OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.WebsocketRoutingFilter#6ba77da3},
order=2147483646},
OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyRoutingFilter#73c24516},
order=2147483647},
OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardRoutingFilter#461a9938},
order=2147483647}] TRACE 13-02-2019 03:32:01
[RouteToRequestUrlFilter.java:59] VTC : RouteToRequestUrlFilter start
TRACE 13-02-2019 03:32:02 [NettyWriteResponseFilter.java:68] VTC :
NettyWriteResponseFilter start TRACE 13-02-2019 03:32:02
[GatewayMetricsFilter.java:101] VTC : Stopping timer
'gateway.requests' with tags
[tag(outcome=CLIENT_ERROR),tag(routeId=rewrite_response_upper),tag(routeUri=http://httpbin.org:80),tag(status=NOT_FOUN
A number of things were needed
disable http2
Disable ssl configuration of httpclient
Update locator predicates and filters to use verbose configuration.
Here is the resulting portions of application.yml
server:
port: 8443
http:
port: 8080
servlet:
# enable HTTP2
# http2:
# enabled: true
# enable compression
# ... removed for brevity
spring:
application:
name: api-gateway
cloud:
consul:
enabled: true
gateway:
# httpclient:
# ssl:
# handshake-timeout-millis: 10000
# close-notify-flush-timeout-millis: 3000
# close-notify-read-timeout-millis: 0
# routes:
# - id: ui_path_route
# predicates:
# - Path="'/**'"
# filters:
# - RewritePath="'/**'", "/ui"
discovery:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
locator:
enabled: true
predicates:
- name: Path
args:
pattern: "'/api/' + serviceId + '/**'"
filters:
- name: RewritePath
args:
regexp: "'/api/' + serviceId + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
#... removed for brevity