Bug 2150: Feature wrappers now log parse errors better.
[controller.git] / opendaylight / config / config-persister-feature-adapter / src / main / java / org / opendaylight / controller / configpusherfeature / internal / ChildAwareFeatureWrapper.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 java.util.LinkedHashSet;
13 import java.util.List;
14 import org.apache.felix.utils.version.VersionRange;
15 import org.apache.felix.utils.version.VersionTable;
16 import org.apache.karaf.features.Dependency;
17 import org.apache.karaf.features.Feature;
18 import org.apache.karaf.features.FeaturesService;
19 import org.osgi.framework.Version;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 /*
24  * Wrap a Feature for the purposes of extracting the FeatureConfigSnapshotHolders from
25  * its underlying ConfigFileInfo's and those of its children recursively
26  *
27  * Delegates the the contained feature and provides additional methods.
28  */
29 public class ChildAwareFeatureWrapper extends AbstractFeatureWrapper implements Feature {
30     private static final Logger LOG = LoggerFactory.getLogger(ChildAwareFeatureWrapper.class);
31     private FeaturesService featuresService= null;
32
33     protected ChildAwareFeatureWrapper(Feature f) {
34         // Don't use without a feature service
35     }
36
37     /*
38      * @param f Feature to wrap
39      * @param s FeaturesService to look up dependencies
40      */
41     ChildAwareFeatureWrapper(Feature f, FeaturesService s) throws Exception {
42         super(s.getFeature(f.getName(), f.getVersion()));
43         Preconditions.checkNotNull(s, "FeatureWrapper requires non-null FeatureService in constructor");
44         this.featuresService = s;
45     }
46
47     protected FeaturesService getFeaturesService() {
48         return featuresService;
49     }
50
51     /*
52      * Get FeatureConfigSnapshotHolders appropriate to feed to the config subsystem
53      * from the underlying Feature Config files and those of its children recursively
54      */
55     public LinkedHashSet <? extends ChildAwareFeatureWrapper> getChildFeatures() throws Exception {
56         List<Dependency> dependencies = feature.getDependencies();
57         LinkedHashSet <ChildAwareFeatureWrapper> childFeatures = new LinkedHashSet<ChildAwareFeatureWrapper>();
58         if(dependencies != null) {
59             for(Dependency dependency: dependencies) {
60                 Feature fi = extractFeatureFromDependency(dependency);
61                 if(fi != null){
62                     ChildAwareFeatureWrapper wrappedFeature = new ChildAwareFeatureWrapper(fi,featuresService);
63                     childFeatures.add(wrappedFeature);
64                 }
65             }
66         }
67         return childFeatures;
68     }
69
70     public LinkedHashSet<FeatureConfigSnapshotHolder> getFeatureConfigSnapshotHolders() throws Exception {
71         LinkedHashSet <FeatureConfigSnapshotHolder> snapShotHolders = new LinkedHashSet<FeatureConfigSnapshotHolder>();
72         for(ChildAwareFeatureWrapper c: getChildFeatures()) {
73             for(FeatureConfigSnapshotHolder h: c.getFeatureConfigSnapshotHolders()) {
74                 final Optional<FeatureConfigSnapshotHolder> featureConfigSnapshotHolder = getFeatureConfigSnapshotHolder(h.getFileInfo());
75                 if(featureConfigSnapshotHolder.isPresent()) {
76                     snapShotHolders.add(featureConfigSnapshotHolder.get());
77                 }
78             }
79         }
80         snapShotHolders.addAll(super.getFeatureConfigSnapshotHolders());
81         return snapShotHolders;
82     }
83
84     protected Feature extractFeatureFromDependency(Dependency dependency) throws Exception {
85         Feature[] features = featuresService.listFeatures();
86         VersionRange range = org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION.equals(dependency.getVersion())
87                 ? VersionRange.ANY_VERSION : new VersionRange(dependency.getVersion(), true, true);
88         Feature fi = null;
89         for(Feature f: features) {
90             if (f.getName().equals(dependency.getName())) {
91                 Version v = VersionTable.getVersion(f.getVersion());
92                 if (range.contains(v) &&
93                     (fi == null || VersionTable.getVersion(fi.getVersion()).compareTo(v) < 0)) {
94                     fi = f;
95                     break;
96                 }
97             }
98         }
99         return fi;
100     }
101
102 }