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