Exception for URI /restconf/operations/module_name:rpc ended with slash
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / restconf / impl / RestconfImpl.xtend
index cfbce736fb70041ad2ee03eb26fdbc47d4c86797..e09dc7ac017d143c65f45564beeb1783ed97a8be 100644 (file)
@@ -230,10 +230,7 @@ class RestconfImpl implements RestconfService {
     }
 
     override invokeRpc(String identifier, CompositeNode payload) {
-        val rpc = identifier.rpcDefinition
-        if (rpc === null) {
-            throw new ResponseException(NOT_FOUND, "RPC does not exist.");
-        }
+        val rpc = resolveIdentifierInInvokeRpc(identifier)
         if (rpc.QName.namespace.toString == SAL_REMOTE_NAMESPACE && rpc.QName.localName == SAL_REMOTE_RPC_SUBSRCIBE) {
             val value = normalizeNode(payload, rpc.input, null)
             val pathNode = value?.getFirstSimpleByName(QName.create(rpc.QName, "path"))
@@ -267,7 +264,22 @@ class RestconfImpl implements RestconfService {
         if (!noPayload.nullOrEmpty) {
             throw new ResponseException(UNSUPPORTED_MEDIA_TYPE, "Content-Type contains unsupported Media Type.");
         }
-        return callRpc(identifier.rpcDefinition, null)
+        val rpc = resolveIdentifierInInvokeRpc(identifier)
+        return callRpc(rpc, null)
+    }
+
+    def resolveIdentifierInInvokeRpc(String identifier) {
+        if (identifier.indexOf("/") === -1) {
+            val identifierDecoded = identifier.urlPathArgDecode
+            val rpc = identifierDecoded.rpcDefinition
+            if (rpc !== null) {
+                return rpc
+            }
+            throw new ResponseException(NOT_FOUND, "RPC does not exist.");
+        }
+        val slashErrorMsg  = String.format("Identifier %n%s%ncan't contain slash character (/). +
+            If slash is part of identifier name then use %2F placeholder.",identifier)
+        throw new ResponseException(NOT_FOUND, slashErrorMsg);
     }
 
     private def StructuredData callRpc(RpcDefinition rpc, CompositeNode payload) {