package de.codecentric.boot.admin.client.registration;
import static org.springframework.util.StringUtils.trimLeadingCharacter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import org.springframework.boot.actuate.autoconfigure.ManagementServerProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.util.UriComponentsBuilder;
import de.codecentric.boot.admin.client.config.AdminClientProperties;
/**
* Default implementation for creating the {@link Application} instance which gets registered at the
* admin server.
*
* @author Johannes Edmeier
* @author Rene Felgenträger
*/
public class DefaultApplicationFactory implements ApplicationFactory {
private AdminClientProperties client;
private ServerProperties server;
private ManagementServerProperties management;
private Integer localServerPort;
private Integer localManagementPort;
private String healthEndpointPath;
public DefaultApplicationFactory(AdminClientProperties client,
ManagementServerProperties management, ServerProperties server,
String healthEndpointPath) {
this.client = client;
this.management = management;
this.server = server;
this.healthEndpointPath = healthEndpointPath;
}
@Override
public Application createApplication() {
return Application.create(getName()).withHealthUrl(getHealthUrl())
.withManagementUrl(getManagementUrl()).withServiceUrl(getServiceUrl())
.withMetadata(getMetadata()).build();
}
protected String getName() {
return client.getName();
}
protected String getServiceUrl() {
if (client.getServiceUrl() != null) {
return client.getServiceUrl();
}
if (getLocalServerPort() == null) {
throw new IllegalStateException(
"serviceUrl must be set when deployed to servlet-container");
}
return UriComponentsBuilder.newInstance().scheme(getScheme(server.getSsl()))
.host(getServiceHost()).port(getLocalServerPort()).path(server.getContextPath())
.toUriString();
}
protected String getManagementUrl() {
if (client.getManagementUrl() != null) {
return client.getManagementUrl();
}
if (getLocalManagementPort() == null
|| getLocalManagementPort().equals(getLocalServerPort())) {
return UriComponentsBuilder.fromHttpUrl(getServiceUrl())
.pathSegment(server.getServletPrefix().split("/"))
.pathSegment(trimLeadingCharacter(management.getContextPath(), '/').split("/"))
.toUriString();
}
Ssl ssl = management.getSsl() != null ? management.getSsl() : server.getSsl();
return UriComponentsBuilder.newInstance().scheme(getScheme(ssl)).host(getManagementHost())
.port(getLocalManagementPort()).path(management.getContextPath()).toUriString();
}
protected String getHealthUrl() {
if (client.getHealthUrl() != null) {
return client.getHealthUrl();
}
return UriComponentsBuilder.fromHttpUrl(getManagementUrl())
.pathSegment(trimLeadingCharacter(getHealthEndpointPath(), '/').split("/"))
.toUriString();
}
protected Map<String, String> getMetadata() {
return client.getMetadata();
}
protected String getServiceHost() {
InetAddress address = server.getAddress();
if (address == null) {
address = getLocalHost();
}
return getHost(address);
}
protected String getManagementHost() {
InetAddress address = management.getAddress();
if (address != null) {
return getHost(address);
}
return getServiceHost();
}
protected InetAddress getLocalHost() {
try {
return InetAddress.getLocalHost();
} catch (UnknownHostException ex) {
throw new IllegalArgumentException(ex.getMessage(), ex);
}
}
protected Integer getLocalServerPort() {
return localServerPort;
}
protected Integer getLocalManagementPort() {
return localManagementPort;
}
protected String getHealthEndpointPath() {
return healthEndpointPath;
}
protected String getScheme(Ssl ssl) {
return ssl != null && ssl.isEnabled() ? "https" : "http";
}
protected String getHost(InetAddress address) {
return client.isPreferIp() ? address.getHostAddress() : address.getCanonicalHostName();
}
@EventListener
public void onApplicationReady(ApplicationReadyEvent event) {
if (event.getApplicationContext() instanceof WebApplicationContext) {
localServerPort = event.getApplicationContext().getEnvironment()
.getProperty("local.server.port", Integer.class);
localManagementPort = event.getApplicationContext().getEnvironment()
.getProperty("local.management.port", Integer.class, localServerPort);
}
}
}