modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServerConfigurationDelegate.java
| 465 ++++++++++
modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
| 162 ---
2 files changed, 485 insertions(+), 142 deletions(-)
New commits:
commit 0e629c47772f9ae540a5e0a7709ddc5983e5626a
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Aug 1 15:12:18 2012 +0200
Pulling the configuration support out of the main component class to make
it more readable. Config update should now work, too.
diff --git
a/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServerConfigurationDelegate.java
b/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServerConfigurationDelegate.java
new file mode 100644
index 0000000..cf4ddf8
--- /dev/null
+++
b/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServerConfigurationDelegate.java
@@ -0,0 +1,465 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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 as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.plugins.hadoop;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.util.file.FileUtil;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class HadoopServerConfigurationDelegate {
+
+ private static final Log LOG =
LogFactory.getLog(HadoopServerConfigurationDelegate.class);
+
+ private static final XMLInputFactory XML_INPUT_FACTORY =
XMLInputFactory.newInstance();
+ private static final XMLOutputFactory XML_OUTPUT_FACTORY =
XMLOutputFactory.newInstance();
+
+ private static final String CONFIGURATION_TAG_NAME = "configuration";
+ private static final String PROPERTY_TAG_NAME = "property";
+ private static final String NAME_TAG_NAME = "name";
+ private static final String VALUE_TAG_NAME = "value";
+
+ private static final Pattern PROPERTY_NAME_EXTRACT_PATTERN =
Pattern.compile("<name>(.*)<\\/name>");
+ private static final Pattern PROPERTY_VALUE_REPLACE_PATTERN =
Pattern.compile("<value>.*<\\/value>");
+
+ private static class DetectedPropertyNameAndUpdatedTag {
+ String propertyName;
+ String updatedTag;
+ }
+
+ private static class PropertiesPerConfigFileBuilder {
+ private static class ConfigFileAndConfigName {
+ File configFile;
+ String propertyName;
+
+ ConfigFileAndConfigName(File homeDir, String propertyDefinitionName) {
+ String[] parts = propertyDefinitionName.split(":");
+
+ String configFileName = parts[0];
+
+ configFile = new File(homeDir, configFileName);
+ propertyName = parts[1];
+
+ if (!configFile.exists()) {
+ throw new IllegalArgumentException("The expected configuration
file ("
+ + configFile.getAbsolutePath() + ") doesn't
exist.");
+ }
+ }
+ }
+
+ private Map<File, Map<String, PropertySimple>> propertiesPerFile =
+ new HashMap<File, Map<String, PropertySimple>>();
+ private File homeDir;
+
+ public PropertiesPerConfigFileBuilder(File homeDir) {
+ this.homeDir = homeDir;
+ }
+
+ void addProperty(String name, Configuration parentConfig) {
+ PropertySimple ret = new PropertySimple();
+ ret.setName(name);
+ parentConfig.put(ret);
+ addProperty(ret);
+ }
+
+ void addProperty(PropertySimple property) {
+ ConfigFileAndConfigName fn = new ConfigFileAndConfigName(homeDir,
property.getName());
+
+ Map<String, PropertySimple> props =
propertiesPerFile.get(fn.configFile);
+ if (props == null) {
+ props = new HashMap<String, PropertySimple>();
+ propertiesPerFile.put(fn.configFile, props);
+ }
+
+ props.put(fn.propertyName, property);
+ }
+
+ Map<File, Map<String, PropertySimple>>
getPropertiesPerFilePerConfigName() {
+ return propertiesPerFile;
+ }
+ }
+
+ private ResourceContext<ResourceComponent<?>> componentContext;
+
+ public
HadoopServerConfigurationDelegate(ResourceContext<ResourceComponent<?>>
componentContext) {
+ this.componentContext = componentContext;
+ }
+
+ public Configuration loadConfiguration() throws Exception {
+ ConfigurationDefinition definition =
componentContext.getResourceType().getResourceConfigurationDefinition();
+ Configuration config = new Configuration();
+
+ File homeDir = getHomeDir();
+
+ fillResourceConfiguration(homeDir, config, definition);
+
+ return config;
+ }
+
+ public void updateConfiguration(Configuration config) throws Exception {
+ //gather the files to update
+ PropertiesPerConfigFileBuilder bld = new
PropertiesPerConfigFileBuilder(getHomeDir());
+
+ for (Property p : config.getProperties()) {
+ if (!(p instanceof PropertySimple)) {
+ continue;
+ }
+
+ PropertySimple property = (PropertySimple) p;
+ bld.addProperty(property);
+ }
+
+ for (Map.Entry<File, Map<String, PropertySimple>> e :
bld.getPropertiesPerFilePerConfigName().entrySet()) {
+ updateFile(e.getKey(), e.getValue());
+ }
+ }
+
+ private File getHomeDir() {
+ File homeDir =
+ new
File(componentContext.getPluginConfiguration().getSimpleValue(HadoopServiceDiscovery.HOME_DIR_PROPERTY));
+
+ if (!homeDir.exists()) {
+ throw new IllegalArgumentException("The configured home directory of
this Hadoop instance ("
+ + homeDir.getAbsolutePath() + ") no longer exists.");
+ }
+
+ if (!homeDir.isDirectory()) {
+ throw new IllegalArgumentException("The configured home directory of
this Hadoop instance ("
+ + homeDir.getAbsolutePath() + ") is not a directory.");
+ }
+
+ if (!homeDir.canRead()) {
+ throw new IllegalArgumentException("The configured home directory of
this Hadoop instance ("
+ + homeDir.getAbsolutePath() + ") is not readable.");
+ }
+
+ return homeDir;
+ }
+
+ public static void
+ fillResourceConfiguration(File homeDir, Configuration config,
ConfigurationDefinition definition)
+ throws XMLStreamException, IOException {
+ //the config is just a bunch of simples, so this is rather easy.. no cumbersome
traversal of property maps and lists
+
+ PropertiesPerConfigFileBuilder bld = new
PropertiesPerConfigFileBuilder(homeDir);
+
+ for (PropertyDefinition pd : definition.getPropertyDefinitions().values()) {
+ if (!(pd instanceof PropertyDefinitionSimple)) {
+ //hmm... well, someone thought it's enough to change the config and
the code would be clever.
+ //it's not ;)
+ continue;
+ }
+
+ String propertyName = pd.getName();
+ bld.addProperty(propertyName, config);
+ }
+
+ for (Map.Entry<File, Map<String, PropertySimple>> e :
bld.getPropertiesPerFilePerConfigName().entrySet()) {
+ File configFile = e.getKey();
+ Map<String, PropertySimple> propertiesToFind = e.getValue();
+
+ parseAndAssignProps(configFile, propertiesToFind);
+ }
+ }
+
+ private static void parseAndAssignProps(File configFile, Map<String,
PropertySimple> props)
+ throws XMLStreamException, IOException {
+ FileInputStream in = new FileInputStream(configFile);
+ XMLStreamReader rdr = XML_INPUT_FACTORY.createXMLStreamReader(in);
+ try {
+ boolean inProperty = false;
+ String propertyName = null;
+ String propertyValue = null;
+
+ while (rdr.hasNext()) {
+ int event = rdr.next();
+
+ String tag = null;
+
+ switch (event) {
+ case XMLStreamReader.START_ELEMENT:
+ tag = rdr.getName().getLocalPart();
+ if (PROPERTY_TAG_NAME.equals(tag)) {
+ inProperty = true;
+ } else if (inProperty && NAME_TAG_NAME.equals(tag)) {
+ propertyName = rdr.getElementText();
+ } else if (inProperty && VALUE_TAG_NAME.equals(tag)) {
+ propertyValue = rdr.getElementText();
+ }
+ break;
+ case XMLStreamReader.END_ELEMENT:
+ tag = rdr.getName().getLocalPart();
+ if (PROPERTY_TAG_NAME.equals(tag)) {
+ inProperty = false;
+
+ PropertySimple prop = props.get(propertyName);
+ if (prop != null) {
+ prop.setValue(propertyValue);
+ }
+
+ propertyName = null;
+ propertyValue = null;
+ }
+ break;
+ }
+ }
+ } finally {
+ rdr.close();
+ in.close();
+ }
+ }
+
+ private static void updateFile(File configFile, Map<String, PropertySimple>
allProps) throws IOException,
+ InterruptedException, XMLStreamException {
+ InputStream in = null;
+ XMLStreamReader rdr = null;
+
+ OutputStream out = null;
+ XMLStreamWriter outWrt = null;
+
+ try {
+ Set<String> processedPropertyNames = new HashSet<String>();
+
+ in = new BufferedInputStream(new FileInputStream(configFile));
+ rdr = XML_INPUT_FACTORY.createXMLStreamReader(in);
+
+ File tmpFile = File.createTempFile("hadoop-plugin", null);
+ out = new FileOutputStream(tmpFile);
+ outWrt = XML_OUTPUT_FACTORY.createXMLStreamWriter(out);
+
+ ByteArrayOutputStream stash = new ByteArrayOutputStream();
+ XMLStreamWriter stashWrt = XML_OUTPUT_FACTORY.createXMLStreamWriter(stash);
+ boolean outputActive = true;
+
+ outWrt.writeStartDocument();
+
+ while (rdr.hasNext()) {
+ int event = rdr.next();
+
+ XMLStreamWriter wrt = outputActive ? outWrt : stashWrt;
+
+ switch (event) {
+ case XMLStreamConstants.ATTRIBUTE:
+ break;
+ case XMLStreamConstants.CDATA:
+ wrt.writeCData(rdr.getText());
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ wrt.writeCharacters(rdr.getText());
+ break;
+ case XMLStreamConstants.COMMENT:
+ wrt.writeComment(rdr.getText());
+ break;
+ case XMLStreamConstants.DTD:
+ wrt.writeDTD(rdr.getText());
+ break;
+ case XMLStreamConstants.END_DOCUMENT:
+ wrt.writeEndDocument();
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (PROPERTY_TAG_NAME.equals(rdr.getName().getLocalPart())) {
+ String encoding = rdr.getEncoding();
+ if (encoding == null) {
+ encoding = "UTF-8";
+ }
+
+ String propertyTagSoFar =
+
Charset.forName(encoding).decode(ByteBuffer.wrap(stash.toByteArray())).toString();
+ DetectedPropertyNameAndUpdatedTag propAndTag =
updateProperty(propertyTagSoFar, allProps);
+
+ //yes, we're intentionally circumventing the xml stream
writer, because we already have the XML data we want to write.
+ outWrt.flush();
+ out.write(propAndTag.updatedTag.getBytes("UTF-8"));
+
+ processedPropertyNames.add(propAndTag.propertyName);
+
+ //reset stuff
+ stash.reset();
+ wrt = outWrt;
+ outputActive = true;
+ } else if
(CONFIGURATION_TAG_NAME.equals(rdr.getName().getLocalPart())) {
+ //now add the new props
+ for(String prop : processedPropertyNames) {
+ allProps.remove(prop);
+ }
+
+ for(Map.Entry<String, PropertySimple> e :
allProps.entrySet()) {
+ outWrt.writeStartElement(PROPERTY_TAG_NAME);
+
+ outWrt.writeStartElement(NAME_TAG_NAME);
+ outWrt.writeCharacters(e.getKey());
+ outWrt.writeEndElement();
+
+ outWrt.writeStartElement(VALUE_TAG_NAME);
+ outWrt.writeCharacters(e.getValue().getStringValue());
+ outWrt.writeEndElement();
+
+ outWrt.writeEndElement();
+ }
+ }
+ wrt.writeEndElement();
+ break;
+ case XMLStreamConstants.ENTITY_DECLARATION:
+ //XXX could not find what to do with this
+ break;
+ case XMLStreamConstants.ENTITY_REFERENCE:
+ wrt.writeEntityRef(rdr.getText());
+ break;
+ case XMLStreamConstants.NAMESPACE:
+ for (int i = 0; i < rdr.getNamespaceCount(); ++i) {
+ wrt.writeNamespace(rdr.getNamespacePrefix(i),
rdr.getNamespaceURI(i));
+ }
+ break;
+ case XMLStreamConstants.NOTATION_DECLARATION:
+ //XXX could not find what to do with this
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ wrt.writeProcessingInstruction(rdr.getPITarget(), rdr.getPIData());
+ break;
+ case XMLStreamConstants.SPACE:
+ wrt.writeCharacters(rdr.getText());
+ break;
+ case XMLStreamConstants.START_DOCUMENT:
+ //this seems to be never called for some strange reason
+ //wrt.writeStartDocument();
+ break;
+ case XMLStreamConstants.START_ELEMENT:
+ wrt.writeStartElement(rdr.getName().getPrefix(),
rdr.getName().getLocalPart(), rdr.getName()
+ .getNamespaceURI());
+
+ for (int i = 0; i < rdr.getAttributeCount(); ++i) {
+ wrt.writeAttribute(rdr.getAttributePrefix(i),
rdr.getAttributeNamespace(i),
+ rdr.getAttributeLocalName(i), rdr.getAttributeValue(i));
+ }
+
+ if (PROPERTY_TAG_NAME.equals(rdr.getName().getLocalPart())) {
+ wrt.writeCharacters("");
+ outputActive = false;
+ }
+ break;
+ }
+ }
+
+ outWrt.flush();
+ out.flush();
+ out.close();
+
+ in.close();
+
+ //now copy the temp file in the place of the original one
+ FileUtil.copyFile(tmpFile, configFile);
+ } finally {
+ rdr.close();
+
+ outWrt.flush();
+ outWrt.close();
+
+ try {
+ in.close();
+ } finally {
+ out.flush();
+ out.close();
+ }
+ }
+ }
+
+ private static DetectedPropertyNameAndUpdatedTag updateProperty(String propertyTag,
Map<String, PropertySimple> allProps) {
+
+ DetectedPropertyNameAndUpdatedTag ret = new DetectedPropertyNameAndUpdatedTag();
+ //for now
+ ret.updatedTag = propertyTag;
+
+ //extract the name of the property we're dealing with
+ Matcher propertyNameMatcher =
PROPERTY_NAME_EXTRACT_PATTERN.matcher(propertyTag);
+ if (!propertyNameMatcher.find()) {
+ return ret;
+ }
+
+ String propertyName = propertyNameMatcher.group(1);
+ ret.propertyName = propertyName;
+
+ if (propertyName == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Possibly invalid property tag?\n" + propertyTag);
+ }
+
+ return ret;
+ }
+
+ //try to find the property in allProps
+ PropertySimple prop = allProps.get(propertyName);
+
+ if (prop == null) {
+ return ret;
+ }
+
+ if (prop.getStringValue() == null) {
+ //this property has been unset
+ ret.updatedTag = "";
+ return ret;
+ }
+
+ Matcher propertyValueMatcher =
PROPERTY_VALUE_REPLACE_PATTERN.matcher(propertyTag);
+ if (!propertyValueMatcher.find()) {
+ return ret;
+ }
+
+ ret.updatedTag = propertyValueMatcher.replaceAll("<value>" +
prop.getStringValue() + "</value>");
+
+ return ret;
+ }
+}
diff --git
a/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
b/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
index 66ac741..a84798b 100644
---
a/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
+++
b/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
@@ -19,24 +19,8 @@
package org.rhq.plugins.hadoop;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Set;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamWriter;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mc4j.ems.connection.EmsConnection;
@@ -45,11 +29,6 @@ import org.mc4j.ems.connection.bean.attribute.EmsAttribute;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
-import org.rhq.core.domain.configuration.Property;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
-import org.rhq.core.domain.configuration.definition.PropertyDefinition;
-import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementDataTrait;
@@ -70,63 +49,16 @@ public class HadoopServiceComponent extends
JMXServerComponent<ResourceComponent
private static final Log LOG = LogFactory.getLog(HadoopServiceComponent.class);
- private static final XMLInputFactory XML_INPUT_FACTORY =
XMLInputFactory.newInstance();
- private static final XMLOutputFactory XML_OUTPUT_FACTORY =
XMLOutputFactory.newInstance();
-
- private static final String PROPERTY_TAG_NAME = "property";
- private static final String NAME_TAG_NAME = "name";
- private static final String VALUE_TAG_NAME = "value";
+ private HadoopServerConfigurationDelegate configurationDelegate;
private HadoopOperationsDelegate operationsDelegate;
- private static class PropertiesPerConfigFileBuilder {
- private static class ConfigFileAndConfigName {
- File configFile;
- String propertyName;
-
- ConfigFileAndConfigName(File homeDir, String propertyDefinitionName) {
- String[] parts = propertyDefinitionName.split(":");
-
- String configFileName = parts[0];
-
- configFile = new File(homeDir, configFileName);
- propertyName = parts[1];
-
- if (!configFile.exists()) {
- throw new IllegalArgumentException("The expected configuration
file (" + configFile.getAbsolutePath() + ") doesn't exist.");
- }
- }
- }
-
- private Map<File, Map<String, PropertySimple>> propertiesPerFile =
new HashMap<File, Map<String,PropertySimple>>();
- private File homeDir;
-
- public PropertiesPerConfigFileBuilder(File homeDir) {
- this.homeDir = homeDir;
- }
-
- void addProperty(String name, Configuration parentConfig) {
- PropertySimple ret = new PropertySimple();
- ret.setName(name);
- parentConfig.put(ret);
- addProperty(ret);
- }
-
- void addProperty(PropertySimple property) {
- ConfigFileAndConfigName fn = new ConfigFileAndConfigName(homeDir,
property.getName());
-
- Map<String, PropertySimple> props =
propertiesPerFile.get(fn.configFile);
- if (props == null) {
- props = new HashMap<String, PropertySimple>();
- propertiesPerFile.put(fn.configFile, props);
- }
-
- props.put(fn.propertyName, property);
- }
-
- Map<File, Map<String, PropertySimple>>
getPropertiesPerFilePerConfigName() {
- return propertiesPerFile;
- }
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void start(ResourceContext context) throws Exception {
+ super.start(context);
+ configurationDelegate = new HadoopServerConfigurationDelegate(context);
+ this.operationsDelegate = new HadoopOperationsDelegate(context);
}
/**
@@ -148,13 +80,6 @@ public class HadoopServiceComponent extends
JMXServerComponent<ResourceComponent
}
- @Override
- public void start(ResourceContext context) throws Exception {
- super.start(context);
- this.operationsDelegate = new HadoopOperationsDelegate(context);
- }
-
-
/**
* Gather measurement data
* @see
org.rhq.core.pluginapi.measurement.MeasurementFacet#getValues(org.rhq.core.domain.measurement.MeasurementReport,
java.util.Set)
@@ -192,22 +117,13 @@ public class HadoopServiceComponent extends
JMXServerComponent<ResourceComponent
}
public Configuration loadResourceConfiguration() throws Exception {
- ConfigurationDefinition definition = getResourceContext().getResourceType()
- .getResourceConfigurationDefinition();
- Configuration config = new Configuration();
-
- File homeDir = getHomeDir();
-
- fillResourceConfiguration(homeDir, config, definition);
-
- return config;
+ return configurationDelegate.loadConfiguration();
}
public void updateResourceConfiguration(ConfigurationUpdateReport report) {
try {
Configuration updatedConfiguration = report.getConfiguration();
- File homeDir = getHomeDir();
- updateConfiguration(homeDir, updatedConfiguration);
+ configurationDelegate.updateConfiguration(updatedConfiguration);
report.setStatus(ConfigurationUpdateStatus.SUCCESS);
} catch (Exception e) {
report.setErrorMessageFromThrowable(e);
@@ -226,200 +142,4 @@ public class HadoopServiceComponent extends
JMXServerComponent<ResourceComponent
HadoopSupportedOperations operation = HadoopSupportedOperations.valueOf(name);
return operationsDelegate.invoke(operation, params);
}
-
- private File getHomeDir() {
- File homeDir = new
File(getResourceContext().getPluginConfiguration().getSimpleValue(HadoopServiceDiscovery.HOME_DIR_PROPERTY));
-
- if (!homeDir.exists()) {
- throw new IllegalArgumentException("The configured home directory of
this Hadoop instance (" + homeDir.getAbsolutePath() + ") no longer
exists.");
- }
-
- if (!homeDir.isDirectory()) {
- throw new IllegalArgumentException("The configured home directory of
this Hadoop instance (" + homeDir.getAbsolutePath() + ") is not a
directory.");
- }
-
- if (!homeDir.canRead()) {
- throw new IllegalArgumentException("The configured home directory of
this Hadoop instance (" + homeDir.getAbsolutePath() + ") is not
readable.");
- }
-
- return homeDir;
- }
-
- public static void fillResourceConfiguration(File homeDir, Configuration config,
ConfigurationDefinition definition) throws XMLStreamException, IOException {
- //the config is just a bunch of simples, so this is rather easy.. no cumbersome
traversal of property maps and lists
-
- PropertiesPerConfigFileBuilder bld = new
PropertiesPerConfigFileBuilder(homeDir);
-
- for(PropertyDefinition pd : definition.getPropertyDefinitions().values()) {
- if (!(pd instanceof PropertyDefinitionSimple)) {
- //hmm... well, someone thought it's enough to change the config and
the code would be clever.
- //it's not ;)
- continue;
- }
-
- String propertyName = pd.getName();
- bld.addProperty(propertyName, config);
- }
-
- for(Map.Entry<File, Map<String, PropertySimple>> e :
bld.getPropertiesPerFilePerConfigName().entrySet()) {
- File configFile = e.getKey();
- Map<String, PropertySimple> propertiesToFind = e.getValue();
-
- parseAndAssignProps(configFile, propertiesToFind);
- }
- }
-
- private static void parseAndAssignProps(File configFile, Map<String,
PropertySimple> props)
- throws XMLStreamException, IOException {
- FileInputStream in = new FileInputStream(configFile);
- XMLStreamReader rdr = XML_INPUT_FACTORY.createXMLStreamReader(in);
- try {
- boolean inProperty = false;
- String propertyName = null;
- String propertyValue = null;
-
- while (rdr.hasNext()) {
- int event = rdr.next();
-
- String tag = null;
-
- switch (event) {
- case XMLStreamReader.START_ELEMENT:
- tag = rdr.getName().getLocalPart();
- if (PROPERTY_TAG_NAME.equals(tag)) {
- inProperty = true;
- } else if (inProperty && NAME_TAG_NAME.equals(tag)) {
- propertyName = rdr.getElementText();
- } else if (inProperty && VALUE_TAG_NAME.equals(tag)) {
- propertyValue = rdr.getElementText();
- }
- break;
- case XMLStreamReader.END_ELEMENT:
- tag = rdr.getName().getLocalPart();
- if (PROPERTY_TAG_NAME.equals(tag)) {
- inProperty = false;
-
- PropertySimple prop = props.get(propertyName);
- if (prop != null) {
- prop.setValue(propertyValue);
- }
-
- propertyName = null;
- propertyValue = null;
- }
- break;
- }
- }
- } finally {
- rdr.close();
- in.close();
- }
- }
-
- private static void updateConfiguration(File homeDir, Configuration configuration)
throws IOException, InterruptedException, XMLStreamException {
- //gather the files to update
- PropertiesPerConfigFileBuilder bld = new
PropertiesPerConfigFileBuilder(homeDir);
-
- for(Property p : configuration.getProperties()) {
- if (!(p instanceof PropertySimple)) {
- continue;
- }
-
- PropertySimple property = (PropertySimple) p;
- bld.addProperty(property);
- }
-
- for(Map.Entry<File, Map<String, PropertySimple>> e :
bld.getPropertiesPerFilePerConfigName().entrySet()) {
- updateFile(e.getKey(), e.getValue());
- }
- }
-
- private static void updateFile(File configFile, Map<String, PropertySimple>
allProps) throws IOException, InterruptedException, XMLStreamException {
- InputStream in = null;
- XMLStreamReader rdr = null;
-
- OutputStream out = null;
- XMLStreamWriter wrt = null;
-
- //TODO implement the actual update logic - update the existing configs, leave out
the deleted configs (tricky?),
- //add new configs
- try {
- in = new BufferedInputStream(new FileInputStream(configFile));
- rdr = XML_INPUT_FACTORY.createXMLStreamReader(in);
-
- File tmpFile = File.createTempFile("hadoop-plugin", null);
- out = new FileOutputStream(tmpFile);
- wrt = XML_OUTPUT_FACTORY.createXMLStreamWriter(out);
-
- wrt.writeStartDocument();
-
- while(rdr.hasNext()) {
- int event = rdr.next();
-
- switch (event) {
- case XMLStreamConstants.ATTRIBUTE:
- for(int i = 0; i < rdr.getAttributeCount(); ++i) {
- wrt.writeAttribute(rdr.getAttributePrefix(i),
rdr.getAttributeNamespace(i), rdr.getAttributeLocalName(i), rdr.getAttributeValue(i));
- }
- break;
- case XMLStreamConstants.CDATA:
- wrt.writeCData(rdr.getText());
- break;
- case XMLStreamConstants.CHARACTERS:
- wrt.writeCharacters(rdr.getText());
- break;
- case XMLStreamConstants.COMMENT:
- wrt.writeComment(rdr.getText());
- break;
- case XMLStreamConstants.DTD:
- wrt.writeDTD(rdr.getText());
- break;
- case XMLStreamConstants.END_DOCUMENT:
- wrt.writeEndDocument();
- break;
- case XMLStreamConstants.END_ELEMENT:
- wrt.writeEndElement();
- break;
- case XMLStreamConstants.ENTITY_DECLARATION:
- //XXX could not find what to do with this
- break;
- case XMLStreamConstants.ENTITY_REFERENCE:
- wrt.writeEntityRef(rdr.getText());
- break;
- case XMLStreamConstants.NAMESPACE:
- for(int i = 0; i < rdr.getNamespaceCount(); ++i) {
- wrt.writeNamespace(rdr.getNamespacePrefix(i),
rdr.getNamespaceURI(i));
- }
- break;
- case XMLStreamConstants.NOTATION_DECLARATION:
- //XXX could not find what to do with this
- break;
- case XMLStreamConstants.PROCESSING_INSTRUCTION:
- wrt.writeProcessingInstruction(rdr.getPITarget(), rdr.getPIData());
- break;
- case XMLStreamConstants.SPACE:
- wrt.writeCharacters(rdr.getText());
- break;
- case XMLStreamConstants.START_DOCUMENT:
- //this seems to be never called for some strange reason
- //wrt.writeStartDocument();
- break;
- case XMLStreamConstants.START_ELEMENT:
- wrt.writeStartElement(rdr.getName().getPrefix(),
rdr.getName().getLocalPart(), rdr.getName().getNamespaceURI());
- break;
- }
- }
- } finally {
- wrt.flush();
- rdr.close();
- wrt.close();
-
- try {
- in.close();
- } finally {
- out.flush();
- out.close();
- }
- }
- }
}
commit b287814b17b2f941692943cfade4825146c1d961
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Aug 1 10:27:04 2012 +0200
start of config update
diff --git
a/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
b/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
index 1bf2e1c..66ac741 100644
---
a/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
+++
b/modules/plugins/hadoop/src/main/java/org/rhq/plugins/hadoop/HadoopServiceComponent.java
@@ -19,17 +19,23 @@
package org.rhq.plugins.hadoop;
+import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -38,6 +44,8 @@ import org.mc4j.ems.connection.bean.EmsBean;
import org.mc4j.ems.connection.bean.attribute.EmsAttribute;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinition;
@@ -63,13 +71,64 @@ public class HadoopServiceComponent extends
JMXServerComponent<ResourceComponent
private static final Log LOG = LogFactory.getLog(HadoopServiceComponent.class);
private static final XMLInputFactory XML_INPUT_FACTORY =
XMLInputFactory.newInstance();
-
+ private static final XMLOutputFactory XML_OUTPUT_FACTORY =
XMLOutputFactory.newInstance();
+
private static final String PROPERTY_TAG_NAME = "property";
private static final String NAME_TAG_NAME = "name";
private static final String VALUE_TAG_NAME = "value";
private HadoopOperationsDelegate operationsDelegate;
+ private static class PropertiesPerConfigFileBuilder {
+ private static class ConfigFileAndConfigName {
+ File configFile;
+ String propertyName;
+
+ ConfigFileAndConfigName(File homeDir, String propertyDefinitionName) {
+ String[] parts = propertyDefinitionName.split(":");
+
+ String configFileName = parts[0];
+
+ configFile = new File(homeDir, configFileName);
+ propertyName = parts[1];
+
+ if (!configFile.exists()) {
+ throw new IllegalArgumentException("The expected configuration
file (" + configFile.getAbsolutePath() + ") doesn't exist.");
+ }
+ }
+ }
+
+ private Map<File, Map<String, PropertySimple>> propertiesPerFile =
new HashMap<File, Map<String,PropertySimple>>();
+ private File homeDir;
+
+ public PropertiesPerConfigFileBuilder(File homeDir) {
+ this.homeDir = homeDir;
+ }
+
+ void addProperty(String name, Configuration parentConfig) {
+ PropertySimple ret = new PropertySimple();
+ ret.setName(name);
+ parentConfig.put(ret);
+ addProperty(ret);
+ }
+
+ void addProperty(PropertySimple property) {
+ ConfigFileAndConfigName fn = new ConfigFileAndConfigName(homeDir,
property.getName());
+
+ Map<String, PropertySimple> props =
propertiesPerFile.get(fn.configFile);
+ if (props == null) {
+ props = new HashMap<String, PropertySimple>();
+ propertiesPerFile.put(fn.configFile, props);
+ }
+
+ props.put(fn.propertyName, property);
+ }
+
+ Map<File, Map<String, PropertySimple>>
getPropertiesPerFilePerConfigName() {
+ return propertiesPerFile;
+ }
+ }
+
/**
* Return availability of this resource
* @see org.rhq.core.pluginapi.inventory.ResourceComponent#getAvailability()
@@ -136,33 +195,24 @@ public class HadoopServiceComponent extends
JMXServerComponent<ResourceComponent
ConfigurationDefinition definition = getResourceContext().getResourceType()
.getResourceConfigurationDefinition();
Configuration config = new Configuration();
-
- File homeDir = new
File(getResourceContext().getPluginConfiguration().getSimpleValue(
- HadoopServiceDiscovery.HOME_DIR_PROPERTY));
-
- if (!homeDir.exists()) {
- throw new IllegalArgumentException("The configured home directory of
this Hadoop instance ("
- + homeDir.getAbsolutePath() + ") no longer exists.");
- }
-
- if (!homeDir.isDirectory()) {
- throw new IllegalArgumentException("The configured home directory of
this Hadoop instance ("
- + homeDir.getAbsolutePath() + ") is not a directory.");
- }
-
- if (!homeDir.canRead()) {
- throw new IllegalArgumentException("The configured home directory of
this Hadoop instance ("
- + homeDir.getAbsolutePath() + ") is not readable.");
- }
-
+
+ File homeDir = getHomeDir();
+
fillResourceConfiguration(homeDir, config, definition);
return config;
}
- public void updateResourceConfiguration(ConfigurationUpdateReport report) {
- // TODO Auto-generated method stub
-
+ public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ try {
+ Configuration updatedConfiguration = report.getConfiguration();
+ File homeDir = getHomeDir();
+ updateConfiguration(homeDir, updatedConfiguration);
+ report.setStatus(ConfigurationUpdateStatus.SUCCESS);
+ } catch (Exception e) {
+ report.setErrorMessageFromThrowable(e);
+ report.setStatus(ConfigurationUpdateStatus.FAILURE);
+ }
}
/**
@@ -176,43 +226,45 @@ public class HadoopServiceComponent extends
JMXServerComponent<ResourceComponent
HadoopSupportedOperations operation = HadoopSupportedOperations.valueOf(name);
return operationsDelegate.invoke(operation, params);
}
+
+ private File getHomeDir() {
+ File homeDir = new
File(getResourceContext().getPluginConfiguration().getSimpleValue(HadoopServiceDiscovery.HOME_DIR_PROPERTY));
+
+ if (!homeDir.exists()) {
+ throw new IllegalArgumentException("The configured home directory of
this Hadoop instance (" + homeDir.getAbsolutePath() + ") no longer
exists.");
+ }
+
+ if (!homeDir.isDirectory()) {
+ throw new IllegalArgumentException("The configured home directory of
this Hadoop instance (" + homeDir.getAbsolutePath() + ") is not a
directory.");
+ }
+
+ if (!homeDir.canRead()) {
+ throw new IllegalArgumentException("The configured home directory of
this Hadoop instance (" + homeDir.getAbsolutePath() + ") is not
readable.");
+ }
- public static void fillResourceConfiguration(File homeDir, Configuration config,
ConfigurationDefinition definition)
- throws XMLStreamException, IOException {
+ return homeDir;
+ }
+
+ public static void fillResourceConfiguration(File homeDir, Configuration config,
ConfigurationDefinition definition) throws XMLStreamException, IOException {
//the config is just a bunch of simples, so this is rather easy.. no cumbersome
traversal of property maps and lists
-
- Map<String, PropertySimple> propertiesToFind = new HashMap<String,
PropertySimple>();
- Set<File> configFilesToParse = new HashSet<File>();
-
- for (PropertyDefinition pd : definition.getPropertyDefinitions().values()) {
+
+ PropertiesPerConfigFileBuilder bld = new
PropertiesPerConfigFileBuilder(homeDir);
+
+ for(PropertyDefinition pd : definition.getPropertyDefinitions().values()) {
if (!(pd instanceof PropertyDefinitionSimple)) {
//hmm... well, someone thought it's enough to change the config and
the code would be clever.
//it's not ;)
continue;
}
-
+
String propertyName = pd.getName();
- String[] parts = propertyName.split(":");
- String fileName = parts[0];
- String configName = parts[1];
-
- File configFile = new File(homeDir, fileName);
-
- if (!configFile.exists()) {
- throw new IllegalArgumentException("The expected configuration file
(" + configFile.getAbsolutePath()
- + ") doesn't exist.");
- }
-
- configFilesToParse.add(configFile);
-
- PropertySimple prop = new PropertySimple();
- prop.setName(propertyName);
- config.put(prop);
-
- propertiesToFind.put(configName, prop);
+ bld.addProperty(propertyName, config);
}
-
- for (File configFile : configFilesToParse) {
+
+ for(Map.Entry<File, Map<String, PropertySimple>> e :
bld.getPropertiesPerFilePerConfigName().entrySet()) {
+ File configFile = e.getKey();
+ Map<String, PropertySimple> propertiesToFind = e.getValue();
+
parseAndAssignProps(configFile, propertiesToFind);
}
}
@@ -262,6 +314,112 @@ public class HadoopServiceComponent extends
JMXServerComponent<ResourceComponent
rdr.close();
in.close();
}
+ }
+
+ private static void updateConfiguration(File homeDir, Configuration configuration)
throws IOException, InterruptedException, XMLStreamException {
+ //gather the files to update
+ PropertiesPerConfigFileBuilder bld = new
PropertiesPerConfigFileBuilder(homeDir);
+
+ for(Property p : configuration.getProperties()) {
+ if (!(p instanceof PropertySimple)) {
+ continue;
+ }
+
+ PropertySimple property = (PropertySimple) p;
+ bld.addProperty(property);
+ }
+
+ for(Map.Entry<File, Map<String, PropertySimple>> e :
bld.getPropertiesPerFilePerConfigName().entrySet()) {
+ updateFile(e.getKey(), e.getValue());
+ }
+ }
+
+ private static void updateFile(File configFile, Map<String, PropertySimple>
allProps) throws IOException, InterruptedException, XMLStreamException {
+ InputStream in = null;
+ XMLStreamReader rdr = null;
+
+ OutputStream out = null;
+ XMLStreamWriter wrt = null;
+
+ //TODO implement the actual update logic - update the existing configs, leave out
the deleted configs (tricky?),
+ //add new configs
+ try {
+ in = new BufferedInputStream(new FileInputStream(configFile));
+ rdr = XML_INPUT_FACTORY.createXMLStreamReader(in);
+
+ File tmpFile = File.createTempFile("hadoop-plugin", null);
+ out = new FileOutputStream(tmpFile);
+ wrt = XML_OUTPUT_FACTORY.createXMLStreamWriter(out);
+
+ wrt.writeStartDocument();
+
+ while(rdr.hasNext()) {
+ int event = rdr.next();
+
+ switch (event) {
+ case XMLStreamConstants.ATTRIBUTE:
+ for(int i = 0; i < rdr.getAttributeCount(); ++i) {
+ wrt.writeAttribute(rdr.getAttributePrefix(i),
rdr.getAttributeNamespace(i), rdr.getAttributeLocalName(i), rdr.getAttributeValue(i));
+ }
+ break;
+ case XMLStreamConstants.CDATA:
+ wrt.writeCData(rdr.getText());
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ wrt.writeCharacters(rdr.getText());
+ break;
+ case XMLStreamConstants.COMMENT:
+ wrt.writeComment(rdr.getText());
+ break;
+ case XMLStreamConstants.DTD:
+ wrt.writeDTD(rdr.getText());
+ break;
+ case XMLStreamConstants.END_DOCUMENT:
+ wrt.writeEndDocument();
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ wrt.writeEndElement();
+ break;
+ case XMLStreamConstants.ENTITY_DECLARATION:
+ //XXX could not find what to do with this
+ break;
+ case XMLStreamConstants.ENTITY_REFERENCE:
+ wrt.writeEntityRef(rdr.getText());
+ break;
+ case XMLStreamConstants.NAMESPACE:
+ for(int i = 0; i < rdr.getNamespaceCount(); ++i) {
+ wrt.writeNamespace(rdr.getNamespacePrefix(i),
rdr.getNamespaceURI(i));
+ }
+ break;
+ case XMLStreamConstants.NOTATION_DECLARATION:
+ //XXX could not find what to do with this
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ wrt.writeProcessingInstruction(rdr.getPITarget(), rdr.getPIData());
+ break;
+ case XMLStreamConstants.SPACE:
+ wrt.writeCharacters(rdr.getText());
+ break;
+ case XMLStreamConstants.START_DOCUMENT:
+ //this seems to be never called for some strange reason
+ //wrt.writeStartDocument();
+ break;
+ case XMLStreamConstants.START_ELEMENT:
+ wrt.writeStartElement(rdr.getName().getPrefix(),
rdr.getName().getLocalPart(), rdr.getName().getNamespaceURI());
+ break;
+ }
+ }
+ } finally {
+ wrt.flush();
+ rdr.close();
+ wrt.close();
+
+ try {
+ in.close();
+ } finally {
+ out.flush();
+ out.close();
+ }
+ }
}
-
}