<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>
--- /dev/null
+/*
+ * 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);
+ }
+
+}
--- /dev/null
+/*
+ * 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 {
+
+}
--- /dev/null
+/*
+ * 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);
+ }
+
+}
--- /dev/null
+/*
+ * 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 {
+
+}
--- /dev/null
+/*
+ * 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
+ }
+}
*/
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;
-
/**
*
*/
@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;
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;
return bindingToLegacy;
}
+ public BindingNormalizedNodeCodecRegistry getCodecRegistry() {
+ return codecRegistry;
+ }
+
@Override
public void close() {
// NOOP Intentionally
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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 {
+
+ }
+
+}
--- /dev/null
+/*
+ * 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 {
+
+ }
+}
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;
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;
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 {
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'";
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;
+ }
+ }
+ }
}
--- /dev/null
+/*
+ * 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;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
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);
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;
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()
GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
bindingToNormalized = new BindingToNormalizedNodeCodec(loading, mappingService, codecRegistry);
schemaService.registerSchemaContextListener(bindingToNormalized);
+ domNotificationRouter = DOMNotificationRouter.create(16);
}
public DOMStore createConfigurationDatastore() {
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();
}
mappingService.onGlobalContextUpdated(ctx);
}
+ public DOMNotificationRouter getDomNotificationRouter() {
+ return domNotificationRouter;
+ }
}
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";
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";
config:java-class "org.opendaylight.controller.sal.binding.api.NotificationService";
}
-}
\ No newline at end of file
+}
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
* 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.
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;
* 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
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;
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);
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 {
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,
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
+}