Merge pull request #5 from csantanapr/nodejs8
NodeJS 8 Runtime
diff --git a/.gitignore b/.gitignore
index f65f024..52f108d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,7 @@
# NodeJS
node_modules
+package-lock.json
# Vagrant
.vagrant*
diff --git a/README.md b/README.md
index ff09334..4d6d23d 100644
--- a/README.md
+++ b/README.md
@@ -3,31 +3,58 @@
### Give it a try today
-To use as a docker action
+To use as a docker action for Node.js 6
```
-wsk action update myAction myAction.js --docker openwhisk/nodejs6action:1.0.0
+wsk action update myAction myAction.js --docker openwhisk/nodejs6action
+```
+To use as a docker action for Node.js 8
+```
+wsk action update myAction myAction.js --docker openwhisk/action-nodejs-v8
```
This works on any deployment of Apache OpenWhisk
### To use on deployment that contains the rutime as a kind
-To use as a kind action
+To use as a kind action using Node.js 6
```
wsk action update myAction myAction.js --kind nodejs:6
```
+To use as a kind action using Node.js 8
+```
+wsk action update myAction myAction.js --kind nodejs:8
+```
### Local development
+For Node.js 6
```
./gradlew core:nodejs6Action:distDocker
```
This will produce the image `whisk/nodejs6action`
-Build and Push image
+For Node.js 8
+```
+./gradlew core:nodejs8Action:distDocker
+```
+This will produce the image `whisk/action-nodejs-v8`
+
+
+Build and Push image for Node.js 6
```
docker login
./gradlew core:nodejs6Action:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io
```
-Deploy OpenWhisk using ansible environment that contains the kind `nodejs:6`
+Build and Push image for Node.js 8
+```
+docker login
+./gradlew core:nodejs8Action:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io
+```
+Then create the action using your image from dockerhub
+```
+wsk action update myAction myAction.js --docker $user_prefix/nodejs6action
+```
+The `$user_prefix` is usually your dockerhub user id.
+
+Deploy OpenWhisk using ansible environment that contains the kind `nodejs:6` and `nodejs:8`
Assuming you have OpenWhisk already deployed locally and `OPENWHISK_HOME` pointing to root directory of OpenWhisk core repository.
Set `ROOTDIR` to the root directory of this repository.
@@ -49,19 +76,6 @@
wskdev fresh -t local-nodejs
```
-To use as docker action push to your own dockerhub account
-```
-docker tag whisk/nodejs6action $user_prefix/nodejs6action
-docker push $user_prefix/nodejs6action
-```
-Then create the action using your image from dockerhub
-```
-wsk action update myAction myAction.js --docker $user_prefix/nodejs6action
-```
-The `$user_prefix` is usually your dockerhub user id.
-
-
-
# License
[Apache 2.0](LICENSE.txt)
diff --git a/ansible/environments/local/group_vars/all b/ansible/environments/local/group_vars/all
index 3ba8955..925ae29 100755
--- a/ansible/environments/local/group_vars/all
+++ b/ansible/environments/local/group_vars/all
@@ -34,5 +34,10 @@
image:
name: "nodejs6action"
deprecated: false
+ - kind: "nodejs:8"
+ default: false
+ image:
+ name: "action-nodejs-v8"
+ deprecated: false
blackboxes:
- name: "dockerskeleton"
diff --git a/core/nodejs8Action/.dockerignore b/core/nodejs8Action/.dockerignore
new file mode 100644
index 0000000..3081e3e
--- /dev/null
+++ b/core/nodejs8Action/.dockerignore
@@ -0,0 +1,8 @@
+node_modules
+package-lock.json
+Dockerfile
+build.gradle
+.project
+.settings
+build.xml
+logs
\ No newline at end of file
diff --git a/core/nodejs8Action/CHANGELOG.md b/core/nodejs8Action/CHANGELOG.md
new file mode 100644
index 0000000..b81a414
--- /dev/null
+++ b/core/nodejs8Action/CHANGELOG.md
@@ -0,0 +1,7 @@
+# NodeJS 8 OpenWhisk Runtime Container
+
+## 1.0.0
+Change: Initial release
+
+Node version = 8.9.1
+- [openwhisk v3.10.0](https://www.npmjs.com/package/openwhisk) - JavaScript client library for the OpenWhisk platform. Provides a wrapper around the OpenWhisk APIs.
\ No newline at end of file
diff --git a/core/nodejs8Action/Dockerfile b/core/nodejs8Action/Dockerfile
new file mode 100644
index 0000000..21771cc
--- /dev/null
+++ b/core/nodejs8Action/Dockerfile
@@ -0,0 +1,11 @@
+FROM node:8.9.1
+RUN apt-get update && apt-get install -y \
+ imagemagick \
+ unzip \
+ && rm -rf /var/lib/apt/lists/*
+WORKDIR /nodejsAction
+COPY . .
+RUN npm install \
+ && npm cache clean --force
+EXPOSE 8080
+CMD node --expose-gc app.js
diff --git a/core/nodejs8Action/build.gradle b/core/nodejs8Action/build.gradle
new file mode 100644
index 0000000..f796acb
--- /dev/null
+++ b/core/nodejs8Action/build.gradle
@@ -0,0 +1,36 @@
+apply plugin: 'eclipse'
+eclipse {
+ project {
+ natures 'org.eclipse.wst.jsdt.core.jsNature'
+ buildCommand 'org.eclipse.wst.jsdt.core.javascriptValidator'
+ }
+}
+
+ext.dockerImageName = 'action-nodejs-v8'
+apply from: '../../gradle/docker.gradle'
+
+distDocker.dependsOn 'copyProxy'
+distDocker.dependsOn 'copyRunner'
+distDocker.dependsOn 'copyService'
+distDocker.finalizedBy('cleanup')
+
+task copyProxy(type: Copy) {
+ from '../nodejsActionBase/app.js'
+ into '.'
+}
+
+task copyRunner(type: Copy) {
+ from '../nodejsActionBase/runner.js'
+ into '.'
+}
+
+task copyService(type: Copy) {
+ from '../nodejsActionBase/src/service.js'
+ into './src'
+}
+
+task cleanup(type: Delete) {
+ delete 'app.js'
+ delete 'runner.js'
+ delete 'src'
+}
\ No newline at end of file
diff --git a/core/nodejs8Action/package.json b/core/nodejs8Action/package.json
new file mode 100644
index 0000000..e715dc5
--- /dev/null
+++ b/core/nodejs8Action/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "action-nodejs-v8",
+ "version": "1.0.0",
+ "description": "Apache OpenWhisk NodeJS Runtime",
+ "repository": {
+ "type": "git",
+ "url": "git@github.com:apache/incubator-openwhisk-runtime-nodejs.git"
+ },
+ "license": "Apache-2.0",
+ "dependencies": {
+ "openwhisk": "3.10.0",
+ "body-parser": "1.18.2",
+ "express": "4.16.2"
+ }
+}
diff --git a/core/nodejsActionBase/app.js b/core/nodejsActionBase/app.js
index eb81856..2da2b89 100644
--- a/core/nodejsActionBase/app.js
+++ b/core/nodejsActionBase/app.js
@@ -25,12 +25,11 @@
var app = express();
-var logger = require('./src/logger').getLogger('logs/nodejsaction.log', 'nodejsAction');
/**
* instantiate an object which handles REST calls from the Invoker
*/
-var service = require('./src/service').getService(config, logger);
+var service = require('./src/service').getService(config);
app.set('port', config.port);
app.use(bodyParser.json({ limit: "48mb" }));
@@ -65,7 +64,7 @@
if (typeof error.code === "number" && typeof error.response !== "undefined") {
res.status(error.code).json(error.response);
} else {
- logger.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
+ console.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
res.status(500).json({ error: "Internal error." });
}
});
@@ -73,7 +72,7 @@
// This should not happen, as the contract for the endpoints is to
// never (externally) throw, and wrap failures in the promise instead,
// but, as they say, better safe than sorry.
- logger.error("[wrapEndpoint]", "exception caught", e);
+ console.error("[wrapEndpoint]", "exception caught", e.message);
res.status(500).json({ error: "Internal error (exception)." });
}
diff --git a/core/nodejsActionBase/src/logger.js b/core/nodejsActionBase/src/logger.js
deleted file mode 100644
index bb59857..0000000
--- a/core/nodejsActionBase/src/logger.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-'use strict';
-
-var fs = require('fs');
-var path = require('path');
-var log4js = require('log4js');
-
-function Logger(filename) {
- this.filename = filename;
-}
-
-Logger.prototype.makeLogger = function makeLogger(category) {
- var dir = path.dirname(this.filename);
- if (dir && !fs.existsSync(dir)) {
- fs.mkdirSync(dir);
- }
- log4js.configure(loggerConfig(this.filename));
- var thelogger = log4js.getLogger(category);
- thelogger.shutdown = function(cb) {
- log4js.shutdown(cb);
- }
- return thelogger;
-}
-
-Logger.getLogger = function(filename, category) {
- return new Logger(filename).makeLogger(category);
-}
-
-function loggerConfig(filename) {
- return {
- appenders : [ {
- type : 'dateFile',
- filename : filename,
- pattern : "-yyyy-MM-dd",
- alwaysIncludePattern : true,
- layout : {
- type : 'pattern',
- pattern : "[%d{yyyy-MM-ddThh:mm:ss.SSSO}] [%h] [%p] [%c] %m"
- }
- }]
- };
-}
-
-module.exports = Logger;
diff --git a/core/nodejsActionBase/src/service.js b/core/nodejsActionBase/src/service.js
index 73aac46..536aad4 100644
--- a/core/nodejsActionBase/src/service.js
+++ b/core/nodejsActionBase/src/service.js
@@ -18,7 +18,7 @@
var NodeActionRunner = require('../runner');
var fs = require('fs');
-function NodeActionService(config, logger) {
+function NodeActionService(config) {
var Status = {
ready: 'ready',
starting: 'starting',
@@ -123,7 +123,7 @@
return Promise.reject(errorMessage(500, "An error has occurred: " + error));
});
} else {
- logger.info('[runCode]', 'cannot schedule runCode due to status', status);
+ console.log('[runCode]', 'cannot schedule runCode due to status', status);
return Promise.reject(errorMessage(500, "Internal system error: container not ready, status: " + status));
}
};
@@ -168,8 +168,8 @@
}
}
-NodeActionService.getService = function(config, logger) {
- return new NodeActionService(config, logger);
+NodeActionService.getService = function(config) {
+ return new NodeActionService(config);
};
module.exports = NodeActionService;
diff --git a/settings.gradle b/settings.gradle
index 00e1bed..501f3c4 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -15,6 +15,8 @@
include 'core:nodejsActionBase'
include 'core:nodejs6Action'
+include 'core:nodejs8Action'
+
rootProject.name = 'runtime-nodejs'
gradle.ext.scala = [
diff --git a/tests/src/test/scala/actionContainers/NodeJs8ActionContainerTests.scala b/tests/src/test/scala/actionContainers/NodeJs8ActionContainerTests.scala
new file mode 100644
index 0000000..8727a7f
--- /dev/null
+++ b/tests/src/test/scala/actionContainers/NodeJs8ActionContainerTests.scala
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package actionContainers
+
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+import spray.json.JsObject
+
+@RunWith(classOf[JUnitRunner])
+class NodeJs8ActionContainerTests extends NodeJsActionContainerTests {
+
+ override lazy val nodejsContainerImageName = "action-nodejs-v8"
+
+ it should "support async and await" in {
+ withNodeJsContainer { c =>
+ val code = """
+ | const util = require('util');
+ | const fs = require('fs');
+ |
+ | const stat = util.promisify(fs.stat);
+ |
+ | async function main() {
+ | const stats = await stat('.');
+ | return stats
+ | }
+ """.stripMargin;
+
+ val (initCode, _) = c.init(initPayload(code))
+ initCode should be(200)
+
+ val (runCode, runRes) = c.run(runPayload(JsObject()))
+ runCode should be(200) // action writer returning an error is OK
+
+ runRes shouldBe defined
+ runRes.get.fields.get("uid") shouldBe defined
+ }
+ }
+
+}
diff --git a/tests/src/test/scala/actionContainers/NodeJsActionContainerTests.scala b/tests/src/test/scala/actionContainers/NodeJsActionContainerTests.scala
index 928118b..be45a52 100644
--- a/tests/src/test/scala/actionContainers/NodeJsActionContainerTests.scala
+++ b/tests/src/test/scala/actionContainers/NodeJsActionContainerTests.scala
@@ -260,13 +260,12 @@
})
}
- it should "have ws and socket.io-client packages available" in {
+ it should "have openwhisk package available" in {
// GIVEN that it should "error when requiring a non-existent package" (see test above for this)
val (out, err) = withNodeJsContainer { c =>
val code = """
| function main(args) {
- | require('ws');
- | require('socket.io-client');
+ | require('openwhisk');
| }
""".stripMargin
diff --git a/tools/travis/build.sh b/tools/travis/build.sh
index e23e934..fb914d8 100755
--- a/tools/travis/build.sh
+++ b/tools/travis/build.sh
@@ -15,6 +15,7 @@
cd $ROOTDIR
TERM=dumb ./gradlew \
:core:nodejs6Action:distDocker \
+:core:nodejs8Action:distDocker \
-PdockerImagePrefix=${IMAGE_PREFIX}