Separate out notification handling 31/99831/4
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 21 Feb 2022 13:34:38 +0000 (14:34 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 22 Feb 2022 14:29:04 +0000 (15:29 +0100)
This reverts another part of 7a17eba49deb73733bdbb9579d2edd672bb0d71e
as well as 576ae2cd595f0ce17abd1f33150b068b7f0f801d, hence not allowing
Notifications to be entered through streamChild().

JIRA: MDSAL-724
Change-Id: I1b37139fcb8bd8aaf92465943a46e71069e87f3e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/SchemaRootCodecContext.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/Mdsal724Test.java
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/AbstractBindingRuntimeContext.java

index be48e153fd1820893683c14fca66ded6817fe4c0..bfa286ac54267f1aea8728fc8883c6a4c1636043 100644 (file)
@@ -61,13 +61,6 @@ final class SchemaRootCodecContext<D extends DataObject> extends DataContainerCo
         CacheBuilder.newBuilder().build(new CacheLoader<>() {
             @Override
             public DataContainerCodecContext<?, ?> load(final Class<? extends DataObject> key) {
-                if (Notification.class.isAssignableFrom(key)) {
-                    checkArgument(key.isInterface(), "Supplied class must be interface.");
-                    final QName qname = BindingReflections.findQName(key);
-                    final NotificationDefinition schema = getSchema().findNotification(qname).orElseThrow(
-                        () -> new IllegalArgumentException("Supplied " + key + " is not valid notification"));
-                    return new NotificationCodecContext<>(key, schema, factory());
-                }
                 return createDataTreeChildContext(key);
             }
         });
@@ -88,6 +81,18 @@ final class SchemaRootCodecContext<D extends DataObject> extends DataContainerCo
             }
         });
 
+    private final LoadingCache<Class<?>, NotificationCodecContext<?>> notificationsByClass = CacheBuilder.newBuilder()
+        .build(new CacheLoader<Class<?>, NotificationCodecContext<?>>() {
+            @Override
+            public NotificationCodecContext<?> load(final Class<?> key) {
+                checkArgument(key.isInterface(), "Supplied class must be interface.");
+                final QName qname = BindingReflections.findQName(key);
+                final NotificationDefinition schema = getSchema().findNotification(qname).orElseThrow(
+                    () -> new IllegalArgumentException("Supplied " + key + " is not valid notification"));
+                return new NotificationCodecContext<>(key, schema, factory());
+            }
+        });
+
     private final LoadingCache<Class<?>, ContainerNodeCodecContext<?>> rpcDataByClass = CacheBuilder.newBuilder()
         .build(new CacheLoader<Class<?>, ContainerNodeCodecContext<?>>() {
             @Override
@@ -205,7 +210,7 @@ final class SchemaRootCodecContext<D extends DataObject> extends DataContainerCo
     }
 
     NotificationCodecContext<?> getNotification(final Class<? extends Notification<?>> notification) {
-        return (NotificationCodecContext<?>) streamChild((Class<? extends DataObject>)notification);
+        return getOrRethrow(notificationsByClass, notification);
     }
 
     NotificationCodecContext<?> getNotification(final Absolute notification) {
index 0da0bed50fe6660ddcbd132aa851c8fd6ec31323..33da2fe7ece7e8635add12a28e7d993fe986e086 100644 (file)
@@ -7,15 +7,28 @@
  */
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThrows;
 
 import org.junit.Test;
 import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.notification.rev150205.OutOfPixieDustNotification;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockInput;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class Mdsal724Test extends AbstractBindingCodecTest {
+    @Test
+    public void testNotificationInstanceIdentifier() {
+        // An InstanceIdentifier pointing at a notification, unsafe to create
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        final var iid = InstanceIdentifier.create((Class) OutOfPixieDustNotification.class);
+
+        final var ex = assertThrows(IllegalArgumentException.class, () -> codecContext.toYangInstanceIdentifier(iid));
+        assertThat(ex.getMessage(), startsWith("Supplied class must not be a notification ("));
+    }
+
     @Test
     public void testRpcInputInstanceIdentifier() {
         // An InstanceIdentifier pointing at a notification, unsafe to create
index 3b0d074c373d0fb268d0275f4169bf5c91a739a9..f7587ee913330b56327c010e913263794cc779ba 100644 (file)
@@ -34,6 +34,7 @@ import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder;
 import org.opendaylight.yangtools.yang.binding.Action;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.Notification;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
@@ -87,6 +88,8 @@ public abstract class AbstractBindingRuntimeContext implements BindingRuntimeCon
         checkArgument(!Augmentation.class.isAssignableFrom(cls), "Supplied class must not be an augmentation (%s is)",
             cls);
         checkArgument(!Action.class.isAssignableFrom(cls), "Supplied class must not be an action (%s is)", cls);
+        checkArgument(!Notification.class.isAssignableFrom(cls), "Supplied class must not be a notification (%s is)",
+            cls);
         return (DataSchemaNode) getTypes().findSchema(Type.of(cls)).orElse(null);
     }