Bug 2578 - Added Binding Adapters for new Notification Broker 17/15417/13
authorJan Hajnar <jhajnar@cisco.com>
Tue, 17 Feb 2015 15:47:54 +0000 (16:47 +0100)
committerTony Tkacik <ttkacik@cisco.com>
Sun, 8 Mar 2015 17:39:59 +0000 (18:39 +0100)
Implement and integrate Binding to DOM Notification adapters

* implemented forwarded notification broker
* added simple test for forwarded notification broker
* added configuration of new modules and services to md-sal config

Change-Id: I259c971f0dc61bc1b00cbaad2956c3d8b37ff780
Signed-off-by: Jan Hajnar <jhajnar@cisco.com>
24 files changed:
opendaylight/md-sal/md-sal-config/src/main/resources/initial/01-md-sal.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationAdapterModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationAdapterModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationPublishAdapterModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationPublishAdapterModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DummyNoopProvider.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/NotificationBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedNotificationPublishService.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedNotificationService.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/compat/HeliumNotificationProviderServiceAdapter.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/compat/HeliumNotificationServiceAdapter.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/BackwardsCompatibleNotificationBrokerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractNotificationBrokerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java
opendaylight/md-sal/sal-binding-config/src/main/yang/opendaylight-md-sal-binding.yang
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMNotificationPublishService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMNotificationService.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.java
opendaylight/md-sal/sal-test-model/src/main/yang/opendaylight-mdsal-list-test.yang

index b9159dc..8b64527 100644 (file)
                     <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-adapter</type>
+                    <name>binding-notification-adapter</name>
+                    <binding-notification-adapter xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                        <binding-mapping-service>
+                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+                            <name>runtime-mapping-singleton</name>
+                        </binding-mapping-service>
+                        <dom-async-broker>
+                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                            <name>dom-broker</name>
+                        </dom-async-broker>
+                    </binding-notification-adapter>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-publish-adapter</type>
+                    <name>binding-notification-publish-adapter</name>
+                    <binding-notification-publish-adapter xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                        <binding-mapping-service>
+                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+                            <name>runtime-mapping-singleton</name>
+                        </binding-mapping-service>
+                        <dom-async-broker>
+                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                            <name>dom-broker</name>
+                        </dom-async-broker>
+                    </binding-notification-publish-adapter>
+                </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>
                             <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
                         </instance>
                     </service>
