Propagate eventTime during notification transformation 83/105683/3
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 25 Apr 2023 21:13:16 +0000 (23:13 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 25 Apr 2023 21:38:02 +0000 (23:38 +0200)
Binding Notification objects expose the time when the event was
generated through an optional EventInstantAware interface. Recognize
when a Notification carries this annotation and propagate it correctly.

JIRA: NETCONF-1001
Change-Id: I06ce94ffbe11bafeedb60aaa28765e151de53b3f
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/netconf/mdsal/notification/impl/NotificationsTransformUtil.java
netconf/mdsal-netconf-notification/src/test/java/org/opendaylight/netconf/mdsal/notification/impl/NotificationsTransformUtilTest.java

index 3ec802835bec0640d1dedfd371de944768c0ba55..26eac2aa909da322ab88a65da9d3f2a9946f0908 100644 (file)
@@ -11,12 +11,12 @@ import static com.google.common.base.Verify.verify;
 
 import java.io.IOException;
 import java.util.Date;
-import java.util.Optional;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.dom.DOMResult;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecFactory;
-import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeGenerator;
 import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
 import org.opendaylight.netconf.api.messages.NotificationMessage;
@@ -26,8 +26,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfConfigChange;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibraryChange;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibraryUpdate;
+import org.opendaylight.yangtools.yang.binding.EventInstantAware;
 import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
@@ -40,7 +40,7 @@ public final class NotificationsTransformUtil {
 
     public NotificationsTransformUtil(final YangParserFactory parserFactory, final BindingRuntimeGenerator generator,
             final BindingDOMCodecFactory codecFactory) throws YangParserException {
-        final BindingRuntimeContext ctx = BindingRuntimeHelpers.createRuntimeContext(parserFactory, generator,
+        final var ctx = BindingRuntimeHelpers.createRuntimeContext(parserFactory, generator,
             Netconf.class, NetconfConfigChange.class, YangLibraryChange.class, YangLibraryUpdate.class);
         schemaContext = ctx.getEffectiveModelContext();
         verify(schemaContext.getOperations().stream()
@@ -53,26 +53,22 @@ public final class NotificationsTransformUtil {
     /**
      * Transform base notification for capabilities into NetconfNotification.
      */
-    public NotificationMessage transform(final Notification<?> notification, final Absolute path) {
-        return transform(notification, Optional.empty(), path);
+    public @NonNull NotificationMessage transform(final Notification<?> notification, final Absolute path) {
+        return transform(notification,
+            notification instanceof EventInstantAware aware ? Date.from(aware.eventInstant()) : null, path);
     }
 
-    public NotificationMessage transform(final Notification<?> notification, final Date eventTime,
+    public @NonNull NotificationMessage transform(final Notification<?> notification, final @Nullable Date eventTime,
             final Absolute path) {
-        return transform(notification, Optional.ofNullable(eventTime), path);
-    }
-
-    private NotificationMessage transform(final Notification<?> notification, final Optional<Date> eventTime,
-            final Absolute path) {
-        final ContainerNode containerNode = serializer.toNormalizedNodeNotification(notification);
-        final DOMResult result = new DOMResult(XmlUtil.newDocument());
+        final var containerNode = serializer.toNormalizedNodeNotification(notification);
+        final var result = new DOMResult(XmlUtil.newDocument());
         try {
             NetconfUtil.writeNormalizedNode(containerNode, result, schemaContext, path);
         } catch (final XMLStreamException | IOException e) {
             throw new IllegalStateException("Unable to serialize " + notification, e);
         }
-        final Document node = (Document) result.getNode();
-        return eventTime.isPresent() ? new NotificationMessage(node, eventTime.orElseThrow())
-            : new NotificationMessage(node);
+
+        final var node = (Document) result.getNode();
+        return eventTime != null ? new NotificationMessage(node, eventTime) : new NotificationMessage(node);
     }
 }
index 94f57766580efced1c1631ccba46e0228a9f17bc..ff26ea584d856d0fa5f9637a4eb2361441fd60ea 100644 (file)
@@ -8,8 +8,10 @@
 package org.opendaylight.netconf.mdsal.notification.impl;
 
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.withSettings;
 
-import java.io.IOException;
 import java.util.Date;
 import java.util.Set;
 import org.custommonkey.xmlunit.DetailedDiff;
@@ -18,17 +20,17 @@ import org.custommonkey.xmlunit.XMLUnit;
 import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.mockito.Answers;
 import org.opendaylight.mdsal.binding.dom.codec.impl.di.DefaultBindingDOMCodecFactory;
 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
 import org.opendaylight.netconf.api.messages.NotificationMessage;
 import org.opendaylight.netconf.api.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
+import org.opendaylight.yangtools.yang.binding.EventInstantAware;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
-import org.xml.sax.SAXException;
 
 public class NotificationsTransformUtilTest {
     private static final Date DATE = new Date();
@@ -57,34 +59,30 @@ public class NotificationsTransformUtilTest {
 
     @Test
     public void testTransform() throws Exception {
-        final NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder();
+        final var capabilityChange = mock(NetconfCapabilityChange.class,
+            withSettings().extraInterfaces(EventInstantAware.class).defaultAnswer(Answers.CALLS_REAL_METHODS));
+        doReturn(Set.of(new Uri("uri1"))).when(capabilityChange).getAddedCapability();
+        doReturn(Set.of(new Uri("uri4"), new Uri("uri3"))).when(capabilityChange).getDeletedCapability();
+        doReturn(DATE.toInstant()).when((EventInstantAware) capabilityChange).eventInstant();
 
-        netconfCapabilityChangeBuilder.setAddedCapability(Set.of(new Uri("uri1")));
-        netconfCapabilityChangeBuilder.setDeletedCapability(Set.of(new Uri("uri4"), new Uri("uri3")));
+        final var notification = UTIL.transform(capabilityChange, Absolute.of(NetconfCapabilityChange.QNAME));
 
-        final NetconfCapabilityChange capabilityChange = netconfCapabilityChangeBuilder.build();
-        final NotificationMessage transform = UTIL.transform(capabilityChange, DATE,
-            Absolute.of(NetconfCapabilityChange.QNAME));
+        compareXml(EXPECTED_NOTIFICATION, XmlUtil.toString(notification.getDocument()));
+    }
 
-        final String serialized = XmlUtil.toString(transform.getDocument());
+    @Test
+    public void testTransformFromDOM() throws Exception {
+        final var notification = new NotificationMessage(XmlUtil.readXmlToDocument(INNER_NOTIFICATION), DATE);
 
-        compareXml(EXPECTED_NOTIFICATION, serialized);
+        XMLUnit.setIgnoreWhitespace(true);
+        compareXml(EXPECTED_NOTIFICATION, notification.toString());
     }
 
-    static void compareXml(final String expected, final String actual) throws SAXException, IOException {
+    private static void compareXml(final String expected, final String actual) throws Exception {
         XMLUnit.setIgnoreWhitespace(true);
-        final Diff diff = new Diff(expected, actual);
-        final DetailedDiff detailedDiff = new DetailedDiff(diff);
+        final var diff = new Diff(expected, actual);
+        final var detailedDiff = new DetailedDiff(diff);
         detailedDiff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
         assertTrue(detailedDiff.toString(), detailedDiff.similar());
     }
-
-    @Test
-    public void testTransformFromDOM() throws Exception {
-        final NotificationMessage netconfNotification =
-                new NotificationMessage(XmlUtil.readXmlToDocument(INNER_NOTIFICATION), DATE);
-
-        XMLUnit.setIgnoreWhitespace(true);
-        compareXml(EXPECTED_NOTIFICATION, netconfNotification.toString());
-    }
 }