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@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@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(); + } + } } - }