From 2188563bd18dccb50bbbfa13235ca4955c7eb7dc Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 11 Apr 2019 22:10:16 +0200 Subject: [PATCH] Make LazySerializedDOMNotification a DOMEvent DOMEvent carries the information about when the event occurred, make sure we propagate it when available and backfill it on submission. It also retrofits some @NonNull annotations to make it clear we are not propagating nulls. JIRA: MDSAL-282 Change-Id: I2153b007af2accbad41f5aea00dbced21030a67d Signed-off-by: Robert Varga --- ...gDOMNotificationPublishServiceAdapter.java | 11 ++-- .../LazySerializedDOMNotification.java | 57 ++++++++++++------- .../LazySerializedDOMNotificationTest.java | 3 +- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationPublishServiceAdapter.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationPublishServiceAdapter.java index 1ac34bed3e..3ce2684d01 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationPublishServiceAdapter.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationPublishServiceAdapter.java @@ -10,13 +10,16 @@ package org.opendaylight.mdsal.binding.dom.adapter; import com.google.common.collect.ClassToInstanceMap; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListenableFuture; +import java.time.Instant; import java.util.Set; import java.util.concurrent.TimeUnit; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.api.NotificationPublishService; import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMAdapterBuilder.Factory; import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService; import org.opendaylight.mdsal.dom.api.DOMService; +import org.opendaylight.yangtools.yang.binding.EventInstantAware; import org.opendaylight.yangtools.yang.binding.Notification; public class BindingDOMNotificationPublishServiceAdapter extends AbstractBindingAdapter @@ -66,12 +69,13 @@ public class BindingDOMNotificationPublishServiceAdapter extends AbstractBinding : offerResult; } - private DOMNotification toDomNotification(final Notification notification) { - return LazySerializedDOMNotification.create(getCodec(), notification); + private @NonNull DOMNotification toDomNotification(final Notification notification) { + final Instant instant = notification instanceof EventInstantAware + ? ((EventInstantAware) notification).eventInstant() : Instant.now(); + return LazySerializedDOMNotification.create(getCodec(), notification, instant); } protected static class Builder extends BindingDOMAdapterBuilder { - @Override public Set> getRequiredDelegates() { return ImmutableSet.of(DOMNotificationPublishService.class); @@ -83,6 +87,5 @@ public class BindingDOMNotificationPublishServiceAdapter extends AbstractBinding final DOMNotificationPublishService domPublish = delegates.getInstance(DOMNotificationPublishService.class); return new BindingDOMNotificationPublishServiceAdapter(codec, domPublish); } - } } diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazySerializedDOMNotification.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazySerializedDOMNotification.java index 6fd7f13ede..f117ca0d03 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazySerializedDOMNotification.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazySerializedDOMNotification.java @@ -7,8 +7,13 @@ */ package org.opendaylight.mdsal.binding.dom.adapter; +import static java.util.Objects.requireNonNull; + +import java.time.Instant; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; +import org.opendaylight.mdsal.dom.api.DOMEvent; import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; @@ -18,28 +23,32 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; * Lazy serialized implementation of DOM Notification. * *

- * This implementation performs serialization of data, only if receiver - * of notification actually accessed data from notification. - * + * This implementation performs serialization of data, only if receiver of notification actually accessed data from + * notification. */ -public final class LazySerializedDOMNotification implements DOMNotification { - - private final BindingNormalizedNodeSerializer codec; - private final Notification data; - private final SchemaPath type; +public final class LazySerializedDOMNotification implements DOMNotification, DOMEvent { + private final @NonNull BindingNormalizedNodeSerializer codec; + private final @NonNull Notification data; + private final @NonNull SchemaPath type; + private final @NonNull Instant eventInstant; - private ContainerNode domBody; + private volatile ContainerNode domBody; - private LazySerializedDOMNotification(final BindingNormalizedNodeSerializer codec, - final Notification data, final SchemaPath type) { - this.codec = codec; - this.data = data; - this.type = type; + LazySerializedDOMNotification(final BindingNormalizedNodeSerializer codec, final Notification data, + final SchemaPath type, final Instant eventInstant) { + this.codec = requireNonNull(codec); + this.data = requireNonNull(data); + this.type = requireNonNull(type); + this.eventInstant = requireNonNull(eventInstant); } - static DOMNotification create(final BindingNormalizedNodeSerializer codec, final Notification data) { - final SchemaPath type = SchemaPath.create(true, BindingReflections.findQName(data.implementedInterface())); - return new LazySerializedDOMNotification(codec, data, type); + static @NonNull DOMNotification create(final BindingNormalizedNodeSerializer codec, final Notification data, + final Instant eventInstant) { + // TODO: for nested (YANG 1.1) notifications we will need the SchemaPath where the notification is being invoked + // and use that instead of ROOT. How Binding users will refer to it is TBD (but probably + // InstanceIdentifier, which means we will need to do some lifting to find the SchemaPath) + final SchemaPath type = SchemaPath.ROOT.createChild(BindingReflections.findQName(data.implementedInterface())); + return new LazySerializedDOMNotification(codec, data, type, eventInstant); } @Override @@ -49,13 +58,19 @@ public final class LazySerializedDOMNotification implements DOMNotification { @Override public ContainerNode getBody() { - if (domBody == null) { - domBody = codec.toNormalizedNodeNotification(data); + ContainerNode local = domBody; + if (local == null) { + domBody = local = codec.toNormalizedNodeNotification(data); } - return domBody; + return local; + } + + @Override + public Instant getEventInstant() { + return eventInstant; } - public Notification getBindingData() { + public @NonNull Notification getBindingData() { return data; } } diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/LazySerializedDOMNotificationTest.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/LazySerializedDOMNotificationTest.java index 0891c5d085..951f286dd7 100644 --- a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/LazySerializedDOMNotificationTest.java +++ b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/LazySerializedDOMNotificationTest.java @@ -12,6 +12,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import java.time.Instant; import org.junit.Test; import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; import org.opendaylight.mdsal.dom.api.DOMNotification; @@ -24,7 +25,7 @@ public class LazySerializedDOMNotificationTest { public void basicTest() throws Exception { BindingNormalizedNodeSerializer codec = mock(BindingNormalizedNodeSerializer.class); final DOMNotification lazySerializedDOMNotification = - LazySerializedDOMNotification.create(codec, new TwoLevelListChangedBuilder().build()); + LazySerializedDOMNotification.create(codec, new TwoLevelListChangedBuilder().build(), Instant.now()); ContainerNode containerNode = mock(ContainerNode.class); doReturn(containerNode).when(codec).toNormalizedNodeNotification(any()); assertEquals(containerNode, lazySerializedDOMNotification.getBody()); -- 2.36.6