Remove yang-test
[controller.git] / opendaylight / config / config-persister-feature-adapter / src / main / java / org / opendaylight / controller / configpusherfeature / internal / AbstractFeatureWrapper.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.configpusherfeature.internal;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.io.Files;
13
14 import java.io.File;
15 import java.io.FileInputStream;
16 import java.io.IOException;
17 import java.util.LinkedHashSet;
18 import java.util.List;
19 import java.util.Set;
20
21 import javax.xml.bind.JAXBException;
22 import javax.xml.parsers.DocumentBuilderFactory;
23 import javax.xml.parsers.ParserConfigurationException;
24 import javax.xml.stream.XMLStreamException;
25
26 import org.apache.karaf.features.BundleInfo;
27 import org.apache.karaf.features.Capability;
28 import org.apache.karaf.features.Conditional;
29 import org.apache.karaf.features.ConfigFileInfo;
30 import org.apache.karaf.features.ConfigInfo;
31 import org.apache.karaf.features.Dependency;
32 import org.apache.karaf.features.Feature;
33 import org.apache.karaf.features.Library;
34 import org.apache.karaf.features.Requirement;
35 import org.apache.karaf.features.Scoping;
36 import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.w3c.dom.Element;
40 import org.xml.sax.SAXException;
41
42 /*
43  * Wrap a Feature for the purposes of extracting the FeatureConfigSnapshotHolders from
44  * its underlying ConfigFileInfo's
45  *
46  * Delegates the the contained feature and provides additional methods.
47  */
48 public class AbstractFeatureWrapper implements Feature {
49     private static final Logger LOG = LoggerFactory.getLogger(AbstractFeatureWrapper.class);
50
51     protected static final String CONFIG_FILE_SUFFIX = "xml";
52
53     protected Feature feature = null;
54
55     protected AbstractFeatureWrapper() {
56         // prevent instantiation without Feature
57     }
58
59     /*
60      * @param f Feature to wrap
61      */
62     public AbstractFeatureWrapper(final Feature feature) {
63         Preconditions.checkNotNull(feature, "FeatureWrapper requires non-null Feature in constructor");
64         this.feature = feature;
65     }
66
67     /*
68      * Get FeatureConfigSnapshotHolders appropriate to feed to the config subsystem
69      * from the underlying Feature Config files
70      */
71     public Set<FeatureConfigSnapshotHolder> getFeatureConfigSnapshotHolders() throws Exception {
72         final Set<FeatureConfigSnapshotHolder> snapShotHolders = new LinkedHashSet<>();
73         for (final ConfigFileInfo c : getConfigurationFiles()) {
74             // Skip non config snapshot XML files
75             if (isConfigSnapshot(c.getFinalname())) {
76                 final Optional<FeatureConfigSnapshotHolder> featureConfigSnapshotHolder =
77                         getFeatureConfigSnapshotHolder(c);
78                 if (featureConfigSnapshotHolder.isPresent()) {
79                     snapShotHolders.add(featureConfigSnapshotHolder.get());
80                 }
81             }
82         }
83         return snapShotHolders;
84     }
85
86     protected Optional<FeatureConfigSnapshotHolder>
87         getFeatureConfigSnapshotHolder(final ConfigFileInfo configFileInfo) {
88         try {
89             return Optional.of(new FeatureConfigSnapshotHolder(configFileInfo, this));
90         } catch (final JAXBException e) {
91             LOG.warn("Unable to parse configuration snapshot. Config from '{}' will be IGNORED. "
92                     + "Note that subsequent config files may fail due to this problem. "
93                     + "Xml markup in this file needs to be fixed, for detailed information see enclosed exception.",
94                     configFileInfo.getFinalname(), e);
95         } catch (final XMLStreamException e) {
96             // Files that cannot be loaded are ignored as non config subsystem files e.g. jetty.xml
97             LOG.debug("Unable to read configuration file '{}'. Not a configuration snapshot",
98                     configFileInfo.getFinalname(), e);
99         }
100         return Optional.absent();
101     }
102
103     private static boolean isConfigSnapshot(final String fileName) {
104         if (!Files.getFileExtension(fileName).equals(CONFIG_FILE_SUFFIX)) {
105             return false;
106         }
107
108         if (fileName.endsWith("jetty.xml")) {
109             // Special case - ignore the jetty.xml file as it contains a DTD and causes a "Connection refused"
110             // error when it tries to go out to the network to retrieve it. We don't want it trying to go out
111             // to the network nor do we want an error logged trying to parse it.
112             return false;
113         }
114
115         File file = new File(System.getProperty("karaf.home"), fileName);
116         try (FileInputStream fis = new FileInputStream(file)) {
117             DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
118             builderFactory.setNamespaceAware(true);
119             builderFactory.setCoalescing(true);
120             builderFactory.setIgnoringElementContentWhitespace(true);
121             builderFactory.setIgnoringComments(true);
122
123             Element root = builderFactory.newDocumentBuilder().parse(fis).getDocumentElement();
124             return ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME.equals(root.getLocalName());
125         } catch (final ParserConfigurationException | IOException | SAXException e) {
126             LOG.error("Could not parse XML file {}", file, e);
127             return false;
128         }
129     }
130
131     @Override
132     public int hashCode() {
133         final int prime = 31;
134         int result = 1;
135         result = prime * result + (feature == null ? 0 : feature.hashCode());
136         return result;
137     }
138
139     @Override
140     public boolean equals(final Object obj) {
141         if (this == obj) {
142             return true;
143         }
144         if (obj == null) {
145             return false;
146         }
147         if (getClass() != obj.getClass()) {
148             return false;
149         }
150         final AbstractFeatureWrapper other = (AbstractFeatureWrapper) obj;
151         if (feature == null) {
152             if (other.feature != null) {
153                 return false;
154             }
155         } else if (!feature.equals(other.feature)) {
156             return false;
157         }
158         return true;
159     }
160
161     @Override
162     public String toString() {
163         return feature.getName();
164     }
165
166     @Override
167     public String getId() {
168         return feature.getId();
169     }
170
171     @Override
172     public String getName() {
173         return feature.getName();
174     }
175
176     @Override
177     public String getDescription() {
178         return feature.getDescription();
179     }
180
181     @Override
182     public String getDetails() {
183         return feature.getDetails();
184     }
185
186     @Override
187     public String getVersion() {
188         return feature.getVersion();
189     }
190
191     @Override
192     public boolean hasVersion() {
193         return feature.hasVersion();
194     }
195
196     @Override
197     public String getResolver() {
198         return feature.getResolver();
199     }
200
201     @Override
202     public String getInstall() {
203         return feature.getInstall();
204     }
205
206     @Override
207     public List<Dependency> getDependencies() {
208         return feature.getDependencies();
209     }
210
211     @Override
212     public List<BundleInfo> getBundles() {
213         return feature.getBundles();
214     }
215
216     @Override
217     public List<ConfigInfo> getConfigurations() {
218         return feature.getConfigurations();
219     }
220
221     @Override
222     public List<ConfigFileInfo> getConfigurationFiles() {
223         return feature.getConfigurationFiles();
224     }
225
226     @Override
227     public List<? extends Conditional> getConditional() {
228         return feature.getConditional();
229     }
230
231     @Override
232     public int getStartLevel() {
233         return feature.getStartLevel();
234     }
235
236     @Override
237     public List<? extends Capability> getCapabilities() {
238         return feature.getCapabilities();
239     }
240
241     @Override
242     public List<? extends Library> getLibraries() {
243         return feature.getLibraries();
244     }
245
246     @Override
247     public String getNamespace() {
248         return feature.getNamespace();
249     }
250
251     @Override
252     public String getRepositoryUrl() {
253         return feature.getRepositoryUrl();
254     }
255
256     @Override
257     public List<? extends Requirement> getRequirements() {
258         return feature.getRequirements();
259     }
260
261     @Override
262     public List<String> getResourceRepositories() {
263         return feature.getResourceRepositories();
264     }
265
266     @Override
267     public Scoping getScoping() {
268         return feature.getScoping();
269     }
270
271     @Override
272     public boolean isHidden() {
273         return feature.isHidden();
274     }
275
276 }