Fixed some problems, added new endpoint definition

This commit is contained in:
Simon Pamies committed 2012-11-28 13:12:48 +01:00
1 parent bcec5b4a81
commit f318256146
6 files changed
+183 -76

No files matched your search

@@ -24,38 +24,32 @@ public abstract class AbstractPortMonitor extends Thread {
private int graceful = 5000;
private int pause = 1000;
protected InetSocketAddress[] endpoints = null;
protected IEndpoint[] endpoints = null;
protected int interval;
boolean started = false;
boolean paused = false;
private long lastmillis;
private InetSocketAddress currentendpoint;
private IEndpoint currentendpoint;
protected Properties properties;
public AbstractPortMonitor(InetSocketAddress[] endpoints, int interval) {
this.endpoints = endpoints;
if (interval < 10000) {
throw new RuntimeException("Interval can not be lower than 10 seconds!");
}
this.interval = interval;
this.started = true;
log.info("Initialized monitoring!");
}
public AbstractPortMonitor(Properties properties) {
String[] prop_endpoints = properties.getProperty("monitor.endpoints").split(",");
this.endpoints = new InetSocketAddress[prop_endpoints.length];
try {
for (int i=0;i<prop_endpoints.length;i++) {
String[] data = prop_endpoints[i].split(":");
this.endpoints[i] = new InetSocketAddress(InetAddress.getByName(data[0].trim()), Integer.parseInt(data[1].trim()));
this.endpoints = new IEndpoint[prop_endpoints.length];
for (int i=0; i<prop_endpoints.length;i++) {
String[] data = prop_endpoints[i].split(":");
try {
Endpoint e = new Endpoint(new InetSocketAddress(InetAddress.getByName(data[0].trim()), Integer.parseInt(data[1].trim())));
this.endpoints[i] = e;
} catch (Exception ex) {
log.severe("Could not parse endpoint definition " + prop_endpoints[i]);
}
} catch (Exception ex) {
ex.printStackTrace();
}
this.interval = Integer.parseInt(properties.getProperty("monitor.interval", ""+interval).trim());
this.timeout = Integer.parseInt(properties.getProperty("monitor.timeout", ""+timeout).trim());
this.graceful = Integer.parseInt(properties.getProperty("monitor.gracetime", ""+graceful).trim());
@@ -72,7 +66,7 @@ public abstract class AbstractPortMonitor extends Thread {
@Override
public void run() {
try {
/* graceful start - give services some time */
/* graceful start - give bundles some time */
Thread.sleep(graceful);
while (started) {
if (!paused) {
@@ -83,17 +77,33 @@ public abstract class AbstractPortMonitor extends Thread {
currentendpoint = endpoints[i];
Socket sn = new Socket();
sn.connect(currentendpoint, timeout);
sn.connect(currentendpoint.getAddress(), timeout);
sn.close();
log.info("Connection succeeded to " + currentendpoint.toString());
handleConnection(currentendpoint);
lastmillis = System.currentTimeMillis();
currentendpoint.setSuccess(System.currentTimeMillis());
}
}
} catch (SocketTimeoutException|ConnectException ex) {
log.info("Connection FAILED to " + currentendpoint.toString());
handleFailure(currentendpoint);
lastmillis = System.currentTimeMillis();
/* if service has failed before then wait at least some time before checking it again */
boolean handle = true;
if (currentendpoint.hasFailed() /* failed before */) {
if ( (currentendpoint.lastFailed()+Integer.parseInt(properties.getProperty("monitor.wait_after_failure", "60000"))) > System.currentTimeMillis()) {
log.info("Not calling handler because failure has been shortly before this call");
handle = false;
}
}
if (handle) {
handleFailure(currentendpoint);
lastmillis = System.currentTimeMillis();
currentendpoint.setFailure(System.currentTimeMillis());
}
} catch (IOException ex) {
ex.printStackTrace();
}
@@ -111,17 +121,8 @@ public abstract class AbstractPortMonitor extends Thread {
this.started = false;
}
protected void removeEndpoint(InetSocketAddress endpoint) {
InetSocketAddress[] new_endpoints = new InetSocketAddress[endpoints.length-1];
for (int i=0;i<endpoints.length;i++) {
if (endpoints[i] != endpoint)
new_endpoints[i] = endpoint;
}
this.endpoints = new_endpoints;
}
public abstract void handleFailure(IEndpoint endpoint);
public abstract void handleFailure(InetSocketAddress endpoint);
public abstract void handleConnection(InetSocketAddress endpoint);
public abstract void handleConnection(IEndpoint endpoint);
}
@@ -0,0 +1,71 @@
package com.sap.sailing.monitoring;
import java.net.InetSocketAddress;
/**
* @see IEndpoint
*
* @author Simon Pamies (info@pamies.de)
* @since Nov 28, 2012
*/
public class Endpoint implements IEndpoint {
private InetSocketAddress address;
private String name = "";
private long last_success = 0;
private long last_fail = 0;
private boolean already_checked = false;
public Endpoint(InetSocketAddress address) {
this.address = address;
}
@Override
public InetSocketAddress getAddress() {
return address;
}
@Override
public long lastSucceeded() {
return last_success;
}
@Override
public long lastFailed() {
return last_fail;
}
@Override
public boolean alreadyChecked() {
return already_checked;
}
@Override
public boolean hasFailed() {
return (last_fail > last_success);
}
public void setSuccess(long millis) {
last_success = millis;
already_checked = true;
}
public void setFailure(long millis) {
last_fail = millis;
}
public String toString() {
return getAddress().toString();
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,35 @@
package com.sap.sailing.monitoring;
import java.net.InetSocketAddress;
/**
* Definition of an endpoint that submits to checks by
* the monitoring service. It consists of an address, a port
* and additional status information.
*
* @author Simon Pamies (info@pamies.de)
* @since Nov 28, 2012
*/
public interface IEndpoint {
public InetSocketAddress getAddress();
public String getName();
public long lastSucceeded();
public long lastFailed();
public boolean alreadyChecked();
public boolean hasFailed();
public void setSuccess(long millis);
public void setFailure(long millis);
public void setName(String name);
public String toString();
}
@@ -1,6 +1,5 @@
package com.sap.sailing.monitoring;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Properties;
import java.util.logging.Logger;
@@ -26,66 +25,61 @@ import org.osgi.framework.BundleException;
public class OSGiRestartingPortMonitor extends AbstractPortMonitor {
Logger log = Logger.getLogger(OSGiRestartingPortMonitor.class.getName());
HashMap<InetSocketAddress, String> endpointservices = new HashMap<InetSocketAddress, String>();
HashMap<String, Bundle> bundles = new HashMap<String, Bundle>();
public OSGiRestartingPortMonitor(InetSocketAddress[] endpoints, String[] services, int interval) {
super(endpoints, interval);
/* store bundles so that we can reference them later */
for (Bundle bundle : Activator.getContext().getBundles()) {
bundles.put(bundle.getSymbolicName(), bundle);
}
for (int i=0; i<endpoints.length;i++) {
endpointservices.put(endpoints[i], services[i]);
}
}
public OSGiRestartingPortMonitor(Properties properties) {
super(properties);
/* store bundles so that we can reference them later */
/* store bundles so that we can reference them later without iterating every time */
for (Bundle bundle : Activator.getContext().getBundles()) {
bundles.put(bundle.getSymbolicName(), bundle);
}
String[] prop_services = properties.getProperty("monitor.services").split(",");
for (int i=0; i<endpoints.length;i++) {
endpointservices.put(endpoints[i], prop_services[i].trim());
endpoints[i].setName(prop_services[i].trim());
}
}
@Override
public void handleFailure(InetSocketAddress endpoint) {
String servicename = endpointservices.get(endpoint);
Bundle bundle = bundles.get(servicename);
public void handleFailure(IEndpoint endpoint) {
Bundle bundle = bundles.get(endpoint.getName());
if (bundle.getState() == BundleEvent.STARTED || bundle.getState() == BundleEvent.STOPPED) {
try {
bundle.stop();
} catch (BundleException e) {
log.severe("Could not stop " + servicename + " trying to start anyway.");
log.severe("Could not stop " + endpoint.getName() + " trying to start anyway.");
}
try {
bundle.start();
} catch (BundleException e) {
log.severe("Could not start " + servicename + "! Handler will try again next time");
log.severe("Could not start " + endpoint.getName() + "! Handler will try again next time");
}
}
log.info("Bundle " + servicename + " restarted");
try {
Session session = Session.getDefaultInstance(this.properties, new SMTPAuthenticator());
MimeMessage msg = new MimeMessage(session);
msg.setSubject("Bundle " + servicename + " restarted");
msg.setContent("The Bundle " + servicename + " has been restarted - port check on " + endpoint.getPort() + " didn't respond!", "text/plain");
msg.addRecipient(RecipientType.TO, new InternetAddress(this.properties.getProperty("mail.to")));
Transport ts = session.getTransport();
ts.connect();
ts.sendMessage(msg, msg.getRecipients(RecipientType.TO));
ts.close();
} catch(Exception ex) {
ex.printStackTrace();
}
log.info("Bundle " + endpoint.getName() + " restarted");
/* only send mail if service has not failed before */
if (!endpoint.hasFailed())
try {
Session session = Session.getDefaultInstance(this.properties, new SMTPAuthenticator());
MimeMessage msg = new MimeMessage(session);
msg.setSubject("Bundle " + endpoint.getName() + " restarted");
msg.setContent("The Bundle " + endpoint.getName() + " has been restarted - port check on " + endpoint.getAddress().getPort() + " didn't respond!\n" +
"This Mail won't be send again if service continues to fail.", "text/plain");
msg.addRecipient(RecipientType.TO, new InternetAddress(this.properties.getProperty("mail.to")));
Transport ts = session.getTransport();
ts.connect();
ts.sendMessage(msg, msg.getRecipients(RecipientType.TO));
ts.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
private class SMTPAuthenticator extends javax.mail.Authenticator {
@@ -97,7 +91,7 @@ public class OSGiRestartingPortMonitor extends AbstractPortMonitor {
}
@Override
public void handleConnection(InetSocketAddress endpoint) {
public void handleConnection(IEndpoint endpoint) {
}
}
@@ -1,6 +1,6 @@
package com.sap.sailing.monitoring;
import java.net.InetSocketAddress;
import java.util.Properties;
/**
* Implementation of port monitor that prints out messages if
@@ -11,17 +11,17 @@ import java.net.InetSocketAddress;
*/
public class SystemPrinterPortMonitor extends AbstractPortMonitor {
public SystemPrinterPortMonitor(InetSocketAddress[] endpoints, int interval) {
super(endpoints, interval);
public SystemPrinterPortMonitor(Properties prop) {
super(prop);
}
@Override
public void handleFailure(InetSocketAddress endpoint) {
public void handleFailure(IEndpoint endpoint) {
System.out.println("ERROR: Could not connect to endpoint " + endpoint.toString());
}
@Override
public void handleConnection(InetSocketAddress endpoint) {
public void handleConnection(IEndpoint endpoint) {
System.out.println("INFO: Connection to " + endpoint.toString() + " succeeded.");
}