/* * Jopr Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.rhq.plugins.jbosscache; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.mc4j.ems.connection.EmsConnection; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; import org.rhq.core.pluginapi.util.SelectiveSkippingEntityResolver; import org.rhq.plugins.jbossas.util.DeploymentUtility; /** * This component will discover JGroups channels within a JBoss Cache instance. * The deal here is that we want to have zero or one JGroups channels per cache. * We will look at the Cache config and see if it contains a * <attribute name="ClusterConfig"> element. If so, we return a JGroups instance, * else we return nothing. * * @author Heiko W. Rupp */ public class JGroupsChannelDiscovery implements ResourceDiscoveryComponent { private final Log log = LogFactory.getLog(JGroupsChannelDiscovery.class); /* (non-Javadoc) * @see org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent#discoverResources(org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext) */ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) throws InvalidPluginConfigurationException, Exception { JBossCacheComponent parent = (JBossCacheComponent) context.getParentResourceComponent(); EmsConnection emsConnection = parent.getEmsConnection(); String resKey = context.getParentResourceContext().getResourceKey(); File file = DeploymentUtility.getDescriptorFile(emsConnection, resKey); if (file == null) { log.warn("File is null for " + resKey); return null; } boolean found = false; try { SAXBuilder builder = new SAXBuilder(); SelectiveSkippingEntityResolver entityResolver = SelectiveSkippingEntityResolver.getDtdAndXsdSkippingInstance(); builder.setEntityResolver(entityResolver); Document doc = builder.build(file); // Get the root element Element root = doc.getRootElement(); // XPath xpath = XPathFactory.newInstance().newXPath(); // TODO this expression would need to work against non-normalized versions of the name attribute // XPathExpression xp = xpath // .compile("/server/mbean[@name='" + resKey + "']/attribute[@name='ClusterConfig']"); // InputSource inputSource = new InputSource(new FileInputStream(file)); // NodeList cconfig = (NodeList) xp.evaluate(inputSource, XPathConstants.NODESET); // if (cconfig != null && cconfig.getLength() > 0) // found = true; // First look for the right mbean of *our* cache - the file may contain more than one // TODO move code in helper, as we'll need it later again // TODO replace the access of 'our' ClusterConfig attribute with an XPath expression for (Object mbeanObj : root.getChildren("mbean")) { if (mbeanObj instanceof Element) { Element mbean = (Element) mbeanObj; String nameAttrib = mbean.getAttributeValue("name"); try { ObjectName on = new ObjectName(nameAttrib); nameAttrib = on.getCanonicalName(); } catch (MalformedObjectNameException e) { log.warn("Can't canonicalize " + nameAttrib); } if (nameAttrib.equals(resKey)) { // our cache instance, look for the right attribute List children = mbean.getChildren("attribute"); for (Object childObj : children) { if (childObj instanceof Element) { Element child = (Element) childObj; String name = child.getAttributeValue("name"); if (name.equals("ClusterConfig")) found = true; } } } } } } catch (IOException e) { log.error("IO error occurred while reading file: " + file, e); } catch (JDOMException e) { log.error("Parsing error occurred while reading file: " + file, e); } if (found) { DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(), // Resource Type resKey + "jgroupsChannel", // ResourceKey TODO good choice ? "JGroups channel", // resource name null, // Version "JGroups config for parent JBossCache", // description context.getDefaultPluginConfiguration(), // config null); // process info Set<DiscoveredResourceDetails> res = new HashSet<DiscoveredResourceDetails>(1); res.add(detail); return res; } return null; } }