+                    <service>
+                        <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-new-notification-service</type>
+                        <instance>
+                            <name>binding-notification-adapter</name>
+                            <provider>/modules/module[type='binding-notification-adapter'][name='binding-notification-adapter']</provider>
+                        </instance>
+                    </service>
+                    <service>
+                        <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-new-notification-publish-service</type>
+                        <instance>
+                            <name>binding-notification-publish-adapter</name>
+                            <provider>/modules/module[type='binding-notification-publish-adapter'][name='binding-notification-publish-adapter']</provider>
+                        </instance>
+                    </service>
                     <service>
                         <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
                         <instance>
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationAdapterModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationAdapterModule.java
new file mode 100644 (file)
index 0000000..e786151
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.md.sal.binding.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedNotificationService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
+import org.opendaylight.controller.sal.core.api.Broker;
+
+public class BindingNotificationAdapterModule extends AbstractBindingNotificationAdapterModule  {
+    public BindingNotificationAdapterModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public BindingNotificationAdapterModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingNotificationAdapterModule 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 BindingToNormalizedNodeCodec codec = getBindingMappingServiceDependency();
+        final Broker.ProviderSession session = getDomAsyncBrokerDependency().registerProvider(new DummyDOMProvider());
+        final DOMNotificationService notifService = session.getService(DOMNotificationService.class);
+        return new ForwardedNotificationService(codec.getCodecRegistry(), notifService, SingletonHolder.INVOKER_FACTORY);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationAdapterModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationAdapterModuleFactory.java
new file mode 100644 (file)
index 0000000..0a5cb91
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * 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.md.sal.binding.impl;
+public class BindingNotificationAdapterModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingNotificationAdapterModuleFactory {
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationPublishAdapterModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationPublishAdapterModule.java
new file mode 100644 (file)
index 0000000..bdac710
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.md.sal.binding.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedNotificationPublishService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
+import org.opendaylight.controller.sal.core.api.Broker;
+
+public class BindingNotificationPublishAdapterModule extends AbstractBindingNotificationPublishAdapterModule {
+    public BindingNotificationPublishAdapterModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public BindingNotificationPublishAdapterModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver, BindingNotificationPublishAdapterModule 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 BindingToNormalizedNodeCodec codec = getBindingMappingServiceDependency();
+        final Broker.ProviderSession session = getDomAsyncBrokerDependency().registerProvider(new DummyDOMProvider());
+        final DOMNotificationPublishService publishService = session.getService(DOMNotificationPublishService.class);
+        return new ForwardedNotificationPublishService(codec.getCodecRegistry(), publishService);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationPublishAdapterModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingNotificationPublishAdapterModuleFactory.java
new file mode 100644 (file)
index 0000000..e9a3df6
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * 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.md.sal.binding.impl;
+public class BindingNotificationPublishAdapterModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingNotificationPublishAdapterModuleFactory {
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DummyNoopProvider.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DummyNoopProvider.java
new file mode 100644 (file)
index 0000000..ca3054e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.md.sal.binding.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Provider;
+
+class DummyDOMProvider implements Provider {
+
+    @Override
+    @Deprecated
+    public Collection<ProviderFunctionality> getProviderFunctionality() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderSession session) {
+        // NOOP
+    }
+}
index b6c27a6..415c978 100644 (file)
@@ -7,11 +7,10 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
+import com.google.common.util.concurrent.ListeningExecutorService;
 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
 import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
 
-import com.google.common.util.concurrent.ListeningExecutorService;
-
 /**
 *
 */
@@ -37,6 +36,13 @@ public final class NotificationBrokerImplModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
+
+        /*
+         *  FIXME: Switch to new broker (which has different threading model)
+         *  once this change is communicated with downstream users or
+         *  we will have adapter implementation which will honor Helium
+         *  threading model for notifications.
+         */
         ListeningExecutorService listeningExecutor = SingletonHolder.getDefaultNotificationExecutor();
         NotificationBrokerImpl broker = new NotificationBrokerImpl(listeningExecutor);
         return broker;
index d7314e5..a973e67 100644 (file)
@@ -9,12 +9,9 @@ package org.opendaylight.controller.md.sal.binding.impl;
 
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
-
 import java.util.Iterator;
 import java.util.Map.Entry;
-
 import javax.annotation.Nonnull;
-
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
@@ -143,6 +140,10 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoC
         return bindingToLegacy;
     }
 
+    public BindingNormalizedNodeCodecRegistry getCodecRegistry() {
+        return codecRegistry;
+    }
+
     @Override
     public void close() {
         // NOOP Intentionally
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedNotificationPublishService.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedNotificationPublishService.java
new file mode 100644 (file)
index 0000000..14d6713
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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.md.sal.binding.impl;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class ForwardedNotificationPublishService implements NotificationPublishService, AutoCloseable {
+    private final BindingNormalizedNodeSerializer codecRegistry;
+    private final DOMNotificationPublishService domPublishService;
+
+    public ForwardedNotificationPublishService(BindingNormalizedNodeSerializer codecRegistry, DOMNotificationPublishService domPublishService) {
+        this.codecRegistry = codecRegistry;
+        this.domPublishService = domPublishService;
+    }
+
+    @Override
+    public void putNotification(final Notification notification) throws InterruptedException {
+        domPublishService.putNotification(toDomNotification(notification));
+    }
+
+    @Override
+    public boolean offerNotification(final Notification notification) {
+        final ListenableFuture<?> listenableFuture = domPublishService.offerNotification(toDomNotification(notification));
+        return !DOMNotificationPublishService.REJECTED.equals(listenableFuture);
+    }
+
+    @Override
+    public boolean offerNotification(final Notification notification, final int timeout, final TimeUnit unit) throws InterruptedException {
+        final ListenableFuture<?> listenableFuture =
+                domPublishService.offerNotification(toDomNotification(notification), timeout, unit);
+        return !DOMNotificationPublishService.REJECTED.equals(listenableFuture);
+    }
+
+    private DOMNotification toDomNotification(final Notification notification) {
+        final ContainerNode domNotification = codecRegistry.toNormalizedNodeNotification(notification);
+        return new DOMNotificationImpl(domNotification);
+    }
+
+    @Override
+    public void close() throws Exception {
+
+    }
+
+    private static class DOMNotificationImpl implements DOMNotification {
+
+        private final SchemaPath type;
+        private final ContainerNode body;
+
+        public DOMNotificationImpl(final ContainerNode body) {
+            this.type = SchemaPath.create(true, body.getIdentifier().getNodeType());
+            this.body = body;
+        }
+
+        @Nonnull
+        @Override
+        public SchemaPath getType() {
+            return this.type;
+        }
+
+        @Nonnull
+        @Override
+        public ContainerNode getBody() {
+            return this.body;
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedNotificationService.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedNotificationService.java
new file mode 100644 (file)
index 0000000..fc7a742
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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.md.sal.binding.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
+import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class ForwardedNotificationService implements NotificationService, AutoCloseable {
+
+    private final BindingNormalizedNodeSerializer codec;
+    private final DOMNotificationService domNotifService;
+    private final NotificationInvokerFactory notificationInvokerFactory;
+
+    public ForwardedNotificationService(BindingNormalizedNodeSerializer codec, DOMNotificationService domNotifService, NotificationInvokerFactory notificationInvokerFactory) {
+        this.codec = codec;
+        this.domNotifService = domNotifService;
+        this.notificationInvokerFactory = notificationInvokerFactory;
+    }
+
+    @Override
+    public <T extends NotificationListener> ListenerRegistration<T> registerNotificationListener(T listener) {
+        final NotificationInvokerFactory.NotificationInvoker invoker = notificationInvokerFactory.invokerFor(listener);
+        final DOMNotificationListener domListener = new NotificationInvokerImpl(invoker);
+        final Collection<SchemaPath> schemaPaths = convertNotifTypesToSchemaPath(invoker.getSupportedNotifications());
+        final ListenerRegistration<DOMNotificationListener> domRegistration =
+                domNotifService.registerNotificationListener(domListener, schemaPaths);
+        return new ListenerRegistrationImpl<>(listener, domRegistration);
+    }
+
+
+
+    private Collection<SchemaPath> convertNotifTypesToSchemaPath(Set<Class<? extends Notification>> notificationTypes) {
+        final List<SchemaPath> schemaPaths = new ArrayList<>();
+        for (Class<? extends Notification> notificationType : notificationTypes) {
+            schemaPaths.add(SchemaPath.create(true, BindingReflections.findQName(notificationType)));
+        }
+        return schemaPaths;
+    }
+
+    @Override
+    public void close() throws Exception {
+
+    }
+
+    private static class ListenerRegistrationImpl<T extends NotificationListener> extends AbstractListenerRegistration<T> {
+        private final ListenerRegistration<?> listenerRegistration;
+
+        public ListenerRegistrationImpl(T listener, ListenerRegistration<?> listenerRegistration) {
+            super(listener);
+            this.listenerRegistration = listenerRegistration;
+        }
+
+        @Override
+        protected void removeRegistration() {
+            listenerRegistration.close();
+        }
+    }
+
+    private class NotificationInvokerImpl implements DOMNotificationListener {
+        private final NotificationInvokerFactory.NotificationInvoker invoker;
+
+        public NotificationInvokerImpl(NotificationInvokerFactory.NotificationInvoker invoker) {
+            this.invoker = invoker;
+        }
+
+        @Override
+        public void onNotification(@Nonnull DOMNotification notification) {
+            final Notification baNotification =
+                    codec.fromNormalizedNodeNotification(notification.getType(), notification.getBody());
+            invoker.getInvocationProxy().onNotification(baNotification);
+
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/compat/HeliumNotificationProviderServiceAdapter.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/compat/HeliumNotificationProviderServiceAdapter.java
new file mode 100644 (file)
index 0000000..e0aedb2
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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.md.sal.binding.impl.compat;
+
+import java.util.concurrent.ExecutorService;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HeliumNotificationProviderServiceAdapter extends HeliumNotificationServiceAdapter implements NotificationProviderService, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(HeliumNotificationProviderServiceAdapter.class);
+
+    private final NotificationPublishService notificationPublishService;
+
+    public HeliumNotificationProviderServiceAdapter(NotificationPublishService notificationPublishService,
+                                                 NotificationService notificationService) {
+        super(notificationService);
+        this.notificationPublishService = notificationPublishService;
+    }
+
+    @Override
+    public void publish(final Notification notification) {
+        try {
+            notificationPublishService.putNotification(notification);
+        } catch (InterruptedException e) {
+            LOG.error("Notification publication was interupted: "  + e);
+        }
+    }
+
+    @Override
+    public void publish(final Notification notification, final ExecutorService executor) {
+        try {
+            notificationPublishService.putNotification(notification);
+        } catch (InterruptedException e) {
+            LOG.error("Notification publication was interupted: "  + e);
+        }
+    }
+
+    @Override
+    public ListenerRegistration<NotificationInterestListener> registerInterestListener(
+            NotificationInterestListener interestListener) {
+        throw new UnsupportedOperationException("InterestListener is not supported.");
+    }
+
+    @Override
+    public void close() throws Exception {
+
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/compat/HeliumNotificationServiceAdapter.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/compat/HeliumNotificationServiceAdapter.java
new file mode 100644 (file)
index 0000000..d68ea1c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.md.sal.binding.impl.compat;
+
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+
+public class HeliumNotificationServiceAdapter implements org.opendaylight.controller.sal.binding.api.NotificationService, AutoCloseable {
+
+    private final NotificationService notificationService;
+
+    public HeliumNotificationServiceAdapter(NotificationService notificationService) {
+        this.notificationService = notificationService;
+    }
+
+    @Override
+    public <T extends Notification> ListenerRegistration<org.opendaylight.controller.sal.binding.api.NotificationListener<T>> registerNotificationListener(
+            final Class<T> notificationType, final org.opendaylight.controller.sal.binding.api.NotificationListener<T> listener) {
+        throw new UnsupportedOperationException("Not supported type of listener.");
+    }
+
+    @Override
+    public ListenerRegistration<NotificationListener> registerNotificationListener(
+            final NotificationListener listener) {
+        return notificationService.registerNotificationListener(listener);
+    }
+
+    @Override
+    public void close() throws Exception {
+
+    }
+}
index de8ab63..8e28089 100644 (file)
@@ -21,6 +21,18 @@ module opendaylight-sal-binding-broker-impl {
         config:java-class "org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec";
     }
 
+    /* FIXME: move to opendaylight-md-sal-binding (cannot be there due to Class name confict with old implementation)*/
+    identity binding-new-notification-service {
+        base config:service-type;
+        config:java-class "org.opendaylight.controller.md.sal.binding.api.NotificationService";
+    }
+
+    /* TODO: move to opendaylight-md-sal-binding (cannot be there due to Class name confict with old implementation)*/
+    identity binding-new-notification-publish-service {
+        base config:service-type;
+        config:java-class "org.opendaylight.controller.md.sal.binding.api.NotificationPublishService";
+    }
+
     identity binding-broker-impl {
         base config:module-type;
         config:provided-service sal:binding-broker-osgi-registry;
@@ -34,7 +46,7 @@ module opendaylight-sal-binding-broker-impl {
         config:provided-service sal:binding-data-consumer-broker;
         config:java-name-prefix ForwardedCompatibleDataBrokerImpl;
     }
-    
+
     identity binding-forwarded-data-broker {
         base config:module-type;
         config:provided-service sal:binding-async-data-broker;
@@ -60,6 +72,18 @@ module opendaylight-sal-binding-broker-impl {
         config:java-name-prefix RuntimeMapping;
     }
 
+    identity binding-notification-adapter {
+        base config:module-type;
+        config:provided-service binding-new-notification-service;
+        config:java-name-prefix BindingNotificationAdapter;
+    }
+
+    identity binding-notification-publish-adapter {
+        base config:module-type;
+        config:provided-service binding-new-notification-publish-service;
+        config:java-name-prefix BindingNotificationPublishAdapter;
+    }
+
     grouping dom-forwarding-component {
         container dom-async-broker {
                 uses config:service-ref {
@@ -130,7 +154,7 @@ module opendaylight-sal-binding-broker-impl {
             uses dom-forwarding-component;
         }
     }
-    
+
     augment "/config:modules/config:module/config:configuration" {
         case binding-forwarded-data-broker {
             when "/config:modules/config:module/config:type = 'binding-forwarded-data-broker'";
@@ -178,10 +202,29 @@ module opendaylight-sal-binding-broker-impl {
             uses common:rpc-state;
         }
     }
+
     augment "/config:modules/config:module/config:state" {
         case binding-notification-broker {
             when "/config:modules/config:module/config:type = 'binding-notification-broker'";
             uses common:notification-state;
         }
     }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case binding-notification-adapter {
+            when "/config:modules/config:module/config:type = 'binding-notification-adapter'";
+            container binding-notification-adapter {
+                uses dom-forwarding-component;
+            }
+        }
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case binding-notification-publish-adapter {
+            when "/config:modules/config:module/config:type = 'binding-notification-publish-adapter'";
+            container binding-notification-publish-adapter {
+                uses dom-forwarding-component;
+            }
+        }
+    }
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/BackwardsCompatibleNotificationBrokerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/BackwardsCompatibleNotificationBrokerTest.java
new file mode 100644 (file)
index 0000000..6da1633
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.md.sal.binding.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.binding.impl.compat.HeliumNotificationProviderServiceAdapter;
+import org.opendaylight.controller.md.sal.binding.test.AbstractNotificationBrokerTest;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.OpendaylightMdsalListTestListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TwoLevelListChanged;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TwoLevelListChangedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+
+public class BackwardsCompatibleNotificationBrokerTest extends AbstractNotificationBrokerTest {
+
+    private NotificationProviderService notificationProviderService;
+
+    @Before
+    public void initTest() {
+        final NotificationService notificationService = getNotificationService();
+        final NotificationPublishService notificationPublishService = getNotificationPublishService();
+        notificationProviderService = new HeliumNotificationProviderServiceAdapter(notificationPublishService, notificationService);
+    }
+
+    private TwoLevelListChanged createTestData() {
+        final TwoLevelListChangedBuilder tb = new TwoLevelListChangedBuilder();
+        tb.setTopLevelList(ImmutableList.of(new TopLevelListBuilder().setKey(new TopLevelListKey("test")).build()));
+        return tb.build();
+    }
+
+    @Test
+    public void testNotifSubscriptionForwarded() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final TwoLevelListChanged testData = createTestData();
+
+        final NotifTestListener testNotifListener = new NotifTestListener(latch);
+        final ListenerRegistration<NotificationListener> listenerRegistration =
+                notificationProviderService.registerNotificationListener(testNotifListener);
+        notificationProviderService.publish(testData);
+
+        latch.await();
+        assertTrue(testNotifListener.getReceivedNotifications().size() == 1);
+        assertEquals(testData, testNotifListener.getReceivedNotifications().get(0));
+        listenerRegistration.close();
+    }
+
+    private static class NotifTestListener implements OpendaylightMdsalListTestListener {
+        private List<TwoLevelListChanged> receivedNotifications = new ArrayList<>();
+        private CountDownLatch latch;
+
+        public NotifTestListener(CountDownLatch latch) {
+            this.latch = latch;
+        }
+
+        @Override
+        public void onTwoLevelListChanged(TwoLevelListChanged notification) {
+            receivedNotifications.add(notification);
+            latch.countDown();
+        }
+
+        public List<TwoLevelListChanged> getReceivedNotifications() {
+            return receivedNotifications;
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java
new file mode 100644 (file)
index 0000000..c2cdc0c
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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.md.sal.binding.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.test.AbstractNotificationBrokerTest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.OpendaylightMdsalListTestListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TwoLevelListChanged;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TwoLevelListChangedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+
+public class ForwardedNotificationAdapterTest extends AbstractNotificationBrokerTest {
+
+    @Override
+    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+        return ImmutableSet.of(BindingReflections.getModuleInfo(TwoLevelListChanged.class));
+
+    }
+
+    private TwoLevelListChanged createTestData() {
+        final TwoLevelListChangedBuilder tb = new TwoLevelListChangedBuilder();
+        tb.setTopLevelList(ImmutableList.of(new TopLevelListBuilder().setKey(new TopLevelListKey("test")).build()));
+        return tb.build();
+    }
+
+    @Test
+    public void testNotifSubscription() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final TwoLevelListChanged testData = createTestData();
+
+        final TestNotifListener testNotifListener = new TestNotifListener(latch);
+        final ListenerRegistration<TestNotifListener> listenerRegistration = getNotificationService()
+                .registerNotificationListener(testNotifListener);
+        getNotificationPublishService().putNotification(testData);
+
+        latch.await();
+        assertTrue(testNotifListener.getReceivedNotifications().size() == 1);
+        assertEquals(testData, testNotifListener.getReceivedNotifications().get(0));
+
+        listenerRegistration.close();
+    }
+
+    @Test
+    public void testNotifSubscription2() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final TwoLevelListChanged testData = createTestData();
+
+        final TestNotifListener testNotifListener = new TestNotifListener(latch);
+        final ListenerRegistration<TestNotifListener> listenerRegistration = getNotificationService()
+                .registerNotificationListener(testNotifListener);
+        assertTrue(getNotificationPublishService().offerNotification(testData));
+
+        latch.await();
+        assertTrue(testNotifListener.getReceivedNotifications().size() == 1);
+        assertEquals(testData, testNotifListener.getReceivedNotifications().get(0));
+
+        listenerRegistration.close();
+    }
+
+    @Test
+    public void testNotifSubscription3() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final TwoLevelListChanged testData = createTestData();
+
+        final TestNotifListener testNotifListener = new TestNotifListener(latch);
+        final ListenerRegistration<TestNotifListener> listenerRegistration = getNotificationService()
+                .registerNotificationListener(testNotifListener);
+        assertTrue(getNotificationPublishService().offerNotification(testData, 5, TimeUnit.SECONDS));
+
+        latch.await();
+        assertTrue(testNotifListener.getReceivedNotifications().size() == 1);
+        assertEquals(testData, testNotifListener.getReceivedNotifications().get(0));
+
+        listenerRegistration.close();
+    }
+
+    private static class TestNotifListener implements OpendaylightMdsalListTestListener {
+        private List<TwoLevelListChanged> receivedNotifications = new ArrayList<>();
+        private CountDownLatch latch;
+
+        public TestNotifListener(CountDownLatch latch) {
+            this.latch = latch;
+        }
+
+        @Override
+        public void onTwoLevelListChanged(TwoLevelListChanged notification) {
+            receivedNotifications.add(notification);
+            latch.countDown();
+        }
+
+        public List<TwoLevelListChanged> getReceivedNotifications() {
+            return receivedNotifications;
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractNotificationBrokerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractNotificationBrokerTest.java
new file mode 100644 (file)
index 0000000..6030983
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.md.sal.binding.test;
+
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class AbstractNotificationBrokerTest extends AbstractSchemaAwareTest{
+    private BindingToNormalizedNodeCodec bindingToNormalizedNodeCodec;
+    private DOMNotificationRouter domNotificationRouter;
+    private NotificationService notificationService;
+    private NotificationPublishService notificationPublishService;
+
+
+    @Override
+    protected void setupWithSchema(final SchemaContext context) {
+        final DataBrokerTestCustomizer testCustomizer = createDataBrokerTestCustomizer();
+        domNotificationRouter = testCustomizer.getDomNotificationRouter();
+        notificationService = testCustomizer.createNotificationService();
+        notificationPublishService = testCustomizer.createNotificationPublishService();
+        bindingToNormalizedNodeCodec = testCustomizer.getBindingToNormalized();
+        testCustomizer.updateSchema(context);
+    }
+
+    protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() {
+        return new DataBrokerTestCustomizer();
+    }
+
+    public NotificationService getNotificationService() {
+        return notificationService;
+    }
+
+    public NotificationPublishService getNotificationPublishService() {
+        return notificationPublishService;
+    }
+
+    public DOMNotificationRouter getDomNotificationRouter() {
+        return domNotificationRouter;
+    }
+
+    public BindingToNormalizedNodeCodec getBindingToNormalizedNodeCodec() {
+        return bindingToNormalizedNodeCodec;
+    }
+}
index 78febb5..6d758aa 100644 (file)
@@ -19,13 +19,13 @@ public abstract class AbstractSchemaAwareTest  {
     private SchemaContext schemaContext;
 
 
-    protected Iterable<YangModuleInfo> getModuleInfos() {
+    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
         return BindingReflections.loadModuleInfos();
     }
 
 
     @Before
-    public final void setup() {
+    public final void setup() throws Exception {
         moduleInfos = getModuleInfos();
         ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
         moduleContext.addModuleInfos(moduleInfos);
index 38b36b3..bf0cd6b 100644 (file)
@@ -12,12 +12,18 @@ import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import javassist.ClassPool;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedNotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedNotificationService;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
 import org.opendaylight.controller.md.sal.dom.broker.impl.SerializedDOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
 import org.opendaylight.controller.sal.binding.test.util.MockSchemaService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
@@ -32,10 +38,11 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 public class DataBrokerTestCustomizer {
 
     private DOMDataBroker domDataBroker;
+    private DOMNotificationRouter domNotificationRouter;
     private final RuntimeGeneratedMappingServiceImpl mappingService;
     private final MockSchemaService schemaService;
     private ImmutableMap<LogicalDatastoreType, DOMStore> datastores;
-    private final BindingToNormalizedNodeCodec bindingToNormalized ;
+    private final BindingToNormalizedNodeCodec bindingToNormalized;
 
     public ImmutableMap<LogicalDatastoreType, DOMStore> createDatastores() {
         return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
@@ -53,6 +60,7 @@ public class DataBrokerTestCustomizer {
         GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
         bindingToNormalized = new BindingToNormalizedNodeCodec(loading, mappingService, codecRegistry);
         schemaService.registerSchemaContextListener(bindingToNormalized);
+        domNotificationRouter = DOMNotificationRouter.create(16);
     }
 
     public DOMStore createConfigurationDatastore() {
@@ -71,6 +79,16 @@ public class DataBrokerTestCustomizer {
         return new SerializedDOMDataBroker(getDatastores(), getCommitCoordinatorExecutor());
     }
 
+    public NotificationService createNotificationService() {
+        return new ForwardedNotificationService(bindingToNormalized.getCodecRegistry(), domNotificationRouter,
+                SingletonHolder.INVOKER_FACTORY);
+    }
+
+    public NotificationPublishService createNotificationPublishService() {
+        return new ForwardedNotificationPublishService(bindingToNormalized.getCodecRegistry(), domNotificationRouter);
+    }
+
+
     public ListeningExecutorService getCommitCoordinatorExecutor() {
         return MoreExecutors.sameThreadExecutor();
     }
@@ -106,4 +124,7 @@ public class DataBrokerTestCustomizer {
         mappingService.onGlobalContextUpdated(ctx);
     }
 
+    public DOMNotificationRouter getDomNotificationRouter() {
+        return domNotificationRouter;
+    }
 }
index 8636ff6..fcfd6fa 100644 (file)
@@ -4,10 +4,10 @@ module opendaylight-md-sal-binding {
     prefix "md-sal-binding";
 
     import config { prefix config; revision-date 2013-04-05; }
+
     description
         "Service definition for Binding Aware MD-SAL.";
+
     revision "2013-10-28" {
         description
             "Initial revision";
@@ -22,7 +22,7 @@ module opendaylight-md-sal-binding {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.sal.binding.api.data.DataProviderService";
     }
-    
+
     identity binding-async-data-broker {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.md.sal.binding.api.DataBroker";
@@ -48,4 +48,4 @@ module opendaylight-md-sal-binding {
         config:java-class "org.opendaylight.controller.sal.binding.api.NotificationService";
     }
 
-}
\ No newline at end of file
+}
index 8a845e8..dc2ced7 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.util.concurrent.TimeUnit;
 import javax.annotation.Nonnegative;
 import javax.annotation.Nonnull;
+import org.opendaylight.controller.sal.core.api.BrokerService;
 
 /**
  * A {@link DOMService} which allows its user to send {@link DOMNotification}s. It
@@ -23,7 +24,7 @@ import javax.annotation.Nonnull;
  *   the caller to specify that it should never wait, or put an upper bound on how
  *   long it is going to wait.
  */
-public interface DOMNotificationPublishService extends DOMService {
+public interface DOMNotificationPublishService extends DOMService, BrokerService {
     /**
      * Well-known value indicating that the implementation is currently not
      * able to accept a notification.
index 4b9f8ca..036ea24 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.md.sal.dom.api;
 
 import java.util.Collection;
 import javax.annotation.Nonnull;
+import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
@@ -16,7 +17,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
  * A {@link DOMService} which allows its users to subscribe to receive
  * {@link DOMNotification}s.
  */
-public interface DOMNotificationService {
+public interface DOMNotificationService extends DOMService, BrokerService {
     /**
      * Register a {@link DOMNotificationListener} to receive a set of notifications. As with
      * other ListenerRegistration-based interfaces, registering an instance multiple times
index b8861b3..4fd6403 100644 (file)
@@ -11,6 +11,9 @@ import com.google.common.collect.ClassToInstanceMap;
 import com.google.common.collect.MutableClassToInstanceMap;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
 import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker;
 import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
 import org.opendaylight.controller.sal.core.api.BrokerService;
@@ -51,6 +54,12 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
 
         final ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
 
+        // TODO: retrieve from config subsystem
+        int queueDepth = 1024;
+
+        final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(queueDepth);
+        services.putInstance(DOMNotificationService.class, domNotificationRouter);
+        services.putInstance(DOMNotificationPublishService.class, domNotificationRouter);
 
         final SchemaService schemaService = getSchemaServiceImpl();
         services.putInstance(SchemaService.class, schemaService);
index ebb923c..c0eb5d5 100644 (file)
@@ -8,18 +8,17 @@
 package org.opendaylight.controller.sal.dom.broker.osgi;
 
 import java.util.Arrays;
-
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.core.api.BrokerService;
-import org.osgi.framework.ServiceReference;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
-import org.opendaylight.controller.sal.core.api.notify.NotificationService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import org.opendaylight.controller.sal.core.api.notify.NotificationService;
+import org.osgi.framework.ServiceReference;
 
 @SuppressWarnings("unchecked")
 public class ProxyFactory {
@@ -101,8 +100,7 @@ public class ProxyFactory {
     private static Object _createProxyImpl(final ServiceReference<?> reference,
             final BrokerService service) {
 
-        throw new IllegalArgumentException("Not supported class: "
-                + service.getClass().getName());
+       return service;
     }
 
     private static Object createProxyImpl(final ServiceReference<?> ref,
index 48666e1..d4775af 100644 (file)
@@ -43,9 +43,13 @@ module opendaylight-mdsal-list-test {
         uses two-level-list;
     }
 
+    notification two-level-list-changed {
+        uses two-level-list;
+    }
+
     rpc put-top {
         input {
             uses two-level-list;
         }
     }
-}
\ No newline at end of file
+}

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.