mdeuser commented on a change in pull request #2966: WIP: Path parameter 
support for API GW
URL: 
https://github.com/apache/incubator-openwhisk/pull/2966#discussion_r156205446
 
 

 ##########
 File path: core/routemgmt/common/apigw-utils.js
 ##########
 @@ -24,6 +24,177 @@ var _ = require('lodash');
 const ApimgmtUserAgent = "OpenWhisk-apimgmt/1.0.0";
 var UserAgent = ApimgmtUserAgent;
 
+/**
+ * Helper method for the validateFinalSwagger function. Generates a map of 
operationId to target-url strings so we
+ * can validate that each operationId we find that has a parameter in the path 
also has its target-url appended with
+ * $(request.path)
+ *
+ * @param ibmConfig   Required. The 'x-ibm-configuration' portion of the 
swaggerApi.
+ * @return A map of operationId->target-url pairs for checking.
+ */
+function generateTargetUrlMap(ibmConfig) {
+  var targetUrls = {};
+  ibmConfig['assembly']['execute'].forEach(function(exec) {
+    if (exec['operation-switch'] && exec['operation-switch']['case']) {
+      exec['operation-switch']['case'].forEach(function(element) {
+        var operations = element['operations'];
+        var isOperationWereLookingFor = false;
+        var ops = [];
+        if (operations) {
+          operations.forEach(function(op){
+            ops.push(op);
+          });
+        }
+        ops.forEach(function(op){
+          element['execute'].forEach(function(exec) {
+            targetUrls[op] = exec['invoke']['target-url'];
+          });
+        });
+      });
+    }
+
+  });
+  return targetUrls;
+}
+
+/**
+ * Helper function that just validates whether a relative path meets the 
following conditions:
+ * 1. It has not path parameters
+ * 2. If it has path parameters, that the parameters are well formed (i.e. 
each param is surrounded by {}).
+ *
+ * @param relativePath   Required. The relative path we are checking.
+ * @return True if the path is valid, false otherwise.
+ */
+function isValidRelativePath(relativePath) {
+  if (isParameterizedPath(relativePath)) {
+    var open = relativePath.indexOf('{', 0);
+    var close = relativePath.indexOf('}', open);
+    while (open != -1 || close != -1) {
+      if (open == -1 || close == -1) {
+        //Could not find a matching close brace
+        return false;
+      }
+      open = relativePath.indexOf('{', close);
+      close = open == -1 ? relativePath.indexOf('}', close + 1) : 
relativePath.indexOf('}', open);
+    }
+  }
+  return true;
+}
+
+/**
+ * Simple function to get the name of each path parameter defined in the path.
+ *
+ * @param path   Required. The path we are checking.
+ * @return An array that contains each named path parameter, or an empty list 
if none are found.
+ */
+function getPathParameters(relativePath) {
+  var params = [];
+   var validNameRegex = /\{([^\/]+)\}/g
+   //Match returns all the matches found, including the {} chars. so we have 
to remove them.
+   var namesFound = relativePath.match(validNameRegex);
+   if (namesFound) {
+     params = namesFound.map(function (pathName){
+       return pathName.substring(1,pathName.length-1);
+     });
+   }
+  return params;
+}
+
+/**
+ * Simple function to determine whether this path contains parameters
+ *
+ * @param path   Required. The path we are checking.
+ * @return True if the path contains parameters, false otherwise.
+ */
+function isParameterizedPath(path) {
+  return path != null && ((path.indexOf('{') != -1) || path.indexOf('}') >= 0);
+}
+
+/**
+ * Currently this only checks the final swagger that will be passed into API 
GW whether the path parameter definition
+ * is correct.
+ *
+ * @param swaggerApi   Required. The API swagger object to send to the API 
gateway
+ * @return A promise with the fully validated swaggerApi, or an error response 
if rejected.
+ */
+function validateFinalSwagger(swaggerApi) {
+  return new Promise(function(resolve, reject) {
+    // This returns a map of urls to check for path parameters.
+    console.log("validateFinalSwagger: Validating swapper before posting to 
API GW.")
+    var errorMsg;
+    var paths = swaggerApi['paths'];
+
+    if (swaggerApi.basePath && isParameterizedPath(swaggerApi.basePath)) {
+      errorMsg = "The base path (" + swaggerApi.basePath + ") cannot have 
parameters. Only the relative path supports path parameters.";
+    }
+    /*
+     * This code will look at each path defined, and look at all the 
parameters in each path, and validate that each
+     * verb (GET,POST, etc) for each path defines parameter objects for each 
parameter defined in the path. For each of
+     * these that contain parameters, it will also check that its target-url 
ends in $(request.path).
+     * #beginPathValidation
+     */
+    var targetUrlMap = generateTargetUrlMap(swaggerApi['x-ibm-configuration']);
+    for (var key in paths) {
+      if (errorMsg) { break; }
+      var idx = 0;
+      if (isParameterizedPath(key)) {
+        if (!isValidRelativePath(key)) {
+          errorMsg = "Relative path '" + key + "' does not include valid path 
parameters.  "
+          errorMsg += "Each parameter must be enclosed in curly braces{}.";
+          break;
+        }
+        //Path is valid, lets check that we have parameters defined for each 
path parameter and that the target-url
+        //has $(request.path) at the end.
+        var namedParamsInPath = getPathParameters(key);
+        //Loop over each verb (GET,POST,etc), each should contain path 
parameters.
+        for (var httpType in paths[key]) {
+          var parameters = paths[key][httpType].parameters;
+          var opId = paths[key][httpType].operationId;
+          var xOpenWhisk = paths[key][httpType]['x-openwhisk']
+          //Look at all the parameters in each verb to ensure they match those 
defined in the path.
+          if (namedParamsInPath == null || parameters == null || 
namedParamsInPath.length != parameters.length) {
 
 Review comment:
   ``` if ((namedParamsInPath != null && parameters != null && 
namedParamsInPath.length != parameters.length)  ||
      (namedParamsInPath != null && parameters == null) ||
      (namedParamsInPath == null && parameters != null))```

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to