From: Jakub Morvay Date: Tue, 6 Nov 2018 18:17:44 +0000 (+0100) Subject: Proxy controller services in DOMMountPointServiceImpl X-Git-Tag: release/neon~68 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=ddbc3eb6ae763f10d466bfdd1c33f0cb30665bc0 Proxy controller services in DOMMountPointServiceImpl When we are proxying a DOMMountPoint, we also need to take care of bridging legacy interfaces on top of MD-SAL interfaces. This patch refactors DOM{Notification,Rpc}Router to factor out DOM{Notification,Rpc}Service adapters and creates DOMActionService adapter. These are then used in DOMMountPointAdapter, which in turn is used by DOMMountPointServiceImpl. This deals with the case when an MD-SAL-registered mount point is accessed via Controller APIs. JIRA: CONTROLLER-1869 Change-Id: Ide4c636afdbd13e233880ab616aec52e46ea115f Signed-off-by: Jakub Morvay Signed-off-by: Robert Varga --- diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMNotificationRouter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMNotificationRouter.java index b5371fc289..c2cf65c469 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMNotificationRouter.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMNotificationRouter.java @@ -9,21 +9,16 @@ package org.opendaylight.controller.md.sal.dom.broker.impl; import com.google.common.util.concurrent.ListenableFuture; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.time.Instant; -import java.util.Arrays; import java.util.Collection; -import java.util.Date; import java.util.concurrent.TimeUnit; -import org.opendaylight.controller.md.sal.dom.api.DOMEvent; 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.DOMNotificationPublishService; import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService; import org.opendaylight.controller.md.sal.dom.spi.DOMNotificationSubscriptionListener; import org.opendaylight.controller.md.sal.dom.spi.DOMNotificationSubscriptionListenerRegistry; -import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; +import org.opendaylight.controller.sal.core.compat.LegacyDOMNotificationServiceAdapter; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; /** @@ -44,18 +39,17 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; * is realized by arming a background wakeup interrupt. */ @SuppressFBWarnings(value = "NP_NONNULL_PARAM_VIOLATION", justification = "Void is the only allowed value") -public final class DOMNotificationRouter implements AutoCloseable, DOMNotificationPublishService, - DOMNotificationService, DOMNotificationSubscriptionListenerRegistry { +public final class DOMNotificationRouter extends LegacyDOMNotificationServiceAdapter implements AutoCloseable, + DOMNotificationPublishService, DOMNotificationSubscriptionListenerRegistry { - private final org.opendaylight.mdsal.dom.api.DOMNotificationService delegateNotificationService; private final org.opendaylight.mdsal.dom.api.DOMNotificationPublishService delegateNotificationPublishService; private final org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListenerRegistry delegateListenerRegistry; private DOMNotificationRouter( - org.opendaylight.mdsal.dom.api.DOMNotificationService delegateNotificationService, - org.opendaylight.mdsal.dom.api.DOMNotificationPublishService delegateNotificationPublishService, - org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListenerRegistry delegateListenerRegistry) { - this.delegateNotificationService = delegateNotificationService; + final org.opendaylight.mdsal.dom.api.DOMNotificationService delegateNotificationService, + final org.opendaylight.mdsal.dom.api.DOMNotificationPublishService delegateNotificationPublishService, + final org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListenerRegistry delegateListenerRegistry) { + super(delegateNotificationService); this.delegateNotificationPublishService = delegateNotificationPublishService; this.delegateListenerRegistry = delegateListenerRegistry; } @@ -84,36 +78,7 @@ public final class DOMNotificationRouter implements AutoCloseable, DOMNotificati @Override public synchronized ListenerRegistration registerNotificationListener( final T listener, final Collection types) { - org.opendaylight.mdsal.dom.api.DOMNotificationListener delegateListener = notification -> { - if (notification instanceof DOMNotification) { - listener.onNotification((DOMNotification)notification); - return; - } - - if (notification instanceof org.opendaylight.mdsal.dom.api.DOMEvent) { - listener.onNotification(new DefaultDOMEvent(notification, - (org.opendaylight.mdsal.dom.api.DOMEvent)notification)); - return; - } - - listener.onNotification(new DefaultDOMNotification(notification)); - }; - - final ListenerRegistration reg = - delegateNotificationService.registerNotificationListener(delegateListener, types); - - return new AbstractListenerRegistration(listener) { - @Override - protected void removeRegistration() { - reg.close(); - } - }; - } - - @Override - public ListenerRegistration registerNotificationListener(final T listener, - final SchemaPath... types) { - return registerNotificationListener(listener, Arrays.asList(types)); + return super.registerNotificationListener(listener, types); } @Override @@ -141,40 +106,4 @@ public final class DOMNotificationRouter implements AutoCloseable, DOMNotificati @Override public void close() { } - - private static class DefaultDOMNotification implements DOMNotification { - private final SchemaPath schemaPath; - private final ContainerNode body; - - DefaultDOMNotification(org.opendaylight.mdsal.dom.api.DOMNotification from) { - this.schemaPath = from.getType(); - this.body = from.getBody(); - } - - @Override - public SchemaPath getType() { - return schemaPath; - } - - @Override - public ContainerNode getBody() { - return body; - } - } - - private static class DefaultDOMEvent extends DefaultDOMNotification implements DOMEvent { - private final Date eventTime; - - DefaultDOMEvent(org.opendaylight.mdsal.dom.api.DOMNotification fromNotification, - org.opendaylight.mdsal.dom.api.DOMEvent fromEvent) { - super(fromNotification); - final Instant eventInstant = fromEvent.getEventInstant(); - this.eventTime = eventInstant != null ? Date.from(eventInstant) : null; - } - - @Override - public Date getEventTime() { - return eventTime; - } - } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMRpcRouter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMRpcRouter.java index d78e9b9c7b..87ba273bbc 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMRpcRouter.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMRpcRouter.java @@ -11,7 +11,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.FluentFuture; -import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; @@ -28,6 +27,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; import org.opendaylight.controller.md.sal.dom.spi.AbstractDOMRpcImplementationRegistration; import org.opendaylight.controller.sal.core.compat.LegacyDOMRpcResultFutureAdapter; import org.opendaylight.controller.sal.core.compat.MdsalDOMRpcResultFutureAdapter; +import org.opendaylight.controller.sal.core.compat.RpcAvailabilityListenerAdapter; import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -77,7 +77,7 @@ public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcP new org.opendaylight.mdsal.dom.api.DOMRpcImplementation() { @Override public FluentFuture invokeRpc( - org.opendaylight.mdsal.dom.api.DOMRpcIdentifier rpc, NormalizedNode input) { + final org.opendaylight.mdsal.dom.api.DOMRpcIdentifier rpc, final NormalizedNode input) { return new MdsalDOMRpcResultFutureAdapter(implementation.invokeRpc(convert(rpc), input)); } @@ -103,19 +103,14 @@ public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcP }; } - private static org.opendaylight.mdsal.dom.api.DOMRpcIdentifier convert(DOMRpcIdentifier from) { + private static org.opendaylight.mdsal.dom.api.DOMRpcIdentifier convert(final DOMRpcIdentifier from) { return org.opendaylight.mdsal.dom.api.DOMRpcIdentifier.create(from.getType(), from.getContextReference()); } - private static DOMRpcIdentifier convert(org.opendaylight.mdsal.dom.api.DOMRpcIdentifier from) { + private static DOMRpcIdentifier convert(final org.opendaylight.mdsal.dom.api.DOMRpcIdentifier from) { return DOMRpcIdentifier.create(from.getType(), from.getContextReference()); } - private static Collection convert( - Collection from) { - return from.stream().map(DOMRpcRouter::convert).collect(Collectors.toList()); - } - @Override public CheckedFuture invokeRpc(final SchemaPath type, final NormalizedNode input) { @@ -129,17 +124,7 @@ public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcP public synchronized ListenerRegistration registerRpcListener( final T listener) { final ListenerRegistration reg = - delegateRpcService.registerRpcListener(new org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener() { - @Override - public void onRpcAvailable(Collection rpcs) { - listener.onRpcAvailable(convert(rpcs)); - } - - @Override - public void onRpcUnavailable(Collection rpcs) { - listener.onRpcUnavailable(convert(rpcs)); - } - + delegateRpcService.registerRpcListener(new RpcAvailabilityListenerAdapter(listener) { @Override public boolean acceptsImplementation(final org.opendaylight.mdsal.dom.api.DOMRpcImplementation impl) { // If the DOMRpcImplementation wasn't registered thru this interface then the mapping won't be @@ -147,7 +132,7 @@ public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcP // behavior. This should be fine since a legacy listener would not be aware of implementation types // registered via the new mdsal API. final DOMRpcImplementation legacyImpl = implMapping.get(impl); - return legacyImpl != null ? listener.acceptsImplementation(legacyImpl) : true; + return legacyImpl != null ? delegate().acceptsImplementation(legacyImpl) : true; } }); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java index bc46b6db3b..27a4a78b73 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java @@ -5,7 +5,6 @@ * 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.dom.broker.impl.mount; import com.google.common.annotations.VisibleForTesting; @@ -17,6 +16,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; import org.opendaylight.controller.md.sal.dom.api.DOMService; import org.opendaylight.controller.md.sal.dom.broker.spi.mount.SimpleDOMMountPoint; +import org.opendaylight.controller.sal.core.compat.DOMMountPointAdapter; import org.opendaylight.mdsal.dom.api.DOMMountPointListener; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.ObjectRegistration; @@ -24,7 +24,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaContext; public class DOMMountPointServiceImpl implements DOMMountPointService { - private final org.opendaylight.mdsal.dom.api.DOMMountPointService delegate; @VisibleForTesting @@ -38,45 +37,7 @@ public class DOMMountPointServiceImpl implements DOMMountPointService { @Override public Optional getMountPoint(final YangInstanceIdentifier path) { - return Optional.fromJavaUtil(delegate.getMountPoint(path).map(DOMMountPointServiceImpl::convert)); - } - - private static DOMMountPoint convert(final org.opendaylight.mdsal.dom.api.DOMMountPoint from) { - return new DOMMountPoint() { - @Override - public YangInstanceIdentifier getIdentifier() { - return from.getIdentifier(); - } - - @Override - public Optional getService(final Class cls) { - return Optional.fromJavaUtil(from.getService(cls)); - } - - @Override - public SchemaContext getSchemaContext() { - return from.getSchemaContext(); - } - - @Override - public int hashCode() { - return from.getIdentifier().hashCode(); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - - if (!(obj instanceof DOMMountPoint)) { - return false; - } - - DOMMountPoint other = (DOMMountPoint) obj; - return from.getIdentifier().equals(other.getIdentifier()); - } - }; + return Optional.fromJavaUtil(delegate.getMountPoint(path).map(DOMMountPointAdapter::new)); } @Override diff --git a/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/DOMMountPointAdapter.java b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/DOMMountPointAdapter.java new file mode 100644 index 0000000000..b78091422a --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/DOMMountPointAdapter.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2018 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.controller.sal.core.compat; + +import static java.util.Objects.requireNonNull; + +import com.google.common.base.Optional; +import com.google.common.collect.ForwardingObject; +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.controller.md.sal.dom.api.DOMActionService; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; +import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; +import org.opendaylight.controller.md.sal.dom.api.DOMService; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Adapter providing Controller DOMMountPoint implementation based on an MD-SAL DOMMountPoint delegate. Services are + * looked up in the delegate first. If a lookup is unsuccessful, this class attempts to transparently proxy well-known + * Controller DOMServices on top of their MD-SAL counterparts available from delegate. + */ +@Deprecated +public class DOMMountPointAdapter extends ForwardingObject implements DOMMountPoint { + private abstract static class CompatFactory { + private final Class mdsalClass; + + CompatFactory(final Class mdsalClass) { + this.mdsalClass = requireNonNull(mdsalClass); + } + + final @Nullable C createService(final org.opendaylight.mdsal.dom.api.DOMMountPoint mountPoint) { + return mountPoint.getService(mdsalClass).map(this::createService).orElse(null); + } + + abstract C createService(M delegate); + } + + private static final Map, CompatFactory> KNOWN_SERVICES = ImmutableMap.of( + DOMActionService.class, new CompatFactory( + org.opendaylight.mdsal.dom.api.DOMActionService.class) { + @Override + DOMActionService createService(final org.opendaylight.mdsal.dom.api.DOMActionService delegate) { + return new LegacyDOMActionServiceAdapter(delegate); + } + }, + DOMDataBroker.class, new CompatFactory( + org.opendaylight.mdsal.dom.api.DOMDataBroker.class) { + @Override + DOMDataBroker createService(final org.opendaylight.mdsal.dom.api.DOMDataBroker delegate) { + return new LegacyDOMDataBrokerAdapter(delegate); + } + }, + DOMNotificationService.class, new CompatFactory(org.opendaylight.mdsal.dom.api.DOMNotificationService.class) { + @Override + DOMNotificationService createService(final org.opendaylight.mdsal.dom.api.DOMNotificationService delegate) { + return new LegacyDOMNotificationServiceAdapter(delegate); + } + }, + DOMRpcService.class, new CompatFactory( + org.opendaylight.mdsal.dom.api.DOMRpcService.class) { + @Override + DOMRpcService createService(final org.opendaylight.mdsal.dom.api.DOMRpcService delegate) { + return new LegacyDOMRpcServiceAdapter(delegate); + } + }); + + private final org.opendaylight.mdsal.dom.api.DOMMountPoint delegate; + + public DOMMountPointAdapter(final org.opendaylight.mdsal.dom.api.DOMMountPoint delegate) { + this.delegate = requireNonNull(delegate); + } + + @Override + public YangInstanceIdentifier getIdentifier() { + return delegate().getIdentifier(); + } + + @Override + public Optional getService(final Class cls) { + final java.util.Optional found = delegate.getService(cls); + if (found.isPresent()) { + return Optional.of(found.get()); + } + + final CompatFactory compat = KNOWN_SERVICES.get(cls); + return Optional.fromNullable(cls.cast(compat == null ? null : compat.createService(delegate))); + } + + @Override + public SchemaContext getSchemaContext() { + return delegate().getSchemaContext(); + } + + @Override + public int hashCode() { + return getIdentifier().hashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof DOMMountPoint)) { + return false; + } + + DOMMountPoint other = (DOMMountPoint) obj; + return getIdentifier().equals(other.getIdentifier()); + } + + @Override + protected org.opendaylight.mdsal.dom.api.DOMMountPoint delegate() { + return delegate; + } +} diff --git a/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMActionServiceAdapter.java b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMActionServiceAdapter.java new file mode 100644 index 0000000000..8331bad7b6 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMActionServiceAdapter.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018 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.controller.sal.core.compat; + +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ClassToInstanceMap; +import com.google.common.collect.ForwardingObject; +import com.google.common.util.concurrent.FluentFuture; +import org.opendaylight.controller.md.sal.dom.api.DOMActionService; +import org.opendaylight.mdsal.dom.api.DOMActionResult; +import org.opendaylight.mdsal.dom.api.DOMActionServiceExtension; +import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; + +@Deprecated +public class LegacyDOMActionServiceAdapter extends ForwardingObject implements DOMActionService { + private final org.opendaylight.mdsal.dom.api.DOMActionService delegate; + + public LegacyDOMActionServiceAdapter(final org.opendaylight.mdsal.dom.api.DOMActionService delegate) { + this.delegate = requireNonNull(delegate); + } + + @Override + protected org.opendaylight.mdsal.dom.api.DOMActionService delegate() { + return delegate; + } + + @Override + public FluentFuture invokeAction(final SchemaPath type, final DOMDataTreeIdentifier path, + final ContainerNode input) { + return delegate.invokeAction(type, path, input); + } + + @Override + public ClassToInstanceMap getExtensions() { + return delegate.getExtensions(); + } +} diff --git a/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMNotificationServiceAdapter.java b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMNotificationServiceAdapter.java new file mode 100644 index 0000000000..293fcb33be --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMNotificationServiceAdapter.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018 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.controller.sal.core.compat; + +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ForwardingObject; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import org.opendaylight.controller.md.sal.dom.api.DOMEvent; +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.yangtools.concepts.AbstractListenerRegistration; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; + +@Deprecated +public class LegacyDOMNotificationServiceAdapter extends ForwardingObject implements DOMNotificationService { + private final org.opendaylight.mdsal.dom.api.DOMNotificationService delegate; + + public LegacyDOMNotificationServiceAdapter(final org.opendaylight.mdsal.dom.api.DOMNotificationService delegate) { + this.delegate = requireNonNull(delegate); + } + + @Override + public ListenerRegistration registerNotificationListener(final T listener, + final Collection types) { + final ListenerRegistration reg = + delegate().registerNotificationListener(notification -> { + if (notification instanceof DOMNotification) { + listener.onNotification((DOMNotification)notification); + return; + } + + if (notification instanceof org.opendaylight.mdsal.dom.api.DOMEvent) { + listener.onNotification(new DefaultDOMEvent(notification, + (org.opendaylight.mdsal.dom.api.DOMEvent)notification)); + return; + } + + listener.onNotification(new DefaultDOMNotification(notification)); + }, types); + + return new AbstractListenerRegistration(listener) { + @Override + protected void removeRegistration() { + reg.close(); + } + }; + } + + @Override + public ListenerRegistration registerNotificationListener(final T listener, + final SchemaPath... types) { + return registerNotificationListener(listener, Arrays.asList(types)); + } + + @Override + protected org.opendaylight.mdsal.dom.api.DOMNotificationService delegate() { + return delegate; + } + + private static class DefaultDOMNotification implements DOMNotification { + private final org.opendaylight.mdsal.dom.api.DOMNotification delegate; + + DefaultDOMNotification(final org.opendaylight.mdsal.dom.api.DOMNotification delegate) { + this.delegate = requireNonNull(delegate); + } + + @Override + public SchemaPath getType() { + return delegate.getType(); + } + + @Override + public ContainerNode getBody() { + return delegate.getBody(); + } + } + + private static class DefaultDOMEvent extends DefaultDOMNotification implements DOMEvent { + private final Date eventTime; + + DefaultDOMEvent(final org.opendaylight.mdsal.dom.api.DOMNotification fromNotification, + final org.opendaylight.mdsal.dom.api.DOMEvent fromEvent) { + super(fromNotification); + final Instant eventInstant = fromEvent.getEventInstant(); + this.eventTime = eventInstant != null ? Date.from(eventInstant) : null; + } + + @Override + public Date getEventTime() { + return eventTime; + } + } +} diff --git a/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMRpcServiceAdapter.java b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMRpcServiceAdapter.java new file mode 100644 index 0000000000..170d9c9175 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMRpcServiceAdapter.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018 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.controller.sal.core.compat; + +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ForwardingObject; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FluentFuture; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; +import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; + +@Deprecated +public class LegacyDOMRpcServiceAdapter extends ForwardingObject implements DOMRpcService { + private final org.opendaylight.mdsal.dom.api.DOMRpcService delegate; + + public LegacyDOMRpcServiceAdapter(final org.opendaylight.mdsal.dom.api.DOMRpcService delegate) { + this.delegate = requireNonNull(delegate); + } + + @Override + public CheckedFuture invokeRpc(final SchemaPath type, + final NormalizedNode input) { + final FluentFuture future = delegate().invokeRpc(type, input); + return future instanceof MdsalDOMRpcResultFutureAdapter ? ((MdsalDOMRpcResultFutureAdapter)future).delegate() + : new LegacyDOMRpcResultFutureAdapter(future); + } + + @Override + public ListenerRegistration registerRpcListener(final T listener) { + final ListenerRegistration reg = + delegate().registerRpcListener(new RpcAvailabilityListenerAdapter<>(listener)); + + return new AbstractListenerRegistration(listener) { + @Override + protected void removeRegistration() { + reg.close(); + } + }; + } + + @Override + protected org.opendaylight.mdsal.dom.api.DOMRpcService delegate() { + return delegate; + } +} diff --git a/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/RpcAvailabilityListenerAdapter.java b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/RpcAvailabilityListenerAdapter.java new file mode 100644 index 0000000000..d5d472a57b --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/RpcAvailabilityListenerAdapter.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018 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.controller.sal.core.compat; + +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ForwardingObject; +import java.util.Collection; +import java.util.stream.Collectors; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier; + +@Deprecated +public class RpcAvailabilityListenerAdapter extends ForwardingObject + implements org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener { + private final @NonNull T delegate; + + public RpcAvailabilityListenerAdapter(final T delegate) { + this.delegate = requireNonNull(delegate); + } + + @Override + public void onRpcAvailable(final Collection rpcs) { + delegate.onRpcAvailable(convert(rpcs)); + } + + @Override + public void onRpcUnavailable(final Collection rpcs) { + delegate.onRpcUnavailable(convert(rpcs)); + } + + @Override + protected T delegate() { + return delegate; + } + + private static @NonNull Collection convert( + final Collection from) { + return from.stream().map(RpcAvailabilityListenerAdapter::convert).collect(Collectors.toList()); + } + + private static @NonNull DOMRpcIdentifier convert(final org.opendaylight.mdsal.dom.api.DOMRpcIdentifier from) { + return DOMRpcIdentifier.create(from.getType(), from.getContextReference()); + } +} diff --git a/opendaylight/md-sal/sal-dom-compat/src/test/java/org/opendaylight/controller/sal/core/compat/DOMMountPointAdapterTest.java b/opendaylight/md-sal/sal-dom-compat/src/test/java/org/opendaylight/controller/sal/core/compat/DOMMountPointAdapterTest.java new file mode 100644 index 0000000000..4c57f1c84e --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/test/java/org/opendaylight/controller/sal/core/compat/DOMMountPointAdapterTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018 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.controller.sal.core.compat; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +import com.google.common.collect.ImmutableClassToInstanceMap; +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.opendaylight.controller.md.sal.dom.api.DOMActionService; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; +import org.opendaylight.mdsal.dom.api.DOMMountPoint; + +@Deprecated +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class DOMMountPointAdapterTest { + @Mock + private DOMMountPoint delegate; + + private DOMMountPointAdapter adapter; + + @Before + public void before() { + doReturn(Optional.empty()).when(delegate).getService(any()); + adapter = new DOMMountPointAdapter(delegate); + } + + @Test + public void testDOMActionService() { + assertFalse(adapter.getService(DOMActionService.class).isPresent()); + + org.opendaylight.mdsal.dom.api.DOMActionService mdsal = + mock(org.opendaylight.mdsal.dom.api.DOMActionService.class); + + doReturn(Optional.of(mdsal)).when(delegate).getService(org.opendaylight.mdsal.dom.api.DOMActionService.class); + assertTrue(adapter.getService(DOMActionService.class).isPresent()); + } + + @Test + public void testDOMDataBroker() { + assertFalse(adapter.getService(DOMDataBroker.class).isPresent()); + + org.opendaylight.mdsal.dom.api.DOMDataBroker mdsal = mock(org.opendaylight.mdsal.dom.api.DOMDataBroker.class); + doReturn(ImmutableClassToInstanceMap.of()).when(mdsal).getExtensions(); + + doReturn(Optional.of(mdsal)).when(delegate).getService(org.opendaylight.mdsal.dom.api.DOMDataBroker.class); + assertTrue(adapter.getService(DOMDataBroker.class).isPresent()); + } + + @Test + public void testDOMNotificationService() { + assertFalse(adapter.getService(DOMNotificationService.class).isPresent()); + + org.opendaylight.mdsal.dom.api.DOMNotificationService mdsal = + mock(org.opendaylight.mdsal.dom.api.DOMNotificationService.class); + + doReturn(Optional.of(mdsal)).when(delegate).getService( + org.opendaylight.mdsal.dom.api.DOMNotificationService.class); + assertTrue(adapter.getService(DOMNotificationService.class).isPresent()); + } + + @Test + public void testDOMRpcService() { + assertFalse(adapter.getService(DOMRpcService.class).isPresent()); + + org.opendaylight.mdsal.dom.api.DOMRpcService mdsal = mock(org.opendaylight.mdsal.dom.api.DOMRpcService.class); + + doReturn(Optional.of(mdsal)).when(delegate).getService(org.opendaylight.mdsal.dom.api.DOMRpcService.class); + assertTrue(adapter.getService(DOMRpcService.class).isPresent()); + } +}