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

com.alibaba.nacos.naming.core.IpAddress Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.nacos.naming.core;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.naming.healthcheck.HealthCheckStatus;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * IP under domain
 *
 * @author nkorange
 */
public class IpAddress extends Instance implements Comparable {

    private static final double MAX_WEIGHT_VALUE = 10000.0D;
    private static final double MIN_POSTIVE_WEIGHT_VALUE = 0.01D;
    private static final double MIN_WEIGHT_VALUE = 0.00D;

    private volatile long lastBeat = System.currentTimeMillis();

    @JSONField(serialize = false)
    private volatile boolean mockValid = false;

    private volatile boolean marked = false;

    private String tenant;

    private String app;

    public static final Pattern IP_PATTERN
            = Pattern.compile("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):?(\\d{1,5})?");

    public static final String SPLITER = "_";

    public IpAddress() {
    }

    public boolean isMockValid() {
        return mockValid;
    }

    public void setMockValid(boolean mockValid) {
        this.mockValid = mockValid;
    }

    public long getLastBeat() {
        return lastBeat;
    }

    public void setLastBeat(long lastBeat) {
        this.lastBeat = lastBeat;
    }

    public IpAddress(String ip, int port) {
        this.setIp(ip);
        this.setPort(port);
        this.setClusterName(UtilsAndCommons.DEFAULT_CLUSTER_NAME);
    }

    public IpAddress(String ip, int port, String clusterName) {
        this.setIp(ip.trim());
        this.setPort(port);
        this.setClusterName(clusterName);
    }

    public IpAddress(String ip, int port, String clusterName, String tenant, String app) {
        this.setIp(ip.trim());
        this.setPort(port);
        this.setClusterName(clusterName);
        this.tenant = tenant;
        this.app = app;
    }

    public static IpAddress fromString(String config) {
        String[] ipAddressAttributes = config.split(SPLITER);
        if (ipAddressAttributes.length < 1) {
            return null;
        }

        String provider = ipAddressAttributes[0];
        Matcher matcher = IP_PATTERN.matcher(provider);
        if (!matcher.matches()) {
            return null;
        }

        int expectedGroupCount = 2;

        int port = 0;
        if (NumberUtils.isNumber(matcher.group(expectedGroupCount))) {
            port = Integer.parseInt(matcher.group(expectedGroupCount));
        }

        IpAddress ipAddress = new IpAddress(matcher.group(1), port);

        // 7 possible formats of config:
        // ip:port
        // ip:port_weight
        // ip:port_weight_cluster
        // ip:port_weight_valid
        // ip:port_weight_valid_cluster
        // ip:port_weight_valid_marked
        // ip:port_weight_valid_marked_cluster
        int minimumLength = 1;

        if (ipAddressAttributes.length > minimumLength) {
            // determine 'weight':
            ipAddress.setWeight(NumberUtils.toDouble(ipAddressAttributes[minimumLength], 1));
        }

        minimumLength++;

        if (ipAddressAttributes.length > minimumLength) {
            // determine 'valid':
            if (Boolean.TRUE.toString().equals(ipAddressAttributes[minimumLength]) ||
                    Boolean.FALSE.toString().equals(ipAddressAttributes[minimumLength])) {
                ipAddress.setValid(Boolean.parseBoolean(ipAddressAttributes[minimumLength]));
            }

            // determine 'cluster':
            if (!Boolean.TRUE.toString().equals(ipAddressAttributes[ipAddressAttributes.length - 1]) &&
                    !Boolean.FALSE.toString().equals(ipAddressAttributes[ipAddressAttributes.length - 1])) {
                ipAddress.setClusterName(ipAddressAttributes[ipAddressAttributes.length - 1]);
            }
        }

        minimumLength++;

        if (ipAddressAttributes.length > minimumLength) {
            // determine 'marked':
            if (Boolean.TRUE.toString().equals(ipAddressAttributes[minimumLength]) ||
                    Boolean.FALSE.toString().equals(ipAddressAttributes[minimumLength])) {
                ipAddress.setMarked(Boolean.parseBoolean(ipAddressAttributes[minimumLength]));
            }
        }

        return ipAddress;
    }

