2 * @author Tomas Olvecky
6 * Copyright (c) 2013 by Cisco Systems, Inc.
9 package org.opendaylight.controller.netconf.persist.impl;
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;
20 import java.util.Collections;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.Map.Entry;
25 import java.util.SortedSet;
26 import java.util.TreeSet;
27 import java.util.regex.Pattern;
29 import static com.google.common.base.Preconditions.checkState;
31 public class CapabilityStrippingConfigSnapshotHolder implements ConfigSnapshotHolder {
32 private static final Logger logger = LoggerFactory.getLogger(CapabilityStrippingConfigSnapshotHolder.class);
34 private final String configSnapshot;
35 private final StripCapabilitiesResult stripCapabilitiesResult;
37 public CapabilityStrippingConfigSnapshotHolder(Element snapshot, Set<String> capabilities, Pattern ignoredMissingCapabilityRegex) {
38 final XmlElement configElement = XmlElement.fromDomElement(snapshot);
39 configSnapshot = XmlUtil.toString(configElement.getDomElement());
40 stripCapabilitiesResult = stripCapabilities(configElement, capabilities, ignoredMissingCapabilityRegex);
43 private static class StripCapabilitiesResult {
44 private final SortedSet<String> requiredCapabilities, missingNamespaces;
46 private StripCapabilitiesResult(SortedSet<String> requiredCapabilities, SortedSet<String> missingNamespaces) {
47 this.requiredCapabilities = Collections.unmodifiableSortedSet(requiredCapabilities);
48 this.missingNamespaces = Collections.unmodifiableSortedSet(missingNamespaces);
54 static StripCapabilitiesResult stripCapabilities(XmlElement configElement, Set<String> allCapabilitiesFromHello,
55 Pattern ignoredMissingCapabilityRegex) {
56 // collect all namespaces
57 Set<String> foundNamespacesInXML = getNamespaces(configElement);
58 logger.trace("All capabilities {}\nFound namespaces in XML {}", allCapabilitiesFromHello, foundNamespacesInXML);
59 // required are referenced both in xml and hello
60 SortedSet<String> requiredCapabilities = new TreeSet<>();
62 Set<String> obsoleteCapabilities = new HashSet<>();
63 // are in xml but not in hello
64 SortedSet<String> missingNamespaces = new TreeSet<>(foundNamespacesInXML);
65 for (String capability : allCapabilitiesFromHello) {
66 String namespace = capability.replaceAll("\\?.*","");
67 if (foundNamespacesInXML.contains(namespace)) {
68 requiredCapabilities.add(capability);
69 checkState(missingNamespaces.remove(namespace));
71 obsoleteCapabilities.add(capability);
75 logger.trace("Required capabilities {}, \nObsolete capabilities {}",
76 requiredCapabilities, obsoleteCapabilities);
78 for(Iterator<String> iterator = missingNamespaces.iterator();iterator.hasNext(); ){
79 String capability = iterator.next();
80 if (ignoredMissingCapabilityRegex.matcher(capability).matches()){
81 logger.trace("Ignoring missing capability {}", capability);
85 if (missingNamespaces.size() > 0) {
86 logger.warn("Some capabilities are missing: {}", missingNamespaces);
88 return new StripCapabilitiesResult(requiredCapabilities, missingNamespaces);
91 static Set<String> getNamespaces(XmlElement element){
92 Set<String> result = new HashSet<>();
93 for (Entry<String,Attr> attribute : element.getAttributes().entrySet()) {
94 if (attribute.getKey().startsWith("xmlns")){
95 result.add(attribute.getValue().getValue());
98 //element.getAttributes()
99 for(XmlElement child: element.getChildElements()) {
100 result.addAll(getNamespaces(child));
106 public SortedSet<String> getCapabilities() {
107 return stripCapabilitiesResult.requiredCapabilities;
111 Set<String> getMissingNamespaces(){
112 return stripCapabilitiesResult.missingNamespaces;
116 public String getConfigSnapshot() {
117 return configSnapshot;