Java tutorial
/************************************************************************* * Copyright 2009-2012 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. * * This file may incorporate work covered under the following copyright * and permission notice: * * Software License Agreement (BSD License) * * Copyright (c) 2008, Regents of the University of California * All rights reserved. * * Redistribution and use of this software in source and binary forms, * with or without modification, are permitted provided that the * following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE * THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL, * COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE, * AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, * SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, * WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, * REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO * IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT * NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS. ************************************************************************/ package com.eucalyptus.util; import java.io.IOException; import java.io.Serializable; import java.net.Inet4Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.log4j.Logger; import com.eucalyptus.bootstrap.BootstrapArgs; import com.eucalyptus.records.Logs; import com.eucalyptus.scripting.Groovyness; import com.eucalyptus.scripting.ScriptExecutionFailedException; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.net.InetAddresses; import static com.eucalyptus.util.Parameters.checkParam; import static org.hamcrest.Matchers.notNullValue; public class Internets { private static Logger LOG = Logger.getLogger(Internets.class); private static final ConcurrentMap<String, InetAddress> localHostAddrList = new ConcurrentHashMap<String, InetAddress>(); private static final InetAddress localHostAddr = determineLocalAddress(); private static final String localId = localHostIdentifier(); // public static List<InetAddress> localInetAddresses( ) { // return localHostAddrList; // } // public static boolean isReachable(InetAddress addr, int timeoutMillis) throws IOException { // try { // timeoutMillis = timeoutMillis / 1000; // return ( Boolean ) Groovyness.eval( String.format( "ret = \"/bin/ping -W %d -c 1 %s\".execute( ); ret.waitFor(); ret.exitValue() == 0;", // timeoutMillis, // addr.getHostAddress( ) ) ); // } catch ( ScriptExecutionFailedException ex ) { // Logs.extreme( ).error( ex, ex ); return addr.isReachable(timeoutMillis); // } } private static InetAddress determineLocalAddress() { InetAddress laddr = null; LOG.info("Trying to determine local bind address based on cli (--bind-addr)... "); if (!BootstrapArgs.bindAddresses().isEmpty()) { laddr = lookupBindAddresses(); } if (laddr == null) { LOG.info("Trying to determine local bind address based on the default route... "); laddr = lookupDefaultRoute(); } if (laddr == null) { LOG.info( "Trying to determine local bind address based on a netmask and scope maximizing heuristic... "); laddr = Internets.getAllInetAddresses().get(0); } LOG.info("==> Decided to use local bind address: " + laddr); System.setProperty("bind_addr", laddr.getHostAddress()); System.setProperty("bind.address", laddr.getHostAddress()); System.setProperty("jgroups.bind_addr", laddr.getHostAddress()); System.setProperty("jgroups.udp.bind_addr", laddr.getHostAddress()); return laddr; } private static InetAddress lookupDefaultRoute() { InetAddress laddr = null; try { String localAddr = (String) Groovyness .eval("hi=\"/sbin/ip -o route get 4.2.2.1\".execute();hi.waitFor();hi.text"); String[] parts = localAddr.replaceAll(".*src *", "").split(" "); if (parts.length >= 1) { laddr = InetAddresses.forString(parts[0]); } } catch (ScriptExecutionFailedException ex) { LOG.error(ex); Logs.extreme().error(ex, ex); } catch (Exception ex) { LOG.error(ex); Logs.extreme().error(ex, ex); } return laddr; } private static InetAddress lookupBindAddresses() { InetAddress laddr = null; List<InetAddress> locallyBoundAddrs = Internets.getAllInetAddresses(); boolean err = false; for (String addrStr : BootstrapArgs.bindAddresses()) { try { InetAddress next = InetAddress.getByName(addrStr); laddr = (laddr == null) ? next : laddr; NetworkInterface iface = NetworkInterface.getByInetAddress(next); if (locallyBoundAddrs.contains(InetAddress.getByName(addrStr))) { localHostAddrList.put(next.getHostAddress(), next); LOG.info("Identified local bind address: " + addrStr + " on interface " + iface.toString()); } else { LOG.error("Failed to find specified --bind-addr=" + addrStr + " as it is not bound to a local interface.\n Known addresses are: " + Joiner.on(", ").join(locallyBoundAddrs)); } } catch (UnknownHostException ex) { LOG.fatal("Invalid argument given for --bind-addr=" + addrStr + " " + ex.getMessage()); LOG.error(ex, ex); err = true; } catch (SocketException ex) { LOG.fatal("Invalid argument given for --bind-addr=" + addrStr + " " + ex.getMessage()); LOG.error(ex, ex); err = true; } if (err) { System.exit(1);//GRZE: special case, failed to determine bind address } } return laddr; } public static InetAddress loopback() { try { return InetAddress.getByName("127.0.0.1"); } catch (UnknownHostException ex) { for (InetAddress i : getAllInetAddresses()) { if (i.isLoopbackAddress()) { return i; } } return localHostInetAddress(); } } public static InetAddress any() { return InetAddresses.fromInteger(0); } public static InetAddress localHostInetAddress() { return localHostAddr; } public static String localHostAddress() { return localHostInetAddress().getHostAddress(); } public static String localHostIdentifier() { return localId != null ? localId : localHostInetAddress().getHostAddress(); } public static List<NetworkInterface> getNetworkInterfaces() { try { List<NetworkInterface> ifaces = Collections.list(NetworkInterface.getNetworkInterfaces()); ifaces = Lists.newArrayList(Iterables.filter(ifaces, new Predicate<NetworkInterface>() { @Override public boolean apply(NetworkInterface input) { return !input.getName().contains("virbr0") && !input.getDisplayName().contains("virbr0"); } })); Collections.sort(ifaces, new Comparator<NetworkInterface>() { @Override public int compare(NetworkInterface o1, NetworkInterface o2) { int min1 = 0; int min2 = 0; for (InterfaceAddress ifaceAddr : o1.getInterfaceAddresses()) { min1 = (min1 > ifaceAddr.getNetworkPrefixLength() ? ifaceAddr.getNetworkPrefixLength() : min1); } for (InterfaceAddress ifaceAddr : o2.getInterfaceAddresses()) { min2 = (min2 > ifaceAddr.getNetworkPrefixLength() ? ifaceAddr.getNetworkPrefixLength() : min2); } return min2 - min1;//return a positive int when min1 has a shorter routing prefix } }); return ifaces; } catch (SocketException ex) { LOG.error(ex, ex); throw new RuntimeException("Getting list of network interfaces failed because of " + ex.getMessage(), ex); } } public static List<InetAddress> getAllInetAddresses() { List<InetAddress> addrs = Lists.newArrayList(); for (NetworkInterface iface : Internets.getNetworkInterfaces()) { try { if (iface.isPointToPoint()) { continue; } } catch (SocketException ex) { LOG.error(ex, ex); } for (InterfaceAddress iaddr : iface.getInterfaceAddresses()) { InetAddress addr = iaddr.getAddress(); if (addr instanceof Inet4Address) { if (!addr.isMulticastAddress() && !addr.isLoopbackAddress() && !addr.isLinkLocalAddress() && !addr.isSiteLocalAddress() && !addr.getHostAddress().contains("192.168.122.")) { addrs.add(addr); } } } for (InterfaceAddress iaddr : iface.getInterfaceAddresses()) { InetAddress addr = iaddr.getAddress(); if (addr instanceof Inet4Address) { if (!addr.isMulticastAddress() && !addr.isLoopbackAddress() && !addr.isLinkLocalAddress() && !addrs.contains(addr.getHostAddress()) && !addr.getHostAddress().contains("192.168.122.")) { addrs.add(addr); } } } } return addrs; } public static List<String> getAllAddresses() { return Lists.transform(Internets.getAllInetAddresses(), new Function<InetAddress, String>() { @Override public String apply(InetAddress arg0) { return arg0.getHostAddress(); } }); } public static class Inet4AddressComparator implements Comparator<InetAddress>, Serializable { private static final long serialVersionUID = 1L; @Override public int compare(InetAddress o1, InetAddress o2) { return o1.getHostAddress().compareTo(o2.getHostAddress()); } } public static final Comparator<InetAddress> INET_ADDRESS_COMPARATOR = new Inet4AddressComparator(); public static boolean testReachability(InetAddress inetAddr) { checkParam("BUG: inetAddr is null.", inetAddr, notNullValue()); try { return inetAddr.isReachable(10000); } catch (IOException ex) { LOG.error(ex, ex); return false; } //TODO:GRZE:make reachability time tuneable } public static boolean testReachability(String addr) { checkParam("BUG: addr is null.", addr, notNullValue()); try { InetAddress inetAddr = Inet4Address.getByName(addr); return testReachability(inetAddr); } catch (UnknownHostException ex) { LOG.error(ex, ex); return false; } } public static InetAddress toAddress(URI uri) { checkParam("BUG: uri is null.", uri, notNullValue()); try { return InetAddress.getByName(uri.getHost()); } catch (UnknownHostException e) { throw Exceptions.toUndeclared("Failed to resolve address for host: " + uri.getHost(), e); } } public static InetAddress toAddress(String maybeUrlMaybeHostname) { checkParam("BUG: maybeUrlMaybeHostname is null.", maybeUrlMaybeHostname, notNullValue()); if (maybeUrlMaybeHostname.startsWith("vm:")) { maybeUrlMaybeHostname = "localhost"; } URI uri = null; String hostAddress = null; try { uri = new URI(maybeUrlMaybeHostname); hostAddress = uri.getHost(); } catch (URISyntaxException e) { hostAddress = maybeUrlMaybeHostname; } InetAddress ret = null; try { ret = InetAddress.getByName(hostAddress); } catch (UnknownHostException e1) { Exceptions.error("Failed to resolve address for host: " + maybeUrlMaybeHostname, e1); } return ret; } public static boolean testLocal(final InetAddress addr) { if (addr == null) return true; try { Boolean result = addr.isAnyLocalAddress(); result |= Iterables.any(Internets.getNetworkInterfaces(), new Predicate<NetworkInterface>() { @Override public boolean apply(NetworkInterface arg0) { return Iterables.any(arg0.getInterfaceAddresses(), new Predicate<InterfaceAddress>() { @Override public boolean apply(InterfaceAddress arg0) { return arg0.getAddress().equals(addr); } }); } }); return result; } catch (Exception e) { // Exceptions.eat( e.getMessage( ), e ); return false; } } public static boolean testLocal(String address) { if (address == null) return true; InetAddress addr; try { addr = InetAddress.getByName(address); return testLocal(addr); } catch (UnknownHostException e) { LOG.error(e.getMessage()); return address.endsWith("Internal"); } } public static boolean testGoodAddress(String address) throws Exception { InetAddress addr = InetAddress.getByName(address); LOG.debug(addr + " site=" + addr.isSiteLocalAddress()); LOG.debug(addr + " any=" + addr.isAnyLocalAddress()); LOG.debug(addr + " loop=" + addr.isLoopbackAddress()); LOG.debug(addr + " link=" + addr.isLinkLocalAddress()); LOG.debug(addr + " multi=" + addr.isMulticastAddress()); return addr.isSiteLocalAddress() || (!addr.isAnyLocalAddress() && !addr.isLoopbackAddress() && !addr.isLinkLocalAddress() && !addr.isMulticastAddress()); } private static void addAddress(Set<String> out, InetAddress addr) { if (addr instanceof Inet4Address && !addr.isMulticastAddress() && !addr.isLinkLocalAddress() && !addr.isLoopbackAddress()) { out.add(addr.getCanonicalHostName()); out.add(addr.getHostName()); out.add(addr.getHostAddress()); } } private static void addName(Set<String> out, String name) { try { for (InetAddress addr : InetAddress.getAllByName(name)) { addAddress(out, addr); } } catch (UnknownHostException uhe) { LOG.error("Failed to get addresses for name " + name + ": " + uhe, uhe); } } public static Set<String> getAllLocalHostNamesIps() { Set<String> results = new HashSet<String>(); try { InetAddress localHost = InetAddress.getLocalHost(); addAddress(results, localHost); addName(results, localHost.getCanonicalHostName()); addName(results, localHost.getHostName()); } catch (UnknownHostException uhe) { LOG.error("Failed to get localhost: " + uhe, uhe); } try { Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); if (ifaces != null) { while (ifaces.hasMoreElements()) { NetworkInterface iface = ifaces.nextElement(); Enumeration<InetAddress> addrs = iface.getInetAddresses(); if (addrs != null) { while (addrs.hasMoreElements()) { addAddress(results, addrs.nextElement()); } } } } } catch (SocketException se) { LOG.error("Failed to get all network interfaces: " + se); } return results; } public static Optional<Cidr> getInterfaceCidr(final InetAddress address) { try { final NetworkInterface networkInterface = NetworkInterface.getByInetAddress(address); for (final InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) { if (address.equals(interfaceAddress.getAddress())) { final int prefix = interfaceAddress.getNetworkPrefixLength(); return Optional.of(Cidr.fromAddress(address, prefix)); } } } catch (SocketException e) { LOG.debug("Error finding interface CIDR for address '" + address + "'", e); } return Optional.absent(); } public static Function<InetAddress, Optional<Cidr>> interfaceCidr() { return InetAddressToCidr.INSTANCE; } private enum InetAddressToCidr implements Function<InetAddress, Optional<Cidr>> { INSTANCE; @Override public Optional<Cidr> apply(final InetAddress address) { return getInterfaceCidr(address); } } public static void main(String[] args) throws Exception { for (String addr : Internets.getAllAddresses()) { System.out.println(addr); } for (String addr : Internets.getAllLocalHostNamesIps()) { System.out.println("Address: " + addr); } System.out.println("Testing if 192.168.7.8 is reachable: " + Internets.testReachability("192.168.7.8")); } }