Merge "Fixed remove rpc api in rpc registry"
[controller.git] / opendaylight / config / config-persister-feature-adapter / src / main / java / org / opendaylight / controller / configpusherfeature / internal / FeatureConfigSnapshotHolder.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 java.io.File;
11 import java.nio.file.Path;
12 import java.nio.file.Paths;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.SortedSet;
16
17 import javax.xml.bind.JAXBContext;
18 import javax.xml.bind.JAXBException;
19 import javax.xml.bind.Unmarshaller;
20
21 import org.apache.karaf.features.ConfigFileInfo;
22 import org.apache.karaf.features.Feature;
23 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
24 import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
25
26 import com.google.common.base.Preconditions;
27 import com.google.common.collect.ImmutableList;
28 import com.google.common.collect.Iterables;
29 import com.google.common.collect.Lists;
30
31 /*
32  * A ConfigSnapshotHolder that can track all the additional information
33  * relavent to the fact we are getting these from a Feature.
34  *
35  * Includes tracking the 'featureChain' - an reverse ordered list of the dependency
36  * graph of features that caused us to push this FeatureConfigSnapshotHolder.
37  * So if A -> B -> C, then the feature chain would be C -> B -> A
38  */
39 public class FeatureConfigSnapshotHolder implements ConfigSnapshotHolder {
40     private ConfigSnapshot unmarshalled = null;
41     private ConfigFileInfo fileInfo = null;
42     private List<Feature> featureChain = new ArrayList<Feature>();
43
44     /*
45      * @param holder - FeatureConfigSnapshotHolder that we
46      * @param feature - new
47      */
48     public FeatureConfigSnapshotHolder(final FeatureConfigSnapshotHolder holder, final Feature feature) throws JAXBException {
49         this(holder.fileInfo,holder.getFeature());
50         this.featureChain.add(feature);
51     }
52
53     /*
54      * Create a FeatureConfigSnapshotHolder for a given ConfigFileInfo and record the associated
55      * feature we are creating it from.
56      * @param fileInfo - ConfigFileInfo to read into the ConfigSnapshot
57      * @param feature - Feature the ConfigFileInfo was attached to
58      */
59     public FeatureConfigSnapshotHolder(final ConfigFileInfo fileInfo, final Feature feature) throws JAXBException {
60         Preconditions.checkNotNull(fileInfo);
61         Preconditions.checkNotNull(fileInfo.getFinalname());
62         Preconditions.checkNotNull(feature);
63         this.fileInfo = fileInfo;
64         this.featureChain.add(feature);
65         JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
66         Unmarshaller um = jaxbContext.createUnmarshaller();
67         File file = new File(fileInfo.getFinalname());
68         unmarshalled = ((ConfigSnapshot) um.unmarshal(file));
69     }
70     /*
71      * (non-Javadoc)
72      * @see java.lang.Object#hashCode()
73      *
74      * We really care most about the underlying ConfigShapshot, so compute hashcode on that
75      */
76     @Override
77     public int hashCode() {
78         final int prime = 31;
79         int result = 1;
80         result = prime * result + ((unmarshalled != null && unmarshalled.getConfigSnapshot() == null) ? 0 : unmarshalled.getConfigSnapshot().hashCode());
81         return result;
82     }
83     /*
84      * (non-Javadoc)
85      * @see java.lang.Object#equals(java.lang.Object)
86      * *
87      * We really care most about the underlying ConfigShapshot, so compute equality on that
88      */
89     @Override
90     public boolean equals(Object obj) {
91         if (this == obj) {
92             return true;
93         }
94         if (obj == null) {
95             return false;
96         }
97         if (getClass() != obj.getClass()) {
98             return false;
99         }
100         FeatureConfigSnapshotHolder fcsh = (FeatureConfigSnapshotHolder)obj;
101         if(this.unmarshalled.getConfigSnapshot().equals(fcsh.unmarshalled.getConfigSnapshot())) {
102             return true;
103         }
104         return false;
105     }
106
107     @Override
108     public String toString() {
109        StringBuilder b = new StringBuilder();
110        Path p = Paths.get(fileInfo.getFinalname());
111        b.append(p.getFileName())
112            .append("(")
113            .append(getCauseFeature())
114            .append(",")
115            .append(getFeature())
116            .append(")");
117        return b.toString();
118
119     }
120
121     @Override
122     public String getConfigSnapshot() {
123         return unmarshalled.getConfigSnapshot();
124     }
125
126     @Override
127     public SortedSet<String> getCapabilities() {
128         return unmarshalled.getCapabilities();
129     }
130
131     public ConfigFileInfo getFileInfo() {
132         return fileInfo;
133     }
134
135     /*
136      * @returns The original feature to which the ConfigFileInfo was attached
137      * Example:
138      * A -> B -> C, ConfigFileInfo Foo is attached to C.
139      * feature:install A
140      * thus C is the 'Feature' Foo was attached.
141      */
142     public Feature getFeature() {
143         return featureChain.get(0);
144     }
145
146     /*
147      * @return The dependency chain of the features that caused the ConfigFileInfo to be pushed in reverse order.
148      * Example:
149      * A -> B -> C, ConfigFileInfo Foo is attached to C.
150      * The returned list is
151      * [C,B,A]
152      */
153     public ImmutableList<Feature> getFeatureChain() {
154         return ImmutableList.copyOf(Lists.reverse(featureChain));
155     }
156
157     /*
158      * @return The feature the installation of which was the root cause
159      * of this pushing of the ConfigFileInfo.
160      * Example:
161      * A -> B -> C, ConfigFileInfo Foo is attached to C.
162      * feature:install A
163      * this A is the 'Cause' of the installation of Foo.
164      */
165     public Feature getCauseFeature() {
166         return Iterables.getLast(featureChain);
167     }
168 }