Spring Boot Admin Client showing only details when there is context path - spring

I am running boot admin server with eureka discovery.
Admin Server:
plugins {
id 'org.springframework.boot' version '2.1.7.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "Greenwich.SR2")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'de.codecentric:spring-boot-admin-starter-server:2.1.6'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
Admin Server Application Yml:
spring:
boot.admin.discovery.converter.management-context-path: /admin
application:
name: spring-boot-admin-sample-eureka
eureka: #<1>
instance:
leaseRenewalIntervalInSeconds: 10
health-check-url-path: /admin/health
metadata-map:
startup: ${random.int} #needed to trigger info and endpoint update after restart
management.context-path: ${management.endpoints.web.base-path}
info.path: ${management.endpoints.web.base-path}/info
client:
registryFetchIntervalSeconds: 5
serviceUrl:
defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
management:
endpoints:
web:
exposure:
include: "*" #<2>
endpoint:
health:
show-details: ALWAYS
Client:
plugins {
id 'org.springframework.boot' version '2.1.7.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "Greenwich.SR2")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
// https://mvnrepository.com/artifact/org.jolokia/jolokia-core
compile group: 'org.jolokia', name: 'jolokia-core', version: '1.6.2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
Application Yml
server:
port: 8083
servlet:
context-path: /mypath
#management config
eureka:
instance:
leaseRenewalIntervalInSeconds: 10
health-check-url-path: /admin/health
statusPageUrlPath: /admin/info
metadata-map:
startup: ${random.int} #needed to trigger info and endpoint update after restart
management.context-path: ${management.endpoints.web.base-path}
info.path: ${management.endpoints.web.base-path}/info
client:
registryFetchIntervalSeconds: 5
serviceUrl:
defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
management:
endpoint:
health:
show-details: ALWAYS
endpoints:
web:
base-path: /admin
exposure:
include: '*'
security.basic.enabled: false
info:
component: Processor2
build:
name: Processor2
description: Processor to Roll up PP
version: 1
eureka:
region: ${eureka.client.region}
zone: ${eureka.instance.metadataMap.zone}
us-east-1b: discovery1
us-east-1c: discovery2
us-east-1e: discovery3
dp:
username: admin
password: admin123
spring:
application.name: procerssor2
jmx:
enabled: true
boot:
admin:
client:
instance:
service-url: /mypath
health:
  config:
    enabled: false
Due to the context path the boot admin is just displaying the details. I verified the http://localhost:8080/applications. It looks like below.
{
"name": "PROCERSSOR2",
"buildVersion": null,
"status": "UP",
"statusTimestamp": "2019-08-28T18:32:19.854Z",
"instances": [
{
"id": "804f35b9b73d",
"version": 1,
"registration": {
"name": "PROCERSSOR2",
"managementUrl": "http://192.168.0.8:8083/admin",
"healthUrl": "http://192.168.0.8:8083/mypath/admin/health",
"serviceUrl": "http://192.168.0.8:8083/",
"source": "discovery",
"metadata": {
"management.context-path": "/admin",
"startup": "-518261604",
"management.port": "8083",
"info.path": "/admin/info"
}
},
"registered": true,
"statusInfo": {
"status": "UP",
"details": {
"hystrix": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"details": {
"total": 499963170816,
"free": 366424887296,
"threshold": 10485760
}
},
"refreshScope": {
"status": "UP"
},
"discoveryComposite": {
"status": "UP",
"details": {
"discoveryClient": {
"status": "UP",
"details": {
"services": [
"procerssor2",
"spring-boot-admin-sample-eureka"
]
}
},
"eureka": {
"description": "Remote status from Eureka server",
"status": "UP",
"details": {
"applications": {
"PROCERSSOR2": 1,
"SPRING-BOOT-ADMIN-SAMPLE-EUREKA": 1
}
}
}
}
}
}
},
"statusTimestamp": "2019-08-28T18:32:19.854Z",
"info": {},
"endpoints": [
{
"id": "health",
"url": "http://192.168.0.8:8083/mypath/admin/health"
}
],
"buildVersion": null,
"tags": {}
}
]
}
when I remove the context path. everything work good. Please help

I had the same problem. At my case I only point eureka.instance.metadata-map.management.context-path at ${service.servlet.context-path}/actuator
server:
port: ${service.auth-service.port}
servlet:
context-path: ${service.auth-service.context-path}
eureka.instance.metadata-map.management.context-path: ${service.servlet.context-path}/actuator
So I think according to your code it should be something like /admin/actuator

Related

Merge 2 hashes recursively with jinja2/ansible

I'm trying to merge 2 hashes in ansible, but I'm running into problems. The hash is mostly merged, but the lists inside are not.
I'm using the combine filter for the merge:
config_hash: "{{ inventory_config | combine(host_config, recursive=True, list_merge='append_rp') }}"
Here are the two hashes/dicts I'd like to merge:
inventory_config:
exoscale:
inventory_name: test_inventory
security_groups:
- name: rancher
state: present
rules:
- port: 22
cidr: "1.2.3.4/32"
type: egress
- port: 80
cidr: "0.0.0.0/32"
type: egress
host_config:
exoscale:
name: host
disk_size: 25 GiB
security_groups:
- name: rancher
state: added
rules:
- port: 21
cidr: "1.2.3.4/32"
type: ingress
- port: 8080
cidr: "0.0.0.0/32"
type: ingress
The result:
TASK [debug] *******************************************************************
ok: [instance] => {
"config_hash": {
"exoscale": {
"disk_size": "25 GiB",
"inventory_name": "test_inventory",
"name": "host",
"security_groups": [
{
"name": "rancher",
"rules": [
{
"cidr": "1.2.3.4/32",
"port": 22,
"type": "egress"
},
{
"cidr": "0.0.0.0/32",
"port": 80,
"type": "egress"
}
],
"state": "present"
},
{
"name": "rancher",
"rules": [
{
"cidr": "1.2.3.4/32",
"port": 21,
"type": "ingress"
},
{
"cidr": "0.0.0.0/32",
"port": 8080,
"type": "ingress"
}
],
"state": "added"
}
]
}
}
}
The result I wanted:
"config_hash": {
"exoscale": {
"disk_size": "25 GiB",
"inventory_name": "test_inventory",
"name": "host",
"security_groups": [
{
"name": "rancher",
"rules": [
{
"cidr": "1.2.3.4/32",
"port": 22,
"type": "egress"
},
{
"cidr": "0.0.0.0/32",
"port": 80,
"type": "egress"
},
{
"cidr": "1.2.3.4/32",
"port": 21,
"type": "ingress"
},
{
"cidr": "0.0.0.0/32",
"port": 8080,
"type": "ingress"
}
],
"state": "added"
},
]
}
}
I tried some other options, and it seems that "list_merge='append_rp'" can combine lists of simple items but not hashes.
Any ideas? Thanks for the help!
Your question is complex, i suggest you to use a custom filter:
you create a folder filter_plugins in your playbook folder (i have named the file myfilters.py and the filter custom)
myfilters.py in folder filter_plugins:
#!/usr/bin/python
class FilterModule(object):
def filters(self):
return {
'custom': self.custom
}
def custom(self, invent, host):
isecu = invent['exoscale']['security_groups']
hsecu = host['exoscale']['security_groups']
inventory_name = invent['exoscale']['inventory_name']
name = host['exoscale']['name']
disk_size = host['exoscale']['disk_size']
security_groups = []
inames_present = [elem['name'] for elem in isecu]
# if you have present and added in inventory_config uncomment next lines
# inames_present = []
# inames_added = []
# for elem in isecu:
# if elem['state'] == 'present':
# inames_present.append(elem['name'])
# else:
# inames_added.append(elem['name'])
for it in hsecu:
secuname = it['name']
state = it['state']
if secuname in inames_present:
if state == 'present': #overwrite data
rules = it['rules']
else: #merge
rules = it['rules'] + isecu[inames_present.index(secuname)]['rules']
else:
rules = it['rules']
state = 'added'
security_groups.append({'name': secuname, 'rules': rules, 'state': state})
result = {'exoscale': {'disk_size': disk_size, 'name': name, 'inventory_name': inventory_name, 'security_groups': security_groups}}
#print(result)
return result
the playbook:
---
- hosts: localhost
vars:
inventory_config:
exoscale:
inventory_name: test_inventory
security_groups:
- name: rancher
state: present
rules:
- port: 22
cidr: "1.2.3.4/32"
type: egress
- port: 80
cidr: "0.0.0.0/32"
type: egress
host_config:
exoscale:
name: host
disk_size: 25 GiB
security_groups:
- name: rancher
state: added
rules:
- port: 21
cidr: "1.2.3.4/32"
type: ingress
- port: 8080
cidr: "0.0.0.0/32"
type: ingress
tasks:
- name: set variable
set_fact:
config_hash: "{{ inventory_config | custom(host_config) }}"
- name: Display
debug:
var: config_hash
result:
ok: [localhost] => {
"config_hash": {
"exoscale": {
"disk_size": "25 GiB",
"inventory_name": "test_inventory",
"name": "host",
"security_groups": [
{
"name": "rancher",
"rules": [
{
"cidr": "1.2.3.4/32",
"port": 21,
"type": "ingress"
},
{
"cidr": "0.0.0.0/32",
"port": 8080,
"type": "ingress"
},
{
"cidr": "1.2.3.4/32",
"port": 22,
"type": "egress"
},
{
"cidr": "0.0.0.0/32",
"port": 80,
"type": "egress"
}
],
"state": "added"
}
]
}
}
}
You have an idea how to use a custom filter in ansible.
You just adapt the code python.

Micrometer ElasticSearch convert JSON name to Key

I have a micrometer + spring actuator in my application that shows in this way in kibana:
"name": "jvm_threads_daemon",
"type": "gauge",
"cluster": "cluster_app",
"kubernetes_namespace": "test",
"kubernetes_pod_name": "fargate-ip-10-121-31-148.ec2.internal",
"value": 18
But I would like to convert to this:
"jvm_threads_daemon": "18",
"type": "gauge",
"cluster": "cluster_app",
"kubernetes_namespace": "test",
"kubernetes_pod_name": "fargate-ip-10-121-31-148.ec2.internal",
"value": 18
So, note that I need the metric as a tag name and not inside "name". This is possible in micrometer?
See my application.yml:
management:
endpoints:
web:
exposure:
include: "*"
base-path: /actuator
path-mapping.health: health
endpoint:
health:
probes:
enabled: true
show-details: always
metrics:
export:
elastic:
host: "https://elastico.url:443"
index: "metricbeat-k8s-apps"
user-name: "elastic"
password: "xxxx"
step: 30s
connect-timeout: 10s
tags:
cluster: "cluster_app"
kubernetes.pod.name: ${NODE_NAME}
kubernetes.namespace: ${POD_NAMESPACE}
You can extend/implement your own ElasticMeterRegistry and define your own format.
One thing to consider though: if you do the change you want, how will you able to query/filter/aggregate metrics in Kibana?

pact-jvm-provider-spring-mvc json4s exception

Just trying to understand pact. We are using spring boot, so naturally I went to trying simple setup using pact-jvm-provider-spring-mvc.
My pact file is a simple
{
"consumer": {
"name": "MyConsumer"
},
"provider": {
"name": "MyProvider"
},
"interactions": [
{
"description": "a request for projects",
"providerState": "i have a list of projects",
"request": {
"method": "GET",
"path": "/dogs",
"headers": {
"Accept": "application/json"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": [
{
"dog": "1"
}
]
}
}
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
}
}
}
I added these dependencies to my gradle build:
```
testCompile group: 'com.reagroup', name: 'pact-jvm-provider-spring-mvc_2.10', version: '0.4.0'
testCompile group: 'au.com.dius', name: 'pact-jvm-provider_2.10', version: '2.4.18'
testCompile group: 'au.com.dius', name: 'pact-jvm-provider-junit_2.11', version: '3.4.1'
```
The test class doesn't do much, just creates a controller in spring fashion.
But what I get from running it is
```
org.json4s.package$MappingException: Case classes defined in function bodies are not supported.
at org.json4s.reflect.package$.fail(package.scala:96)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun$9.apply(Reflector.scala:115)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun$9.apply(Reflector.scala:115)
at scala.util.control.Exception$Catch$$anon$2.apply(Exception.scala:137)
at scala.util.control.Exception$Catch$$anon$2.apply(Exception.scala:135)
at scala.util.control.Exception$Catch.apply(Exception.scala:106)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.constructorsAndCompanion(Reflector.scala:115)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.result(Reflector.scala:156)
at org.json4s.reflect.Reflector$.createDescriptor(Reflector.scala:50)
at org.json4s.reflect.Reflector$$anonfun$describe$1.apply(Reflector.scala:44)
at org.json4s.reflect.Reflector$$anonfun$describe$1.apply(Reflector.scala:44)
at org.json4s.reflect.package$Memo.apply(package.scala:39)
at org.json4s.reflect.Reflector$.describe(Reflector.scala:44)
at org.json4s.Extraction$.extract(Extraction.scala:330)
```
It seems like a bug in the underlying jar file which is resolved. But I am just wondering if this is the right approach, can I simply bump the jar version for json4s?
The pact-jvm-provider-spring-mvc is not touched in a while, and the 0.5.0 version never released. Again note that I don't need spring-mvc. I just want to test Pact against my rest api.
I thought there might be another way of doing this.
Make sure the request body matches what the api expects.
I've gotten similar errors (but from jackson) when that was the case.

