All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.kiwiproject.registry.eureka.common.EurekaInstance Maven / Gradle / Ivy
package org.kiwiproject.registry.eureka.common;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static java.util.stream.Collectors.toMap;
import static org.kiwiproject.collect.KiwiMaps.isNullOrEmpty;
import static org.kiwiproject.registry.util.Ports.findFirstPortPreferSecure;
import static org.kiwiproject.registry.util.Ports.findPort;
import static org.kiwiproject.registry.util.ServiceInstancePaths.urlForPath;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Builder;
import lombok.Value;
import lombok.With;
import org.kiwiproject.registry.model.NativeRegistryData;
import org.kiwiproject.registry.model.Port;
import org.kiwiproject.registry.model.Port.PortType;
import org.kiwiproject.registry.model.Port.Security;
import org.kiwiproject.registry.model.ServiceInstance;
import org.kiwiproject.registry.model.ServicePaths;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
/**
* This model matches the format of the data being sent to the Eureka server
*/
@Builder
@Value
@JsonIgnoreProperties(ignoreUnknown = true)
public class EurekaInstance {
private static final String COMMIT_REF_FIELD = "commitRef";
private static final String DESCRIPTION_FIELD = "description";
private static final String VERSION_FIELD = "version";
private static final List METADATA_EXCLUDED_KEYS = List.of(COMMIT_REF_FIELD, DESCRIPTION_FIELD, VERSION_FIELD);
@With
String app;
@With
String status;
@With
Map dataCenterInfo;
@With
Map leaseInfo;
@With
Map rawResponse;
String hostName;
String ipAddr;
String vipAddress;
String secureVipAddress;
Map port;
Map securePort;
int adminPort;
String homePageUrl;
String statusPageUrl;
String healthCheckUrl;
Map metadata;
public String getInstanceId() {
return hostName;
}
public static EurekaInstance fromServiceInstance(ServiceInstance serviceInstance) {
var hostName = serviceInstance.getHostName();
var ports = serviceInstance.getPorts();
var paths = serviceInstance.getPaths();
return EurekaInstance.builder()
.hostName(hostName)
.ipAddr(serviceInstance.getIp())
.vipAddress(serviceInstance.getServiceName())
.secureVipAddress(serviceInstance.getServiceName())
.status(serviceInstance.getStatus().name())
.port(portToEurekaPortMap(findPort(ports, PortType.APPLICATION, Security.NOT_SECURE)))
.securePort(portToEurekaPortMap(findPort(ports, PortType.APPLICATION, Security.SECURE)))
.adminPort(findFirstAdminPortNumberPreferSecure(ports))
.homePageUrl(urlForPath(hostName, ports, PortType.APPLICATION, paths.getHomePagePath()))
.statusPageUrl(urlForPath(hostName, ports, PortType.ADMIN, paths.getStatusPath()))
.healthCheckUrl(urlForPath(hostName, ports, PortType.ADMIN, paths.getHealthCheckPath()))
.metadata(mergeMetadata(serviceInstance))
.build();
}
private static Map mergeMetadata(ServiceInstance serviceInstance) {
var defaultMetadataMap = Map.of(
COMMIT_REF_FIELD, serviceInstance.getCommitRef(),
DESCRIPTION_FIELD, serviceInstance.getDescription(),
VERSION_FIELD, serviceInstance.getVersion()
);
if (isNullOrEmpty(serviceInstance.getMetadata())) {
return defaultMetadataMap;
}
return Stream.concat(defaultMetadataMap.entrySet().stream(), serviceInstance.getMetadata().entrySet().stream())
.collect(toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(value1, value2) -> value2
));
}
private static Map portToEurekaPortMap(Port port) {
return Map.of(
"$", port.getNumber(),
"@enabled", (port.getNumber() > 0)
);
}
private static int findFirstAdminPortNumberPreferSecure(List ports) {
var firstAdminPort = findFirstPortPreferSecure(ports, PortType.ADMIN);
return firstAdminPort.getNumber();
}
public ServiceInstance toServiceInstance() {
return toServiceInstance(NativeRegistryData.IGNORE_NATIVE_DATA);
}
public ServiceInstance toServiceInstance(NativeRegistryData nativeRegistryData) {
var ports = portListFromPortsIgnoringNulls(
buildAdminPortOrNull(),
buildApplicationPortOrNull(port, Security.NOT_SECURE),
buildApplicationPortOrNull(securePort, Security.SECURE));
var serviceMetadata = filterMetadata();
serviceMetadata.put("registryType", "EUREKA");
var upSince = nonNull(leaseInfo) && leaseInfo.containsKey("serviceUpTimestamp")
? Instant.ofEpochMilli((long) leaseInfo.get("serviceUpTimestamp")) : Instant.EPOCH;
var instance = ServiceInstance.builder()
.instanceId(getInstanceId())
.status(ServiceInstance.Status.valueOf(status))
.serviceName(vipAddress)
.hostName(hostName)
.ip(ipAddr)
.commitRef(metadata.get(COMMIT_REF_FIELD))
.description(metadata.get(DESCRIPTION_FIELD))
.version(metadata.get(VERSION_FIELD))
.metadata(serviceMetadata)
.paths(buildPaths())
.ports(ports)
.upSince(upSince)
.build();
if (nativeRegistryData == NativeRegistryData.INCLUDE_NATIVE_DATA) {
return instance.withNativeRegistryData(rawResponse);
}
return instance.withNativeRegistryData(Map.of());
}
private Map filterMetadata() {
return metadata.entrySet().stream()
.filter(entry -> !METADATA_EXCLUDED_KEYS.contains(entry.getKey()))
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
}
private List portListFromPortsIgnoringNulls(Port... ports) {
return Arrays.stream(ports)
.filter(Objects::nonNull)
.toList();
}
private Port buildAdminPortOrNull() {
if (adminPort == 0) {
return null;
}
var secure = isNull(statusPageUrl) || statusPageUrl.startsWith("https") ? Security.SECURE : Security.NOT_SECURE;
return Port.of(adminPort, PortType.ADMIN, secure);
}
private Port buildApplicationPortOrNull(Map portDef, Security secure) {
if (!isEnabled(portDef.get("@enabled"))) {
return null;
}
var portNumber = (int) portDef.get("$");
return Port.of(portNumber, PortType.APPLICATION, secure);
}
private boolean isEnabled(Object enabledFlag) {
if (enabledFlag instanceof String s) {
return Boolean.parseBoolean(s);
}
return (boolean) enabledFlag;
}
private ServicePaths buildPaths() {
return ServicePaths.builder()
.homePagePath(extractPathOrDefault(homePageUrl, ServicePaths.DEFAULT_HOMEPAGE_PATH))
.statusPath(extractPathOrDefault(statusPageUrl, ServicePaths.DEFAULT_STATUS_PATH))
.healthCheckPath(extractPathOrDefault(healthCheckUrl, ServicePaths.DEFAULT_HEALTHCHECK_PATH))
.build();
}
private String extractPathOrDefault(String url, String defaultPath) {
try {
return new URL(url).getPath();
} catch (MalformedURLException e) {
return defaultPath;
}
}
}