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 <robert.varga@pantheon.tech>
import com.google.common.collect.ClassToInstanceMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListenableFuture;
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 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.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<DOMNotificationPublishService>
import org.opendaylight.yangtools.yang.binding.Notification;
public class BindingDOMNotificationPublishServiceAdapter extends AbstractBindingAdapter<DOMNotificationPublishService>
- 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<NotificationPublishService> {
}
protected static class Builder extends BindingDOMAdapterBuilder<NotificationPublishService> {
@Override
public Set<Class<? extends DOMService>> getRequiredDelegates() {
return ImmutableSet.of(DOMNotificationPublishService.class);
@Override
public Set<Class<? extends DOMService>> getRequiredDelegates() {
return ImmutableSet.of(DOMNotificationPublishService.class);
final DOMNotificationPublishService domPublish = delegates.getInstance(DOMNotificationPublishService.class);
return new BindingDOMNotificationPublishServiceAdapter(codec, domPublish);
}
final DOMNotificationPublishService domPublish = delegates.getInstance(DOMNotificationPublishService.class);
return new BindingDOMNotificationPublishServiceAdapter(codec, domPublish);
}
*/
package org.opendaylight.mdsal.binding.dom.adapter;
*/
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.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;
import org.opendaylight.mdsal.dom.api.DOMNotification;
import org.opendaylight.yangtools.yang.binding.Notification;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
* Lazy serialized implementation of DOM Notification.
*
* <p>
* Lazy serialized implementation of DOM Notification.
*
* <p>
- * 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
public ContainerNode getBody() {
@Override
public ContainerNode getBody() {
- if (domBody == null) {
- domBody = codec.toNormalizedNodeNotification(data);
+ ContainerNode local = domBody;
+ if (local == null) {
+ domBody = local = codec.toNormalizedNodeNotification(data);
+ return local;
+ }
+
+ @Override
+ public Instant getEventInstant() {
+ return eventInstant;
- public Notification getBindingData() {
+ public @NonNull Notification getBindingData() {
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
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;
import org.junit.Test;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
import org.opendaylight.mdsal.dom.api.DOMNotification;
public void basicTest() throws Exception {
BindingNormalizedNodeSerializer codec = mock(BindingNormalizedNodeSerializer.class);
final DOMNotification lazySerializedDOMNotification =
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());
ContainerNode containerNode = mock(ContainerNode.class);
doReturn(containerNode).when(codec).toNormalizedNodeNotification(any());
assertEquals(containerNode, lazySerializedDOMNotification.getBody());