Introduce UriInfoSupport 04/98104/4
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 24 Oct 2021 14:51:15 +0000 (16:51 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 24 Oct 2021 16:14:00 +0000 (18:14 +0200)
While we are figuring out JAX-RS integration around complex types,
let's concentrate utilities involved in these conversions into a
dedicated databind package.

JIRA: NETCONF-773
Change-Id: I5e5718773de8436279c37d52320f1272f62d9bc2
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/FilterParameter.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/NotificationQueryParams.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/StartTimeParameter.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/StopTimeParameter.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/UriInfoSupport.java [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/package-info.java [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfDataServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtil.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/UriInfoSupportTest.java [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtilTest.java

index 2c2777081ee5b5520c49e189164dc68a28067d74..8d4ed56bd4846dcf18c68004873f863851a6c318 100644 (file)
@@ -10,37 +10,37 @@ package org.opendaylight.restconf.nb.rfc8040;
 import static java.util.Objects.requireNonNull;
 
 import java.net.URI;
-import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.concepts.Immutable;
 
 /**
  * This class represents a {@code filter} parameter as defined in
  * <a href="https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.4">RFC8040 section 4.8.4</a>.
  */
-@NonNullByDefault
+
 public final class FilterParameter implements Immutable {
-    private static final URI CAPABILITY = URI.create("urn:ietf:params:restconf:capability:filter:1.0");
+    private static final @NonNull URI CAPABILITY = URI.create("urn:ietf:params:restconf:capability:filter:1.0");
 
     // FIXME: can we have a parsed, but not bound version of an XPath, please?
-    private final String value;
+    private final @NonNull String value;
 
     private FilterParameter(final String value) {
         this.value = requireNonNull(value);
     }
 
-    public static FilterParameter forUriValue(final String uriValue) {
+    public static @NonNull FilterParameter forUriValue(final String uriValue) {
         return new FilterParameter(uriValue);
     }
 
-    public static String uriName() {
+    public static @NonNull String uriName() {
         return "filter";
     }
 
-    public String uriValue() {
+    public @NonNull String uriValue() {
         return value;
     }
 
-    public static URI capabilityUri() {
+    public static @NonNull URI capabilityUri() {
         return CAPABILITY;
     }
 }
index 45e2c82cad2d9d3b1e43f7d81a4547ddf1c864a9..728a1df621254d4fce70ef8568a109f4f5b40144 100644 (file)
@@ -8,13 +8,11 @@
  */
 package org.opendaylight.restconf.nb.rfc8040;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 import com.google.common.base.MoreObjects;
-import java.util.List;
-import java.util.Map.Entry;
-import javax.ws.rs.core.UriInfo;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.yangtools.concepts.Immutable;
 
 /**
@@ -34,69 +32,10 @@ public final class NotificationQueryParams implements Immutable {
         this.skipNotificationData = skipNotificationData;
     }
 
-    // FIXME: this is JAX-RS specific
-    public static @NonNull NotificationQueryParams fromUriInfo(final UriInfo uriInfo) {
-        StartTimeParameter startTime = null;
-        StopTimeParameter stopTime = null;
-        FilterParameter filter = null;
-        boolean skipNotificationData = false;
-
-        for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
-            final String paramName = entry.getKey();
-            final List<String> paramValues = entry.getValue();
-            if (paramName.equals(StartTimeParameter.uriName())) {
-                switch (paramValues.size()) {
-                    case 0:
-                        break;
-                    case 1:
-                        final String str = paramValues.get(0);
-                        try {
-                            startTime = StartTimeParameter.forUriValue(str);
-                        } catch (IllegalArgumentException e) {
-                            throw new RestconfDocumentedException("Invalid start-time date: " + str, e);
-                        }
-                        break;
-                    default:
-                        throw new RestconfDocumentedException("Start-time parameter can be used only once.");
-                }
-            } else if (paramName.equals(StopTimeParameter.uriName())) {
-                switch (paramValues.size()) {
-                    case 0:
-                        break;
-                    case 1:
-                        final String str = paramValues.get(0);
-                        try {
-                            stopTime = StopTimeParameter.forUriValue(str);
-                        } catch (IllegalArgumentException e) {
-                            throw new RestconfDocumentedException("Invalid stop-time date: " + str, e);
-                        }
-                        break;
-                    default:
-                        throw new RestconfDocumentedException("Stop-time parameter can be used only once.");
-                }
-            } else if (paramName.equals(FilterParameter.uriName())) {
-                if (!paramValues.isEmpty()) {
-                    filter = FilterParameter.forUriValue(paramValues.get(0));
-                }
-            } else if (paramName.equals("odl-skip-notification-data")) {
-                switch (paramValues.size()) {
-                    case 0:
-                        break;
-                    case 1:
-                        skipNotificationData = Boolean.parseBoolean(paramValues.get(0));
-                        break;
-                    default:
-                        throw new RestconfDocumentedException(
-                            "Odl-skip-notification-data parameter can be used only once.");
-                }
-            } else {
-                throw new RestconfDocumentedException("Bad parameter used with notifications: " + paramName);
-            }
-        }
-        if (startTime == null && stopTime != null) {
-            throw new RestconfDocumentedException("Stop-time parameter has to be used with start-time parameter.");
-        }
-
+    public static @NonNull NotificationQueryParams of(final StartTimeParameter startTime,
+            final StopTimeParameter stopTime, final FilterParameter filter, final boolean skipNotificationData) {
+        checkArgument(stopTime == null || startTime != null,
+            "Stop-time parameter has to be used with start-time parameter.");
         return new NotificationQueryParams(startTime, stopTime, filter, skipNotificationData);
     }
 
index 191bc2adda9d53372f9e201deb22d92d98bd1ff3..01d8de9f2da1ebff560c96fbe6ebc30479cb741f 100644 (file)
@@ -7,28 +7,27 @@
  */
 package org.opendaylight.restconf.nb.rfc8040;
 
-import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
 
 /**
  * This class represents a {@code start-time} parameter as defined in
  * <a href="https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.7">RFC8040 section 4.8.7</a>.
  */
-@NonNullByDefault
 public final class StartTimeParameter extends AbstractReplayParameter {
     private StartTimeParameter(final DateAndTime value) {
         super(value);
     }
 
-    public static StartTimeParameter of(final DateAndTime value) {
+    public static @NonNull StartTimeParameter of(final DateAndTime value) {
         return new StartTimeParameter(value);
     }
 
-    public static String uriName() {
+    public static @NonNull String uriName() {
         return "start-time";
     }
 
-    public static StartTimeParameter forUriValue(final String uriValue) {
+    public static @NonNull StartTimeParameter forUriValue(final String uriValue) {
         return of(new DateAndTime(uriValue));
     }
 }
index 994a3dc3ec01884f922c77897afaf6c03e35b9bd..98c62dfe24bf3de27f8f9f08ac36bb1a61be99bd 100644 (file)
@@ -7,28 +7,27 @@
  */
 package org.opendaylight.restconf.nb.rfc8040;
 
-import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
 
 /**
  * This class represents a {@code stop-time} parameter as defined in
  * <a href="https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.8">RFC8040 section 4.8.8</a>.
  */
-@NonNullByDefault
 public final class StopTimeParameter extends AbstractReplayParameter {
     private StopTimeParameter(final DateAndTime value) {
         super(value);
     }
 
-    public static StopTimeParameter of(final DateAndTime value) {
+    public static @NonNull StopTimeParameter of(final DateAndTime value) {
         return new StopTimeParameter(value);
     }
 
-    public static String uriName() {
+    public static @NonNull String uriName() {
         return "stop-time";
     }
 
-    public static StopTimeParameter forUriValue(final String uriValue) {
+    public static @NonNull StopTimeParameter forUriValue(final String uriValue) {
         return of(new DateAndTime(uriValue));
     }
 }
diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/UriInfoSupport.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/UriInfoSupport.java
new file mode 100644 (file)
index 0000000..b2d892c
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2021 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.nb.rfc8040.databind.jaxrs;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.Beta;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.function.Function;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.nb.rfc8040.FilterParameter;
+import org.opendaylight.restconf.nb.rfc8040.NotificationQueryParams;
+import org.opendaylight.restconf.nb.rfc8040.StartTimeParameter;
+import org.opendaylight.restconf.nb.rfc8040.StopTimeParameter;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.opendaylight.yangtools.yang.common.ErrorType;
+
+@Beta
+public final class UriInfoSupport {
+    private UriInfoSupport() {
+        // Utility class
+    }
+
+    public static @NonNull NotificationQueryParams newNotificationQueryParams(final UriInfo uriInfo) {
+        StartTimeParameter startTime = null;
+        StopTimeParameter stopTime = null;
+        FilterParameter filter = null;
+        boolean skipNotificationData = false;
+
+        for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
+            final String paramName = entry.getKey();
+            final List<String> paramValues = entry.getValue();
+
+            try {
+                if (paramName.equals(StartTimeParameter.uriName())) {
+                    startTime = optionalParam(StartTimeParameter::forUriValue, paramName, paramValues);
+                    break;
+                } else if (paramName.equals(StopTimeParameter.uriName())) {
+                    stopTime = optionalParam(StopTimeParameter::forUriValue, paramName, paramValues);
+                    break;
+                } else if (paramName.equals(FilterParameter.uriName())) {
+                    filter = optionalParam(FilterParameter::forUriValue, paramName, paramValues);
+                } else if (paramName.equals("odl-skip-notification-data")) {
+                    // FIXME: this should be properly encapsulated in SkipNotificatioDataParameter
+                    skipNotificationData = Boolean.parseBoolean(optionalParam(paramName, paramValues));
+                } else {
+                    throw new RestconfDocumentedException("Bad parameter used with notifications: " + paramName);
+                }
+            } catch (IllegalArgumentException e) {
+                throw new RestconfDocumentedException("Invalid " + paramName + " value: " + e.getMessage(), e);
+            }
+        }
+
+        try {
+            return NotificationQueryParams.of(startTime, stopTime, filter, skipNotificationData);
+        } catch (IllegalArgumentException e) {
+            throw new RestconfDocumentedException("Invalid query parameters: " + e.getMessage(), e);
+        }
+    }
+
+    public static @Nullable String getSingleParameter(final MultivaluedMap<String, String> params, final String name) {
+        final var values = params.get(name);
+        return values == null ? null : optionalParam(name, values);
+    }
+
+    public static @Nullable String optionalParam(final String name, final List<String> values) {
+        switch (values.size()) {
+            case 0:
+                return null;
+            case 1:
+                return requireNonNull(values.get(0));
+            default:
+                throw new RestconfDocumentedException("Parameter " + name + " can appear at most once in request URI",
+                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        }
+    }
+
+    private static <T> @Nullable T optionalParam(final Function<String, @NonNull T> factory, final String name,
+            final List<String> values) {
+        final String str = optionalParam(name, values);
+        return str == null ? null : factory.apply(str);
+    }
+}
diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/package-info.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/package-info.java
new file mode 100644 (file)
index 0000000..da3c52c
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2021 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 holding JAX-RS data binding components.
+ */
+package org.opendaylight.restconf.nb.rfc8040.databind.jaxrs;
\ No newline at end of file
index 36056992fc62f6b653b28957ff45cfbd78e7b6ce..e9b6139122ccd2d8acf57962a46b2b9a67d719c3 100644 (file)
@@ -54,6 +54,7 @@ import org.opendaylight.restconf.common.patch.PatchStatusContext;
 import org.opendaylight.restconf.nb.rfc8040.InsertParameter;
 import org.opendaylight.restconf.nb.rfc8040.PointParameter;
 import org.opendaylight.restconf.nb.rfc8040.Rfc8040;
+import org.opendaylight.restconf.nb.rfc8040.databind.jaxrs.UriInfoSupport;
 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
 import org.opendaylight.restconf.nb.rfc8040.legacy.QueryParameters;
@@ -247,57 +248,52 @@ public class RestconfDataServiceImpl implements RestconfDataService {
     }
 
     private static QueryParams checkQueryParameters(final UriInfo uriInfo) {
-        boolean insertUsed = false;
-        boolean pointUsed = false;
         InsertParameter insert = null;
         PointParameter point = null;
 
         for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
             final String uriName = entry.getKey();
-            if (InsertParameter.uriName().equals(uriName)) {
-                if (insertUsed) {
-                    throw new RestconfDocumentedException("Insert parameter can be used only once.",
-                        ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
-                }
-
-                insertUsed = true;
-                final String str = entry.getValue().get(0);
-                insert = InsertParameter.forUriValue(str);
-                if (insert == null) {
-                    throw new RestconfDocumentedException("Unrecognized insert parameter value '" + str + "'",
-                        ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
+            final List<String> paramValues = entry.getValue();
+            if (uriName.equals(InsertParameter.uriName())) {
+                final String str = UriInfoSupport.optionalParam(uriName, paramValues);
+                if (str != null) {
+                    insert = InsertParameter.forUriValue(str);
+                    if (insert == null) {
+                        throw new RestconfDocumentedException("Unrecognized insert parameter value '" + str + "'",
+                            ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
+                    }
                 }
             } else if (PointParameter.uriName().equals(uriName)) {
-                if (pointUsed) {
-                    throw new RestconfDocumentedException("Point parameter can be used only once.",
-                        ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
+                final String str = UriInfoSupport.optionalParam(uriName, paramValues);
+                if (str != null) {
+                    point = PointParameter.forUriValue(str);
                 }
-
-                pointUsed = true;
-                point = PointParameter.forUriValue(entry.getValue().get(0));
             } else {
                 throw new RestconfDocumentedException("Bad parameter for post: " + uriName,
                     ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
             }
         }
 
-        checkQueryParams(insertUsed, pointUsed, insert);
-        return new QueryParams(insert, point);
-    }
-
-    private static void checkQueryParams(final boolean insertUsed, final boolean pointUsed,
-            final InsertParameter insert) {
-        if (pointUsed) {
-            if (!insertUsed) {
-                throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.",
-                    ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
-            }
-            if (insert != InsertParameter.BEFORE && insert != InsertParameter.AFTER) {
-                throw new RestconfDocumentedException(
-                    "Point parameter can be used only with 'after' or 'before' values of Insert parameter.",
-                    ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
-            }
+        // https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.5:
+        //        If the values "before" or "after" are used, then a "point" query
+        //        parameter for the "insert" query parameter MUST also be present, or a
+        //        "400 Bad Request" status-line is returned.
+        if ((insert == InsertParameter.BEFORE || insert == InsertParameter.AFTER) && point == null) {
+            throw new RestconfDocumentedException(
+                "Insert parameter " + insert.uriValue() + " cannot be used without a Point parameter.",
+                ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
         }
+        // https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.6:
+        //        If the "insert" query parameter is not present or has a value other
+        //        than "before" or "after", then a "400 Bad Request" status-line is
+        //        returned.
+        if (point != null && insert != InsertParameter.BEFORE && insert != InsertParameter.AFTER) {
+            throw new RestconfDocumentedException(
+                "Point parameter can be used only with 'after' or 'before' values of Insert parameter.",
+                ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
+        }
+
+        return new QueryParams(insert, point);
     }
 
     @Override
index a6d5dca51d09ceceaffef65adf3059fe72324103..81f23c0417230c6bd258a8a3ec77b3e8d30c05d7 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.mdsal.dom.api.DOMNotificationService;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.nb.rfc8040.NotificationQueryParams;
+import org.opendaylight.restconf.nb.rfc8040.databind.jaxrs.UriInfoSupport;
 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfStreamsSubscriptionService;
@@ -70,7 +71,7 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu
 
     @Override
     public NormalizedNodePayload subscribeToStream(final String identifier, final UriInfo uriInfo) {
-        final NotificationQueryParams notificationQueryParams = NotificationQueryParams.fromUriInfo(uriInfo);
+        final NotificationQueryParams notificationQueryParams = UriInfoSupport.newNotificationQueryParams(uriInfo);
 
         final URI response;
         if (identifier.contains(RestconfStreamsConstants.DATA_SUBSCRIPTION)) {
index 40ab0b3a49d503cc5de81c935cf544f4b967650f..f74edc1edcb11dfb11e8cf11ae2fb71b6cd94995 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.rests.utils;
 
-import static com.google.common.base.Verify.verifyNotNull;
+import static org.opendaylight.restconf.nb.rfc8040.databind.jaxrs.UriInfoSupport.getSingleParameter;
 import static org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserFieldsParameter.parseFieldsParameter;
 import static org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserFieldsParameter.parseFieldsPaths;
 
@@ -240,24 +240,6 @@ public final class ReadDataTransactionUtil {
         }
     }
 
-    @VisibleForTesting
-    static @Nullable String getSingleParameter(final MultivaluedMap<String, String> params, final String name) {
-        final var values = params.get(name);
-        if (values == null) {
-            return null;
-        }
-
-        switch (values.size()) {
-            case 0:
-                return null;
-            case 1:
-                return verifyNotNull(values.get(0));
-            default:
-                throw new RestconfDocumentedException("Parameter " + name + " can appear at most once in request URI",
-                    ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
-        }
-    }
-
     /**
      * Check if URI does not contain not allowed parameters for specified operation.
      *
diff --git a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/UriInfoSupportTest.java b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/UriInfoSupportTest.java
new file mode 100644 (file)
index 0000000..5037e24
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021 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.nb.rfc8040.databind.jaxrs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import java.util.List;
+import javax.ws.rs.core.MultivaluedHashMap;
+import org.junit.Test;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.common.errors.RestconfError;
+import org.opendaylight.restconf.nb.rfc8040.ContentParameter;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.opendaylight.yangtools.yang.common.ErrorType;
+
+public class UriInfoSupportTest {
+    /**
+     * Test when parameter is present at most once.
+     */
+    @Test
+    public void getSingleParameterTest() {
+        final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
+        parameters.putSingle(ContentParameter.uriName(), "all");
+        assertEquals("all", UriInfoSupport.getSingleParameter(parameters, ContentParameter.uriName()));
+    }
+
+    /**
+     * Test when parameter is present more than once.
+     */
+    @Test
+    public void getSingleParameterNegativeTest() {
+        final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
+        parameters.put(ContentParameter.uriName(), List.of("config", "nonconfig", "all"));
+
+        final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
+            () -> UriInfoSupport.getSingleParameter(parameters, ContentParameter.uriName()));
+        final List<RestconfError> errors = ex.getErrors();
+        assertEquals(1, errors.size());
+
+        final RestconfError error = errors.get(0);
+        assertEquals("Error type is not correct", ErrorType.PROTOCOL, error.getErrorType());
+        assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, error.getErrorTag());
+    }
+}
index b57a287c5ba13baec30e0897176b56923a677c47..f27f9755b0ff33985f19e3ec26b5dbfe0ee6b849 100644 (file)
@@ -513,34 +513,6 @@ public class ReadDataTransactionUtilTest {
         assertFalse(writerParameters.isTagged());
     }
 
-    /**
-     * Test when parameter is present at most once.
-     */
-    @Test
-    public void getSingleParameterTest() {
-        final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
-        parameters.putSingle(ContentParameter.uriName(), "all");
-        assertEquals("all", ReadDataTransactionUtil.getSingleParameter(parameters, ContentParameter.uriName()));
-    }
-
-    /**
-     * Test when parameter is present more than once.
-     */
-    @Test
-    public void getSingleParameterNegativeTest() {
-        final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
-        parameters.put(ContentParameter.uriName(), List.of("config", "nonconfig", "all"));
-
-        final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
-            () -> ReadDataTransactionUtil.getSingleParameter(parameters, ContentParameter.uriName()));
-        final List<RestconfError> errors = ex.getErrors();
-        assertEquals(1, errors.size());
-
-        final RestconfError error = errors.get(0);
-        assertEquals("Error type is not correct", ErrorType.PROTOCOL, error.getErrorType());
-        assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, error.getErrorTag());
-    }
-
     /**
      * Test when all parameters are allowed.
      */