2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.controller.netconf.persist.impl;
10 import com.google.common.annotations.VisibleForTesting;
11 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
12 import org.opendaylight.controller.netconf.util.xml.XmlElement;
13 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16 import org.w3c.dom.Attr;
17 import org.w3c.dom.Element;
19 import java.util.Collections;
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.Map.Entry;
24 import java.util.SortedSet;
25 import java.util.TreeSet;
26 import java.util.regex.Pattern;
28 import static com.google.common.base.Preconditions.checkState;
30 public class CapabilityStrippingConfigSnapshotHolder implements ConfigSnapshotHolder {
31 private static final Logger logger = LoggerFactory.getLogger(CapabilityStrippingConfigSnapshotHolder.class);
33 private final String configSnapshot;
34 private final StripCapabilitiesResult stripCapabilitiesResult;
36 public CapabilityStrippingConfigSnapshotHolder(Element snapshot, Set<String> capabilities, Pattern ignoredMissingCapabilityRegex) {
37 final XmlElement configElement = XmlElement.fromDomElement(snapshot);
38 configSnapshot = XmlUtil.toString(configElement.getDomElement());
39 stripCapabilitiesResult = stripCapabilities(configElement, capabilities, ignoredMissingCapabilityRegex);
42 private static class StripCapabilitiesResult {
43 private final SortedSet<String> requiredCapabilities, missingNamespaces;
45 private StripCapabilitiesResult(SortedSet<String> requiredCapabilities, SortedSet<String> missingNamespaces) {
46 this.requiredCapabilities = Collections.unmodifiableSortedSet(requiredCapabilities);
47 this.missingNamespaces = Collections.unmodifiableSortedSet(missingNamespaces);
53 static StripCapabilitiesResult stripCapabilities(XmlElement configElement, Set<String> allCapabilitiesFromHello,
54 Pattern ignoredMissingCapabilityRegex) {
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<>();
61 Set<String> obsoleteCapabilities = new HashSet<>();
62 // are in xml but not in hello
63 SortedSet<String> missingNamespaces = new TreeSet<>(foundNamespacesInXML);
64 for (String capability : allCapabilitiesFromHello) {
65 String namespace = capability.replaceAll("\\?.*","");
66 if (foundNamespacesInXML.contains(namespace)) {
67 requiredCapabilities.add(capability);
68 checkState(missingNamespaces.remove(namespace));
70 obsoleteCapabilities.add(capability);
74 logger.trace("Required capabilities {}, \nObsolete capabilities {}",
75 requiredCapabilities, obsoleteCapabilities);
77 for(Iterator<String> iterator = missingNamespaces.iterator();iterator.hasNext(); ){
78 String capability = iterator.next();
79 if (ignoredMissingCapabilityRegex.matcher(capability).matches()){
80 logger.trace("Ignoring missing capability {}", capability);
84 if (missingNamespaces.size() > 0) {
85 logger.warn("Some capabilities are missing: {}", missingNamespaces);
87 return new StripCapabilitiesResult(requiredCapabilities, missingNamespaces);
90 static Set<String> getNamespaces(XmlElement element){
91 Set<String> result = new HashSet<>();
92 for (Entry<String,Attr> attribute : element.getAttributes().entrySet()) {
93 if (attribute.getKey().startsWith("xmlns")){
94 result.add(attribute.getValue().getValue());
97 //element.getAttributes()
98 for(XmlElement child: element.getChildElements()) {
99 result.addAll(getNamespaces(child));
105 public SortedSet<String> getCapabilities() {
106 return stripCapabilitiesResult.requiredCapabilities;
110 Set<String> getMissingNamespaces(){
111 return stripCapabilitiesResult.missingNamespaces;
115 public String getConfigSnapshot() {
116 return configSnapshot;