+ try {
+ if (response.getErrors().isEmpty()) {
+ return response;
+ }
+ LOG.debug("InvokeAction Error Message {}", response.getErrors());
+ throw new RestconfDocumentedException("InvokeAction Error Message ", null, response.getErrors());
+ } catch (final CancellationException e) {
+ final String errMsg = "The Action Operation was cancelled while executing.";
+ LOG.debug("Cancel Execution: {}", errMsg, e);
+ throw new RestconfDocumentedException(errMsg, ErrorType.RPC, ErrorTag.PARTIAL_OPERATION, e);
+ }
+ }
+
+ /**
+ * Valid input data based on presence of a schema node.
+ *
+ * @param haveSchemaNode true if there is an underlying schema node
+ * @param payload input data
+ */
+ @VisibleForTesting
+ public static void validInputData(final boolean haveSchemaNode, final NormalizedNodePayload payload) {
+ final boolean haveData = payload.getData() != null;
+ if (haveSchemaNode) {
+ if (!haveData) {
+ throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL,
+ ErrorTag.MALFORMED_MESSAGE);
+ }
+ } else if (haveData) {
+ throw new RestconfDocumentedException("No input expected.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
+ }
+ }
+
+ /**
+ * Valid top level node name.
+ *
+ * @param path path of node
+ * @param payload data
+ */
+ @VisibleForTesting
+ public static void validTopLevelNodeName(final YangInstanceIdentifier path, final NormalizedNodePayload payload) {
+ final QName dataNodeType = payload.getData().getIdentifier().getNodeType();
+ if (path.isEmpty()) {
+ if (!NETCONF_BASE_QNAME.equals(dataNodeType)) {
+ throw new RestconfDocumentedException("Instance identifier has to contain at least one path argument",
+ ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
+ }
+ } else {
+ final String identifierName = path.getLastPathArgument().getNodeType().getLocalName();
+ final String payloadName = dataNodeType.getLocalName();
+ if (!payloadName.equals(identifierName)) {
+ throw new RestconfDocumentedException(
+ "Payload name (" + payloadName + ") is different from identifier name (" + identifierName + ")",
+ ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
+ }
+ }
+ }
+
+
+ /**
+ * Validates whether keys in {@code payload} are equal to values of keys in
+ * {@code iiWithData} for list schema node.
+ *
+ * @throws RestconfDocumentedException if key values or key count in payload and URI isn't equal
+ */
+ @VisibleForTesting
+ public static void validateListKeysEqualityInPayloadAndUri(final NormalizedNodePayload payload) {
+ final InstanceIdentifierContext iiWithData = payload.getInstanceIdentifierContext();
+ final PathArgument lastPathArgument = iiWithData.getInstanceIdentifier().getLastPathArgument();
+ final SchemaNode schemaNode = iiWithData.getSchemaNode();
+ final NormalizedNode data = payload.getData();
+ if (schemaNode instanceof ListSchemaNode) {
+ final List<QName> keyDefinitions = ((ListSchemaNode) schemaNode).getKeyDefinition();
+ if (lastPathArgument instanceof NodeIdentifierWithPredicates && data instanceof MapEntryNode) {
+ final Map<QName, Object> uriKeyValues = ((NodeIdentifierWithPredicates) lastPathArgument).asMap();
+ isEqualUriAndPayloadKeyValues(uriKeyValues, (MapEntryNode) data, keyDefinitions);
+ }
+ }
+ }
+
+ private static void isEqualUriAndPayloadKeyValues(final Map<QName, Object> uriKeyValues, final MapEntryNode payload,
+ final List<QName> keyDefinitions) {
+ final Map<QName, Object> mutableCopyUriKeyValues = new HashMap<>(uriKeyValues);
+ for (final QName keyDefinition : keyDefinitions) {
+ final Object uriKeyValue = RestconfDocumentedException.throwIfNull(
+ mutableCopyUriKeyValues.remove(keyDefinition), ErrorType.PROTOCOL, ErrorTag.DATA_MISSING,
+ "Missing key %s in URI.", keyDefinition);
+
+ final Object dataKeyValue = payload.getIdentifier().getValue(keyDefinition);
+
+ if (!uriKeyValue.equals(dataKeyValue)) {
+ final String errMsg = "The value '" + uriKeyValue + "' for key '" + keyDefinition.getLocalName()
+ + "' specified in the URI doesn't match the value '" + dataKeyValue
+ + "' specified in the message body. ";
+ throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+ }
+ }