/*
* 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;
}
}