Spring Cloud Config: NoSuchLabelException

I have a simple Spring Config Server application which consumes the configuration data from a GIT repository. This Config Server works perfectly as expected in my local and development environment. Once deployed to the production server though, I kept seeing this error: org.springframework.cloud.config.server.environment.NoSuchLabelException: No such label: master
Here is the whole JSON return:
{
"status": "DOWN",
"configServer": {
"status": "DOWN",
"repository": {
"application": "app",
"profiles": "default"
},
"error": "org.springframework.cloud.config.server.environment.NoSuchLabelException: No such label: master"
},
"discoveryComposite": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN",
"discoveryClient": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN"
}
},
"diskSpace": {
"status": "UP",
"total": 10434699264,
"free": 6599856128,
"threshold": 10485760
},
"refreshScope": {
"status": "UP"
},
"hystrix": {
"status": "UP"
}
}
So I traced it down to the spring-cloud-config GitHub repo, and saw that it is being thrown here: https://github.com/spring-cloud/spring-cloud-config/blob/b7afa2bb641913b89e32ae258bd6ec442080b9e6/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java#185 This error is thrown by GitCommand class's call() method on line 235 when a Git branch is not found. But I can't for the life of me understand why!!! I have double-checked and verified that the "master" branch does indeed exist in the GIT repository for configuration properties.
The application properties for the Config Server are defined in a bootstrap.yml file, as follows:
server:
port: 8080
management:
context-path: /admin
endpoints:
enabled: false
health:
enabled: true
logging:
level:
com.netflix.discovery: 'OFF'
org.springframework.cloud: 'DEBUG'
eureka:
instance:
leaseRenewalIntervalInSeconds: 10
statusPageUrlPath: /admin/info
healthCheckUrlPath: /admin/health
spring:
application:
name: config-service
cloud:
config:
enabled: false
failFast: true
server:
git:
uri: 'https://some-spring-config-repo.git'
username: 'fakeuser'
password: 'fakepass'
basedir: "${catalina.home}/target/config"`
Any help would be most appreciated!!
Posting this in case someone else finds this uselful
I'm using the below setting in the properties file of the config server to indicate the "main" branch
spring.cloud.config.server.git.default-label=main
Additional info - my git repo is not public , I'm using the new personal access token based authentication instead of the older username/password authentication

Spring Cloud Consul Deregister Failing

I am using Spring Boot / Cloud / Consul (1.0.0.M2 and have tried current code as of 10/6/2015). I'm trying to register/deregister a service that uses a dynamic port and a dynamic id.
I have the following bootstrap:
spring:
cloud:
consul:
config:
enabled: true
host: localhost
port: 8500
And application.yml
spring:
main:
show-banner: false
application:
name: helloService
cloud:
consul:
config:
prefix: config
defaultContext: helloService
discovery:
instanceId: ${spring.application.name}:${spring.application.instance.id:${random.value}}
healthCheckPath: /${spring.application.name}/health
healthCheckInterval: 15s
endpoints:
shutdown:
enabled: true
And in the Key Values under config/application/server.port = 0 for a dynamic port.
The service is registered correctly during startup:
{
"consul": {
"ID": "consul",
"Service": "consul",
"Tags": [],
"Address": "",
"Port": 8300
},
"helloService-6596692c4e8af31ddd1589b0d359899f": {
"ID": "helloService-6596692c4e8af31ddd1589b0d359899f",
"Service": "helloService",
"Tags": [],
"Address": "",
"Port": 50307
} }
After issuing the shutdown:
curl http://localhost:50307/shutdown -X POST
{"message":"Shutting down, bye..."}
The service is still registered and the health check starts failing.
{
"consul": {
"ID": "consul",
"Service": "consul",
"Tags": [],
"Address": "",
"Port": 8300
},
"helloService-6596692c4e8af31ddd1589b0d359899f": {
"ID": "helloService-6596692c4e8af31ddd1589b0d359899f",
"Service": "helloService",
"Tags": [],
"Address": "",
"Port": 50307
} }
What is missing?

Resources