X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fconfig%2Fconfig-persister-feature-adapter%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfigpusherfeature%2Finternal%2FAbstractFeatureWrapper.java;h=3c8622a16880bfb425852f4b4f12538953830625;hp=3e004b4d7cf03a99a7bcfb4e2906f0c437fadf73;hb=35cfadae941fb2a8722b40b829569d8754fa309e;hpb=b3c034675957f963c5878ce1e5e183ec2de8b5e2 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 3e004b4d7c..3c8622a168 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 @@ -7,21 +7,37 @@ */ 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.io.IOException; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; +import java.util.Set; import javax.xml.bind.JAXBException; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLStreamException; import org.apache.karaf.features.BundleInfo; +import org.apache.karaf.features.Capability; import org.apache.karaf.features.Conditional; 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.apache.karaf.features.Library; +import org.apache.karaf.features.Requirement; +import org.apache.karaf.features.Scoping; +import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.google.common.base.Preconditions; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; /* * Wrap a Feature for the purposes of extracting the FeatureConfigSnapshotHolders from @@ -30,7 +46,10 @@ import com.google.common.base.Preconditions; * Delegates the the contained feature and provides additional methods. */ public class AbstractFeatureWrapper implements Feature { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFeatureWrapper.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractFeatureWrapper.class); + + protected static final String CONFIG_FILE_SUFFIX = "xml"; + protected Feature feature = null; protected AbstractFeatureWrapper() { @@ -40,37 +59,85 @@ public class AbstractFeatureWrapper implements Feature { /* * @param f Feature to wrap */ - public AbstractFeatureWrapper(Feature f) { - Preconditions.checkNotNull(f,"FeatureWrapper requires non-null Feature in constructor"); - this.feature = f; + public AbstractFeatureWrapper(final Feature feature) { + Preconditions.checkNotNull(feature, "FeatureWrapper requires non-null Feature in constructor"); + this.feature = feature; } /* * Get FeatureConfigSnapshotHolders appropriate to feed to the config subsystem * from the underlying Feature Config files */ - public LinkedHashSet getFeatureConfigSnapshotHolders() throws Exception { - LinkedHashSet snapShotHolders = new LinkedHashSet(); - for(ConfigFileInfo c: getConfigurationFiles()) { - try { - snapShotHolders.add(new FeatureConfigSnapshotHolder(c,this)); - } catch (JAXBException e) { - LOGGER.debug("{} is not a config subsystem config file",c.getFinalname()); + public Set getFeatureConfigSnapshotHolders() throws Exception { + final Set snapShotHolders = new LinkedHashSet<>(); + for (final ConfigFileInfo c : getConfigurationFiles()) { + // Skip non config snapshot XML files + if (isConfigSnapshot(c.getFinalname())) { + final Optional featureConfigSnapshotHolder = + getFeatureConfigSnapshotHolder(c); + if (featureConfigSnapshotHolder.isPresent()) { + snapShotHolders.add(featureConfigSnapshotHolder.get()); + } } } return snapShotHolders; } + protected Optional + getFeatureConfigSnapshotHolder(final ConfigFileInfo configFileInfo) { + try { + return Optional.of(new FeatureConfigSnapshotHolder(configFileInfo, 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.", + configFileInfo.getFinalname(), e); + } catch (final XMLStreamException e) { + // Files that cannot be loaded are ignored as non config subsystem files e.g. jetty.xml + LOG.debug("Unable to read configuration file '{}'. Not a configuration snapshot", + configFileInfo.getFinalname(), e); + } + return Optional.absent(); + } + + private static boolean isConfigSnapshot(final 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 (final ParserConfigurationException | IOException | SAXException e) { + LOG.error("Could not parse XML file {}", file, e); + return false; + } + } + @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((feature == null) ? 0 : feature.hashCode()); + result = prime * result + (feature == null ? 0 : feature.hashCode()); return result; } @Override - public boolean equals(Object obj) { + public boolean equals(final Object obj) { if (this == obj) { return true; } @@ -80,7 +147,7 @@ public class AbstractFeatureWrapper implements Feature { if (getClass() != obj.getClass()) { return false; } - AbstractFeatureWrapper other = (AbstractFeatureWrapper) obj; + final AbstractFeatureWrapper other = (AbstractFeatureWrapper) obj; if (feature == null) { if (other.feature != null) { return false; @@ -96,124 +163,114 @@ public class AbstractFeatureWrapper implements Feature { return feature.getName(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getId() - */ + @Override public String getId() { return feature.getId(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getName() - */ + @Override public String getName() { return feature.getName(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getDescription() - */ + @Override public String getDescription() { return feature.getDescription(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getDetails() - */ + @Override public String getDetails() { return feature.getDetails(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getVersion() - */ + @Override public String getVersion() { return feature.getVersion(); } - /** - * @return - * @see org.apache.karaf.features.Feature#hasVersion() - */ + @Override public boolean hasVersion() { return feature.hasVersion(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getResolver() - */ + @Override public String getResolver() { return feature.getResolver(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getInstall() - */ + @Override public String getInstall() { return feature.getInstall(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getDependencies() - */ + @Override public List getDependencies() { return feature.getDependencies(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getBundles() - */ + @Override public List getBundles() { return feature.getBundles(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getConfigurations() - */ - public Map> getConfigurations() { + @Override + public List getConfigurations() { return feature.getConfigurations(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getConfigurationFiles() - */ + @Override public List getConfigurationFiles() { return feature.getConfigurationFiles(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getConditional() - */ + @Override public List getConditional() { return feature.getConditional(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getStartLevel() - */ + @Override public int getStartLevel() { return feature.getStartLevel(); } - /** - * @return - * @see org.apache.karaf.features.Feature#getRegion() - */ - public String getRegion() { - return feature.getRegion(); + @Override + public List getCapabilities() { + return feature.getCapabilities(); + } + + @Override + public List getLibraries() { + return feature.getLibraries(); + } + + @Override + public String getNamespace() { + return feature.getNamespace(); + } + + @Override + public String getRepositoryUrl() { + return feature.getRepositoryUrl(); + } + + @Override + public List getRequirements() { + return feature.getRequirements(); + } + + @Override + public List getResourceRepositories() { + return feature.getResourceRepositories(); + } + + @Override + public Scoping getScoping() { + return feature.getScoping(); + } + + @Override + public boolean isHidden() { + return feature.isHidden(); } -} \ No newline at end of file +}