Bug 6535: Fix feature config pusher warning 69/44669/6
authorTom Pantelis <tpanteli@brocade.com>
Thu, 25 Aug 2016 13:52:35 +0000 (09:52 -0400)
committerTom Pantelis <tpanteli@brocade.com>
Tue, 30 Aug 2016 18:51:57 +0000 (18:51 +0000)
The feature config pusher assumes config files installed by features
that have XML extension are CSS files and tries to parse them. On failure
it prints a warning but ignores it and moves on. Up till now we've only
had CSS XML files but we now have XML files related to the
clustered-app-config. To avoid the warning I added a check to see if the
root element is "snapshot" if JAXB parsing fails.

Change-Id: I877921afc13564f131f61a1eb8327db71d3638fe
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
opendaylight/config/config-persister-feature-adapter/src/main/java/org/opendaylight/controller/configpusherfeature/internal/AbstractFeatureWrapper.java

index 9e3806b..f437659 100644 (file)
@@ -10,9 +10,12 @@ package org.opendaylight.controller.configpusherfeature.internal;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.io.Files;
+import java.io.File;
+import java.io.FileInputStream;
 import java.util.LinkedHashSet;
 import java.util.List;
 import javax.xml.bind.JAXBException;
+import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.stream.XMLStreamException;
 import org.apache.karaf.features.BundleInfo;
 import org.apache.karaf.features.Conditional;
@@ -20,8 +23,10 @@ import org.apache.karaf.features.ConfigFileInfo;
 import org.apache.karaf.features.ConfigInfo;
 import org.apache.karaf.features.Dependency;
 import org.apache.karaf.features.Feature;
+import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
 
 /*
  * Wrap a Feature for the purposes of extracting the FeatureConfigSnapshotHolders from
@@ -55,8 +60,8 @@ public class AbstractFeatureWrapper implements Feature {
     public LinkedHashSet<FeatureConfigSnapshotHolder> getFeatureConfigSnapshotHolders() throws Exception {
         final LinkedHashSet <FeatureConfigSnapshotHolder> snapShotHolders = new LinkedHashSet<>();
         for(final ConfigFileInfo c: getConfigurationFiles()) {
-            // Skip non xml files
-            if(isConfigXMLFile(c.getFinalname())) {
+            // Skip non config snapshot XML files
+            if(isConfigSnapshot(c.getFinalname())) {
                 final Optional<FeatureConfigSnapshotHolder> featureConfigSnapshotHolder = getFeatureConfigSnapshotHolder(c);
                 if(featureConfigSnapshotHolder.isPresent()) {
                     snapShotHolders.add(featureConfigSnapshotHolder.get());
@@ -66,17 +71,13 @@ public class AbstractFeatureWrapper implements Feature {
         return snapShotHolders;
     }
 
-    private static boolean isConfigXMLFile(String fullName) {
-        return Files.getFileExtension(fullName).equals(CONFIG_FILE_SUFFIX);
-    }
-
     protected Optional<FeatureConfigSnapshotHolder> getFeatureConfigSnapshotHolder(final ConfigFileInfo c) {
         try {
             return Optional.of(new FeatureConfigSnapshotHolder(c, this));
         } catch (final JAXBException e) {
             LOG.warn("Unable to parse configuration snapshot. Config from '{}' will be IGNORED. " +
-                            "Note that subsequent config files may fail due to this problem. " +
-                            "Xml markup in this file needs to be fixed, for detailed information see enclosed exception.",
+                    "Note that subsequent config files may fail due to this problem. " +
+                    "Xml markup in this file needs to be fixed, for detailed information see enclosed exception.",
                     c.getFinalname(), e);
         } catch (final XMLStreamException e) {
             // Files that cannot be loaded are ignored as non config subsystem files e.g. jetty.xml
@@ -86,6 +87,34 @@ public class AbstractFeatureWrapper implements Feature {
         return Optional.absent();
     }
 
+    private static boolean isConfigSnapshot(String fileName) {
+        if(!Files.getFileExtension(fileName).equals(CONFIG_FILE_SUFFIX)) {
+            return false;
+        }
+
+        if(fileName.endsWith("jetty.xml")) {
+            // Special case - ignore the jetty.xml file as it contains a DTD and causes a "Connection refused"
+            // error when it tries to go out to the network to retrieve it. We don't want it trying to go out
+            // to the network nor do we want an error logged trying to parse it.
+            return false;
+        }
+
+        File file = new File(System.getProperty("karaf.home"), fileName);
+        try(FileInputStream fis = new FileInputStream(file)) {
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+            builderFactory.setNamespaceAware(true);
+            builderFactory.setCoalescing(true);
+            builderFactory.setIgnoringElementContentWhitespace(true);
+            builderFactory.setIgnoringComments(true);
+
+            Element root = builderFactory.newDocumentBuilder().parse(fis).getDocumentElement();
+            return ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME.equals(root.getLocalName());
+        } catch (Exception e) {
+            LOG.error("Could not parse XML file {}", file, e);
+            return false;
+        }
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;