    public String toIPAddr() {
        return getIp() + ":" + getPort();
    }

    @Override
    public String toString() {
        return getDatumKey() + SPLITER + getWeight() + SPLITER + isHealthy() + SPLITER + marked + SPLITER + getClusterName();
    }

    public String toJSON() {
        return JSON.toJSONString(this);
    }


    public static IpAddress fromJSON(String json) {
        IpAddress ip;

        try {
            ip = JSON.parseObject(json, IpAddress.class);
        } catch (Exception e) {
            ip = fromString(json);
        }

        if (ip == null) {
            throw new IllegalArgumentException("malfomed ip config: " + json);
        }

        if (ip.getWeight() > MAX_WEIGHT_VALUE) {
            ip.setWeight(MAX_WEIGHT_VALUE);
        }

        if (ip.getWeight() < MIN_POSTIVE_WEIGHT_VALUE && ip.getWeight() > MIN_WEIGHT_VALUE) {
            ip.setWeight(MIN_POSTIVE_WEIGHT_VALUE);
        } else if (ip.getWeight() < MIN_WEIGHT_VALUE) {
            ip.setWeight(0.0D);
        }
        return ip;
    }

    @Override
    public boolean equals(Object obj) {
        if (null == obj || obj.getClass() != getClass()) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        IpAddress other = (IpAddress) obj;

        // 0 means wild
        return getIp().equals(other.getIp()) && (getPort() == other.getPort() || getPort() == 0);
    }

    @JSONField(serialize = false)
    public String getDatumKey() {
        if (getPort() > 0) {
            return getIp() + ":" + getPort() + ":" + DistroMapper.LOCALHOST_SITE;
        } else {
            return getIp() + ":" + DistroMapper.LOCALHOST_SITE;
        }
    }

    @JSONField(serialize = false)
    public String getDefaultKey() {
        if (getPort() > 0) {
            return getIp() + ":" + getPort() + ":" + UtilsAndCommons.UNKNOWN_SITE;
        } else {
            return getIp() + ":" + UtilsAndCommons.UNKNOWN_SITE;
        }
    }

    @Override
    public int hashCode() {
        return getIp().hashCode();
    }

    public void setBeingChecked(boolean isBeingChecked) {
        HealthCheckStatus.get(this).isBeingChecked.set(isBeingChecked);
    }

    public boolean markChecking() {
        return HealthCheckStatus.get(this).isBeingChecked.compareAndSet(false, true);
    }

    @JSONField(serialize = false)
    public long getCheckRT() {
        return HealthCheckStatus.get(this).checkRT;
    }

    @JSONField(serialize = false)
    public AtomicInteger getOKCount() {
        return HealthCheckStatus.get(this).checkOKCount;
    }

    @JSONField(serialize = false)
    public AtomicInteger getFailCount() {
        return HealthCheckStatus.get(this).checkFailCount;
    }

    @JSONField(serialize = false)
    public void setCheckRT(long checkRT) {
        HealthCheckStatus.get(this).checkRT = checkRT;
    }

    public synchronized void setValid(boolean valid) {
        setHealthy(valid);
    }

    public boolean isValid() {
        return isHealthy();
    }

    public boolean isMarked() {
        return marked;
    }

    public void setMarked(boolean marked) {
        this.marked = marked;
    }

    public String getApp() {
        return app;
    }

    public void setApp(String app) {
        this.app = app;
    }

    public String getTenant() {
        return tenant;
    }

    public void setTenant(String tenant) {
        this.tenant = tenant;
    }

    public String generateInstanceId() {
        return getIp() + "#" + getPort() + "#" + getClusterName() + "#" + getServiceName();
    }

    @Override
    public int compareTo(Object o) {
        if (!(o instanceof IpAddress)) {
            Loggers.SRV_LOG.error("[IPADDRESS-COMPARE] Object is not an instance of IPAdress, object: {}", o.getClass());
            throw new IllegalArgumentException("Object is not an instance of IPAdress,object: " + o.getClass());
        }

        IpAddress ipAddress = (IpAddress) o;
        String ipKey = ipAddress.toString();

        return this.toString().compareTo(ipKey);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy