/*
*------------------------------------------------------------------------------
* Copyright (C) 2006-2014 University of Dundee & Open Microscopy Environment.
* All rights reserved.
*
*
* 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; either version 2 of the License, or
* (at your option) any later version.
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package omero.gateway.util;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import omero.log.Logger;
/**
* Checks if the network is still up.
*
* @author Jean-Marie Burel <a
* href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @since 4.4
*/
public class NetworkChecker {
private final AtomicLong lastCheck = new AtomicLong(
System.currentTimeMillis());
private final AtomicBoolean lastValue = new AtomicBoolean(true);
/**
* The IP Address of the server the client is connected to or
* <code>null</code>.
*/
private InetAddress ipAddress;
/** The address of the server to reach. */
private final String address;
/** Reference to the logger. */
private Logger logger;
/** The list of interfaces when the network checker is initialized. */
private long interfacesCount;
/**
* Creates a new instance.
*
* @param address
* The address of the server the client is connected to or
* <code>null</code>.
* @param logger Reference to the logger.
*/
public NetworkChecker(String address, Logger logger) {
this.address = address;
this.logger = logger;
if (ipAddress != null) {
try {
this.ipAddress = InetAddress.getByName(address);
} catch (UnknownHostException e) {
// Ignored
}
}
interfacesCount = 0;
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface
.getNetworkInterfaces();
if (interfaces != null) {
NetworkInterface ni;
while (interfaces.hasMoreElements()) {
ni = interfaces.nextElement();
if (ni.isLoopback() || !ni.isUp())
continue;
interfacesCount++;
}
}
} catch (Exception e) {
// Ignored
}
}
/**
* Returns <code>true</code> if the network is still up, otherwise throws an
* <code>UnknownHostException</code>. This tests if the adapter is ready.
*
* @param useCachedValue Pass <code>true</code> if we use the cached value,
* <code>false</code> otherwise.
* @return See above.
* @throws Exception
* Thrown if the network is down.
*/
public boolean isNetworkup(boolean useCachedValue) throws Exception {
if (useCachedValue) {
long elapsed = System.currentTimeMillis() - lastCheck.get();
if (elapsed <= 5000) {
return lastValue.get();
}
}
boolean newValue = _isNetworkup();
long stop = System.currentTimeMillis();
lastValue.set(newValue);
lastCheck.set(stop);
return newValue;
}
/**
* Checks the network is available or not.
*
* @return See above.
* @throws Exception
* Thrown if an error occurred if we cannot reach.
*/
public boolean isAvailable() throws Exception {
if (ipAddress != null && ipAddress.isLoopbackAddress()) {
return true;
}
if (address != null) {
try {
URL url = new URL("http://" + address);
HttpURLConnection urlConnect = (HttpURLConnection) url
.openConnection();
urlConnect.setConnectTimeout(1000);
urlConnect.getContent();
} catch (Exception e) {
log("Not available %s", e);
return false;
}
}
return true;
}
/**
* Returns <code>true</code> if the network is still up, otherwise throws an
* <code>UnknownHostException</code>.
*
* @return See above.
* @throws Exception
* Thrown if the network is down.
*/
private boolean _isNetworkup() throws Exception {
if (ipAddress != null && ipAddress.isLoopbackAddress()) {
return true;
}
boolean networkup = false;
Enumeration<NetworkInterface> interfaces = NetworkInterface
.getNetworkInterfaces();
long count = 0;
if (interfaces != null && !networkup) {
NetworkInterface ni;
while (interfaces.hasMoreElements()) {
ni = interfaces.nextElement();
if (ni.isLoopback() || !ni.isUp())
continue;
count++;
}
}
if (count >= interfacesCount) {
networkup = true;
} else {
networkup = isAvailable();
if (networkup) { // one interface was dropped e.g. wireless
interfacesCount = count;
}
}
if (!networkup) {
throw new UnknownHostException("Network is down.");
}
return networkup;
}
/**
* Logs the error.
*
* @param msg
* The message to log
* @param objs
* The objects to add to the message.
*/
void log(String msg, Object... objs) {
if (logger != null) {
logger.debug(this, String.format(msg, objs));
}
}
}