This is an automated email from the ASF dual-hosted git repository.

pdesai pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/incubator-openwhisk-devtools.git


The following commit(s) were added to refs/heads/master by this push:
     new ddbbdc2  Fix Knative dedicated function request pre-processing logic 
(#253)
ddbbdc2 is described below

commit ddbbdc25af80ba38b91c8f17f26e0ec7aa009b33
Author: Matt Rutkowski <[email protected]>
AuthorDate: Thu Apr 25 13:29:14 2019 -0500

    Fix Knative dedicated function request pre-processing logic (#253)
    
    * cleanup README to be more clear and handoff properly to language runtime 
READMEs
    
    * cleanup README to be more clear and handoff properly to language runtime 
READMEs
    
    * cleanup README to be more clear and handoff properly to language runtime 
READMEs
    
    * cleanup README to be more clear and handoff properly to language runtime 
READMEs
    
    * javascript README fix to path
    
    * Fix Knative dedicated pre-procssing logic path
    
    * Fix Knative dedicated pre-procssing logic path
    
    * Fix Knative dedicated pre-procssing logic path
---
 knative-build/README.md                            |  14 ++-
 knative-build/runtimes/javascript/README.md        |  20 ++--
 .../runtimes/javascript/platform/knative.js        | 108 +++++++++++----------
 .../tests/helloworld/payload-knative-init.http     |  13 +++
 .../tests/helloworld/payload-knative-run.http      |  17 ++++
 .../payload-knative-init-run.http                  |   2 +-
 6 files changed, 111 insertions(+), 63 deletions(-)

diff --git a/knative-build/README.md b/knative-build/README.md
index a0b94dc..22739fd 100644
--- a/knative-build/README.md
+++ b/knative-build/README.md
@@ -152,7 +152,6 @@ status:
   phase: Active
 ```
 
-
 **Note**: If you do not see the **istio-injection** label, verify you issued 
the 'kubectl' command to set this label to the default namespace. See 
[Troubleshooting](#troubleshooting) section for more information.
 
 # Building and Serving OpenWhisk Runtime Build Templates
@@ -163,7 +162,7 @@ All OpenWhisk Runtime Build Templates require a valid 
Kubernetes **Service Accou
 
 ```bash
 $ git clone https://github.com/apache/incubator-openwhisk-devtools.git
-$ cd knative-build
+$ cd incubator-openwhisk-devtools/knative-build
 ```
 
 ## Register Secrets for Docker Hub
@@ -181,7 +180,7 @@ $ export DOCKERHUB_PASSWORD_BASE64_ENCODED=`echo -n 
"${DOCKERHUB_PASSWORD_PLAIN_
 # make sure that DOCKERHUB_PASSWORD_BASE64_ENCODED is set to something similar 
to t80szzToPshrpDr3sdMn==
 ```
 
-On your local system, copy the file 
[docker-secret.yaml.tmpl](docker-secret.yaml.tmpl) to `docker-secrets.yaml` and 
replace the **username** and **password** values with the base64 encoded 
versions of your Docker Hub username and password using following `sed` command:
+Use the following `sed` command which will generate a `docker-secrets.yaml` 
file from the file [docker-secret.yaml.tmpl](docker-secret.yaml.tmpl) and 
replace the **username** and **password** values with the base64 encoded 
versions of your Docker Hub username and password from the environment 
variables you exported above:
 
 ```
 sed -e 
's/${DOCKERHUB_USERNAME_BASE64_ENCODED}/'"$DOCKERHUB_USERNAME_BASE64_ENCODED"'/'
 -e 
's/${DOCKERHUB_PASSWORD_BASE64_ENCODED}/'"$DOCKERHUB_PASSWORD_BASE64_ENCODED"'/'
 docker-secret.yaml.tmpl > docker-secret.yaml
@@ -219,6 +218,13 @@ NAME                        SECRETS   AGE
 openwhisk-runtime-builder   2         3m46s
 ```
 
+## Building Knative runtimes and executing functions
+
+At this point, you have completed all the pre-reqs to build and run OpenWhisk 
runtimes on Knative.  In order to actually build and run them, you will need to 
continue following the instructions on the READMEs for the respective language 
runtimes listed below:
+- [NodeJS Runtime](./runtimes/javascript/#OpenWhisk-NodeJS-Runtime-for-Knative)
+
+---
+
 ## Troubleshooting
 
 ### Knative and Istio Install
@@ -268,7 +274,7 @@ statefulset "prometheus-system" created
 
 #### PROBLEM: Knative build fails initializing at `Init:1/4`
 
-Check the GitHub revision is set to right branch:
+Check the GitHub revision is set to right branch within your ```build.yaml``` 
file:
 
 ```
   source:
diff --git a/knative-build/runtimes/javascript/README.md 
b/knative-build/runtimes/javascript/README.md
index 413f571..2592646 100644
--- a/knative-build/runtimes/javascript/README.md
+++ b/knative-build/runtimes/javascript/README.md
@@ -169,7 +169,7 @@ metadata:
 We will use the simple "helloworld" test case to demonstrate how to use 
Knative to Build your function into container image and then deploy it as a 
Service.
 
 The testcase resides within this repo. at:
-- 
[/runtimes/javascript/tests/helloworld/](/runtimes/javascript/tests/helloworld/)
+- 
[tests/helloworld/](tests/helloworld/#Hello-World-Test-for-OpenWhisk-NodeJS-Runtime-using-Knative)
 
 For a complete listing of testcases, please view the [README](tests/README.md) 
in the tests subdirectory.
 
@@ -186,8 +186,11 @@ To do this,
 If you wish to run repeated tests you MAY set an environment variable and use 
```sed``` to replace the ```${DOCKER_USERNAME}``` within any of the test's 
Kubernetes Build YAML files as follows:
 
 ```
-export DOCKER_USERNAME="myusername"
-sed 's/${DOCKER_USERNAME}/'"$DOCKER_USERNAME"'/' build.yaml.tmpl > build.yaml
+# If you have not already exported your Dockerhub username, use the following 
command:
+export DOCKERHUB_USERNAME_PLAIN_TEXT="myusername"
+
+# Generate the build file from the template using your Dockerhub username set 
in the environment
+sed 's/${DOCKER_USERNAME}/'"$DOCKERHUB_USERNAME_PLAIN_TEXT"'/' build.yaml.tmpl 
> build.yaml
 ```
 
 <details>
@@ -225,7 +228,12 @@ spec:
 kubectl apply -f build.yaml
 ```
 
-This creates a pod with a NodeJS runtime and all the action metadata (action 
code, main function name, etc) integrated into the container image. If for any 
reason there is a failure creating the pod, we can troubleshoot the deployment 
with:
+This creates a pod with a NodeJS runtime and all the action metadata (action 
code, main function name, etc) integrated into the container image.
+
+
+#### Troubleshootinh the build
+
+If for any reason there is a failure creating the pod, we can troubleshoot the 
deployment with:
 
 #### `kubectl get pods`
 
@@ -280,8 +288,8 @@ To do this,
 As described for 'build.yaml.tmpl', you MAY set an environment variable and 
use ```sed``` to replace the ```${DOCKER_USERNAME}``` within any of the test's 
Kubernetes Build YAML files as follows:
 
 ```
-export DOCKER_USERNAME="myusername"
-sed 's/${DOCKER_USERNAME}/'"$DOCKER_USERNAME"'/' service.yaml.tmpl > 
service.yaml
+export DOCKERHUB_USERNAME_PLAIN_TEXT="myusername"
+sed 's/${DOCKER_USERNAME}/'"$DOCKERHUB_USERNAME_PLAIN_TEXT"'/' 
service.yaml.tmpl > service.yaml
 ```
 
 <details>
diff --git a/knative-build/runtimes/javascript/platform/knative.js 
b/knative-build/runtimes/javascript/platform/knative.js
index a537aa5..194f4be 100644
--- a/knative-build/runtimes/javascript/platform/knative.js
+++ b/knative-build/runtimes/javascript/platform/knative.js
@@ -78,76 +78,78 @@ function removeInitData(body) {
     }
 }
 
+
 /**
- * Pre-process the incoming
+ * Create request init data from the process environment
  */
-function preProcessInitData(env, initdata, valuedata, activationdata) {
+function createInitDataFromEnvironment(env) {
     DEBUG.functionStart();
     try {
-        // Set defaults to use INIT data not provided on the request
-        // Look first to the process (i.e., Container's) environment variables.
-        var main = (typeof env.__OW_ACTION_MAIN === 'undefined') ? "main" : 
env.__OW_ACTION_MAIN;
+        var initdata = {};
+        initdata.main = (typeof env.__OW_ACTION_MAIN === 'undefined') ? "main" 
: env.__OW_ACTION_MAIN;
         // TODO: Throw error if CODE is NOT defined!
-        var code = (typeof env.__OW_ACTION_CODE === 'undefined') ? "" : 
env.__OW_ACTION_CODE;
-        var binary = (typeof env.__OW_ACTION_BINARY === 'undefined') ? false : 
env.__OW_ACTION_BINARY.toLowerCase() === "true";
+        initdata.code = (typeof env.__OW_ACTION_CODE === 'undefined') ? "" : 
env.__OW_ACTION_CODE;
+        initdata.binary = (typeof env.__OW_ACTION_BINARY === 'undefined') ? 
false : env.__OW_ACTION_BINARY.toLowerCase() === "true";
         // TODO: default to empty?
-        var actionName = (typeof env.__OW_ACTION_NAME === 'undefined') ? "" : 
env.__OW_ACTION_NAME;
-        var raw = (typeof env.__OW_ACTION_RAW === 'undefined') ? false : 
env.__OW_ACTION_RAW.toLowerCase() === "true";
+        initdata.actionName = (typeof env.__OW_ACTION_NAME === 'undefined') ? 
"" : env.__OW_ACTION_NAME;
+        initdata.raw = (typeof env.__OW_ACTION_RAW === 'undefined') ? false : 
env.__OW_ACTION_RAW.toLowerCase() === "true";
 
-        DEBUG.dumpObject(actionName, "Action name");
-        DEBUG.dumpObject(main, "Action main");
-        DEBUG.dumpObject(code, "Action code");
-        DEBUG.dumpObject(binary, "Action binary");
-        DEBUG.dumpObject(raw, "Action Raw");
+        DEBUG.dumpObject(initdata, "initdata");
+        return initdata;
 
+    } catch(e){
+        console.error(e);
+        DEBUG.functionEndError(e.message);
+        throw("Unable to process Initialization data: " + e.message);
+    }
+    DEBUG.functionEnd();
+}
+
+
+/**
+ * Pre-process the init data from the request
+ */
+function preProcessInitData(initdata, valuedata, activationdata) {
+    DEBUG.functionStart();
+    try {
         // Look for init data within the request (i.e., "stem cell" runtime, 
where code is injected by request)
         if (typeof(initdata) !== "undefined") {
-            if (initdata.name && typeof initdata.name === 'string') {
-                actionName = initdata.name;
-            }
+
             if (initdata.main && typeof initdata.main === 'string') {
-                main = initdata.main;
+                valuedata.main = initdata.main;
             }
             if (initdata.code && typeof initdata.code === 'string') {
-                code = initdata.code;
+                valuedata.code = initdata.code;
             }
             if (initdata.binary) {
                 if (typeof initdata.binary === 'boolean') {
-                    binary = initdata.binary;
+                    valuedata.binary = initdata.binary;
                 } else {
                     throw ("Invalid Init. data; expected boolean for key 
'binary'.");
                 }
             }
-            if (initdata.raw ) {
+            if (initdata.raw) {
                 if (typeof initdata.raw === 'boolean') {
-                    raw = initdata.raw;
+                    valuedata.raw = initdata.raw;
                 } else {
                     throw ("Invalid Init. data; expected boolean for key 
'raw'.");
                 }
             }
-        }
 
-        // Move the init data to the request body under the "value" key.
-        // This will allow us to reuse the "openwhisk" /init route handler 
function
-        valuedata.main = main;
-        valuedata.code = code;
-        valuedata.binary = binary;
-        valuedata.raw = raw;
-
-        // Action name is a special case, as we have a key collision on "name" 
between init. data and request
-        // param. data (as they both appear within "body.value") so we must 
save it to its final location
-        // as the default Action name as part of the activation data
-        // NOTE: if action name is not present in the action data, we will set 
it regardless even if an empty string
-        if (typeof(activationdata) !== "undefined" ) {
-            if (typeof(activationdata.action_name) === "undefined" ||
-                (typeof(activationdata.action_name) === "string" && 
activationdata.action_name.length == 0)){
-                activationdata.action_name = actionName;
+            // Action name is a special case, as we have a key collision on 
"name" between init. data and request
+            // param. data (as they both appear within "body.value") so we 
must save it to its final location
+            // as the default Action name as part of the activation data
+            if (initdata.name && typeof initdata.name === 'string') {
+                if (typeof (activationdata) !== "undefined") {
+                    if (typeof (activationdata.action_name) === "undefined" ||
+                        (typeof (activationdata.action_name) === "string" &&
+                            activationdata.action_name.length === 0)) {
+                        activationdata.action_name = initdata.name;
+                    }
+                }
             }
+        DEBUG.dumpObject(valuedata, "valuedata");
         }
-        DEBUG.dumpObject(valuedata.main, "valuedata.main");
-        DEBUG.dumpObject(valuedata.code , "valuedata.code");
-        DEBUG.dumpObject(valuedata.binary, "valuedata.binary");
-        DEBUG.dumpObject(valuedata.raw, "valuedata.raw");
 
     } catch(e){
         console.error(e);
@@ -267,7 +269,7 @@ function preProcessRequest(req){
             preProcessInitData(env, initData, valueData, activationData);
         }
 
-        if( hasActivationData(req)) {
+        if(hasActivationData(req)) {
             // process HTTP request header and body to make it available to 
function as parameter data
             preProcessHTTPContext(req, valueData);
 
@@ -351,7 +353,7 @@ function postProcessResponse(req, result, res) {
         delete body['binary'];
     }
 
-    //When the content-type is defined, check if the response is binary data or
+    // When the content-type is defined, check if the response is binary data 
or
     // plain text and decode the plain text using a base64 decoder whenever 
needed.
     // Should the body fail to decoded correctly, return an error to the 
caller.
     if (contentTypeInHeader && headers[CONTENT_TYPE].lastIndexOf("image", 0) 
=== 0) {
@@ -414,10 +416,15 @@ function PlatformKnativeImpl(platformFactory) {
             if (hasInitData(req) && !isStemCell(process.env))
                 throw ("Cannot initialize a runtime with a dedicated 
function.");
 
-            if(hasInitData(req) && hasActivationData(req)){
+            // If this is a dedicated, uninitialized runtime, then copy INIT 
data from env. into the request
+            if( !isStemCell(process.env) && !service.initialized()){
+                let body = req.body || {};
+                body.init = createInitDataFromEnvironment(process.env);
+            }
 
-                // Process request and process env. variables to provide them 
in the manner
-                // an OpenWhisk Action expects them, as well as enable 
additional Http features.
+            // Different pre-processing logic based upon request data needed 
due Promise behavior
+            if(hasInitData(req) && hasActivationData(req)){
+                // Request has both Init and Run (activation) data
                 preProcessRequest(req);
                 // Invoke the OW "init" entrypoint
                 service.initCode(req).then(function () {
@@ -437,9 +444,7 @@ function PlatformKnativeImpl(platformFactory) {
                     }
                 });
             } else if(hasInitData(req)){
-
-                // Process request and process env. variables to provide them 
in the manner
-                // an OpenWhisk Action expects them, as well as enable 
additional Http features.
+                // Request has ONLY Init data
                 preProcessRequest(req);
                 // Invoke the OW "init" entrypoint
                 service.initCode(req).then(function (result) {
@@ -454,8 +459,7 @@ function PlatformKnativeImpl(platformFactory) {
                     }
                 });
             } else if(hasActivationData(req)){
-                // Process request and process env. variables to provide them 
in the manner
-                // an OpenWhisk Action expects them, as well as enable 
additional Http features.
+                // Request has ONLY Run (activation) data
                 preProcessRequest(req);
                 // Invoke the OW "run" entrypoint
                 service.runCode(req).then(function (result) {
diff --git 
a/knative-build/runtimes/javascript/tests/helloworld/payload-knative-init.http 
b/knative-build/runtimes/javascript/tests/helloworld/payload-knative-init.http
new file mode 100644
index 0000000..a2b27d9
--- /dev/null
+++ 
b/knative-build/runtimes/javascript/tests/helloworld/payload-knative-init.http
@@ -0,0 +1,13 @@
+POST http://localhost:8080/ HTTP/1.1
+content-type: application/json
+
+{
+  "init": {
+    "name": "nodejs-helloworld",
+    "main": "main",
+    "binary": false,
+    "code": "function main() {return {payload: 'Hello World!'};}"
+  }
+}
+
+###
diff --git 
a/knative-build/runtimes/javascript/tests/helloworld/payload-knative-run.http 
b/knative-build/runtimes/javascript/tests/helloworld/payload-knative-run.http
new file mode 100644
index 0000000..e83b884
--- /dev/null
+++ 
b/knative-build/runtimes/javascript/tests/helloworld/payload-knative-run.http
@@ -0,0 +1,17 @@
+POST http://localhost:8080/ HTTP/1.1
+content-type: application/json
+
+{
+  "activation": {
+    "namespace": "default",
+    "action_name": "nodejs-helloworld",
+    "api_host": "",
+    "api_key": "",
+    "activation_id": "",
+    "deadline": "4102498800000"
+  },
+  "value": {
+  }
+}
+
+###
diff --git 
a/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-init-run.http
 
b/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-init-run.http
index 7b4a421..61d9ef6 100644
--- 
a/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-init-run.http
+++ 
b/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-init-run.http
@@ -6,7 +6,7 @@ content-type: application/json
     "name" : "nodejs-helloworld-with-params",
     "main" : "main",
     "binary": false,
-    "code" : "function main(params) {return {payload: 'Hello ' + params.name + 
' from ' + params.place +  '!'};}"
+    "code" : "function main(params) {return {payload: 'Hello ' + params.name + 
' from ' + params.place + '!'};}"
   },
   "activation": {
     "namespace": "default",

Reply via email to