From bde61c4e874d8c7288ba20bcbda326f5904c25b6 Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Thu, 25 Aug 2016 09:52:35 -0400 Subject: [PATCH] Bug 6535: Fix feature config pusher warning 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 --- .../internal/AbstractFeatureWrapper.java | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/opendaylight/config/config-persister-feature-adapter/src/main/java/org/opendaylight/controller/configpusherfeature/internal/AbstractFeatureWrapper.java b/opendaylight/config/config-persister-feature-adapter/src/main/java/org/opendaylight/controller/configpusherfeature/internal/AbstractFeatureWrapper.java index 9e3806b13b..f43765901d 100644 --- a/opendaylight/config/config-persister-feature-adapter/src/main/java/org/opendaylight/controller/configpusherfeature/internal/AbstractFeatureWrapper.java +++ b/opendaylight/config/config-persister-feature-adapter/src/main/java/org/opendaylight/controller/configpusherfeature/internal/AbstractFeatureWrapper.java @@ -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 getFeatureConfigSnapshotHolders() throws Exception { final LinkedHashSet 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 = 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 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; -- 2.36.6