I got Spring Boot Admin running locally with Eureka Service Discovery (No SBA Dependeny in the Clients). Now i tried to deploy it in Cloudfoundry. According the Documentation, Version 2.0.1 should "support CloudFoundry out of the box".
My Problem is that when I scale a service up to multiple instances, they are all registered under the same hostname and port. Eureka shows me all Instances with their InstanceID that I configured like this:
eureka:
instance:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
But Spring Boot Admin only lists one instance with hostname:port as identifier. I think i have to configure something on the client so that it sends the instance ID per HTTP Header when registering. But i don't know how.
Apparently you have to set the ApplicationId and InstanceIndex that Cloudfoundry generates as Eureka ApplicationId and InstanceId at Startup/ContextRefresh of your Client.
CloudFoundryApplicationInitializer.kt
@Component
@Profile("cloud")
@EnableConfigurationProperties(CloudFoundryApplicationProperties::class)
class CloudFoundryApplicationInitializer {
private val log = LoggerFactory.getLogger(CloudFoundryApplicationInitializer::class.java)
@Autowired
private val applicationInfoManager: ApplicationInfoManager? = null
@Autowired
private val cloudFoundryApplicationProperties: CloudFoundryApplicationProperties? = null
@EventListener
fun onRefreshScopeRefreshed(event: RefreshScopeRefreshedEvent) {
injectCfMetadata()
}
@PostConstruct
fun onPostConstruct() {
injectCfMetadata()
}
fun injectCfMetadata() {
if(this.cloudFoundryApplicationProperties == null) {
log.error("Cloudfoundry Properties not set")
return
}
if(this.applicationInfoManager == null) {
log.error("ApplicationInfoManager is null")
return
}
val map = applicationInfoManager.info.metadata
map.put("applicationId", this.cloudFoundryApplicationProperties.applicationId)
map.put("instanceId", this.cloudFoundryApplicationProperties.instanceIndex)
}
}
CloudFoundryApplicationProperties.kt
@ConfigurationProperties("vcap.application")
class CloudFoundryApplicationProperties {
var applicationId: String? = null
var instanceIndex: String? = null
var uris: List<String> = ArrayList()
}