Binding v2 runtime - adapters - impl - notifications 34/59234/2
authorJakub Toth <jakub.toth@pantheon.tech>
Fri, 16 Jun 2017 10:54:20 +0000 (12:54 +0200)
committerMartin Ciglan <martin.ciglan@pantheon.tech>
Tue, 20 Jun 2017 13:57:06 +0000 (13:57 +0000)
Change-Id: Ibfff70b6f4e9c5e4c7c198c95fb41ac278301eca
Signed-off-by: Jakub Toth <jakub.toth@pantheon.tech>
(cherry picked from commit bb582aed99ca77913439628b1356b1b81877fd46)

binding2/mdsal-binding2-api/src/main/java/org/opendaylight/mdsal/binding/javav2/api/NotificationPublishService.java
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationListenerAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationPublishServiceAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationServiceAdapter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/NotificationListenerInvoker.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/spi/loader/BindingDOMAdapterLoader.java

index eb5d8c2c0926a4bd83ffca97cb4318f2c6b7754f..d6f7c0d808ec15ef4ee3efb51f1af8b10f2da51c 100644 (file)
@@ -12,10 +12,7 @@ import com.google.common.annotations.Beta;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.concurrent.TimeUnit;
-import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
-import org.opendaylight.mdsal.binding.javav2.spec.base.KeyedInstanceIdentifier;
 import org.opendaylight.mdsal.binding.javav2.spec.base.Notification;
-import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
 
 /**
  * A {@link NotificationService} which also allows its users to submit YANG-modeled notifications for delivery.
@@ -31,9 +28,6 @@ import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
  * - {@link #offerNotification(org.opendaylight.mdsal.binding.javav2.spec.base.Notification, int, TimeUnit)}, which may
  * block for specified time if resources are thin.
  *
- * <p>
- * Every method has two alternatives for YANG 1.1 notifications tied to container or list node.
- *
  *<p>
  * The actual delivery to listeners is asynchronous and implementation-specific.
  * Users of this interface should not make any assumptions as to whether the
@@ -41,35 +35,16 @@ import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
  */
 
 @Beta
