Bug 3863 - Milestone: Add support for netconf notifications in MD-SAL netconf northbound 46/26146/11
authorJMorvay <jmorvay@cisco.com>
Tue, 25 Aug 2015 14:05:32 +0000 (16:05 +0200)
committerJMorvay <jmorvay@cisco.com>
Tue, 29 Sep 2015 07:18:25 +0000 (09:18 +0200)
Add support for netconf-capability-change notification.

Change-Id: Ib05f0d57c744275dbf569e3b26821274671f6787
Signed-off-by: JMorvay <jmorvay@cisco.com>
19 files changed:
features/netconf/src/main/resources/features.xml
opendaylight/netconf/mdsal-netconf-notification/pom.xml [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/BaseCapabilityChangeNotificationPublisher.java [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NetconfMdsalNotificationMapperModule.java [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NetconfMdsalNotificationMapperModuleFactory.java [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NotificationToMdsalWriter.java [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/netconf/mdsal/notification/NetconfNotificationOperationService.java [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/netconf/mdsal/notification/NetconfNotificationOperationServiceFactory.java [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/main/yang/netconf-mdsal-notification.yang [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/test/java/org.opendaylight.controller.config.yang.netconf.mdsal.notification/BaseCapabilityChangeNotificationPublisherTest.java [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-notification/src/test/java/org.opendaylight.controller.config.yang.netconf.mdsal.notification/NotificationToMdsalWriterTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-mdsal-config/src/main/resources/initial/08-netconf-mdsal.xml
opendaylight/netconf/netconf-notifications-api/src/main/yang/netconf-northbound-notification.yang [new file with mode: 0644]
opendaylight/netconf/netconf-notifications-impl/pom.xml
opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/config/yang/netconf/northbound/notification/impl/NetconfNotificationManagerModule.java [new file with mode: 0644]
opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/config/yang/netconf/northbound/notification/impl/NetconfNotificationManagerModuleFactory.java [new file with mode: 0644]
opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/netconf/notifications/impl/ops/CreateSubscription.java
opendaylight/netconf/netconf-notifications-impl/src/main/yang/netconf-northbound-notification-impl.yang [new file with mode: 0644]
opendaylight/netconf/pom.xml

index 68ab14c8ebcce6e652f790ac4cd7f77fb94b0524..bb5945068fa68a4be1c2c2085be2e2b93010b9e6 100644 (file)
     <feature version='${project.version}'>odl-netconf-ssh</feature>
     <feature version='${project.version}'>odl-netconf-client</feature>
     <feature version='${controller.mdsal.version}'>odl-mdsal-broker</feature>
+    <bundle>mvn:org.opendaylight.netconf/mdsal-netconf-notification/${project.version}</bundle>
     <bundle>mvn:org.opendaylight.netconf/mdsal-netconf-connector/${project.version}</bundle>
     <bundle>mvn:org.opendaylight.netconf/mdsal-netconf-monitoring/${project.version}</bundle>
     <configfile finalname='${config.configfile.directory}/${config.netconf.mdsal.configfile}'>mvn:org.opendaylight.netconf/netconf-mdsal-config/${project.version}/xml/config</configfile>
diff --git a/opendaylight/netconf/mdsal-netconf-notification/pom.xml b/opendaylight/netconf/mdsal-netconf-notification/pom.xml
new file mode 100644 (file)
index 0000000..542ab35
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.netconf</groupId>
+        <artifactId>netconf-subsystem</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>mdsal-netconf-notification</artifactId>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+
+    <dependencies>
+        <!-- compile dependencies -->
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>netconf-mapping-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>netconf-notifications-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>netconf-notifications-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-config</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>mockito-configuration</artifactId>
+        </dependency>
+    </dependencies>
+
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Import-Package>*</Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/BaseCapabilityChangeNotificationPublisher.java b/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/BaseCapabilityChangeNotificationPublisher.java
new file mode 100644 (file)
index 0000000..42a4124
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yang.netconf.mdsal.notification;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.util.Collections;
+import java.util.Set;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.netconf.notifications.BaseNotificationPublisherRegistration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.ChangedByBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.changed.by.server.or.user.ServerBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+
+/**
+ * Listens on capabilities changes in data store and publishes them to base
+ * netconf notification stream listener.
+ */
+final class BaseCapabilityChangeNotificationPublisher implements DataChangeListener, AutoCloseable {
+
+    private final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration;
+
+    public BaseCapabilityChangeNotificationPublisher(BaseNotificationPublisherRegistration baseNotificationPublisherRegistration) {
+        this.baseNotificationPublisherRegistration = baseNotificationPublisherRegistration;
+    }
+
+    @Override
+    public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        baseNotificationPublisherRegistration.onCapabilityChanged(computeCapabilitycChange(change));
+    }
+
+    private NetconfCapabilityChange computeCapabilitycChange(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        final NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder();
+        netconfCapabilityChangeBuilder.setChangedBy(new ChangedByBuilder().setServerOrUser(new ServerBuilder().setServer(true).build()).build());
+
+        if (!change.getCreatedData().isEmpty()) {
+            final InstanceIdentifier capabilitiesIdentifier = InstanceIdentifier.create(NetconfState.class).child(Capabilities.class).builder().build();
+            Preconditions.checkArgument(change.getCreatedData().get(capabilitiesIdentifier) instanceof Capabilities);
+            netconfCapabilityChangeBuilder.setAddedCapability(((Capabilities) change.getCreatedData().get(capabilitiesIdentifier)).getCapability());
+            netconfCapabilityChangeBuilder.setDeletedCapability(Collections.<Uri>emptyList());
+        } else {
+            Preconditions.checkArgument(change.getUpdatedSubtree() instanceof Capabilities);
+            final Set<Uri> currentState = Sets.newHashSet(((Capabilities) change.getUpdatedSubtree()).getCapability());
+            final Set<Uri> previousState = Sets.newHashSet(((Capabilities) change.getOriginalSubtree()).getCapability());
+
+            netconfCapabilityChangeBuilder.setAddedCapability(Lists.newArrayList(Sets.difference(currentState, previousState)));
+            netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(Sets.difference(previousState, currentState)));
+        }
+
+        // TODO modified should be computed ... but why ?
+        netconfCapabilityChangeBuilder.setModifiedCapability(Collections.<Uri>emptyList());
+        return netconfCapabilityChangeBuilder.build();
+    }
+
+    @Override
+    public void close() throws Exception {
+
+    }
+}
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NetconfMdsalNotificationMapperModule.java b/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NetconfMdsalNotificationMapperModule.java
new file mode 100644 (file)
index 0000000..df97717
--- /dev/null
@@ -0,0 +1,53 @@
+package org.opendaylight.controller.config.yang.netconf.mdsal.notification;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netconf.mdsal.notification.NetconfNotificationOperationServiceFactory;
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class NetconfMdsalNotificationMapperModule extends org.opendaylight.controller.config.yang.netconf.mdsal.notification.AbstractNetconfMdsalNotificationMapperModule {
+    public NetconfMdsalNotificationMapperModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NetconfMdsalNotificationMapperModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.netconf.mdsal.notification.NetconfMdsalNotificationMapperModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        final NetconfNotificationCollector notificationCollector = getNotificationCollectorDependency();
+
+        final NotificationToMdsalWriter notificationToMdsalWriter = new NotificationToMdsalWriter(notificationCollector);
+        getBindingAwareBrokerDependency().registerProvider(notificationToMdsalWriter);
+
+        InstanceIdentifier capabilitiesIdentifier = InstanceIdentifier.create(NetconfState.class).child(Capabilities.class).builder().build();
+
+        final ListenerRegistration capabilityChangeListenerRegistration = getDataBrokerDependency().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, capabilitiesIdentifier,
+                new BaseCapabilityChangeNotificationPublisher(notificationCollector.registerBaseNotificationPublisher()), AsyncDataBroker.DataChangeScope.SUBTREE);
+
+        final NetconfNotificationOperationServiceFactory netconfNotificationOperationServiceFactory =
+            new NetconfNotificationOperationServiceFactory(getNotificationRegistryDependency()) {
+                @Override
+                public void close() {
+                    super.close();
+                    notificationToMdsalWriter.close();
+                    capabilityChangeListenerRegistration.close();
+                    getAggregatorDependency().onRemoveNetconfOperationServiceFactory(this);
+                }
+            };
+
+        getAggregatorDependency().onAddNetconfOperationServiceFactory(netconfNotificationOperationServiceFactory);
+
+        return netconfNotificationOperationServiceFactory;
+    }
+}
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NetconfMdsalNotificationMapperModuleFactory.java b/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NetconfMdsalNotificationMapperModuleFactory.java
new file mode 100644 (file)
index 0000000..0f8f08f
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: netconf-mdsal-notification yang module local name: netconf-mdsal-notification-mapper
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Aug 05 10:21:08 CEST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.netconf.mdsal.notification;
+
+public class NetconfMdsalNotificationMapperModuleFactory extends org.opendaylight.controller.config.yang.netconf.mdsal.notification.AbstractNetconfMdsalNotificationMapperModuleFactory {
+
+}
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NotificationToMdsalWriter.java b/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/notification/NotificationToMdsalWriter.java
new file mode 100644 (file)
index 0000000..4a8c09e
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yang.netconf.mdsal.notification;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
+import org.opendaylight.netconf.notifications.NotificationRegistration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Listens on changes in netconf notification stream availability and writes
+ * changes to the data store.
+ */
+final class NotificationToMdsalWriter implements AutoCloseable, NetconfNotificationCollector.NetconfNotificationStreamListener, BindingAwareProvider {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NotificationToMdsalWriter.class);
+
+    private final NetconfNotificationCollector netconfNotificationCollector;
+    private NotificationRegistration notificationRegistration;
+    private DataBroker dataBroker;
+
+    public NotificationToMdsalWriter(NetconfNotificationCollector netconfNotificationCollector) {
+        this.netconfNotificationCollector = netconfNotificationCollector;
+    }
+
+    @Override
+    public void close() {
+        final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+        tx.delete(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Netconf.class));
+        final CheckedFuture<Void, TransactionCommitFailedException> submit = tx.submit();
+
+        Futures.addCallback(submit, new FutureCallback<Void>() {
+            @Override
+            public void onSuccess(Void aVoid) {
+                LOG.debug("Streams cleared successfully");
+            }
+
+            @Override
+            public void onFailure(Throwable throwable) {
+                LOG.warn("Unable to clear streams", throwable);
+            }
+        });
+
+        notificationRegistration.close();
+    }
+
+    @Override
+    public void onSessionInitiated(BindingAwareBroker.ProviderContext session) {
+        dataBroker = session.getSALService(DataBroker.class);
+        notificationRegistration = netconfNotificationCollector.registerStreamListener(this);
+    }
+
+    @Override
+    public void onStreamRegistered(Stream stream) {
+        final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+
+        final InstanceIdentifier streamIdentifier = InstanceIdentifier.create(Netconf.class).child(Streams.class).
+                builder().child(Stream.class, stream.getKey()).build();
+        tx.merge(LogicalDatastoreType.OPERATIONAL, streamIdentifier, stream, true);
+
+        try {
+            tx.submit().checkedGet();
+            LOG.debug("Stream %s registered successfully.", stream.getName());
+        } catch (TransactionCommitFailedException e) {
+            LOG.warn("Unable to register stream.", e);
+        }
+    }
+
+    @Override
+    public void onStreamUnregistered(StreamNameType stream) {
+        final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+
+        final StreamKey streamKey = new StreamKey(stream);
+        final InstanceIdentifier streamIdentifier = InstanceIdentifier.create(Netconf.class).child(Streams.class).
+                builder().child(Stream.class, streamKey).build();
+
+        tx.delete(LogicalDatastoreType.OPERATIONAL, streamIdentifier);
+
+        try {
+            tx.submit().checkedGet();
+            LOG.debug("Stream %s unregistered successfully.", stream);
+        } catch (TransactionCommitFailedException e) {
+            LOG.warn("Unable to unregister stream", e);
+        }
+    }
+}
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/netconf/mdsal/notification/NetconfNotificationOperationService.java b/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/netconf/mdsal/notification/NetconfNotificationOperationService.java
new file mode 100644 (file)
index 0000000..94678c9
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.mdsal.notification;
+
+import java.util.Collections;
+import java.util.Set;
+import org.opendaylight.netconf.mapping.api.NetconfOperation;
+import org.opendaylight.netconf.mapping.api.NetconfOperationService;
+import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
+import org.opendaylight.netconf.notifications.impl.ops.CreateSubscription;
+
+public class NetconfNotificationOperationService implements NetconfOperationService {
+    private final Set<NetconfOperation> netconfOperations;
+
+    public NetconfNotificationOperationService(String netconfSessionIdForReporting, NetconfNotificationRegistry netconfNotificationRegistry) {
+        this.netconfOperations = Collections.<NetconfOperation>singleton(new CreateSubscription(netconfSessionIdForReporting, netconfNotificationRegistry));
+    }
+
+
+    @Override
+    public Set<NetconfOperation> getNetconfOperations() {
+        return netconfOperations;
+    }
+
+    @Override
+    public void close() {
+
+    }
+}
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/netconf/mdsal/notification/NetconfNotificationOperationServiceFactory.java b/opendaylight/netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/netconf/mdsal/notification/NetconfNotificationOperationServiceFactory.java
new file mode 100644 (file)
index 0000000..7c82d64
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.mdsal.notification;
+
+import java.util.Collections;
+import java.util.Set;
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.netconf.api.monitoring.CapabilityListener;
+import org.opendaylight.netconf.mapping.api.NetconfOperationService;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
+
+public class NetconfNotificationOperationServiceFactory implements NetconfOperationServiceFactory, AutoCloseable {
+
+    private final NetconfNotificationRegistry netconfNotificationRegistry;
+
+    private static final AutoCloseable AUTO_CLOSEABLE = new AutoCloseable() {
+        @Override
+        public void close() throws Exception {
+            // NOOP
+        }
+    };
+
+    public NetconfNotificationOperationServiceFactory(NetconfNotificationRegistry netconfNotificationRegistry) {
+        this.netconfNotificationRegistry = netconfNotificationRegistry;
+    }
+
+    @Override
+    public Set<Capability> getCapabilities() {
+        // TODO
+        // No capabilities exposed to prevent clashes with schemas from config-netconf-connector (it exposes all the schemas)
+        // If the schemas exposed by config-netconf-connector are filtered, this class would expose monitoring related models
+        return Collections.emptySet();
+    }
+
+    @Override
+    public NetconfOperationService createService(String netconfSessionIdForReporting) {
+        return new NetconfNotificationOperationService(netconfSessionIdForReporting, netconfNotificationRegistry);
+    }
+
+    @Override
+    public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
+        return AUTO_CLOSEABLE;
+    }
+
+    @Override
+    public void close() {
+    }
+}
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/main/yang/netconf-mdsal-notification.yang b/opendaylight/netconf/mdsal-netconf-notification/src/main/yang/netconf-mdsal-notification.yang
new file mode 100644 (file)
index 0000000..db4e8be
--- /dev/null
@@ -0,0 +1,79 @@
+module netconf-mdsal-notification {
+     yang-version 1;
+     namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:notification";
+     prefix "nnotification";
+
+     import netconf-northbound-mapper { prefix nnm; revision-date 2015-01-14; }
+     import opendaylight-md-sal-dom { prefix md-sal-dom; revision-date 2013-10-28; }
+     import opendaylight-md-sal-binding {prefix md-sal-binding; revision-date 2013-10-28;}
+     import netconf-northbound-notification {prefix nnn; revision-date 2015-08-06;}
+     import config { prefix config; revision-date 2013-04-05; }
+
+
+     organization "Cisco Systems, Inc.";
+
+     description
+         "This module contains the base YANG definitions for
+         an SAL notification mapper implementation";
+
+     revision "2015-08-03" {
+         description
+         "Initial revision.";
+     }
+
+     identity netconf-mdsal-notification-mapper {
+         base config:module-type;
+         config:provided-service nnm:netconf-northbound-mapper;
+     }
+
+     augment "/config:modules/config:module/config:configuration" {
+         case netconf-mdsal-notification-mapper {
+             when "/config:modules/config:module/config:type = 'netconf-mdsal-notification-mapper'";
+
+             container aggregator {
+                 uses config:service-ref {
+                     refine type {
+                         mandatory true;
+                         config:required-identity nnm:netconf-mapper-registry;
+                         }
+                 }
+             }
+
+             container binding-aware-broker {
+                 uses config:service-ref {
+                     refine type {
+                         mandatory true;
+                         config:required-identity md-sal-binding:binding-broker-osgi-registry;
+                     }
+                 }
+             }
+
+             container data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-async-data-broker;
+                    }
+                }
+             }
+
+             container notification-collector {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity nnn:netconf-notification-collector;
+                    }
+                }
+             }
+
+            container notification-registry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity nnn:netconf-notification-registry;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/test/java/org.opendaylight.controller.config.yang.netconf.mdsal.notification/BaseCapabilityChangeNotificationPublisherTest.java b/opendaylight/netconf/mdsal-netconf-notification/src/test/java/org.opendaylight.controller.config.yang.netconf.mdsal.notification/BaseCapabilityChangeNotificationPublisherTest.java
new file mode 100644 (file)
index 0000000..223bfee
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yang.netconf.mdsal.notification;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.netconf.notifications.BaseNotificationPublisherRegistration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.ChangedByBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.changed.by.server.or.user.ServerBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class BaseCapabilityChangeNotificationPublisherTest {
+
+    @Mock
+    private BaseNotificationPublisherRegistration baseNotificationPublisherRegistration;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        doNothing().when(baseNotificationPublisherRegistration).onCapabilityChanged(any(NetconfCapabilityChange.class));
+    }
+
+    @Test
+    public void testOnDataChanged() {
+        final BaseCapabilityChangeNotificationPublisher baseCapabilityChangeNotificationPublisher =
+                new BaseCapabilityChangeNotificationPublisher(baseNotificationPublisherRegistration);
+        final InstanceIdentifier capabilitiesIdentifier = InstanceIdentifier.create(NetconfState.class).child(Capabilities.class).builder().build();
+        final List<Uri> newCapabilitiesList = Lists.newArrayList(new Uri("newCapability"), new Uri("createdCapability"));
+
+        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> capabilitiesChange = mock(AsyncDataChangeEvent.class);
+        Capabilities newCapabilities = new CapabilitiesBuilder().setCapability(newCapabilitiesList).build();
+        Map<InstanceIdentifier<?>, DataObject> createdData = Maps.newHashMap();
+        createdData.put(capabilitiesIdentifier, newCapabilities);
+        doReturn(createdData).when(capabilitiesChange).getCreatedData();
+        baseCapabilityChangeNotificationPublisher.onDataChanged(capabilitiesChange);
+
+        verify(baseNotificationPublisherRegistration).onCapabilityChanged(changedCapabilitesFrom(newCapabilitiesList, Collections.<Uri>emptyList()));
+
+        final List<Uri> originalCapabilitiesList = Lists.newArrayList(new Uri("originalCapability"), new Uri("anotherOriginalCapability"));
+        final List<Uri> updatedCapabilitiesList = Lists.newArrayList(new Uri("originalCapability"), new Uri("newCapability"));
+
+        Capabilities originalCapabilities = new CapabilitiesBuilder().setCapability(originalCapabilitiesList).build();
+        Capabilities updatedCapabilities = new CapabilitiesBuilder().setCapability(updatedCapabilitiesList).build();
+
+        doReturn(Collections.emptyMap()).when(capabilitiesChange).getCreatedData();
+        doReturn(originalCapabilities).when(capabilitiesChange).getOriginalSubtree();
+        doReturn(updatedCapabilities).when(capabilitiesChange).getUpdatedSubtree();
+        baseCapabilityChangeNotificationPublisher.onDataChanged(capabilitiesChange);
+
+        verify(baseNotificationPublisherRegistration).onCapabilityChanged(changedCapabilitesFrom(
+                Lists.newArrayList(new Uri("newCapability")), Lists.newArrayList(new Uri("anotherOriginalCapability"))));
+    }
+
+    private NetconfCapabilityChange changedCapabilitesFrom(List<Uri> added, List<Uri> deleted) {
+        NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder();
+        netconfCapabilityChangeBuilder.setChangedBy(new ChangedByBuilder().setServerOrUser(
+                new ServerBuilder().setServer(true).build()).build());
+
+        netconfCapabilityChangeBuilder.setModifiedCapability(Collections.<Uri>emptyList());
+        netconfCapabilityChangeBuilder.setAddedCapability(added);
+        netconfCapabilityChangeBuilder.setDeletedCapability(deleted);
+
+        return netconfCapabilityChangeBuilder.build();
+    }
+}
diff --git a/opendaylight/netconf/mdsal-netconf-notification/src/test/java/org.opendaylight.controller.config.yang.netconf.mdsal.notification/NotificationToMdsalWriterTest.java b/opendaylight/netconf/mdsal-netconf-notification/src/test/java/org.opendaylight.controller.config.yang.netconf.mdsal.notification/NotificationToMdsalWriterTest.java
new file mode 100644 (file)
index 0000000..601315a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yang.netconf.mdsal.notification;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.util.concurrent.Futures;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class NotificationToMdsalWriterTest {
+
+    @Mock
+    private DataBroker dataBroker;
+
+    private NotificationToMdsalWriter writer;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final NetconfNotificationCollector notificationCollector = mock(NetconfNotificationCollector.class);
+        final BindingAwareBroker.ProviderContext session = mock(BindingAwareBroker.ProviderContext.class);
+        doReturn(null).when(notificationCollector).registerStreamListener(any(
+                NetconfNotificationCollector.NetconfNotificationStreamListener.class));
+        doReturn(dataBroker).when(session).getSALService(DataBroker.class);
+
+        WriteTransaction tx = mock(WriteTransaction.class);
+        doNothing().when(tx).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class)
+                , any(DataObject.class), anyBoolean());
+        doNothing().when(tx).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        doReturn(Futures.immediateCheckedFuture(null)).when(tx).submit();
+        doReturn(tx).when(dataBroker).newWriteOnlyTransaction();
+
+        writer = new NotificationToMdsalWriter(notificationCollector);
+        writer.onSessionInitiated(session);
+    }
+
+    @Test
+    public void testStreamRegisteration() {
+        final StreamNameType testStreamName = new StreamNameType("TESTSTREAM");
+        final Stream testStream = new StreamBuilder().setName(testStreamName).build();
+        final InstanceIdentifier streamIdentifier = InstanceIdentifier.create(Netconf.class).child(Streams.class)
+                .builder().child(Stream.class, testStream.getKey()).build();
+
+        writer.onStreamRegistered(testStream);
+
+        verify(dataBroker.newWriteOnlyTransaction()).merge(LogicalDatastoreType.OPERATIONAL, streamIdentifier, testStream, true);
+
+        writer.onStreamUnregistered(testStreamName);
+
+        verify(dataBroker.newWriteOnlyTransaction()).delete(LogicalDatastoreType.OPERATIONAL, streamIdentifier);
+    }
+}
index be3bb09ed529af84af8cf526899875f31d1fa4cf..81add4d4522e9bce9f13f3692ba24008109b9259 100644 (file)
               </auth-provider>
           </module>
 
