/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/MachineList.java
http://github.com/apache/hadoop-common · Java · 210 lines · 130 code · 20 blank · 60 comment · 36 complexity · 6fab22ab35f1038a40f439e500e15d49 MD5 · raw file
- /**
- * 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.hadoop.util;
- import java.net.InetAddress;
- import java.net.UnknownHostException;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashSet;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Set;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.commons.net.util.SubnetUtils;
- import com.google.common.annotations.VisibleForTesting;
- import com.google.common.net.InetAddresses;
- /**
- * Container class which holds a list of ip/host addresses and
- * answers membership queries.
- *
- * Accepts list of ip addresses, ip addreses in CIDR format and/or
- * host addresses.
- */
- public class MachineList {
-
- public static final Log LOG = LogFactory.getLog(MachineList.class);
- /**
- * InetAddressFactory is used to obtain InetAddress from host.
- * This class makes it easy to simulate host to ip mappings during testing.
- *
- */
- public static class InetAddressFactory {
- static final InetAddressFactory S_INSTANCE = new InetAddressFactory();
- public InetAddress getByName (String host) throws UnknownHostException {
- return InetAddress.getByName(host);
- }
- }
- private final boolean all;
- private final Set<String> ipAddresses;
- private final List<SubnetUtils.SubnetInfo> cidrAddresses;
- private final Set<String> hostNames;
- private final InetAddressFactory addressFactory;
- /**
- *
- * @param hostEntries comma separated ip/cidr/host addresses
- */
- public MachineList(String hostEntries) {
- this(StringUtils.getTrimmedStringCollection(hostEntries));
- }
- /**
- *
- * @param hostEntries collection of separated ip/cidr/host addresses
- */
- public MachineList(Collection<String> hostEntries) {
- this(hostEntries, InetAddressFactory.S_INSTANCE);
- }
- /**
- * Accepts a collection of ip/cidr/host addresses
- *
- * @param hostEntries
- * @param addressFactory addressFactory to convert host to InetAddress
- */
- public MachineList(Collection<String> hostEntries, InetAddressFactory addressFactory) {
- this.addressFactory = addressFactory;
- if (hostEntries != null) {
- if ((hostEntries.size() == 1) && (hostEntries.contains("*"))) {
- all = true;
- ipAddresses = null;
- hostNames = null;
- cidrAddresses = null;
- } else {
- all = false;
- Set<String> ips = new HashSet<String>();
- List<SubnetUtils.SubnetInfo> cidrs = new LinkedList<SubnetUtils.SubnetInfo>();
- Set<String> hosts = new HashSet<String>();
- for (String hostEntry : hostEntries) {
- //ip address range
- if (hostEntry.indexOf("/") > -1) {
- try {
- SubnetUtils subnet = new SubnetUtils(hostEntry);
- subnet.setInclusiveHostCount(true);
- cidrs.add(subnet.getInfo());
- } catch (IllegalArgumentException e) {
- LOG.warn("Invalid CIDR syntax : " + hostEntry);
- throw e;
- }
- } else if (InetAddresses.isInetAddress(hostEntry)) { //ip address
- ips.add(hostEntry);
- } else { //hostname
- hosts.add(hostEntry);
- }
- }
- ipAddresses = (ips.size() > 0) ? ips : null;
- cidrAddresses = (cidrs.size() > 0) ? cidrs : null;
- hostNames = (hosts.size() > 0) ? hosts : null;
- }
- } else {
- all = false;
- ipAddresses = null;
- hostNames = null;
- cidrAddresses = null;
- }
- }
- /**
- * Accepts an ip address and return true if ipAddress is in the list
- * @param ipAddress
- * @return true if ipAddress is part of the list
- */
- public boolean includes(String ipAddress) {
-
- if (all) {
- return true;
- }
-
- //check in the set of ipAddresses
- if ((ipAddresses != null) && ipAddresses.contains(ipAddress)) {
- return true;
- }
-
- //iterate through the ip ranges for inclusion
- if (cidrAddresses != null) {
- for(SubnetUtils.SubnetInfo cidrAddress : cidrAddresses) {
- if(cidrAddress.isInRange(ipAddress)) {
- return true;
- }
- }
- }
-
- //check if the ipAddress matches one of hostnames
- if (hostNames != null) {
- //convert given ipAddress to hostname and look for a match
- InetAddress hostAddr;
- try {
- hostAddr = addressFactory.getByName(ipAddress);
- if ((hostAddr != null) && hostNames.contains(hostAddr.getCanonicalHostName())) {
- return true;
- }
- } catch (UnknownHostException e) {
- //ignore the exception and proceed to resolve the list of hosts
- }
- //loop through host addresses and convert them to ip and look for a match
- for (String host : hostNames) {
- try {
- hostAddr = addressFactory.getByName(host);
- } catch (UnknownHostException e) {
- continue;
- }
- if (hostAddr.getHostAddress().equals(ipAddress)) {
- return true;
- }
- }
- }
- return false;
- }
- /**
- * returns the contents of the MachineList as a Collection<String>
- * This can be used for testing
- * @return contents of the MachineList
- */
- @VisibleForTesting
- public Collection<String> getCollection() {
- Collection<String> list = new ArrayList<String>();
- if (all) {
- list.add("*");
- } else {
- if (ipAddresses != null) {
- list.addAll(ipAddresses);
- }
- if (hostNames != null) {
- list.addAll(hostNames);
- }
- if (cidrAddresses != null) {
- for(SubnetUtils.SubnetInfo cidrAddress : cidrAddresses) {
- list.add(cidrAddress.getCidrSignature());
- }
- }
- }
- return list;
- }
- }