-public interface NotificationPublishService {
+public interface NotificationPublishService extends BindingService {
 
     ListenableFuture<Object> REJECTED = Futures.immediateFailedFuture(
         new NotificationRejectedException("Rejected due to resource constraints."));
 
-    void putNotification(Notification notification) throws InterruptedException;
-
-    ListenableFuture<?> offerNotification(Notification notification);
-
-    ListenableFuture<?> offerNotification(Notification notification, int timeout, TimeUnit unit)
-        throws InterruptedException;
+    void putNotification(Notification<?> notification) throws InterruptedException;
 
+    ListenableFuture<?> offerNotification(Notification<?> notification);
 
-    <T extends TreeNode> void putContainerNotification(Notification notification, InstanceIdentifier<T> ii)
+    ListenableFuture<?> offerNotification(Notification<?> notification, int timeout, TimeUnit unit)
         throws InterruptedException;
 
-    <T extends TreeNode> ListenableFuture<?> offerContainerNotification(Notification notification,
-        InstanceIdentifier<T> ii);
-
-    <T extends TreeNode> ListenableFuture<?> offerContainerNotification(Notification notification, int timeout,
-        TimeUnit unit, InstanceIdentifier<T> ii) throws InterruptedException;
-
-
-    <T extends TreeNode, K> void putListNotification(Notification notification, KeyedInstanceIdentifier<T, K> kii)
-        throws InterruptedException;
-
-    <T extends TreeNode, K> ListenableFuture<?> offerListNotification(Notification notification,
-        KeyedInstanceIdentifier<T, K> kii);
-
-    <T extends TreeNode, K> ListenableFuture<?> offerListNotification(Notification notification, int timeout,
-        TimeUnit unit, KeyedInstanceIdentifier<T, K> kii) throws InterruptedException;
 }
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationListenerAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationListenerAdapter.java
new file mode 100644 (file)
index 0000000..b16c236
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.dom.adapter.impl.notification;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.api.serializer.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.serialized.LazySerializedDOMNotification;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Notification;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.NotificationListener;
+import org.opendaylight.mdsal.dom.api.DOMNotification;
+import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * Notification listener adapter.
+ */
+@Beta
+public class BindingDOMNotificationListenerAdapter implements DOMNotificationListener {
+
+    private final BindingNormalizedNodeSerializer codec;
+    private final NotificationListener delegate;
+    private final Map<SchemaPath, NotificationListenerInvoker> invokers;
+
+    public BindingDOMNotificationListenerAdapter(final BindingNormalizedNodeSerializer codec,
+            final NotificationListener delegate) {
+        this.codec = codec;
+        this.delegate = delegate;
+        this.invokers = createInvokerMapFor(delegate.getClass());
+    }
+
+    @Override
+    public void onNotification(@Nonnull final DOMNotification notification) {
+        final Notification<?> baNotification = deserialize(notification);
+        final QName notificationQName = notification.getType().getLastComponent();
+        getInvoker(notification.getType()).invokeNotification(delegate, notificationQName,
+                (Instantiable<?>) baNotification);
+    }
+
+    private Notification<?> deserialize(final DOMNotification notification) {
+        if (notification instanceof LazySerializedDOMNotification) {
+            return ((LazySerializedDOMNotification) notification).getBindingData();
+        }
+        return codec.fromNormalizedNodeNotification(notification.getType(), notification.getBody());
+    }
+
+    private NotificationListenerInvoker getInvoker(final SchemaPath type) {
+        return invokers.get(type);
+    }
+
+    /**
+     * Get supported notifications.
+     *
+     * @return supported notifications
+     */
+    public Set<SchemaPath> getSupportedNotifications() {
+        return invokers.keySet();
+    }
+
+    /**
+     * Create map of all notification listeners.
+     *
+     * @param implClz
+     *            - class type of {@link NotificationListener}
+     * @return map of notification listeners
+     */
+    private static Map<SchemaPath, NotificationListenerInvoker>
+            createInvokerMapFor(final Class<? extends NotificationListener> implClz) {
+        final Map<SchemaPath, NotificationListenerInvoker> builder = new HashMap<>();
+        for (final TypeToken<?> ifaceToken : TypeToken.of(implClz).getTypes().interfaces()) {
+            final Class<?> iface = ifaceToken.getRawType();
+            if (NotificationListener.class.isAssignableFrom(iface) && BindingReflections.isBindingClass(iface)) {
+                @SuppressWarnings("unchecked")
+                final Class<? extends NotificationListener> listenerType =
+                        (Class<? extends NotificationListener>) iface;
+                final NotificationListenerInvoker invoker = NotificationListenerInvoker.from(listenerType);
+                for (final SchemaPath path : getNotificationTypes(listenerType)) {
+                    builder.put(path, invoker);
+                }
+            }
+        }
+        return ImmutableMap.copyOf(builder);
+    }
+
+    private static Set<SchemaPath> getNotificationTypes(final Class<? extends NotificationListener> type) {
+        // TODO: Investigate possibility and performance impact if we cache this or expose
+        // it from NotificationListenerInvoker
+        final Set<SchemaPath> ret = new HashSet<>();
+        for (final Method method : type.getMethods()) {
+            if (BindingReflections.isNotificationCallback(method)) {
+                final Class<?> notification = method.getParameterTypes()[0];
+                final QName name = BindingReflections.findQName(notification);
+                ret.add(SchemaPath.create(true, name));
+            }
+        }
+        return ret;
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationPublishServiceAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationPublishServiceAdapter.java
new file mode 100644 (file)
index 0000000..19b760d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.dom.adapter.impl.notification;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.mdsal.binding.javav2.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.BindingDOMAdapterBuilder;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.BindingDOMAdapterBuilder.Factory;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.serialized.LazySerializedDOMNotification;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Notification;
+import org.opendaylight.mdsal.dom.api.DOMNotification;
+import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
+import org.opendaylight.mdsal.dom.api.DOMService;
+
+/**
+ * Adapter for notification publisher service.
+ */
+@Beta
+public class BindingDOMNotificationPublishServiceAdapter implements NotificationPublishService, AutoCloseable {
+
+    public static final Factory<NotificationPublishService> BUILDER_FACTORY = Builder::new;
+
+    private final BindingToNormalizedNodeCodec codecRegistry;
+    private final DOMNotificationPublishService domPublishService;
+
+    public BindingDOMNotificationPublishServiceAdapter(final BindingToNormalizedNodeCodec codec,
+            final DOMNotificationPublishService domPublishService) {
+        this.codecRegistry = codec;
+        this.domPublishService = domPublishService;
+    }
+
+    public BindingToNormalizedNodeCodec getCodecRegistry() {
+        return codecRegistry;
+    }
+
+    public DOMNotificationPublishService getDomPublishService() {
+        return domPublishService;
+    }
+
+    @Override
+    public void putNotification(final Notification<?> notification) throws InterruptedException {
+        domPublishService.putNotification(toDomNotification(notification));
+    }
+
+    @Override
+    public ListenableFuture<? extends Object> offerNotification(final Notification<?> notification) {
+        final ListenableFuture<?> offerResult = domPublishService.offerNotification(toDomNotification(notification));
+        return DOMNotificationPublishService.REJECTED.equals(offerResult) ? NotificationPublishService.REJECTED
+                : offerResult;
+    }
+
+    @Override
+    public ListenableFuture<? extends Object> offerNotification(final Notification<?> notification, final int timeout,
+            final TimeUnit unit) throws InterruptedException {
+        final ListenableFuture<?> offerResult =
+                domPublishService.offerNotification(toDomNotification(notification), timeout, unit);
+        return DOMNotificationPublishService.REJECTED.equals(offerResult) ? NotificationPublishService.REJECTED
+                : offerResult;
+    }
+
+    private DOMNotification toDomNotification(final Notification<?> notification) {
+        return LazySerializedDOMNotification.create(codecRegistry, notification);
+    }
+
+    @Override
+    public void close() throws Exception {
+        // NOOP
+    }
+
+    private static class Builder extends BindingDOMAdapterBuilder<NotificationPublishService> {
+
+        @Override
+        public Set<Class<? extends DOMService>> getRequiredDelegates() {
+            return ImmutableSet.of(DOMNotificationPublishService.class);
+        }
+
+        @Override
+        protected NotificationPublishService createInstance(final BindingToNormalizedNodeCodec codec,
+                final ClassToInstanceMap<DOMService> delegates) {
+            final DOMNotificationPublishService domPublish = delegates.getInstance(DOMNotificationPublishService.class);
+            return new BindingDOMNotificationPublishServiceAdapter(codec, domPublish);
+        }
+    }
+}
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationServiceAdapter.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/BindingDOMNotificationServiceAdapter.java
new file mode 100644 (file)
index 0000000..5a8c6a8
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.dom.adapter.impl.notification;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.opendaylight.mdsal.binding.javav2.api.NotificationService;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.BindingDOMAdapterBuilder;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.BindingDOMAdapterBuilder.Factory;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.api.serializer.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.NotificationListener;
+import org.opendaylight.mdsal.dom.api.DOMNotificationService;
+import org.opendaylight.mdsal.dom.api.DOMService;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+
+/**
+ * Notification service adapter.
+ */
+@Beta
+public class BindingDOMNotificationServiceAdapter implements NotificationService, AutoCloseable {
+
+    public static final Factory<NotificationService> BUILDER_FACTORY = Builder::new;
+
+    private final BindingNormalizedNodeSerializer codec;
+    private final DOMNotificationService domNotifService;
+
+    public BindingDOMNotificationServiceAdapter(final BindingNormalizedNodeSerializer codec,
+            final DOMNotificationService domNotifService) {
+        this.codec = codec;
+        this.domNotifService = domNotifService;
+    }
+
+    @Override
+    public <T extends NotificationListener> ListenerRegistration<T> registerNotificationListener(final T listener) {
+        final BindingDOMNotificationListenerAdapter domListener =
+                new BindingDOMNotificationListenerAdapter(codec, listener);
+        final ListenerRegistration<BindingDOMNotificationListenerAdapter> domRegistration =
+                domNotifService.registerNotificationListener(domListener, domListener.getSupportedNotifications());
+        return new ListenerRegistrationImpl<>(listener, domRegistration);
+    }
+
+    @Override
+    public void close() throws Exception {
+        // NOOP
+    }
+
+    private static class ListenerRegistrationImpl<T extends NotificationListener>
+            extends AbstractListenerRegistration<T> {
+        private final ListenerRegistration<?> listenerRegistration;
+
+        ListenerRegistrationImpl(final T listener, final ListenerRegistration<?> listenerRegistration) {
+            super(listener);
+            this.listenerRegistration = listenerRegistration;
+        }
+
+        @Override
+        protected void removeRegistration() {
+            listenerRegistration.close();
+        }
+    }
+
+    private static class Builder extends BindingDOMAdapterBuilder<NotificationService> {
+
+        @Override
+        protected NotificationService createInstance(final BindingToNormalizedNodeCodec codec,
+                final ClassToInstanceMap<DOMService> delegates) {
+            final DOMNotificationService domNotification = delegates.getInstance(DOMNotificationService.class);
+            return new BindingDOMNotificationServiceAdapter(codec.getCodecRegistry(), domNotification);
+        }
+
+        @Override
+        public Set<? extends Class<? extends DOMService>> getRequiredDelegates() {
+            return ImmutableSet.of(DOMNotificationService.class);
+        }
+    }
+
+    /**
+     * Get DOM notification service.
+     *
+     * @return DOM notification service
+     */
+    public DOMNotificationService getDomService() {
+        return domNotifService;
+    }
+}
+
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/NotificationListenerInvoker.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/notification/NotificationListenerInvoker.java
new file mode 100644 (file)
index 0000000..511660f
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.dom.adapter.impl.notification;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Method;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.NotificationListener;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ * Provides single method invocation of notification callbacks on supplied instance.
+ *
+ * <p>
+ * Notification Listener invoker provides common invocation interface for any subtype of
+ * {@link NotificationListener}. via {@link #invokeNotification(NotificationListener, QName, Instantiable)}
+ * method.
+ */
+@Beta
+public final class NotificationListenerInvoker {
+
+    private static final Lookup LOOKUP = MethodHandles.publicLookup();
+
+    private static final LoadingCache<Class<? extends NotificationListener>, NotificationListenerInvoker> INVOKERS =
+            CacheBuilder.newBuilder().weakKeys()
+                    .build(new CacheLoader<Class<? extends NotificationListener>, NotificationListenerInvoker>() {
+
+                        private NotificationListenerInvoker
+                                createInvoker(final Class<? extends NotificationListener> key) {
+                            return new NotificationListenerInvoker(createInvokerMap(key));
+                        }
+
+                        private Map<QName, MethodHandle>
+                                createInvokerMap(final Class<? extends NotificationListener> key) {
+                            final Builder<QName, MethodHandle> ret = ImmutableMap.builder();
+                            for (final Method method : key.getMethods()) {
+                                if (BindingReflections.isNotificationCallback(method)) {
+
+                                    final Class<?> notification = method.getParameterTypes()[0];
+                                    final QName name = BindingReflections.findQName(notification);
+                                    MethodHandle handle;
+                                    try {
+                                        handle = LOOKUP.unreflect(method).asType(MethodType.methodType(void.class,
+                                                NotificationListener.class, Instantiable.class));
+                                        ret.put(name, handle);
+                                    } catch (final IllegalAccessException e) {
+                                        throw new IllegalStateException("Can not access public method.", e);
+                                    }
+                                }
+
+                            }
+                            return ret.build();
+                        }
+
+                        @Override
+                        public NotificationListenerInvoker load(final Class<? extends NotificationListener> key)
+                                throws Exception {
+                            return createInvoker(key);
+                        }
+
+                    });
+
+    private final Map<QName, MethodHandle> methodInvokers;
+
+    public NotificationListenerInvoker(final Map<QName, MethodHandle> map) {
+        this.methodInvokers = map;
+    }
+
+    /**
+     * Creates Notification service invoker for specified type.
+     *
+     * @param type
+     *            - NotificationListener interface, which was generated from model.
+     * @return Cached instance of {@link NotificationListenerInvoker} for supplied notification type.
+     *
+     */
+    public static NotificationListenerInvoker from(final Class<? extends NotificationListener> type) {
+        Preconditions.checkArgument(type.isInterface());
+        Preconditions.checkArgument(BindingReflections.isBindingClass(type));
+        return INVOKERS.getUnchecked(type);
+    }
+
+    /**
+     * Invokes supplied Notification on provided implementation of NotificationListener.
+     *
+     * @param impl
+     *            - implementation on which notification callback should be invoked.
+     * @param notificationName
+     *            - name of notification to be invoked.
+     * @param input
+     *            - input data for notification.
+     *
+     */
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    public void invokeNotification(@Nonnull final NotificationListener impl, @Nonnull final QName notificationName,
+            @Nullable final Instantiable<?> input) {
+        Preconditions.checkNotNull(impl, "implementation must be supplied");
+        final MethodHandle invoker = methodInvokers.get(notificationName);
+        Preconditions.checkArgument(invoker != null, "Supplied notification is not valid for implementation %s", impl);
+        try {
+            invoker.invokeExact(impl, input);
+        } catch (final Throwable e) {
+            throw Throwables.propagate(e);
+        }
+    }
+}
+
index 2d686c2ef029e033c307759c226492861ad319a7..447f60eb6e1452619b29e27d15e5d24df192ed52 100644 (file)
@@ -14,7 +14,11 @@ import java.util.Map;
 import javax.annotation.Nonnull;
 import org.opendaylight.mdsal.binding.javav2.api.BindingService;
 import org.opendaylight.mdsal.binding.javav2.api.DataBroker;
+import org.opendaylight.mdsal.binding.javav2.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.javav2.api.NotificationService;
 import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.data.BindingDOMDataBrokerAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.notification.BindingDOMNotificationPublishServiceAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.notification.BindingDOMNotificationServiceAdapter;
 import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.AdapterBuilder;
 import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.BindingDOMAdapterBuilder;
 import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.BindingDOMAdapterBuilder.Factory;
@@ -32,6 +36,8 @@ public abstract class BindingDOMAdapterLoader extends AdapterLoader<BindingServi
     private static final Map<Class<?>, BindingDOMAdapterBuilder.Factory<?>> FACTORIES =
             ImmutableMap.<Class<?>, BindingDOMAdapterBuilder.Factory<?>> builder()
                     .put(DataBroker.class, BindingDOMDataBrokerAdapter.BUILDER_FACTORY)
+                    .put(NotificationPublishService.class, BindingDOMNotificationPublishServiceAdapter.BUILDER_FACTORY)
+                    .put(NotificationService.class, BindingDOMNotificationServiceAdapter.BUILDER_FACTORY)
                     .build();
 
     private final BindingToNormalizedNodeCodec codec;