Simplify RestconfValidationUtils users 90/83790/3
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 19 Aug 2019 13:26:19 +0000 (15:26 +0200)
committerRobert Varga <nite@hq.sk>
Sun, 22 Sep 2019 03:14:12 +0000 (03:14 +0000)
Rather than having users to immediate formatting of the String
value, introduce a simple alternative to throw exceptions.

Change-Id: Id82506398858667f5bd9214beab34dd5bb6638e6
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 90e5e532acdc55c8fc8f5f245c53a85cffc1f779)

restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/errors/RestconfDocumentedException.java
restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/validation/RestconfValidationUtils.java
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/md/sal/rest/schema/SchemaRetrievalServiceImpl.java
restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/PutDataTransactionUtil.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/YangInstanceIdentifierDeserializer.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/validations/RestconfValidation.java

index 30e1615d88f0ad403221c7dd4b26faf46066d56d..ecd894b7ff913816f2152d117d027e65801e6979 100644 (file)
@@ -5,7 +5,6 @@
  * 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.common.errors;
 
 import com.google.common.base.Preconditions;
@@ -15,6 +14,8 @@ import java.util.Collection;
 import java.util.List;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response.Status;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
 import org.opendaylight.yangtools.yang.common.OperationFailedException;
@@ -175,6 +176,60 @@ public class RestconfDocumentedException extends WebApplicationException {
         throw new RestconfDocumentedException(message, cause, cause.getErrorList());
     }
 
