blob: e8190fdf71425ba64f79611b7a18fffce1c948cd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.iotdb.commons.utils;
import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TEndPoint;
import org.apache.iotdb.commons.exception.BadNodeUrlException;
import org.apache.iotdb.rpc.UrlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;
public class NodeUrlUtils {
private static final Logger logger = LoggerFactory.getLogger(NodeUrlUtils.class);
public static final String WILD_CARD_ADDRESS = "0.0.0.0";
public static final String LOOPBACK_HOST_NAME = "localhost";
/**
* Convert TEndPoint to TEndPointUrl
*
* @param endPoint TEndPoint
* @return TEndPointUrl with format ip:port
*/
public static String convertTEndPointUrl(TEndPoint endPoint) {
StringJoiner url = new StringJoiner(":");
url.add(endPoint.getIp());
url.add(String.valueOf(endPoint.getPort()));
return url.toString();
}
/**
* Convert TEndPoints to TEndPointUrls
*
* @param endPoints List<TEndPoint>
* @return TEndPointUrls with format TEndPointUrl_0,TEndPointUrl_1,...,TEndPointUrl_n
*/
public static String convertTEndPointUrls(List<TEndPoint> endPoints) {
StringJoiner urls = new StringJoiner(",");
for (TEndPoint endPoint : endPoints) {
urls.add(convertTEndPointUrl(endPoint));
}
return urls.toString();
}
/**
* Parse TEndPoint from a given TEndPointUrl
*
* @param endPointUrl ip:port
* @return TEndPoint
* @throws BadNodeUrlException Throw when unable to parse
*/
public static TEndPoint parseTEndPointUrl(String endPointUrl) throws BadNodeUrlException {
return UrlUtils.parseTEndPointIpv4AndIpv6Url(endPointUrl);
}
/**
* Parse TEndPoints from given TEndPointUrls
*
* @param endPointUrls List<TEndPointUrl>
* @return List<TEndPoint>
*/
public static List<TEndPoint> parseTEndPointUrls(List<String> endPointUrls) {
if (endPointUrls == null) {
throw new NumberFormatException("endPointUrls is null");
}
List<TEndPoint> result = new ArrayList<>();
for (String url : endPointUrls) {
result.add(UrlUtils.parseTEndPointIpv4AndIpv6Url(url));
}
return result;
}
/**
* Parse TEndPoints from given TEndPointUrls
*
* @param endPointUrls TEndPointUrls
* @return List<TEndPoint>
* @throws BadNodeUrlException Throw when unable to parse
*/
public static List<TEndPoint> parseTEndPointUrls(String endPointUrls) throws BadNodeUrlException {
return parseTEndPointUrls(Arrays.asList(endPointUrls.split(",")));
}
/**
* Convert TConfigNodeLocation to TConfigNodeUrl
*
* @param configNodeLocation TConfigNodeLocation
* @return TConfigNodeUrl with format InternalEndPointUrl,ConsensusEndPointUrl
*/
public static String convertTConfigNodeUrl(TConfigNodeLocation configNodeLocation) {
StringJoiner url = new StringJoiner(",");
url.add(String.valueOf(configNodeLocation.getConfigNodeId()));
url.add(convertTEndPointUrl(configNodeLocation.getInternalEndPoint()));
url.add(convertTEndPointUrl(configNodeLocation.getConsensusEndPoint()));
return url.toString();
}
/**
* Convert TConfigNodeLocations to TConfigNodeUrls
*
* @param configNodeLocations List<TConfigNodeLocation>
* @return TConfigNodeUrls with format TConfigNodeUrl_0,TConfigNodeUrl_1,...,TConfigNodeUrl_n
*/
public static String convertTConfigNodeUrls(List<TConfigNodeLocation> configNodeLocations) {
StringJoiner urls = new StringJoiner(";");
for (TConfigNodeLocation configNodeLocation : configNodeLocations) {
urls.add(convertTConfigNodeUrl(configNodeLocation));
}
return urls.toString();
}
/**
* Parse TConfigNodeLocation from given TConfigNodeUrl
*
* @param configNodeUrl InternalEndPointUrl,ConsensusEndPointUrl
* @return TConfigNodeLocation
* @throws BadNodeUrlException Throw when unable to parse
*/
public static TConfigNodeLocation parseTConfigNodeUrl(String configNodeUrl)
throws BadNodeUrlException {
String[] split = configNodeUrl.split(",");
if (split.length != 3) {
logger.warn("Bad ConfigNode url: {}", configNodeUrl);
throw new BadNodeUrlException(String.format("Bad node url: %s", configNodeUrl));
}
return new TConfigNodeLocation(
Integer.parseInt(split[0]),
UrlUtils.parseTEndPointIpv4AndIpv6Url(split[1]),
UrlUtils.parseTEndPointIpv4AndIpv6Url(split[2]));
}
/**
* Parse TConfigNodeLocations from given TConfigNodeUrls
*
* @param configNodeUrls List<TConfigNodeUrl>
* @return List<TConfigNodeLocation>
* @throws BadNodeUrlException Throw when unable to parse
*/
public static List<TConfigNodeLocation> parseTConfigNodeUrls(List<String> configNodeUrls)
throws BadNodeUrlException {
List<TConfigNodeLocation> result = new ArrayList<>();
for (String url : configNodeUrls) {
result.add(parseTConfigNodeUrl(url));
}
return result;
}
/**
* Parse TConfigNodeLocations from given TConfigNodeUrls
*
* @param configNodeUrls TConfigNodeUrls
* @return List<TConfigNodeLocation>
* @throws BadNodeUrlException Throw when unable to parse
*/
public static List<TConfigNodeLocation> parseTConfigNodeUrls(String configNodeUrls)
throws BadNodeUrlException {
return parseTConfigNodeUrls(Arrays.asList(configNodeUrls.split(";")));
}
/**
* Detect whether the given addresses or host names(may contain both) point to the node itself.
*
* @param addressesOrHostNames List of the addresses or host name to check
* @return true if one of the given strings point to the node itself
* @throws UnknownHostException Throw when unable to parse the given addresses or host names
*/
public static boolean containsLocalAddress(List<String> addressesOrHostNames)
throws UnknownHostException {
if (addressesOrHostNames == null) {
return false;
}
Set<String> selfAddresses = getAllLocalAddresses();
for (String addressOrHostName : addressesOrHostNames) {
if (addressOrHostName == null) {
continue;
}
// Unify address or hostName, converting them to addresses
Set<String> translatedAddresses =
Arrays.stream(InetAddress.getAllByName(addressOrHostName))
.map(InetAddress::getHostAddress)
.collect(Collectors.toCollection(HashSet::new));
translatedAddresses.retainAll(selfAddresses);
if (!translatedAddresses.isEmpty()) {
return true;
}
}
return false;
}
/**
* Return all the internal, external, IPv4, IPv6 and loopback addresses(without hostname) of the
* node
*
* @return the local addresses set
* @throws UnknownHostException Throw when unable to self addresses or host names (Normally not
* thrown)
*/
public static Set<String> getAllLocalAddresses() throws UnknownHostException {
// Check internal and external, IPv4 and IPv6 network addresses
Set<String> selfAddresses =
Arrays.stream(InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()))
.map(InetAddress::getHostAddress)
.collect(Collectors.toCollection(HashSet::new));
// Check IPv4 and IPv6 loopback addresses 127.0.0.1 and 0.0.0.0.0.0.0.1
selfAddresses.addAll(
Arrays.stream(InetAddress.getAllByName(LOOPBACK_HOST_NAME))
.map(InetAddress::getHostAddress)
.collect(Collectors.toCollection(HashSet::new)));
// Check general address 0.0.0.0
selfAddresses.add(WILD_CARD_ADDRESS);
return selfAddresses;
}
}