/* * The MIT License * * Original work sponsored and donated by National Board of e-Health (NSI), Denmark (http://www.nsi.dk) * * Copyright (C) 2011 National Board of e-Health (NSI), Denmark (http://www.nsi.dk) * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * $HeadURL$ * $Id$ */ package com.trifork.sosigw.sts; import mx4j.AbstractDynamicMBean; import org.apache.log4j.Logger; import javax.management.*; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import java.io.IOException; import java.util.List; import java.util.Set; public class CircuitBreakerManagerMBean extends AbstractDynamicMBean { private final static Logger logger = Logger.getLogger(CircuitBreakerManagerMBean.class); private static Class wrappedClass = CircuitBreakerSTSProxy.class; protected String getMBeanDescription() { return "Class Descript for " + wrappedClass.getName(); } protected MBeanAttributeInfo[] createMBeanAttributeInfo() { return new MBeanAttributeInfo[]{ new MBeanAttributeInfo("StateDescription", String.class.getName(), "CircuitBreaker state", true, false, false), new MBeanAttributeInfo("FailureCount", int.class.getName(), "Number of recorded failures since the circuit breaker entered the 'closed' state", true, false, false), new MBeanAttributeInfo("NumberOfFailuresBeforeOpening", int.class.getName(), "Number of failures allowed before the circuit breaker opens", true, false, false), new MBeanAttributeInfo("MillisecondsBeforeAttemptingClose", int.class.getName(), "Milliseconds to elapse before an open circuit breaker retries", true, false, false), new MBeanAttributeInfo("AttemptedCalls", int.class.getName(), "Number of calls to this STS, both succesful and failing", true, false, false), new MBeanAttributeInfo("SuccessfulCalls", int.class.getName(), "Number of succesful calls to this STS", true, false, false) }; } private CircuitBreakerManagerMBean(CircuitBreakerSTSProxy wrappedInstance, int instanceNo) { setResource(wrappedInstance); registerWithMBeanServer(instanceNo); } @SuppressWarnings({"TypeMayBeWeakened"}) public static void registerMBeans(List proxies) { unregisterMBeans(); int i = 1; for (CircuitBreakerSTSProxy proxy : proxies) { new CircuitBreakerManagerMBean(proxy, i); i++; } } private static void unregisterMBeans() { MBeanServer mBeanServer = getServer(); if (mBeanServer == null) return; Set objectNames; try { objectNames = mBeanServer.queryNames(new ObjectName("sosigw:*"), null); } catch (MalformedObjectNameException e) { throw new RuntimeException(e); } for (ObjectName objectName : objectNames) { try { mBeanServer.unregisterMBean(objectName); } catch (InstanceNotFoundException ignored) { } catch (MBeanRegistrationException ignored) { } } } private void registerWithMBeanServer(int instanceNo) { try { String url = ((CircuitBreakerSTSProxy) getResource()).getUrlString(); logger.debug("RegisterWithMBeanServer(" + instanceNo + ") - [" + url + "]"); ObjectName name = new ObjectName("sosigw:sosi-gw-sts-cb=STS " + instanceNo + " - " + url.replaceAll(":", "_")); MBeanServer mBeanServer = getServer(); if (mBeanServer != null) { mBeanServer.registerMBean(this, name); } else { logger.warn("Failed looking up MBeanServer, unable to register MBean for URL: " + url); } } catch (Exception e) { logger.error("Unable to register MBean", e); } } private static MBeanServer getServer() { MBeanServer mbserver = null; List mbservers = MBeanServerFactory.findMBeanServer(null); if (mbservers.size() > 0) { mbserver = mbservers.get(0); } if (mbserver == null) { mbserver = lookupJBossServer(); } return mbserver; } private static MBeanServer lookupJBossServer() { JMXConnector jmxc = null; try { final String serverURL = "service:jmx:rmi:///jndi/rmi://localhost:1190/jmxconnector"; JMXServiceURL url = new JMXServiceURL(serverURL); logger.debug("Connecting to " + url); jmxc = JMXConnectorFactory.connect(url); logger.debug("Acquiring MBeanServerConnection"); MBeanServerConnection server = jmxc.getMBeanServerConnection(); if (server instanceof MBeanServer) { logger.debug("Found server - " + server); return (MBeanServer) server; } } catch (Exception e) { logger.error("Unable to lookup JBoss MBeanServer", e); } finally { tryToClose(jmxc); } return null; } private static void tryToClose(JMXConnector jmxc) { if (jmxc != null) { try { jmxc.close(); } catch (IOException e) { logger.warn("Ignoring exception while trying to close JMXConnector " + jmxc, e); } } } }