ab353e349b2908b67ade7f583f3601b7aa16ce3b
[controller.git] / opendaylight / netconf / config-persister-impl / src / main / java / org / opendaylight / controller / netconf / persist / impl / CapabilityStrippingConfigSnapshotHolder.java
1 /*
2  * Copyright (c) 2013 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
9 package org.opendaylight.controller.netconf.persist.impl;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
13 import org.opendaylight.controller.netconf.util.xml.XmlElement;
14 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.w3c.dom.Attr;
18 import org.w3c.dom.Element;
19
20 import java.util.Collections;
21 import java.util.HashSet;
22 import java.util.Map.Entry;
23 import java.util.Set;
24 import java.util.SortedSet;
25 import java.util.TreeSet;
26
27 /**
28  * Inspects snapshot xml to be stored, remove all capabilities that are not referenced by it.
29  * Useful when persisting current configuration.
30  */
31 public class CapabilityStrippingConfigSnapshotHolder implements ConfigSnapshotHolder {
32     private static final Logger logger = LoggerFactory.getLogger(CapabilityStrippingConfigSnapshotHolder.class);
33
34     private final String configSnapshot;
35     private final StripCapabilitiesResult stripCapabilitiesResult;
36
37     public CapabilityStrippingConfigSnapshotHolder(Element snapshot, Set<String> capabilities) {
38         final XmlElement configElement = XmlElement.fromDomElement(snapshot);
39         configSnapshot = XmlUtil.toString(configElement.getDomElement());
40         stripCapabilitiesResult = stripCapabilities(configElement, capabilities);
41     }
42
43     private static class StripCapabilitiesResult {
44         private final SortedSet<String> requiredCapabilities, obsoleteCapabilities;
45
46         private StripCapabilitiesResult(SortedSet<String> requiredCapabilities, SortedSet<String> obsoleteCapabilities) {
47             this.requiredCapabilities = Collections.unmodifiableSortedSet(requiredCapabilities);
48             this.obsoleteCapabilities = Collections.unmodifiableSortedSet(obsoleteCapabilities);
49         }
50     }
51
52
53     @VisibleForTesting
54     static StripCapabilitiesResult stripCapabilities(XmlElement configElement, Set<String> allCapabilitiesFromHello) {
55         // collect all namespaces
56         Set<String> foundNamespacesInXML = getNamespaces(configElement);
57         logger.trace("All capabilities {}\nFound namespaces in XML {}", allCapabilitiesFromHello, foundNamespacesInXML);
58         // required are referenced both in xml and hello
59         SortedSet<String> requiredCapabilities = new TreeSet<>();
60         // can be removed
61         SortedSet<String> obsoleteCapabilities = new TreeSet<>();
62         for (String capability : allCapabilitiesFromHello) {
63             String namespace = capability.replaceAll("\\?.*","");
64             if (foundNamespacesInXML.contains(namespace)) {
65                 requiredCapabilities.add(capability);
66             } else {
67                 obsoleteCapabilities.add(capability);
68             }
69         }
70
71         logger.trace("Required capabilities {}, \nObsolete capabilities {}",
72                 requiredCapabilities, obsoleteCapabilities);
73
74         return new StripCapabilitiesResult(requiredCapabilities, obsoleteCapabilities);
75     }
76
77     static Set<String> getNamespaces(XmlElement element){
78         Set<String> result = new HashSet<>();
79         for (Entry<String,Attr> attribute : element.getAttributes().entrySet()) {
80             if  (attribute.getKey().startsWith("xmlns")){
81                 result.add(attribute.getValue().getValue());
82             }
83         }
84         for(XmlElement child: element.getChildElements()) {
85             result.addAll(getNamespaces(child));
86         }
87         return result;
88     }
89
90     @Override
91     public SortedSet<String> getCapabilities() {
92         return stripCapabilitiesResult.requiredCapabilities;
93     }
94
95     @VisibleForTesting
96     Set<String> getObsoleteCapabilities(){
97         return stripCapabilitiesResult.obsoleteCapabilities;
98     }
99
100     @Override
101     public String getConfigSnapshot() {
102         return configSnapshot;
103     }
104 }