Java tutorial
/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004-2008], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.hq.agent; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A callback class that notifies the starting entity (most likely the agent * client) as to the startup status of the agent (success/failure). */ public class AgentStartupCallback { private final Log _log = LogFactory.getLog(AgentStartupCallback.class); private Socket _startupSock; /** * Creates an instance. * * @param config The agent configuration. * @throws IOException if the callback fails to establish a connection * to the starting entity. */ public AgentStartupCallback(AgentConfig config) throws AgentConfigException, IOException { int sPort = config.getNotifyUpPort(); if (sPort != -1) { connectToPort(sPort); } else { _log.debug("Agent startup callback is disabled"); _startupSock = null; } } private void connectToPort(int sPort) throws IOException { final int minute = 60000; int nextAttemptGap = (int) (0.5 * minute); // start with half a minute int maxAttemptGap = 30 * 60000; // wait no more then half an hour IOException exceptionToThrow = null; while (nextAttemptGap <= maxAttemptGap) { try { _startupSock = new Socket("127.0.0.1", sPort); return; } catch (IOException exc) { exceptionToThrow = exc; _log.error("Failed to connect to startup port (" + sPort + ")", exc); } try { _log.info("Waiting " + ((double) nextAttemptGap / minute) + " minutes before retrying connection to Server port."); Thread.sleep(nextAttemptGap); } catch (InterruptedException e) { _log.error("Failed to wait for next connection to startup port (" + sPort + ")", e); } nextAttemptGap *= 2; } throw new IOException( "Failed to connect to startup " + "port (" + sPort + "): " + exceptionToThrow.getMessage()); } /** * Notify the starting entity. * * @param succeeded <code>true</code> if the agent startup succeeded; * <code>false</code> if the agent startup failed. */ public void onAgentStartup(boolean succeeded) { if (succeeded) { writeStartupState(1); } else { writeStartupState(0); } } /** * Clean up resources just in case! */ protected void finalize() throws Throwable { if (_startupSock != null) { try { _startupSock.close(); } catch (Exception e) { } } } private void writeStartupState(int state) { if (_startupSock == null) { _log.debug("Agent startup callback is disabled"); return; } try { DataOutputStream dOs = new DataOutputStream(_startupSock.getOutputStream()); dOs.writeInt(state); dOs.flush(); } catch (IOException exc) { _log.error("Error writing startup state to startup port: " + exc.getMessage()); } finally { try { _startupSock.close(); } catch (IOException iexc) { } } } }