All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kiwiproject.registry.eureka.common.EurekaResponseParser Maven / Gradle / Ivy

There is a newer version: 2.1.4
Show newest version
package org.kiwiproject.registry.eureka.common;

import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Verify.verify;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.kiwiproject.base.KiwiObjects.firstNonNullOrNull;
import static org.kiwiproject.base.KiwiPreconditions.checkArgumentNotNull;

import com.google.common.annotations.VisibleForTesting;
import lombok.experimental.UtilityClass;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.kiwiproject.net.KiwiInternetAddresses;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@UtilityClass
public class EurekaResponseParser {

    private static final String INSTANCE_KEY = "instance";

    @SuppressWarnings("unchecked")
    public static List parseEurekaApplicationsResponse(Map eurekaResponse) {
        checkArgumentNotNull(eurekaResponse, "Eureka applications response must not be null");

        var applications = (Map) eurekaResponse.get("applications");

        checkState(nonNull(applications), "Eureka data must contain a key 'applications' that contains a Map");

        var applicationOrApplicationList = applications.get("application");

        var eurekaInstances = new ArrayList();

        if (nonNull(applicationOrApplicationList)) {
            if (applicationOrApplicationList instanceof List) {
                for (Map application : (List>) applicationOrApplicationList) {
                    var instances = application.get(INSTANCE_KEY);
                    eurekaInstances.addAll(parseInstances(instances));
                }
            } else {
                eurekaInstances.addAll(parseInstances(((Map) applicationOrApplicationList).get(INSTANCE_KEY)));
            }
        }

        return eurekaInstances;
    }

    @SuppressWarnings("unchecked")
    private static List parseInstances(Object instanceOrInstanceList) {
        checkArgumentNotNull(instanceOrInstanceList, "Instance data from Eureka can not be null");

        if (instanceOrInstanceList instanceof List) {
            var instanceList = (List>) instanceOrInstanceList;
            return instanceList.stream()
                    .map(EurekaResponseParser::buildInstance)
                    .toList();
        }

        var instance = (Map) instanceOrInstanceList;
        return newArrayList(buildInstance(instance));
    }

    public static EurekaInstance parseEurekaInstanceResponse(Map eurekaResponse) {
        checkArgumentNotNull(eurekaResponse, "Eureka instance response must not be null");

        var instanceObj = eurekaResponse.get(INSTANCE_KEY);
        checkState(instanceObj instanceof Map, "Eureka data must contain a key 'instance' that contains a Map");

        //noinspection unchecked
        var instance = (Map) instanceObj;

        return buildInstance(instance);
    }

    @SuppressWarnings("unchecked")
    private static EurekaInstance buildInstance(Map instanceData) {

        var portMap = (Map) instanceData.get("port");
        var securePortMap = (Map) instanceData.get("securePort");
        var metadataMap = (Map) instanceData.get("metadata");
        var leaseInfoMap = (Map) instanceData.get("leaseInfo");

        Map leaseInfo = extractLeaseInfo(leaseInfoMap);

        var statusUrl = getStringOrNull(instanceData, "statusPageUrl");
        var healthCheckUrl = getStringOrNull(instanceData, "healthCheckUrl");
        var url = firstNonNullOrNull(statusUrl, healthCheckUrl);
        var adminPort = getAdminPort(url);

        return EurekaInstance.builder()
                .vipAddress(getStringOrNull(instanceData, "vipAddress"))
                .secureVipAddress(getStringOrNull(instanceData, "vipAddress"))
                .app(getStringOrNull(instanceData, "app"))
                .hostName(getStringOrNull(instanceData, "hostName"))
                .ipAddr(getStringOrNull(instanceData, "ipAddr"))
                .status(getStringOrNull(instanceData, "status"))
                .homePageUrl(getStringOrNull(instanceData, "homePageUrl"))
                .healthCheckUrl(healthCheckUrl)
                .statusPageUrl(statusUrl)
                .port(portMap)
                .securePort(securePortMap)
                .adminPort(adminPort)
                .leaseInfo(leaseInfo)
                .metadata(metadataMap)
                .rawResponse(instanceData)
                .build();
    }

    private static Map extractLeaseInfo(Map leaseInfoMap) {
        if (nonNull(leaseInfoMap)) {
            return Map.of(
                    "renewalIntervalInSecs", leaseInfoMap.getOrDefault("renewalIntervalInSecs", 0),
                    "durationInSecs", leaseInfoMap.getOrDefault("durationInSecs", 0),
                    "registrationTimestamp", leaseInfoMap.getOrDefault("registrationTimestamp", 0L),
                    "lastRenewalTimestamp", leaseInfoMap.getOrDefault("lastRenewalTimestamp", 0L),
                    "evictionTimestamp", leaseInfoMap.getOrDefault("evictionTimestamp", 0L),
                    "serviceUpTimestamp", leaseInfoMap.getOrDefault("serviceUpTimestamp", 0L));
        }

        return Map.of();
    }

    private static  String getStringOrNull(final Map map, final K key) {
        var value = map.getOrDefault(key, null);

        verify(isNull(value) || value instanceof String, "Value from Map must be a string or null");

        return (String) value;
    }

    @VisibleForTesting
    static int getAdminPort(@Nullable String url) {
        if (isBlank(url)) {
            return 0;
        }

        return KiwiInternetAddresses.portFrom(url).orElseGet(() -> defaultPortForScheme(url));
    }

    private static int defaultPortForScheme(String url) {
        return url.startsWith("https") ? 443 : 80;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy