Split out YangLibraryVersionResource 10/111310/4
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 7 Apr 2024 12:20:00 +0000 (14:20 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 8 Apr 2024 12:51:49 +0000 (14:51 +0200)
Juggle the implementation around, allowing us to capture failure early.

JIRA: NETCONF-773
Change-Id: Ib2a587f3a73698ca2b4da1f6775dc0bdf0436be3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
protocol/restconf-api/src/main/java/org/opendaylight/restconf/api/FormattableBody.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/MdsalRestconfStrategy.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/mdsal/MdsalRestconfServer.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/DefaultYangLibraryVersionResource.java [new file with mode: 0644]
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/FailedYangLibraryVersionResource.java [new file with mode: 0644]
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/YangLibraryVersionResource.java [new file with mode: 0644]

index 9d8e1f57657d51a266000ea6b4f7ecc1253bb1b3..ae277a23efcea042eb88631516e94eee70d92fd9 100644 (file)
@@ -53,7 +53,7 @@ public abstract class FormattableBody implements Immutable {
 
     @Override
     public final String toString() {
-        return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
+        return addToStringAttributes(MoreObjects.toStringHelper(this).omitNullValues()).toString();
     }
 
     protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
index e93f67f84630285ce5a103e50d001f0a39f8818f..313a9e9ac8adc07b29321283a0d14d26b74d5f50 100644 (file)
@@ -37,12 +37,15 @@ import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfFuture;
 import org.opendaylight.restconf.common.errors.SettableRestconfFuture;
 import org.opendaylight.restconf.nb.rfc8040.jersey.providers.ParameterAwareNormalizedNodeWriter;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
 import org.opendaylight.restconf.nb.rfc8040.legacy.WriterParameters;
 import org.opendaylight.restconf.server.api.DataGetParams;
 import org.opendaylight.restconf.server.api.DataGetResult;
 import org.opendaylight.restconf.server.api.DatabindContext;
 import org.opendaylight.restconf.server.api.DatabindPath.Data;
+import org.opendaylight.restconf.server.api.QueryParams;
 import org.opendaylight.restconf.server.spi.RpcImplementation;
+import org.opendaylight.restconf.server.spi.YangLibraryVersionResource;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
@@ -61,7 +64,8 @@ import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
  * @see DOMDataTreeReadWriteTransaction
  */
 public final class MdsalRestconfStrategy extends RestconfStrategy {
-    private final DOMDataBroker dataBroker;
+    private final @NonNull YangLibraryVersionResource yangLibraryVersion;
+    private final @NonNull DOMDataBroker dataBroker;
 
     public MdsalRestconfStrategy(final DatabindContext databind, final DOMDataBroker dataBroker,
             final ImmutableMap<QName, RpcImplementation> localRpcs, final @Nullable DOMRpcService rpcService,
@@ -69,6 +73,11 @@ public final class MdsalRestconfStrategy extends RestconfStrategy {
             final @Nullable DOMMountPointService mountPointService) {
         super(databind, localRpcs, rpcService, actionService, sourceProvider, mountPointService);
         this.dataBroker = requireNonNull(dataBroker);
+        yangLibraryVersion = YangLibraryVersionResource.of(databind);
+    }
+
+    public @NonNull RestconfFuture<NormalizedNodePayload> yangLibraryVersionGET(final QueryParams params) {
+        return yangLibraryVersion.httpGET(params);
     }
 
     @Override
@@ -302,8 +311,6 @@ public final class MdsalRestconfStrategy extends RestconfStrategy {
             level.add(qualifiedName);
             currentNode = currentMixin.childByQName(qualifiedName);
         }
-
         return currentNode;
     }
-
 }
index da7db1afd86bfd1d6aee9a8a3d56e8c2d499bc18..a7692c50bc9b552401ad3a372f89bad31947b968 100644 (file)
@@ -35,7 +35,6 @@ import org.opendaylight.restconf.api.query.PrettyPrintParam;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfFuture;
 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
-import org.opendaylight.restconf.nb.rfc8040.legacy.WriterParameters;
 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy.StrategyAndTail;
@@ -57,20 +56,16 @@ import org.opendaylight.restconf.server.api.ResourceBody;
 import org.opendaylight.restconf.server.api.RestconfServer;
 import org.opendaylight.restconf.server.spi.RestconfServerConfiguration;
 import org.opendaylight.restconf.server.spi.RpcImplementation;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.YangApi;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.restconf.Restconf;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.common.YangNames;
-import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.source.SourceRepresentation;
 import org.opendaylight.yangtools.yang.model.api.source.YangTextSource;
 import org.opendaylight.yangtools.yang.model.api.source.YinTextSource;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
@@ -85,7 +80,6 @@ import org.osgi.service.metatype.annotations.Designate;
 @Component(service = RestconfServer.class, configurationPid = "org.opendaylight.restconf.server")
 @Designate(ocd = RestconfServerConfiguration.class)
 public final class MdsalRestconfServer implements RestconfServer, AutoCloseable {
-    private static final QName YANG_LIBRARY_VERSION = QName.create(Restconf.QNAME, "yang-library-version").intern();
     private static final VarHandle LOCAL_STRATEGY;
 
     static {
@@ -389,18 +383,6 @@ public final class MdsalRestconfServer implements RestconfServer, AutoCloseable
 
     @Override
     public RestconfFuture<NormalizedNodePayload> yangLibraryVersionGET() {
-        final var stack = SchemaInferenceStack.of(localStrategy().modelContext());
-        try {
-            stack.enterYangData(YangApi.NAME);
-            stack.enterDataTree(Restconf.QNAME);
-            stack.enterDataTree(YANG_LIBRARY_VERSION);
-        } catch (IllegalArgumentException e) {
-            return RestconfFuture.failed(new RestconfDocumentedException("RESTCONF is not available"));
-        }
-        return RestconfFuture.of(new NormalizedNodePayload(stack.toInference(),
-            ImmutableNodes.leafNode(YANG_LIBRARY_VERSION,
-                stack.modelContext().findModuleStatements("ietf-yang-library").iterator().next().localQNameModule()
-                    .revisionUnion().unionString()),
-            WriterParameters.of(prettyPrint, null)));
+        return localStrategy().yangLibraryVersionGET(queryParams(QueryParameters.of()));
     }
 }
diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/DefaultYangLibraryVersionResource.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/DefaultYangLibraryVersionResource.java
new file mode 100644 (file)
index 0000000..00f4967
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.server.spi;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.restconf.common.errors.RestconfFuture;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
+import org.opendaylight.restconf.nb.rfc8040.legacy.WriterParameters;
+import org.opendaylight.restconf.server.api.QueryParams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.restconf.Restconf;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
+
+@NonNullByDefault
+record DefaultYangLibraryVersionResource(Inference leafInference, LeafNode<String> leaf)
+        implements YangLibraryVersionResource {
+    static final QName YANG_LIBRARY_VERSION = QName.create(Restconf.QNAME, "yang-library-version").intern();
+
+    DefaultYangLibraryVersionResource {
+        requireNonNull(leafInference);
+        requireNonNull(leaf);
+    }
+
+    @Override
+    public RestconfFuture<NormalizedNodePayload> httpGET(final QueryParams params) {
+        return RestconfFuture.of(new NormalizedNodePayload(leafInference, leaf,
+            WriterParameters.of(params.prettyPrint(), null)));
+    }
+}
\ No newline at end of file
diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/FailedYangLibraryVersionResource.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/FailedYangLibraryVersionResource.java
new file mode 100644 (file)
index 0000000..e8e0931
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.server.spi;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.common.errors.RestconfFuture;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
+import org.opendaylight.restconf.server.api.QueryParams;
+
+@NonNullByDefault
+record FailedYangLibraryVersionResource(RestconfDocumentedException cause) implements YangLibraryVersionResource {
+    FailedYangLibraryVersionResource {
+        requireNonNull(cause);
+    }
+
+    @Override
+    public RestconfFuture<NormalizedNodePayload> httpGET(final QueryParams params) {
+        return RestconfFuture.failed(cause);
+    }
+}
diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/YangLibraryVersionResource.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/spi/YangLibraryVersionResource.java
new file mode 100644 (file)
index 0000000..eeb5db2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.server.spi;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.common.errors.RestconfFuture;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
+import org.opendaylight.restconf.server.api.DatabindContext;
+import org.opendaylight.restconf.server.api.QueryParams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.YangApi;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.restconf.Restconf;
+import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
+
+/**
+ * RESTCONF {@code /yang-library-version} content for a {@code GET} operation as per
+ * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.3.3">RFC8040, section 3.3.3</a>.
+ */
+@NonNullByDefault
+public sealed interface YangLibraryVersionResource
+        permits DefaultYangLibraryVersionResource, FailedYangLibraryVersionResource {
+
+    RestconfFuture<NormalizedNodePayload> httpGET(QueryParams params);
+
+    static YangLibraryVersionResource of(final DatabindContext databind) {
+        final var modelContext = databind.modelContext();
+
+        final Inference leafInference;
+        try {
+            final var stack = SchemaInferenceStack.of(modelContext);
+            stack.enterYangData(YangApi.NAME);
+            stack.enterDataTree(Restconf.QNAME);
+            stack.enterDataTree(DefaultYangLibraryVersionResource.YANG_LIBRARY_VERSION);
+            leafInference = stack.toInference();
+        } catch (IllegalArgumentException e) {
+            return new FailedYangLibraryVersionResource(new RestconfDocumentedException(
+                "yang-library-version is not available", e));
+        }
+
+        final var it = modelContext.findModuleStatements("ietf-yang-library").iterator();
+        return it.hasNext()
+            ? new DefaultYangLibraryVersionResource(leafInference,
+                ImmutableNodes.leafNode(DefaultYangLibraryVersionResource.YANG_LIBRARY_VERSION,
+                    it.next().localQNameModule().revisionUnion().unionString()))
+            : new FailedYangLibraryVersionResource(new RestconfDocumentedException("No ietf-yang-library present"));
+    }
+}