/*
* 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.jbossas.util;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.resource.CreateResourceStatus;
import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.core.pluginapi.util.SelectiveSkippingEntityResolver;
import org.rhq.plugins.jbossas.JBossMessagingComponent;
/**
* @author Mark Spritzler
* @author Heiko W. Rupp
*/
public class JBossMessagingConfigurationEditor extends AbstractMessagingConfigurationEditor implements
XMLConfigurationEditor {
private static Map<String, String> types = new HashMap<String, String>();
private static final String SECURITY_CONF = "SecurityConfig";
{
types.put("JBM JMS Topic", JBossMessagingComponent.TOPIC_MBEAN_NAME);
types.put("JBM JMS Queue", JBossMessagingComponent.QUEUE_MBEAN_NAME);
}
private static Map<String, String> codes = new HashMap<String, String>();
private static final String JBM_QUEUE_CODE = "org.jboss.jms.server.destination.QueueService";
private static final String JBM_TOPIC_CODE = "org.jboss.jms.server.destination.TopicService";
{
codes.put("JBM JMS Topic", JBM_TOPIC_CODE);
codes.put("JBM JMS Queue", JBM_QUEUE_CODE);
}
// Instance vars
private String[] dependsProperties = { "ServerPeer", "SecurityManager", "ExpiryDestination" };
private String[] simpleAttributeProperties = { "JNDIName", "Clustered", "MaxDeliveryAttempts", "RedeliveryDelay",
"MessageCounterHistoryDayLimit", "MaxSize", "FullSize", "PageSize", "DownCacheSize" };
public JBossMessagingConfigurationEditor(String type) {
this.type = types.get(type);
code = codes.get(type);
securityConfig = SECURITY_CONF;
}
public void updateConfiguration(File deploymentFile, String name, ConfigurationUpdateReport report) {
report.setStatus(ConfigurationUpdateStatus.INPROGRESS);
this.deploymentFile = deploymentFile;
this.updateReport = report;
try {
config = report.getConfiguration();
updateConfiguration(deploymentFile, name);
if (report.getStatus() != ConfigurationUpdateStatus.FAILURE) {
report.setStatus(ConfigurationUpdateStatus.SUCCESS);
}
} catch (IOException e) {
LOG.error("IOException when trying to read xml file for type " + type + " component " + name, e);
report.setErrorMessageFromThrowable(e);
} catch (JDOMException e) {
LOG.error("JDOMException when trying to read xml file for type " + type + " component " + name, e);
report.setErrorMessageFromThrowable(e);
}
}
public void updateConfiguration(File deploymentFile, String name, CreateResourceReport report) {
report.setStatus(CreateResourceStatus.IN_PROGRESS);
this.deploymentFile = deploymentFile;
this.createReport = report;
try {
config = report.getResourceConfiguration();
updateConfiguration(deploymentFile, name);
if (report.getStatus() != CreateResourceStatus.FAILURE) {
report.setStatus(CreateResourceStatus.SUCCESS);
}
} catch (IOException e) {
LOG.error("Unable to write to a new file", e);
report.setException(e);
} catch (JDOMException e) {
LOG.error("Unable to convert resource into xml file elements", e);
report.setException(e);
}
}
/**
* Method that actually will build and update the XML @see Document object from the @see Configuration object. This
* is called from the public interface methods.
*
* @param file XML File to save to
* @param name name of the Component
*
* @throws org.jdom.JDOMException If there is a parsing or creation exception of the document
* @throws java.io.IOException If there is IO reading errors for the File
*/
void updateConfiguration(File file, String name) throws JDOMException, IOException {
deploymentFile = file;
Document doc;
if (deploymentFile.exists()) {
SAXBuilder builder = new SAXBuilder();
SelectiveSkippingEntityResolver entityResolver = SelectiveSkippingEntityResolver.getDtdAndXsdSkippingInstance();
builder.setEntityResolver(entityResolver);
doc = builder.build(deploymentFile);
root = doc.getRootElement();
} else {
doc = new Document();
root = new Element(rootElementString);
doc.setRootElement(root);
}
if (!root.getName().equals(rootElementString)) {
throw new RuntimeException(rootElementString + " file format exception on [" + deploymentFile
+ "], expected [" + rootElementString + "] element but found [" + root.getName() + "]");
}
Element componentElement = findComponentElement(name);
boolean isNewComponent = false;
if (componentElement == null) {
isNewComponent = true;
componentElement = new Element("mbean");
Attribute codeAttribute = new Attribute("code", code);
componentElement.setAttribute(codeAttribute);
String xtype;
if (type.contains("Topic"))
xtype = "Topic";
else
xtype = "Queue";
Attribute xmBeanDD = new Attribute("xmbean-dd", "xmdesc/" + xtype + "-xmbean.xml");
componentElement.setAttribute(xmBeanDD);
addNameAttributeToMBeanElement(componentElement, getNameProperty());
} else {
componentElement.removeContent();
// update if the Name has changed
updateIfNameChanged(componentElement);
}
// Add a dependency to the postoffice
Element postOffice = new Element("depends");
postOffice.addContent("jboss.messaging:service=PostOffice");
componentElement.addContent(postOffice);
// Make the Elements from the Configuration object here
//First the depends properties
bindSimplePropertiesToConfiguration(dependsProperties, DEPENDS, "optional-attribute-name", componentElement);
//Now the simple attributes tags
bindSimplePropertiesToConfiguration(simpleAttributeProperties, ATTRIBUTE, "name", componentElement);
//Now the fun part, getting securityConfig into Elements
PropertyList securityListProperty = config.getList(SECURITY_CONF);
if (securityListProperty != null) {
// Create the basic elements for putting all roles into
Element securityConf = new Element("attribute");
Attribute secConfAttribute = new Attribute("name", SECURITY_CONF);
securityConf.setAttribute(secConfAttribute);
Element security = new Element("security");
securityConf.addContent(security);
List<Property> roles = securityListProperty.getList();
for (Property role : roles) {
PropertyMap roleMap = (PropertyMap) role;
Map<String, Property> map = roleMap.getMap();
Element roleElement = new Element(roleMap.getName());
Set<String> keys = map.keySet();
for (String key : keys) {
PropertySimple attribute = (PropertySimple) map.get(key);
if (attribute.getStringValue() != null) {
Attribute keyAttribute = new Attribute(attribute.getName(), attribute.getStringValue());
roleElement.setAttribute(keyAttribute);
}
}
security.addContent(roleElement);
}
componentElement.addContent(securityConf);
}
if (isNewComponent) {
root.addContent(componentElement);
}
updateFile(doc);
}
}