+          <module>
+              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification:impl">prefix:netconf-notification-manager</type>
+              <name>netconf-notification-manager</name>
+          </module>
+
+          <module>
+              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:notification">prefix:netconf-mdsal-notification-mapper</type>
+              <name>netconf-mdsal-notification-mapper</name>
+              <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:notification">
+                  <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+                  <name>binding-data-broker</name>
+              </data-broker>
+              <binding-aware-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:notification">
+                  <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
+                  <name>binding-osgi-broker</name>
+              </binding-aware-broker>
+              <aggregator xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:notification">
+                  <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">prefix:netconf-mapper-registry</type>
+                  <name>mapper-aggregator-registry</name>
+              </aggregator>
+              <notification-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:notification">
+                  <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification">prefix:netconf-notification-registry</type>
+                  <name>netconf-notification-manager</name>
+              </notification-registry>
+              <notification-collector>
+                  <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification">prefix:netconf-notification-collector</type>
+                  <name>netconf-notification-manager</name>
+              </notification-collector>
+          </module>
+
+
 
           <!--TCP endpoint for MD-SAL netconf server -->
           <!--<module>-->
                     <provider>/modules/module[type='netconf-server-dispatcher-impl'][name='netconf-mdsal-server-dispatcher']</provider>
                 </instance>
             </service>
