/* * Copyright 2012 JBoss Inc * * Licensed 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.overlord.sramp.governance; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Timer; import java.util.TimerTask; import org.apache.commons.codec.binary.Base64; import org.overlord.dtgov.common.exception.ConfigException; import org.overlord.dtgov.server.i18n.Messages; import org.overlord.sramp.client.SrampClientException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Singleton. The SRAMPMonitor queries the S-RAMP repository using * XPath2 like queries to find interesting changes in the repository. */ public class SRAMPMonitor extends TimerTask { private Logger log = LoggerFactory.getLogger(this.getClass()); private static Governance governance = new Governance(); private static SRAMPMonitor srampMonitor = null; private static Timer timer = null; private static long interval = governance.getQueryInterval(); private long acceptableLagTime = governance.getAcceptableLagtime(); private SRAMPMonitor() { } public static synchronized SRAMPMonitor getInstance () { if (srampMonitor==null) { srampMonitor = new SRAMPMonitor(); timer = new Timer(true); timer.scheduleAtFixedRate(srampMonitor, 60000, interval); } return srampMonitor; } @Override public boolean cancel() { timer.cancel(); return super.cancel(); } @Override public synchronized void run() { try { if (firedOnTime(scheduledExecutionTime()) && isAppserverReady()) { long startTime = System.currentTimeMillis(); QueryExecutor.execute(); long endTime = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug(Messages.i18n.format("SRAMPMonitor.QueryTiming", (endTime-startTime))); //$NON-NLS-1$ } if ((endTime-startTime) > interval) { log.debug(Messages.i18n.format("SRAMPMonitor.IntervalExceeded", //$NON-NLS-1$ interval, (endTime - startTime))); } else { log.debug(Messages.i18n.format("SRAMPMonitor.TaskTiming", (endTime - startTime))); //$NON-NLS-1$ } } else { log.debug(Messages.i18n.format("SRAMPMonitor.NotReady")); //$NON-NLS-1$ } } catch (ConfigException confEx) { log.error(confEx.getMessage()); } catch (SrampClientException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Checks to see that the event are fired on time. If they are late this may indicate that the server * is under load. The acceptableLagTime is configurable using the "juddi.notification.acceptable.lagtime" * property and is defaulted to 1000ms. A negative value means that you do not care about the lag time * and you simply always want to go do the notification work. * * @param scheduleExecutionTime * @return true if the server is within the acceptable latency lag. */ private boolean firedOnTime(long scheduleExecutionTime) { long lagTime = System.currentTimeMillis() - scheduleExecutionTime; if (lagTime <= acceptableLagTime || acceptableLagTime < 0) { return true; } else { log.debug(Messages.i18n.format("SRAMPMonitor.LaggingTimer", lagTime, acceptableLagTime)); //$NON-NLS-1$ return false; } } /** * Checks if we can ready the S-RAMP repository as well as the BPM API. * * @return * @throws MalformedURLException */ private boolean isAppserverReady() throws MalformedURLException { boolean isReady = true; String serviceDocumentUrl = governance.getSrampUrl().toExternalForm() + "/s-ramp/servicedocument"; //$NON-NLS-1$ isReady = urlExists(serviceDocumentUrl); if (!isReady) log.debug(Messages.i18n.format("SRAMPMonitor.CannotConnect", governance.getSrampUrl().toExternalForm())); //$NON-NLS-1$ return isReady; } /** * Returns true if the given URL can be accessed. * @param checkUrl */ public boolean urlExists(String checkUrl) { HttpURLConnection checkConnection = null; try { URL checkURL = new URL(checkUrl); checkConnection = (HttpURLConnection) checkURL.openConnection(); checkConnection.setRequestMethod("HEAD"); //$NON-NLS-1$ checkConnection.setConnectTimeout(10000); checkConnection.setReadTimeout(10000); addAuthorization(checkConnection); checkConnection.connect(); return (checkConnection.getResponseCode() == 200); } catch (Exception e) { return false; } finally { if (checkConnection!=null) checkConnection.disconnect(); } } /** * Adds Authorization config to the connection prior to the request * being sent to the server. * @param connection */ private void addAuthorization(HttpURLConnection connection) { Governance governance = new Governance(); String username = governance.getSrampUser(); String password = governance.getSrampPassword(); if (username != null && password != null) { String b64Auth = Base64.encodeBase64String((username + ":" + password).getBytes()).trim(); //$NON-NLS-1$ connection.setRequestProperty("Authorization", "Basic " + b64Auth); //$NON-NLS-1$ //$NON-NLS-2$ } else { log.warn(Messages.i18n.format("SRAMPMonitor.MissingCreds")); //$NON-NLS-1$ } } }