Refactor NormalizedNodePayload 69/107869/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 14 Sep 2023 11:42:49 +0000 (13:42 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 14 Sep 2023 12:13:40 +0000 (14:13 +0200)
Turn this class into a record, with complete non-null semantics.

JIRA: NETCONF-773
Change-Id: I73e35fe4bd55f8382a86de0052839efc7b98be81
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/AbstractNormalizedNodeBodyWriter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/legacy/NormalizedNodePayload.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfDataServiceImpl.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfImpl.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfInvokeOperationsServiceImpl.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/XmlNormalizedNodeBodyWriterTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfDataServiceImplTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfImplTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfInvokeOperationsServiceImplTest.java

index 2107bf85314bac026cbc0cd3a76e427929e02576..f54d39b5f9f4ca02542f75a04fb1c3c2e4be1517 100644 (file)
@@ -36,11 +36,6 @@ abstract class AbstractNormalizedNodeBodyWriter implements MessageBodyWriter<Nor
     public final void writeTo(final NormalizedNodePayload context, final Class<?> type, final Type genericType,
             final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders,
             final OutputStream entityStream) throws IOException {
-        final var data = context.getData();
-        if (data == null) {
-            return;
-        }
-
         final var output = requireNonNull(entityStream);
         final var stack = context.inference().toSchemaInferenceStack();
         // FIXME: this dispatch is here to handle codec transition to 'output', but that should be completely okay with
@@ -49,13 +44,13 @@ abstract class AbstractNormalizedNodeBodyWriter implements MessageBodyWriter<Nor
             final var stmt = stack.currentStatement();
             if (stmt instanceof RpcEffectiveStatement rpc) {
                 stack.enterSchemaTree(rpc.output().argument());
-                writeOperationOutput(stack, context.getWriterParameters(), (ContainerNode) data, output);
+                writeOperationOutput(stack, context.writerParameters(), (ContainerNode) context.data(), output);
             } else if (stmt instanceof ActionEffectiveStatement action) {
                 stack.enterSchemaTree(action.output().argument());
-                writeOperationOutput(stack, context.getWriterParameters(), (ContainerNode) data, output);
+                writeOperationOutput(stack, context.writerParameters(), (ContainerNode) context.data(), output);
             }
         }
-        writeData(stack, context.getWriterParameters(), data, output);
+        writeData(stack, context.writerParameters(), context.data(), output);
     }
 
     abstract void writeOperationOutput(@NonNull SchemaInferenceStack stack, @NonNull QueryParameters writerParameters,
index aa241ddec25dca4ac68f91d19231cda3d425c4dc..272695ff8415a69e392a0f3dc467f5b600926231 100644 (file)
@@ -9,8 +9,7 @@ package org.opendaylight.restconf.nb.rfc8040.legacy;
 
 import static java.util.Objects.requireNonNull;
 
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
 
@@ -18,44 +17,15 @@ import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference
  * A RFC8040 overlay from our marriage to NormalizedNodeContext. This represents a NormalizedNode along with further
  * messy details needed to deal with the payload.
  */
-public final class NormalizedNodePayload {
-    private final @NonNull QueryParameters writerParameters;
-    private final @NonNull Inference inference;
-    private final NormalizedNode data;
-
-    private NormalizedNodePayload(final Inference inference, final NormalizedNode data,
-            final QueryParameters writerParameters) {
-        this.inference = requireNonNull(inference);
-        this.data = data;
-        this.writerParameters = requireNonNull(writerParameters);
-    }
-
-    public static @NonNull NormalizedNodePayload empty(final Inference inference) {
-        return new NormalizedNodePayload(inference, null, QueryParameters.empty());
-    }
-
-    public static @NonNull NormalizedNodePayload of(final Inference inference, final NormalizedNode data) {
-        return new NormalizedNodePayload(inference, requireNonNull(data), QueryParameters.empty());
-    }
-
-    public static @NonNull NormalizedNodePayload ofNullable(final Inference inference, final NormalizedNode data) {
-        return data == null ? empty(inference) : of(inference, data);
-    }
-
-    public static Object ofReadData(final Inference inference, final NormalizedNode data,
-            final QueryParameters parameters) {
-        return new NormalizedNodePayload(inference, requireNonNull(data), parameters);
-    }
-
-    public @NonNull Inference inference() {
-        return inference;
-    }
-
-    public @Nullable NormalizedNode getData() {
-        return data;
+@NonNullByDefault
+public record NormalizedNodePayload(Inference inference, NormalizedNode data, QueryParameters writerParameters) {
+    public NormalizedNodePayload {
+        requireNonNull(inference);
+        requireNonNull(data);
+        requireNonNull(writerParameters);
     }
 
-    public @NonNull QueryParameters getWriterParameters() {
-        return writerParameters;
+    public NormalizedNodePayload(final Inference inference, final NormalizedNode data) {
+        this(inference, data, QueryParameters.empty());
     }
 }
index 40cedda9248a9ae775183c5eaa172f50e318dcb8..bbc924fa796e109a29250be007f701e44bcb511f 100644 (file)
@@ -221,14 +221,14 @@ public final class RestconfDataServiceImpl {
             case ALL, CONFIG -> {
                 final QName type = node.name().getNodeType();
                 yield Response.status(Status.OK)
-                    .entity(NormalizedNodePayload.ofReadData(instanceIdentifier.inference(), node, queryParams))
+                    .entity(new NormalizedNodePayload(instanceIdentifier.inference(), node, queryParams))
                     .header("ETag", '"' + type.getModule().getRevision().map(Revision::toString).orElse(null) + "-"
                         + type.getLocalName() + '"')
                     .header("Last-Modified", FORMATTER.format(LocalDateTime.now(Clock.systemUTC())))
                     .build();
             }
             case NONCONFIG -> Response.status(Status.OK)
-                .entity(NormalizedNodePayload.ofReadData(instanceIdentifier.inference(), node, queryParams))
+                .entity(new NormalizedNodePayload(instanceIdentifier.inference(), node, queryParams))
                 .build();
         };
     }
@@ -823,7 +823,7 @@ public final class RestconfDataServiceImpl {
         if (resultData == null || resultData.isEmpty()) {
             return Response.status(Status.NO_CONTENT).build();
         }
-        return Response.status(Status.OK).entity(NormalizedNodePayload.of(inference, resultData)).build();
+        return Response.status(Status.OK).entity(new NormalizedNodePayload(inference, resultData)).build();
     }
 
     /**
index cc12a915ff20e7599a3bc39c0182dea96bf41a36..e8a5582c7bd531eddc8830fbe7c67c85fc2c847f 100644 (file)
@@ -60,7 +60,7 @@ public final class RestconfImpl {
         stack.enterDataTree(Restconf.QNAME);
         stack.enterDataTree(YANG_LIBRARY_VERSION);
 
-        return NormalizedNodePayload.of(stack.toInference(),
+        return new NormalizedNodePayload(stack.toInference(),
             ImmutableNodes.leafNode(YANG_LIBRARY_VERSION, YANG_LIBRARY_REVISION));
     }
 }
index 5e94ad25e9a6de4cba45e71cca97baeb0cf57b21..a13a628e81872f4719a67aa220b7743f6a9532df 100644 (file)
@@ -188,7 +188,7 @@ public final class RestconfInvokeOperationsServiceImpl {
                 if (resultData == null || resultData.isEmpty()) {
                     ar.resume(new WebApplicationException(Status.NO_CONTENT));
                 } else {
-                    ar.resume(NormalizedNodePayload.of(context.inference(), resultData));
+                    ar.resume(new NormalizedNodePayload(context.inference(), resultData));
                 }
             }
 
index c4162650bd869483b8a61e9775e447d99fd856a3..ce5643b3bd1bed50e62ec415235a3e48d3673566 100644 (file)
@@ -73,7 +73,7 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu
 
         return Response.ok()
             .location(location)
-            .entity(NormalizedNodePayload.of(
+            .entity(new NormalizedNodePayload(
                 Inference.ofDataTreePath(handlersHolder.getDatabindProvider().currentContext().modelContext(),
                     Notifi.QNAME, LOCATION_QNAME),
                 ImmutableNodes.leafNode(LOCATION_NODEID, location.toString())))
index c987d9351902d301184ee7315d7bb3b4a18621ce..0545672d4ecc6cbe6d3640024e5b1aefe0ef3b6e 100644 (file)
@@ -32,7 +32,7 @@ public class XmlNormalizedNodeBodyWriterTest extends AbstractInstanceIdentifierT
     public void testWriteEmptyRootContainer() throws IOException {
         final EffectiveModelContext schemaContext = mock(EffectiveModelContext.class);
 
-        final NormalizedNodePayload nodePayload = NormalizedNodePayload.of(Inference.ofDataTreePath(schemaContext),
+        final NormalizedNodePayload nodePayload = new NormalizedNodePayload(Inference.ofDataTreePath(schemaContext),
             Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(SchemaContext.NAME)).build());
 
         final ByteArrayOutputStream output = new ByteArrayOutputStream();
@@ -46,7 +46,7 @@ public class XmlNormalizedNodeBodyWriterTest extends AbstractInstanceIdentifierT
 
     @Test
     public void testRootContainerWrite() throws IOException {
-        final NormalizedNodePayload nodePayload = NormalizedNodePayload.of(
+        final NormalizedNodePayload nodePayload = new NormalizedNodePayload(
             Inference.ofDataTreePath(IID_SCHEMA),
             Builders.containerBuilder()
                 .withNodeIdentifier(new NodeIdentifier(SchemaContext.NAME))
index 690a2f4457e98d3ac53113be46939d9cd738122d..69e12d2ed4a7bd227827151f4374451c3b83dba9 100644 (file)
@@ -157,7 +157,7 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         final Response response = dataService.readData("example-jukebox:jukebox", uriInfo);
         assertNotNull(response);
         assertEquals(200, response.getStatus());
-        assertEquals(EMPTY_JUKEBOX, ((NormalizedNodePayload) response.getEntity()).getData());
+        assertEquals(EMPTY_JUKEBOX, ((NormalizedNodePayload) response.getEntity()).data());
     }
 
     @Test
@@ -173,7 +173,7 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         assertNotNull(response);
         assertEquals(200, response.getStatus());
 
-        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).getData();
+        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
         assertTrue(data instanceof ContainerNode);
         final Collection<DataContainerChild> rootNodes = ((ContainerNode) data).body();
         assertEquals(1, rootNodes.size());
@@ -207,7 +207,7 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         assertEquals(200, response.getStatus());
 
         // response must contain all child nodes from config and operational containers merged in one container
-        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).getData();
+        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
         assertTrue(data instanceof ContainerNode);
         assertEquals(3, ((ContainerNode) data).size());
         assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
@@ -251,7 +251,7 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         assertEquals(200, response.getStatus());
 
         // response must contain only config data
-        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).getData();
+        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
 
         // config data present
         assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
@@ -279,7 +279,7 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
         assertEquals(200, response.getStatus());
 
         // response must contain only operational data
-        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).getData();
+        final NormalizedNode data = ((NormalizedNodePayload) response.getEntity()).data();
 
         // state data present
         assertNotNull(((ContainerNode) data).childByArg(CONT_PLAYER.name()));
index ce0039fa622c1bfb1f21c02ec3e99493206c6907..1c12be80742194551bc7886ca6b9ac891ab2cfcb 100644 (file)
@@ -19,6 +19,6 @@ public class RestconfImplTest {
         final var context = YangParserTestUtils.parseYangResourceDirectory("/restconf/impl");
         final var restconfImpl = new RestconfImpl(() -> DatabindContext.ofModel(context));
         final var libraryVersion = restconfImpl.getLibraryVersion();
-        assertEquals("2019-01-04", libraryVersion.getData().body());
+        assertEquals("2019-01-04", libraryVersion.data().body());
     }
 }
index 6ab73b33d40904aa2363d4189ef787aa3c395b57..63a56a10c8e963b295bf7577d87d74032167371c 100644 (file)
@@ -106,7 +106,7 @@ public class RestconfInvokeOperationsServiceImplTest {
             """.getBytes(StandardCharsets.UTF_8)), mock(UriInfo.class), ar);
         verify(ar).resume(response.capture());
 
-        assertSame(result, response.getValue().getData());
+        assertSame(result, response.getValue().data());
     }
 
     @Test