+            <service>
+                <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">prefix:netconf-northbound-mapper</type>
+                <instance>
+                    <name>netconf-mdsal-notification-mapper</name>
+                    <provider>/modules/module[type='netconf-mdsal-notification-mapper'][name='netconf-mdsal-notification-mapper']</provider>
+                </instance>
+            </service>
+            <service>
+                <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification">prefix:netconf-notification-collector</type>
+                <instance>
+                    <name>netconf-notification-manager</name>
+                    <provider>/modules/module[type='netconf-notification-manager'][name='netconf-notification-manager']</provider>
+                </instance>
+            </service>
+            <service>
+                <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification">prefix:netconf-notification-registry</type>
+                <instance>
+                    <name>netconf-notification-manager</name>
+                    <provider>/modules/module[type='netconf-notification-manager'][name='netconf-notification-manager']</provider>
+                </instance>
+            </service>
         </services>
 
     </data>
       <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp?module=netconf-northbound-tcp&amp;revision=2015-04-23</capability>
       <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl?module=netconf-northbound-impl&amp;revision=2015-01-12</capability>
       <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled?module=threadpool-impl-scheduled&amp;revision=2013-12-01</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:notification?module=netconf-mdsal-notification&amp;revision=2015-08-03</capability>
   </required-capabilities>
 </snapshot>
