Cross-relate WithDefaultsParam 27/107827/8
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 12 Sep 2023 02:52:07 +0000 (04:52 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 12 Sep 2023 10:00:38 +0000 (12:00 +0200)
RFC6243 defines with-defaults-mode typedef, tie it together with
WithDefaultsParam. This improves interoperability with NETCONF.

JIRA: NETCONF-1107
Change-Id: Ia4823f60dcb5d8fc240b3c028a892f9bbe59fa43
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
protocol/restconf-api/pom.xml
protocol/restconf-api/src/main/java/module-info.java
protocol/restconf-api/src/main/java/org/opendaylight/restconf/api/query/WithDefaultsParam.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtil.java

index 2cb498e7bbef0076c6211398767a70bf2b816a7c..8b0c707c12b176e5216b52615bcb556f4f97ca6c 100644 (file)
@@ -45,5 +45,9 @@
             <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
             <artifactId>rfc6991-ietf-yang-types</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf.model</groupId>
+            <artifactId>rfc6243</artifactId>
+        </dependency>
     </dependencies>
 </project>
index ef2b99c831ed090d2c6b4dcc93bea7bd56c62db1..09e99785835fb56c7bc9409c341e62ca818aa630 100644 (file)
@@ -10,6 +10,7 @@ module org.opendaylight.restconf.api {
     exports org.opendaylight.restconf.api.query;
 
     requires transitive com.google.common;
+    requires transitive org.opendaylight.yang.gen.ietf.netconf.with.defaults.rfc6243;
     requires transitive org.opendaylight.yang.gen.ietf.yang.types.rfc6991;
     requires transitive org.opendaylight.yangtools.concepts;
     requires transitive org.opendaylight.yangtools.yang.common;
index dce2345fab83429681336604be6ea5894c413d8d..c2a30c62d48e4c94b169822e3efefdf73114a24b 100644 (file)
@@ -11,28 +11,32 @@ import static java.util.Objects.requireNonNull;
 
 import java.net.URI;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.with.defaults.rev110601.WithDefaultsMode;
 
 /**
  * Enumeration of possible {@code with-defaults} parameter values as defined by
- * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.8.9">RFC8040, section 4.8.9</a>.
+ * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.8.9">RFC8040, section 4.8.9</a>. This is an equivalent
+ * of with-defaults retrieval mode as defined by
+ * <a href="https://www.rfc-editor.org/rfc/rfc6243#section-3">RFC6243 section 3</a> and expressed as the
+ * {@code typedef with-defaults-mode}} in the corresponding YANG model.
  */
 public enum WithDefaultsParam implements RestconfQueryParam<WithDefaultsParam> {
     /**
      * Data nodes set to the YANG default by the client are reported.
      */
-    EXPLICIT("explicit"),
+    EXPLICIT(WithDefaultsMode.Explicit),
     /**
      * All data nodes are reported.
      */
-    REPORT_ALL("report-all"),
+    REPORT_ALL(WithDefaultsMode.ReportAll),
     /**
      * All data nodes are reported, and defaults are tagged.
      */
-    REPORT_ALL_TAGGED("report-all-tagged"),
+    REPORT_ALL_TAGGED(WithDefaultsMode.ReportAllTagged),
     /**
      * Data nodes set to the YANG default are not reported.
      */
-    TRIM("trim");
+    TRIM(WithDefaultsMode.Trim);
 
     // API consistency: must not be confused with enum constants
     @SuppressWarnings("checkstyle:ConstantName")
@@ -40,10 +44,23 @@ public enum WithDefaultsParam implements RestconfQueryParam<WithDefaultsParam> {
 
     private static final @NonNull URI CAPABILITY = URI.create("urn:ietf:params:restconf:capability:with-defaults:1.0");
 
-    private final @NonNull String uriValue;
+    private final @NonNull WithDefaultsMode mode;
 
-    WithDefaultsParam(final String uriValue) {
-        this.uriValue = requireNonNull(uriValue);
+    WithDefaultsParam(final WithDefaultsMode mode) {
+        this.mode = requireNonNull(mode);
+    }
+
+    public static @NonNull WithDefaultsParam of(final WithDefaultsMode mode) {
+        return switch (mode) {
+            case Explicit -> EXPLICIT;
+            case ReportAll -> REPORT_ALL;
+            case ReportAllTagged -> REPORT_ALL_TAGGED;
+            case Trim -> TRIM;
+        };
+    }
+
+    public static @NonNull WithDefaultsParam forUriValue(final String uriValue) {
+        return of(WithDefaultsMode.ofName(uriValue));
     }
 
     @Override
@@ -58,18 +75,11 @@ public enum WithDefaultsParam implements RestconfQueryParam<WithDefaultsParam> {
 
     @Override
     public String paramValue() {
-        return uriValue;
+        return mode.getName();
     }
 
-    public static @NonNull WithDefaultsParam forUriValue(final String uriValue) {
-        return switch (uriValue) {
-            case "explicit" -> EXPLICIT;
-            case "report-all" -> REPORT_ALL;
-            case "report-all-tagged" -> REPORT_ALL_TAGGED;
-            case "trim" -> TRIM;
-            default -> throw new IllegalArgumentException(
-                "Value can be 'explicit', 'report-all', 'report-all-tagged' or 'trim', not '" + uriValue + "'");
-        };
+    public @NonNull WithDefaultsMode mode() {
+        return mode;
     }
 
     public static @NonNull URI capabilityUri() {
index 38dccd33c8288f6bb4d7c2c7ec473094b280343e..a9619a80c990125620c8a457cd7095b0e3196e63 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.restconf.api.query.ContentParam;
 import org.opendaylight.restconf.api.query.WithDefaultsParam;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.with.defaults.rev110601.WithDefaultsMode;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -76,13 +77,13 @@ public final class ReadDataTransactionUtil {
      * @param content        type of data to read (config, state, all)
      * @param path           the path to read
      * @param strategy       {@link RestconfStrategy} - object that perform the actual DS operations
-     * @param withDefa       value of with-defaults parameter
+     * @param defaultsMode   value of with-defaults parameter
      * @param ctx            schema context
      * @return {@link NormalizedNode}
      */
     public static @Nullable NormalizedNode readData(final @NonNull ContentParam content,
             final @NonNull YangInstanceIdentifier path, final @NonNull RestconfStrategy strategy,
-            final WithDefaultsParam withDefa, final EffectiveModelContext ctx) {
+            final WithDefaultsParam defaultsMode, final EffectiveModelContext ctx) {
         return switch (content) {
             case ALL -> {
                 // PREPARE STATE DATA NODE
@@ -90,12 +91,12 @@ public final class ReadDataTransactionUtil {
                 // PREPARE CONFIG DATA NODE
                 final var configDataNode = readDataViaTransaction(strategy, LogicalDatastoreType.CONFIGURATION, path);
 
-                yield mergeConfigAndSTateDataIfNeeded(stateDataNode, withDefa == null ? configDataNode
-                    : prepareDataByParamWithDef(configDataNode, path, withDefa, ctx));
+                yield mergeConfigAndSTateDataIfNeeded(stateDataNode, defaultsMode == null ? configDataNode
+                    : prepareDataByParamWithDef(configDataNode, path, defaultsMode.mode(), ctx));
             }
             case CONFIG -> {
                 final var read = readDataViaTransaction(strategy, LogicalDatastoreType.CONFIGURATION, path);
-                yield withDefa == null ? read : prepareDataByParamWithDef(read, path, withDefa, ctx);
+                yield defaultsMode == null ? read : prepareDataByParamWithDef(read, path, defaultsMode.mode(), ctx);
             }
             case NONCONFIG -> readDataViaTransaction(strategy, LogicalDatastoreType.OPERATIONAL, path);
         };
@@ -127,23 +128,23 @@ public final class ReadDataTransactionUtil {
                     fields);
 
                 yield mergeConfigAndSTateDataIfNeeded(stateDataNode, withDefa == null ? configDataNode
-                    : prepareDataByParamWithDef(configDataNode, path, withDefa, ctx));
+                    : prepareDataByParamWithDef(configDataNode, path, withDefa.mode(), ctx));
             }
             case CONFIG -> {
                 final var read = readDataViaTransaction(strategy, LogicalDatastoreType.CONFIGURATION, path, fields);
-                yield withDefa == null ? read : prepareDataByParamWithDef(read, path, withDefa, ctx);
+                yield withDefa == null ? read : prepareDataByParamWithDef(read, path, withDefa.mode(), ctx);
             }
             case NONCONFIG -> readDataViaTransaction(strategy, LogicalDatastoreType.OPERATIONAL, path, fields);
         };
     }
 
     private static NormalizedNode prepareDataByParamWithDef(final NormalizedNode readData,
-            final YangInstanceIdentifier path, final WithDefaultsParam withDefa, final EffectiveModelContext ctx) {
-        final boolean trim = switch (withDefa) {
-            case TRIM -> true;
-            case EXPLICIT -> false;
-            case REPORT_ALL, REPORT_ALL_TAGGED -> throw new RestconfDocumentedException(
-                "Unsupported with-defaults value " + withDefa.paramValue());
+            final YangInstanceIdentifier path, final WithDefaultsMode defaultsMode, final EffectiveModelContext ctx) {
+        final boolean trim = switch (defaultsMode) {
+            case Trim -> true;
+            case Explicit -> false;
+            case ReportAll, ReportAllTagged -> throw new RestconfDocumentedException(
+                "Unsupported with-defaults value " + defaultsMode.getName());
         };
 
         final var ctxNode = DataSchemaContextTree.from(ctx).findChild(path).orElseThrow();