/** * Starts the embedded agent, but only if the embedded agent is installed and it is enabled. * * @throws RuntimeException if the agent is installed and enabled but failed to start * @deprecated we don't have an embedded agent anymore, leaving this in case we resurrect it */ private void startEmbeddedAgent() throws RuntimeException { // we can't use EmbeddedAgentBootstrapServiceMBean because if the embedded agent // isn't installed, that class will not be available; we must use JMX API final ObjectName agentBootstrapMBean = ObjectNameFactory.create("rhq:service=EmbeddedAgentBootstrap"); final String agentEnabledAttribute = "AgentEnabled"; final String startAgentMethod = "startAgent"; final String configurationOverridesAttribute = "ConfigurationOverrides"; final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); try { // this will fail if the embedded agent isn't installed String enabled = (String) mbs.getAttribute(agentBootstrapMBean, agentEnabledAttribute); // if we got this far, the embedded agent is at least installed // now check to see if its enabled - if so start it; any startup exceptions now are thrown try { if (Boolean.valueOf(enabled)) { log.info("The embedded Agent is installed and enabled - it will now be started..."); // NOTE: we cannot directly import AgentConfigurationConstants, so we hardcode the // actual constant values here - need to keep an eye on these in the unlikely event // the constant values change. String AgentConfigurationConstants_SERVER_TRANSPORT = "rhq.agent.server.transport"; String AgentConfigurationConstants_SERVER_BIND_ADDRESS = "rhq.agent.server.bind-address"; String AgentConfigurationConstants_SERVER_BIND_PORT = "rhq.agent.server.bind-port"; // Get the configuration overrides as set in the configuration file. // If the agent's bind address isn't overridden with a non-empty value, // then we need to get the Server bind address and use it for the agent's bind address. // If the agent's server endpoint address/port are empty, we again use the values // appropriate for the Server this agent is embedded in. // Note that we don't look for the values in persisted preferences - we assume they // are always present in the configuration overrides (which they should always be); Properties overrides; String serverTransport; String serverAddress; String serverPort; String agentAddress; overrides = (Properties) mbs.getAttribute(agentBootstrapMBean, configurationOverridesAttribute); serverTransport = overrides.getProperty(AgentConfigurationConstants_SERVER_TRANSPORT); serverAddress = overrides.getProperty(AgentConfigurationConstants_SERVER_BIND_ADDRESS); serverPort = overrides.getProperty(AgentConfigurationConstants_SERVER_BIND_PORT); agentAddress = overrides.getProperty(ServiceContainerConfigurationConstants.CONNECTOR_BIND_ADDRESS); Server server = serverManager.getServer(); if (agentAddress == null || agentAddress.trim().equals("")) { overrides.setProperty( ServiceContainerConfigurationConstants.CONNECTOR_BIND_ADDRESS, server.getAddress()); } if (serverAddress == null || serverAddress.trim().equals("")) { overrides.setProperty( AgentConfigurationConstants_SERVER_BIND_ADDRESS, server.getAddress()); } if (serverPort == null || serverPort.trim().equals("")) { if (SecurityUtil.isTransportSecure(serverTransport)) { overrides.setProperty( AgentConfigurationConstants_SERVER_BIND_PORT, Integer.toString(server.getSecurePort())); } else { overrides.setProperty( AgentConfigurationConstants_SERVER_BIND_PORT, Integer.toString(server.getPort())); } } mbs.setAttribute( agentBootstrapMBean, new Attribute(configurationOverridesAttribute, overrides)); // We need to do the agent startup in a separate thread so we do not hang // this startup servlet. JBossAS 4.2 will not begin accepting HTTP requests // until this startup servlet has finished (this is different from JBossAS 4.0). // The agent needs to submit an HTTP request in order to complete its startup // (it needs to register with the server). // The side effect of this is the RHQ Server will still start even if the embedded // agent fails to start - this may not be a bad thing. We probably do not want // the entire RHQ Server to go down if its agent fails to start. Runnable agentStartRunnable = new Runnable() { public void run() { // this returns only when the agent has started and is registered (sends HTTP // request) try { mbs.invoke(agentBootstrapMBean, startAgentMethod, new Object[0], new String[0]); } catch (Throwable t) { log.error("Failed to start the embedded Agent - it will not be available!", t); } } }; Thread agentStartThread = new Thread(agentStartRunnable, "Embedded Agent Startup"); agentStartThread.setDaemon(true); agentStartThread.start(); } else { log.debug("The embedded Agent is not enabled, so it will not be started."); } } catch (Throwable t) { throw new RuntimeException("Failed to start the embedded Agent.", t); } } catch (RuntimeException se) { throw se; } catch (Throwable t) { log.info("The embedded Agent is not installed, so it will not be started (" + t + ")."); } return; }
@Override public void run() { LOG.info(AgentI18NResourceKeys.PRIMARY_SERVER_SWITCHOVER_THREAD_STARTED); while (!isInterrupted() && !toldToStop) { try { // Note that if the agent is not sending or the failover list doesn't have any servers, // then we skip this time and wait some more. // However, it the agent is sending and we have a failover list, then we need to check // to see if the server we are currently talking to is the same as primary server, listed // at the top of the failover list. If not the same, we ask the agent to switch to that // server. ClientCommandSender sender = this.agent.getClientCommandSender(); if (sender.isSending()) { FailoverListComposite failoverList = this.agent.downloadServerFailoverList(); // ask the server for a new one // if the failover list doesn't have any servers, skip our poll and wait some more if (failoverList.size() > 0) { AgentConfiguration config = this.agent.getConfiguration(); String transport = config.getServerTransport(); String transportParams = config.getServerTransportParams(); String currentServerAddress = config.getServerBindAddress(); int currentServerPort = config.getServerBindPort(); ServerEntry primary = failoverList.get(0); // get the top of the list, aka primary server String primaryAddress = primary.address; int primaryPort = (SecurityUtil.isTransportSecure(transport)) ? primary.securePort : primary.port; if (!primaryAddress.equals(currentServerAddress) || primaryPort != currentServerPort) { LOG.info( AgentI18NResourceKeys.NOT_TALKING_TO_PRIMARY_SERVER, primaryAddress, primaryPort, currentServerAddress, currentServerPort); // create our own comm so we ping in an isolated client - don't reuse the sender's // comm for this RemoteCommunicator comm = this.agent.createServerRemoteCommunicator( transport, primaryAddress, primaryPort, transportParams); if (ping(comm)) { LOG.info(AgentI18NResourceKeys.PRIMARY_SERVER_UP, primaryAddress, primaryPort); failoverList.resetIndex(); // so the failover method call starts at the top this.agent.failoverToNewServer( sender .getRemoteCommunicator()); // note that we make sure we pass in the sender's // comm } else { LOG.info( AgentI18NResourceKeys.PRIMARY_SERVER_STILL_DOWN, primaryAddress, primaryPort); } } } } // to do sleep until its time to check again synchronized (this) { wait(interval); } } catch (InterruptedException ie) { break; // exiting } catch (Exception e) { LOG.warn(e, AgentI18NResourceKeys.PRIMARY_SERVER_SWITCHOVER_EXCEPTION, e); } } LOG.info(AgentI18NResourceKeys.PRIMARY_SERVER_SWITCHOVER_THREAD_STOPPED); return; }