diff --git a/opendaylight/netconf/netconf-notifications-api/src/main/yang/netconf-northbound-notification.yang b/opendaylight/netconf/netconf-notifications-api/src/main/yang/netconf-northbound-notification.yang
new file mode 100644 (file)
index 0000000..a770a6e
--- /dev/null
@@ -0,0 +1,23 @@
+module netconf-northbound-notification {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification";
+    prefix "nnn";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description "TODO";
+
+    revision "2015-08-06" {
+            description "Initial revision.";
+    }
+
+    identity netconf-notification-collector {
+            base "config:service-type";
+            config:java-class "org.opendaylight.netconf.notifications.NetconfNotificationCollector";
+        }
+
+    identity netconf-notification-registry {
+           base "config:service-type";
+           config:java-class "org.opendaylight.netconf.notifications.NetconfNotificationRegistry";
+    }
+}
\ No newline at end of file
index b0c2d0b8eb522da79a05346d397f364d2daef6b7..59658a6dcf4ab904946e4eac3b469728c9d22bb6 100644 (file)
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.netconf</groupId>
         <version>1.0.0-SNAPSHOT</version>
     </parent>
-    <modelVersion>4.0.0</modelVersion>
     <packaging>bundle</packaging>
     <artifactId>netconf-notifications-impl</artifactId>
 
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>mdsal-binding-generator-impl</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>netconf-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>mdsal-binding-dom-codec</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ietf-netconf-notifications</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
diff --git a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/config/yang/netconf/northbound/notification/impl/NetconfNotificationManagerModule.java b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/config/yang/netconf/northbound/notification/impl/NetconfNotificationManagerModule.java
new file mode 100644 (file)
index 0000000..b50ff02
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.controller.config.yang.netconf.northbound.notification.impl;
+
+import org.opendaylight.netconf.notifications.impl.NetconfNotificationManager;
+
+public class NetconfNotificationManagerModule extends org.opendaylight.controller.config.yang.netconf.northbound.notification.impl.AbstractNetconfNotificationManagerModule {
+    public NetconfNotificationManagerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NetconfNotificationManagerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.netconf.northbound.notification.impl.NetconfNotificationManagerModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return new NetconfNotificationManager();
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/config/yang/netconf/northbound/notification/impl/NetconfNotificationManagerModuleFactory.java b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/config/yang/netconf/northbound/notification/impl/NetconfNotificationManagerModuleFactory.java
new file mode 100644 (file)
index 0000000..624c262
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: netconf-northbound-notification-impl yang module local name: netconf-notification-manager
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Aug 07 17:09:20 CEST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.netconf.northbound.notification.impl;
+public class NetconfNotificationManagerModuleFactory extends org.opendaylight.controller.config.yang.netconf.northbound.notification.impl.AbstractNetconfNotificationManagerModuleFactory {
+
+}
index 6fb297219879ee977615cf97d29730aa5afad2b8..3e5a0a8c71ef7c4553f1f6e7959cb2e5d8b5457c 100644 (file)
@@ -15,7 +15,6 @@ import java.util.List;
 import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.netconf.util.mapping.AbstractLastNetconfOperation;
 import org.opendaylight.netconf.api.NetconfSession;
 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.netconf.mapping.api.SessionAwareNetconfOperation;
@@ -24,6 +23,7 @@ import org.opendaylight.netconf.notifications.NetconfNotificationListener;
 import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
 import org.opendaylight.netconf.notifications.NotificationListenerRegistration;
 import org.opendaylight.netconf.notifications.impl.NetconfNotificationManager;
+import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
 import org.slf4j.Logger;
@@ -35,7 +35,7 @@ import org.w3c.dom.Element;
  * Create subscription listens for create subscription requests and registers notification listeners into notification registry.
  * Received notifications are sent to the client right away
  */
-public class CreateSubscription extends AbstractLastNetconfOperation implements SessionAwareNetconfOperation, AutoCloseable {
+public class CreateSubscription extends AbstractSingletonNetconfOperation implements SessionAwareNetconfOperation, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(CreateSubscription.class);
 
diff --git a/opendaylight/netconf/netconf-notifications-impl/src/main/yang/netconf-northbound-notification-impl.yang b/opendaylight/netconf/netconf-notifications-impl/src/main/yang/netconf-northbound-notification-impl.yang
new file mode 100644 (file)
index 0000000..cd5ca46
--- /dev/null
@@ -0,0 +1,27 @@
+module netconf-northbound-notification-impl {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:notification:impl";
+    prefix "nnnimpl";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import netconf-northbound-notification { prefix nnn; revision-date 2015-08-06; }
+
+    description "TODO";
+
+    revision "2015-08-07"{
+        description "Initial revision.";
+    }
+
+    identity netconf-notification-manager {
+        base config:module-type;
+        config:provided-service nnn:netconf-notification-collector;
+        config:provided-service nnn:netconf-notification-registry;
+        config:java-name-prefix NetconfNotificationManager;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case netconf-notification-manager {
+            when "/config:modules/config:module/config:type = 'netconf-notification-manager'";
+        }
+    }
+}
\ No newline at end of file
index 1dc83d873370384850bcf7fcd12bfcc0b12285ca..f2027d53ea5e2b9d53f36468bd3b0a232b1c2961 100644 (file)
@@ -20,6 +20,7 @@
     <module>config-netconf-connector</module>
     <module>mdsal-netconf-connector</module>
     <module>mdsal-netconf-monitoring</module>
+    <module>mdsal-netconf-notification</module>
     <module>netconf-util</module>
     <module>netconf-netty-util</module>
     <module>netconf-mapping-api</module>