Also repair logback bug preventing it from taking snapshot configuration.
Change-Id: I48c0383441bfaee3c192159f5158f833e7e1d938
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
import java.io.Closeable;
import java.io.IOException;
-import java.util.Set;
+import java.util.SortedSet;
/**
* Base interface for persister implementation.
public static interface ConfigSnapshotHolder {
+ /**
+ * Get part of get-config document that contains just
+ */
String getConfigSnapshot();
- Set<String> getCapabilities();
+
+ /**
+ * Get only required capabilities referenced by the snapshot.
+ */
+ SortedSet<String> getCapabilities();
}
}
import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
import com.google.common.io.Files;
import org.apache.commons.lang3.StringUtils;
import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* StorageAdapter that stores configuration in a plan file.
private boolean inLastConfig, inLastSnapshot;
private final StringBuffer snapshotBuffer = new StringBuffer();
- private final Set<String> caps = Sets.newHashSet();
+ private final SortedSet<String> caps = new TreeSet<>();
@Override
public String getResult() {
return Optional.of(xmlContent);
}
- Set<String> getCapabilities() throws IOException, SAXException, ParserConfigurationException {
+ SortedSet<String> getCapabilities() throws IOException, SAXException, ParserConfigurationException {
return caps;
}
private class PersistedConfigImpl implements ConfigSnapshotHolder {
private final String snapshot;
- private final Set<String> caps;
+ private final SortedSet<String> caps;
- public PersistedConfigImpl(Optional<String> configSnapshot, Set<String> capabilities) {
+ public PersistedConfigImpl(Optional<String> configSnapshot, SortedSet<String> capabilities) {
this.snapshot = configSnapshot.get();
this.caps = capabilities;
}
}
@Override
- public Set<String> getCapabilities() {
+ public SortedSet<String> getCapabilities() {
return caps;
}
}
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
-import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.io.File;
import java.nio.file.Files;
import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
}
@Override
- public Set<String> getCapabilities() {
+ public SortedSet<String> getCapabilities() {
return createCaps();
}
};
assertEquals(createCaps(), lastConf.get().getCapabilities());
}
- private Set<String> createCaps() {
- Set<String> caps = Sets.newHashSet();
+ private SortedSet<String> createCaps() {
+ SortedSet<String> caps = new TreeSet<>();
caps.add("cap1");
caps.add("cap2");
}
@Override
- public Set<String> getCapabilities() {
+ public SortedSet<String> getCapabilities() {
return createCaps();
}
};
}
@Override
- public Set<String> getCapabilities() {
+ public SortedSet<String> getCapabilities() {
return createCaps();
}
};
}
@Override
- public Set<String> getCapabilities() {
- return Collections.<String> emptySet();
+ public SortedSet<String> getCapabilities() {
+ return new TreeSet<>();
}
} );
}
private void addNewAppenders(Map<String, Appender<ILoggingEvent>> appendersMap, LoggerTO logger,
ch.qos.logback.classic.Logger logbackLogger, Optional<Set<Appender<ILoggingEvent>>> appendersBefore) {
- for (String appenderName : logger.getAppenders()) {
- if (appendersMap.containsKey(appenderName)) {
- logbackLogger.addAppender(appendersMap.get(appenderName));
- classLogger.trace("Logger {}: Adding new appender: {}", logger.getLoggerName(), appenderName);
- } else {
- throw new IllegalStateException("No appender " + appenderName
- + " found. This error should have been discovered by validation");
+ if (logger.getAppenders() != null) {
+ for (String appenderName : logger.getAppenders()) {
+ if (appendersMap.containsKey(appenderName)) {
+ logbackLogger.addAppender(appendersMap.get(appenderName));
+ classLogger.trace("Logger {}: Adding new appender: {}", logger.getLoggerName(), appenderName);
+ } else {
+ throw new IllegalStateException("No appender " + appenderName
+ + " found. This error should have been discovered by validation");
+ }
}
}
}
"LoggerName needs to be set", loggersJmxAttribute);
JmxAttributeValidationException.checkCondition(!loggerToValidate.getLevel().isEmpty(),
"Level needs to be set", loggersJmxAttribute);
-
- for (String appenderName : loggerToValidate.getAppenders()) {
- JmxAttributeValidationException.checkCondition(appenderNames.contains(appenderName), "Appender "
- + appenderName + " referenced by logger " + loggerToValidate.getLoggerName()
- + " not present in configuration, present appenders: " + appenderNames, loggersJmxAttribute);
+ if (loggerToValidate.getAppenders() != null) {
+ for (String appenderName : loggerToValidate.getAppenders()) {
+ JmxAttributeValidationException.checkCondition(appenderNames.contains(appenderName), "Appender "
+ + appenderName + " referenced by logger " + loggerToValidate.getLoggerName()
+ + " not present in configuration, present appenders: " + appenderNames, loggersJmxAttribute);
+ }
}
}
<version>${bgpcep.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
--- /dev/null
+/**
+ * @author Tomas Olvecky
+ *
+ * 11 2013
+ *
+ * Copyright (c) 2013 by Cisco Systems, Inc.
+ * All rights reserved.
+ */
+package org.opendaylight.controller.netconf.persist.impl;
+
+import com.google.common.annotations.VisibleForTesting;
+import org.opendaylight.controller.config.persist.api.Persister.ConfigSnapshotHolder;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class CapabilityStrippingConfigSnapshotHolder implements ConfigSnapshotHolder {
+ private static final Logger logger = LoggerFactory.getLogger(CapabilityStrippingConfigSnapshotHolder.class);
+
+ private final String configSnapshot;
+ private final StripCapabilitiesResult stripCapabilitiesResult;
+
+ public CapabilityStrippingConfigSnapshotHolder(Element snapshot, Set<String> capabilities, Pattern ignoredMissingCapabilityRegex) {
+ final XmlElement configElement = XmlElement.fromDomElement(snapshot);
+ configSnapshot = XmlUtil.toString(configElement.getDomElement());
+ stripCapabilitiesResult = stripCapabilities(configElement, capabilities, ignoredMissingCapabilityRegex);
+ }
+
+ private static class StripCapabilitiesResult {
+ private final SortedSet<String> requiredCapabilities, missingNamespaces;
+
+ private StripCapabilitiesResult(SortedSet<String> requiredCapabilities, SortedSet<String> missingNamespaces) {
+ this.requiredCapabilities = Collections.unmodifiableSortedSet(requiredCapabilities);
+ this.missingNamespaces = Collections.unmodifiableSortedSet(missingNamespaces);
+ }
+ }
+
+
+ @VisibleForTesting
+ static StripCapabilitiesResult stripCapabilities(XmlElement configElement, Set<String> allCapabilitiesFromHello,
+ Pattern ignoredMissingCapabilityRegex) {
+ // collect all namespaces
+ Set<String> foundNamespacesInXML = getNamespaces(configElement);
+ logger.trace("All capabilities {}\nFound namespaces in XML {}", allCapabilitiesFromHello, foundNamespacesInXML);
+ // required are referenced both in xml and hello
+ SortedSet<String> requiredCapabilities = new TreeSet<>();
+ // can be removed
+ Set<String> obsoleteCapabilities = new HashSet<>();
+ // are in xml but not in hello
+ SortedSet<String> missingNamespaces = new TreeSet<>(foundNamespacesInXML);
+ for (String capability : allCapabilitiesFromHello) {
+ String namespace = capability.replaceAll("\\?.*","");
+ if (foundNamespacesInXML.contains(namespace)) {
+ requiredCapabilities.add(capability);
+ checkState(missingNamespaces.remove(namespace));
+ } else {
+ obsoleteCapabilities.add(capability);
+ }
+ }
+
+ logger.trace("Required capabilities {}, \nObsolete capabilities {}",
+ requiredCapabilities, obsoleteCapabilities);
+
+ for(Iterator<String> iterator = missingNamespaces.iterator();iterator.hasNext(); ){
+ String capability = iterator.next();
+ if (ignoredMissingCapabilityRegex.matcher(capability).matches()){
+ logger.trace("Ignoring missing capability {}", capability);
+ iterator.remove();
+ }
+ }
+ if (missingNamespaces.size() > 0) {
+ logger.warn("Some capabilities are missing: {}", missingNamespaces);
+ }
+ return new StripCapabilitiesResult(requiredCapabilities, missingNamespaces);
+ }
+
+ static Set<String> getNamespaces(XmlElement element){
+ Set<String> result = new HashSet<>();
+ for (Entry<String,Attr> attribute : element.getAttributes().entrySet()) {
+ if (attribute.getKey().startsWith("xmlns")){
+ result.add(attribute.getValue().getValue());
+ }
+ }
+ //element.getAttributes()
+ for(XmlElement child: element.getChildElements()) {
+ result.addAll(getNamespaces(child));
+ }
+ return result;
+ }
+
+ @Override
+ public SortedSet<String> getCapabilities() {
+ return stripCapabilitiesResult.requiredCapabilities;
+ }
+
+ @VisibleForTesting
+ Set<String> getMissingNamespaces(){
+ return stripCapabilitiesResult.missingNamespaces;
+ }
+
+ @Override
+ public String getConfigSnapshot() {
+ return configSnapshot;
+ }
+}
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import java.util.regex.Pattern;
/**
* Responsible for listening for notifications from netconf containing latest
public class ConfigPersisterNotificationHandler implements NotificationListener, Closeable {
private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterNotificationHandler.class);
+ private static final int NETCONF_SEND_ATTEMPT_MS_DELAY = 1000;
+ private static final int NETCONF_SEND_ATTEMPTS = 20;
private final InetSocketAddress address;
private final EventLoopGroup nettyThreadgroup;
private final ObjectName on = DefaultCommitOperationMXBean.objectName;
- public static final long DEFAULT_TIMEOUT = 40000L;
+ public static final long DEFAULT_TIMEOUT = 120000L;// 120 seconds until netconf must be stable
private final long timeout;
+ private final Pattern ignoredMissingCapabilityRegex;
public ConfigPersisterNotificationHandler(Persister persister, InetSocketAddress address,
- MBeanServerConnection mbeanServer) {
- this(persister, address, mbeanServer, DEFAULT_TIMEOUT);
+ MBeanServerConnection mbeanServer, Pattern ignoredMissingCapabilityRegex) {
+ this(persister, address, mbeanServer, DEFAULT_TIMEOUT, ignoredMissingCapabilityRegex);
+
}
public ConfigPersisterNotificationHandler(Persister persister, InetSocketAddress address,
- MBeanServerConnection mbeanServer, long timeout) {
+ MBeanServerConnection mbeanServer, long timeout, Pattern ignoredMissingCapabilityRegex) {
this.persister = persister;
this.address = address;
this.mbeanServer = mbeanServer;
this.timeout = timeout;
this.nettyThreadgroup = new NioEventLoopGroup();
+ this.ignoredMissingCapabilityRegex = ignoredMissingCapabilityRegex;
}
public void init() throws InterruptedException {
private void handleAfterCommitNotification(final CommitJMXNotification notification) {
try {
- final XmlElement configElement = XmlElement.fromDomElement(notification.getConfigSnapshot());
- persister.persistConfig(new Persister.ConfigSnapshotHolder() {
- @Override
- public String getConfigSnapshot() {
- return XmlUtil.toString(configElement.getDomElement());
- }
-
- @Override
- public Set<String> getCapabilities() {
- return notification.getCapabilities();
- }
- });
+ persister.persistConfig(new CapabilityStrippingConfigSnapshotHolder(notification.getConfigSnapshot(),
+ notification.getCapabilities(), ignoredMissingCapabilityRegex));
logger.debug("Configuration persisted successfully");
} catch (IOException e) {
throw new RuntimeException("Unable to persist configuration snapshot", e);
NetconfMessage message = createEditConfigMessage(xmlToBePersisted, "/netconfOp/editConfig.xml");
// sending message to netconf
- NetconfMessage responseMessage = netconfClient.sendMessage(message);
+ NetconfMessage responseMessage = netconfClient.sendMessage(message, NETCONF_SEND_ATTEMPTS, NETCONF_SEND_ATTEMPT_MS_DELAY);
XmlElement element = XmlElement.fromDomDocument(responseMessage.getDocument());
Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
checkIsOk(element, responseMessage);
response.append(XmlUtil.toString(responseMessage.getDocument()));
response.append("}");
- responseMessage = netconfClient.sendMessage(getNetconfMessageFromResource("/netconfOp/commit.xml"));
+ responseMessage = netconfClient.sendMessage(getNetconfMessageFromResource("/netconfOp/commit.xml"), NETCONF_SEND_ATTEMPTS, NETCONF_SEND_ATTEMPT_MS_DELAY);
element = XmlElement.fromDomDocument(responseMessage.getDocument());
Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
import javax.management.MBeanServer;
import java.lang.management.ManagementFactory;
import java.net.InetSocketAddress;
+import java.util.regex.Pattern;
public class ConfigPersisterActivator implements BundleActivator {
private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterActivator.class);
private final static MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
+ private static final String IGNORED_MISSING_CAPABILITY_REGEX_SUFFIX = "ignoredMissingCapabilityRegex";
private ConfigPersisterNotificationHandler configPersisterNotificationHandler;
private static final String NETCONF_CONFIG_PERSISTER_PREFIX = "netconf.config.persister.";
public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass";
+ public static final String DEFAULT_IGNORED_REGEX = "^urn:ietf:params:xml:ns:netconf:base:1.0";
@Override
public void start(final BundleContext context) throws Exception {
}
};
+ String regexProperty = propertiesProvider.getProperty(IGNORED_MISSING_CAPABILITY_REGEX_SUFFIX);
+ String regex;
+ if (regexProperty != null) {
+ regex = regexProperty;
+ } else {
+ regex = DEFAULT_IGNORED_REGEX;
+ }
+ Pattern ignoredMissingCapabilityRegex = Pattern.compile(regex);
PersisterImpl persister = PersisterImpl.createFromProperties(propertiesProvider);
InetSocketAddress address = NetconfConfigUtil.extractTCPNetconfAddress(context,
"Netconf is not configured, persister is not operational");
configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(persister, address,
- platformMBeanServer);
+ platformMBeanServer, ignoredMissingCapabilityRegex);
// offload initialization to another thread in order to stop blocking activator
Runnable initializationRunnable = new Runnable() {
--- /dev/null
+/**
+ * @author Tomas Olvecky
+ *
+ * 11 2013
+ *
+ * Copyright (c) 2013 by Cisco Systems, Inc.
+ * All rights reserved.
+ */
+package org.opendaylight.controller.netconf.persist.impl;
+
+import com.google.common.collect.Sets;
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.w3c.dom.Element;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import static org.junit.Assert.assertEquals;
+
+public class CapabilityStrippingConfigSnapshotHolderTest {
+
+ @Test
+ public void testCapabilityStripping() throws Exception {
+ Set<String> allCapabilities = readLines("/capabilities-all.txt");
+ Set<String> expectedCapabilities = readLines("/capabilities-stripped.txt");
+ String snapshotAsString = readToString("/snapshot.xml");
+ Element element = XmlUtil.readXmlToElement(snapshotAsString);
+ {
+ CapabilityStrippingConfigSnapshotHolder tested = new CapabilityStrippingConfigSnapshotHolder(
+ element, allCapabilities, Pattern.compile(
+ ConfigPersisterActivator.DEFAULT_IGNORED_REGEX
+ ));
+ assertEquals(expectedCapabilities, tested.getCapabilities());
+ assertEquals(Collections.emptySet(), tested.getMissingNamespaces());
+ }
+ {
+ // test regex
+ CapabilityStrippingConfigSnapshotHolder tested = new CapabilityStrippingConfigSnapshotHolder(
+ element, allCapabilities, Pattern.compile(
+ "^bar"
+ ));
+ assertEquals(expectedCapabilities, tested.getCapabilities());
+ assertEquals(Sets.newHashSet(ConfigPersisterActivator.DEFAULT_IGNORED_REGEX.substring(1)),
+ tested.getMissingNamespaces());
+ }
+ }
+
+ private Set<String> readLines(String fileName) throws IOException {
+ return new HashSet<>(IOUtils.readLines(getClass().getResourceAsStream(fileName)));
+ }
+
+ private String readToString(String fileName) throws IOException {
+ return IOUtils.toString(getClass().getResourceAsStream(fileName));
+ }
+
+}
--- /dev/null
+urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&revision=2013-04-09
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
+urn:ietf:params:netconf:capability:candidate:1.0
+urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
+urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
+urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
+urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
+urn:ietf:params:netconf:capability:rollback-on-error:1.0
+urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
+urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16
+urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
+urn:opendaylight:params:xml:ns:yang:iana?module=iana&revision=2013-08-16
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&revision=2013-08-19
--- /dev/null
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
--- /dev/null
+<configuration scan="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="error">
+ <appender-ref ref="STDOUT" />
+ </root>
+ <logger name="org.opendaylight.controller.netconf.persist.impl" level="TRACE"/>
+</configuration>
--- /dev/null
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
+ <name>yang-schema-service</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
+ <name>hash-map-data-store</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+ <name>dom-broker</name>
+ <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+ <name>ref_hash-map-data-store</name>
+ </data-store>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
+ <name>binding-broker-impl</name>
+ <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+ <name>ref_binding-notification-broker</name>
+ </notification-service>
+ <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+ <name>ref_binding-data-broker</name>
+ </data-broker>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+ <name>runtime-mapping-singleton</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+ <name>binding-notification-broker</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
+ <name>binding-data-broker</name>
+ <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+ <name>ref_dom-broker</name>
+ </dom-broker>
+ <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+ <name>ref_runtime-mapping-singleton</name>
+ </mapping-service>
+ </module>
+ </modules>
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <instance>
+ <name>ref_yang-schema-service</name>
+ <provider>/config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+ <instance>
+ <name>ref_binding-notification-broker</name>
+ <provider>/config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+ <instance>
+ <name>ref_hash-map-data-store</name>
+ <provider>/config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+ <instance>
+ <name>ref_binding-broker-impl</name>
+ <provider>/config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+ <instance>
+ <name>ref_runtime-mapping-singleton</name>
+ <provider>/config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+ <instance>
+ <name>ref_dom-broker</name>
+ <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+ <instance>
+ <name>ref_binding-data-broker</name>
+ <provider>/config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']</provider>
+ </instance>
+ </service>
+ </services>
+</data>
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
import javax.management.ObjectName;
import javax.net.ssl.SSLContext;
import javax.xml.parsers.ParserConfigurationException;
import org.opendaylight.controller.netconf.impl.mapping.ExiEncoderHandler;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
+import org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator;
import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
import org.opendaylight.controller.netconf.util.xml.ExiParameters;
Persister persister = mock(Persister.class);
doReturn("mockPersister").when(persister).toString();
doReturn(Optional.absent()).when(persister).loadLastConfig();
- ConfigPersisterNotificationHandler h = new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer());
+ ConfigPersisterNotificationHandler h =
+ new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer(), Pattern.compile(ConfigPersisterActivator.DEFAULT_IGNORED_REGEX));
h.init();
}