[rhq] Branch 'feature/hadoop-plugin' - 2 commits - modules/plugins

lkrejci lkrejci at fedoraproject.org
Wed Aug 1 13:12:42 UTC 2012


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




More information about the rhq-commits mailing list