+    /**
+     * Throw an instance of this exception if an expression evaluates to true. If the expression evaluates to false,
+     * this method does nothing.
+     *
+     * @param expression Expression to be evaluated
+     * @param errorType The enumerated type indicating the layer where the error occurred.
+     * @param errorTag The enumerated tag representing a more specific error cause.
+     * @param format Format string, according to {@link String#format(String, Object...)}.
+     * @param args Format string arguments, according to {@link String#format(String, Object...)}
+     * @throws RestconfDocumentedException if the expression evaluates to true.
+     */
+    public static void throwIf(final boolean expression, final ErrorType errorType, final ErrorTag errorTag,
+            final @NonNull String format, final Object... args) {
+        if (expression) {
+            throw new RestconfDocumentedException(String.format(format, args), errorType, errorTag);
+        }
+    }
+
+    /**
+     * Throw an instance of this exception if an expression evaluates to true. If the expression evaluates to false,
+     * this method does nothing.
+     *
+     * @param expression Expression to be evaluated
+     * @param message error message
+     * @param errorType The enumerated type indicating the layer where the error occurred.
+     * @param errorTag The enumerated tag representing a more specific error cause.
+     * @throws RestconfDocumentedException if the expression evaluates to true.
+     */
+    public static void throwIf(final boolean expression, final @NonNull String message,
+            final ErrorType errorType, final ErrorTag errorTag) {
+        if (expression) {
+            throw new RestconfDocumentedException(message, errorType, errorTag);
+        }
+    }
+
+    /**
+     * Throw an instance of this exception if an object is null. If the object is non-null, it will
+     * be returned as the result of this method.
+     *
+     * @param obj Object reference to be checked
+     * @param errorType The enumerated type indicating the layer where the error occurred.
+     * @param errorTag The enumerated tag representing a more specific error cause.
+     * @param format Format string, according to {@link String#format(String, Object...)}.
+     * @param args Format string arguments, according to {@link String#format(String, Object...)}
+     * @throws RestconfDocumentedException if the expression evaluates to true.
+     */
+    public static <T> @NonNull T throwIfNull(final @Nullable T obj, final ErrorType errorType, final ErrorTag errorTag,
+            final @NonNull String format, final Object... args) {
+        if (obj == null) {
+            throw new RestconfDocumentedException(String.format(format, args), errorType, errorTag);
+        }
+        return obj;
+    }
+
     private static List<RestconfError> convertToRestconfErrors(final Collection<? extends RpcError> rpcErrors) {
         final List<RestconfError> errorList = new ArrayList<>();
         if (rpcErrors != null) {
index 117b7041ddb6132b3b7d7d316387c1fc5fcbcfbe..b8e955770e0cea66daa7dee60acee51ea6da5dfe 100644 (file)
@@ -28,21 +28,6 @@ public final class RestconfValidationUtils {
         throw new UnsupportedOperationException("Utility class");
     }
 
-    /**
-     * Method returns {@link RestconfDocumentedException} for a false condition.
-     *
-     * @param condition - condition for rise {@link RestconfDocumentedException}
-     * @param type      - input {@link ErrorType} for create {@link RestconfDocumentedException}
-     * @param tag       - input {@link ErrorTag} for create {@link RestconfDocumentedException}
-     * @param message   - input error message for create {@link RestconfDocumentedException}
-     */
-    public static void checkDocumentedError(final boolean condition, final ErrorType type,
-            final ErrorTag tag, final String message) {
-        if (!condition) {
-            throw new RestconfDocumentedException(message, type, tag);
-        }
-    }
-
     /**
      * Method returns {@link RestconfDocumentedException} if value is NULL or same input value.
      * {@link ErrorType} is relevant for server application layer
index 45a677df1c2f1eb337f7912f5f5d7fc7db88bfca..8cff24c393c330edfeb87722c0a13a648320c9d6 100644 (file)
@@ -61,11 +61,11 @@ public class SchemaRetrievalServiceImpl implements SchemaRetrievalService {
 
         }
 
-        RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Module name must be supplied.");
+        RestconfDocumentedException.throwIf(!componentIter.hasNext(), "Module name must be supplied.",
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         final String moduleName = componentIter.next();
-        RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Revision date must be supplied.");
+        RestconfDocumentedException.throwIf(!componentIter.hasNext(), "Revision date must be supplied.",
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         final String revisionString = componentIter.next();
         return getExportUsingNameAndRevision(schemaContext, moduleName, revisionString,
                 salContext.getYangTextSourceProvider());
index 4b868fe88a5410ea14e943779d8e78f83bd370a1..c9cd06b3d0701227769b304dc94c85336452275a 100644 (file)
@@ -73,7 +73,6 @@ import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
 import org.opendaylight.restconf.common.patch.PatchContext;
 import org.opendaylight.restconf.common.patch.PatchStatusContext;
 import org.opendaylight.restconf.common.util.DataChangeScope;
-import org.opendaylight.restconf.common.validation.RestconfValidationUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
 import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
 import org.opendaylight.yangtools.yang.common.Empty;
@@ -913,10 +912,10 @@ public final class RestconfImpl implements RestconfService {
 
         final Map<QName, Object> mutableCopyUriKeyValues = Maps.newHashMap(uriKeyValues);
         for (final QName keyDefinition : keyDefinitions) {
-            final Object uriKeyValue = mutableCopyUriKeyValues.remove(keyDefinition);
-            // should be caught during parsing URI to InstanceIdentifier
-            RestconfValidationUtils.checkDocumentedError(uriKeyValue != null, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING,
-                    "Missing key " + keyDefinition + " in URI.");
+            final Object uriKeyValue = RestconfDocumentedException.throwIfNull(
+                // should be caught during parsing URI to InstanceIdentifier
+                mutableCopyUriKeyValues.remove(keyDefinition), ErrorType.PROTOCOL, ErrorTag.DATA_MISSING,
+                "Missing key %s in URI.", keyDefinition);
 
             final Object dataKeyValue = payload.getIdentifier().getKeyValues().get(keyDefinition);
 
index 10217a07f357b88b1100f2a5c9741c7f3247870d..f8774819d662278fd0e2914c0cfa108137aff84a 100644 (file)
@@ -24,7 +24,6 @@ import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
-import org.opendaylight.restconf.common.validation.RestconfValidationUtils;
 import org.opendaylight.restconf.nb.rfc8040.handlers.TransactionChainHandler;
 import org.opendaylight.restconf.nb.rfc8040.references.SchemaContextRef;
 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.TransactionVarsWrapper;
@@ -126,9 +125,9 @@ public final class PutDataTransactionUtil {
             final List<QName> keyDefinitions) {
         final Map<QName, Object> mutableCopyUriKeyValues = Maps.newHashMap(uriKeyValues);
         for (final QName keyDefinition : keyDefinitions) {
-            final Object uriKeyValue = mutableCopyUriKeyValues.remove(keyDefinition);
-            RestconfValidationUtils.checkDocumentedError(uriKeyValue != null, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING,
-                    "Missing key " + keyDefinition + " in URI.");
+            final Object uriKeyValue = RestconfDocumentedException.throwIfNull(
+                mutableCopyUriKeyValues.remove(keyDefinition), ErrorType.PROTOCOL, ErrorTag.DATA_MISSING,
+                "Missing key %s in URI.", keyDefinition);
 
             final Object dataKeyValue = payload.getIdentifier().getKeyValues().get(keyDefinition);
 
index 758398b78db61e27b912acd3a23e50319adaf008..e9986d0c4414dc7aecce2ad5c525613a06717efa 100644 (file)
@@ -34,7 +34,6 @@ import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.restconf.common.util.RestUtil;
 import org.opendaylight.restconf.common.util.RestconfSchemaUtil;
-import org.opendaylight.restconf.common.validation.RestconfValidationUtils;
 import org.opendaylight.restconf.nb.rfc8040.codecs.RestCodec;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -135,8 +134,8 @@ public final class YangInstanceIdentifierDeserializer {
             }
 
             // check if next value is parsable
-            RestconfValidationUtils.checkDocumentedError(IDENTIFIER_PREDICATE.matches(currentChar()),
-                    RestconfError.ErrorType.PROTOCOL,RestconfError.ErrorTag.MALFORMED_MESSAGE, "");
+            RestconfDocumentedException.throwIf(!IDENTIFIER_PREDICATE.matches(currentChar()), "",
+                    RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.MALFORMED_MESSAGE);
 
             // parse value
             final QName key = keys.next();
@@ -164,12 +163,9 @@ public final class YangInstanceIdentifierDeserializer {
             }
 
             // there should be no more missing keys
-            RestconfValidationUtils.checkDocumentedError(
-                    !keys.hasNext(),
-                    RestconfError.ErrorType.PROTOCOL,
-                    RestconfError.ErrorTag.MISSING_ATTRIBUTE,
-                    "Key value missing for: " + qname
-            );
+            RestconfDocumentedException.throwIf(keys.hasNext(),
+                    RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.MISSING_ATTRIBUTE,
+                    "Key value missing for: %s", qname);
         }
 
         path.add(new YangInstanceIdentifier.NodeIdentifierWithPredicates(qname, values.build()));
@@ -236,12 +232,11 @@ public final class YangInstanceIdentifierDeserializer {
         final String value = nextIdentifierFromNextSequence(IDENTIFIER_PREDICATE);
 
         // exception if value attribute is missing
-        RestconfValidationUtils.checkDocumentedError(
-                !value.isEmpty(),
+        RestconfDocumentedException.throwIf(
+                value.isEmpty(),
                 RestconfError.ErrorType.PROTOCOL,
                 RestconfError.ErrorTag.MISSING_ATTRIBUTE,
-                "Value missing for: " + qname
-        );
+                "Value missing for: %s", qname);
         final DataSchemaNode dataSchemaNode = current.getDataSchemaNode();
         final Object valueByType = prepareValueByType(dataSchemaNode, findAndParsePercentEncoded(value));
         path.add(new YangInstanceIdentifier.NodeWithValue<>(qname, valueByType));
@@ -346,7 +341,7 @@ public final class YangInstanceIdentifierDeserializer {
     }
 
     private static <T extends DataNodeContainer & SchemaNode & ActionNodeContainer> QName getQNameOfDataSchemaNode(
-            final T parent, String nodeName) {
+            final T parent, final String nodeName) {
         final Optional<ActionDefinition> actionDef = findActionDefinition(parent, nodeName);
         final SchemaNode node;
         if (actionDef.isPresent()) {
index 1db58e4473c0e088088143f800d1b7083d27acb8..a48d27d64c2df78730d97ad8ee5b93632441e0f2 100644 (file)
@@ -14,7 +14,6 @@ import java.util.Locale;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
-import org.opendaylight.restconf.common.validation.RestconfValidationUtils;
 import org.opendaylight.restconf.nb.rfc8040.utils.parser.builder.ParserBuilderConstants;
 import org.opendaylight.yangtools.yang.common.Revision;
 
@@ -36,8 +35,8 @@ public final class RestconfValidation {
      * @return {@link Date}
      */
     public static Revision validateAndGetRevision(final Iterator<String> revisionDate) {
-        RestconfValidationUtils.checkDocumentedError(revisionDate.hasNext(), ErrorType.PROTOCOL,
-                ErrorTag.INVALID_VALUE, "Revision date must be supplied.");
+        RestconfDocumentedException.throwIf(!revisionDate.hasNext(), "Revision date must be supplied.",
+            ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         try {
             return Revision.of(revisionDate.next());
         } catch (final DateTimeParseException e) {
@@ -53,31 +52,18 @@ public final class RestconfValidation {
      * @return {@link String}
      */
     public static String validateAndGetModulName(final Iterator<String> moduleName) {
-        RestconfValidationUtils.checkDocumentedError(
-                moduleName.hasNext(),
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
-                "Module name must be supplied."
-        );
-
+        RestconfDocumentedException.throwIf(!moduleName.hasNext(), "Module name must be supplied.", ErrorType.PROTOCOL,
+            ErrorTag.INVALID_VALUE);
         final String name = moduleName.next();
 
-        RestconfValidationUtils.checkDocumentedError(
-                !name.isEmpty() && ParserBuilderConstants.Deserializer.IDENTIFIER_FIRST_CHAR.matches(name.charAt(0)),
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
-                "Identifier must start with character from set 'a-zA-Z_"
-        );
-
-        RestconfValidationUtils.checkDocumentedError(
-                !name.toUpperCase(Locale.ROOT).startsWith("XML"),
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
-                "Identifier must NOT start with XML ignore case."
-        );
-
-        RestconfValidationUtils.checkDocumentedError(
-                ParserBuilderConstants.Deserializer.IDENTIFIER.matchesAllOf(name.substring(1)),
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
-                "Supplied name has not expected identifier format."
-        );
+        RestconfDocumentedException.throwIf(
+            name.isEmpty() || !ParserBuilderConstants.Deserializer.IDENTIFIER_FIRST_CHAR.matches(name.charAt(0)),
+            "Identifier must start with character from set 'a-zA-Z_", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        RestconfDocumentedException.throwIf(name.toUpperCase(Locale.ROOT).startsWith("XML"),
+            "Identifier must NOT start with XML ignore case.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        RestconfDocumentedException.throwIf(
+            !ParserBuilderConstants.Deserializer.IDENTIFIER.matchesAllOf(name.substring(1)),
+            "Supplied name has not expected identifier format.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
 
         return name;
     }