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

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


The following commit(s) were added to refs/heads/master by this push:
     new 58bdd12  Add method and command to export the generated conductor 
action code (#22)
58bdd12 is described below

commit 58bdd12c9ddc351ea2c83645918fb4f1c21e2c9e
Author: Olivier Tardieu <[email protected]>
AuthorDate: Tue Feb 12 08:11:37 2019 -0500

    Add method and command to export the generated conductor action code (#22)
---
 bin/compose.js       | 12 ++++++---
 bin/deploy.js        |  4 +--
 client.js            | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 conductor.js         | 52 ++-----------------------------------
 docs/COMMANDS.md     |  4 +++
 docs/COMPOSITIONS.md | 10 ++++++++
 docs/README.md       |  5 +++-
 package.json         |  1 +
 test/conductor.js    |  3 +--
 9 files changed, 105 insertions(+), 58 deletions(-)

diff --git a/bin/compose.js b/bin/compose.js
index b581700..e9b95ef 100755
--- a/bin/compose.js
+++ b/bin/compose.js
@@ -17,13 +17,14 @@
 'use strict'
 
 const composer = require('../composer')
+const conductor = require('../conductor')
 const json = require('../package.json')
 const minimist = require('minimist')
 const Module = require('module')
 const path = require('path')
 
 const argv = minimist(process.argv.slice(2), {
-  boolean: ['version', 'ast'],
+  boolean: ['version', 'ast', 'js'],
   alias: { version: 'v' }
 })
 
@@ -51,6 +52,7 @@ if (argv._.length !== 1 || path.extname(argv._[0]) !== '.js') 
{
   console.error('  compose composition.js [flags]')
   console.error('Flags:')
   console.error('  --ast                  only output the ast for the 
composition')
+  console.error('  --js                   output the conductor action code for 
the composition')
   console.error('  -v, --version          output the composer version')
   process.exit(1)
 }
@@ -64,5 +66,9 @@ try {
   console.error(error)
   process.exit(422 - 256) // Unprocessable Entity
 }
-if (argv.ast) composition = composition.ast
-console.log(JSON.stringify(composition, null, 4))
+if (argv.js) {
+  console.log(conductor.generate(composition).action.exec.code)
+} else {
+  if (argv.ast) composition = composition.ast
+  console.log(JSON.stringify(composition, null, 4))
+}
diff --git a/bin/deploy.js b/bin/deploy.js
index ec1343c..433bdc1 100755
--- a/bin/deploy.js
+++ b/bin/deploy.js
@@ -17,7 +17,7 @@
 'use strict'
 
 const composer = require('../composer')
-const conductor = require('../conductor')
+const client = require('../client')
 const fqn = require('../fqn')
 const fs = require('fs')
 const json = require('../package.json')
@@ -85,7 +85,7 @@ try {
   console.error(error)
   process.exit(400 - 256) // Bad Request
 }
-conductor(options).compositions.deploy(composition, argv.overwrite)
+client(options).compositions.deploy(composition, argv.overwrite)
   .then(actions => {
     const names = actions.map(action => action.name)
     console.log(`ok: created action${actions.length > 1 ? 's' : ''} ${names}`)
diff --git a/client.js b/client.js
new file mode 100644
index 0000000..82fbae1
--- /dev/null
+++ b/client.js
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/* eslint no-eval: 0 */
+
+'use strict'
+
+const conductor = require('./conductor')
+const fs = require('fs')
+const openwhisk = require('openwhisk')
+const os = require('os')
+const path = require('path')
+
+// return enhanced openwhisk client capable of deploying compositions
+module.exports = function (options) {
+  // try to extract apihost and key first from whisk property file file and 
then from process.env
+  let apihost
+  let apikey
+  let ignorecerts
+
+  try {
+    const wskpropsPath = process.env.WSK_CONFIG_FILE || 
path.join(os.homedir(), '.wskprops')
+    const lines = fs.readFileSync(wskpropsPath, { encoding: 'utf8' 
}).split('\n')
+
+    for (let line of lines) {
+      let parts = line.trim().split('=')
+      if (parts.length === 2) {
+        if (parts[0] === 'APIHOST') {
+          apihost = parts[1]
+        } else if (parts[0] === 'AUTH') {
+          apikey = parts[1]
+        }
+      }
+    }
+  } catch (error) { }
+
+  if (process.env.__OW_API_HOST) apihost = process.env.__OW_API_HOST
+  if (process.env.__OW_API_KEY) apikey = process.env.__OW_API_KEY
+  if (process.env.__OW_IGNORE_CERTS) ignorecerts = 
process.env.__OW_IGNORE_CERTS
+
+  const wsk = openwhisk(Object.assign({ apihost, api_key: apikey, 
ignore_certs: ignorecerts }, options))
+  wsk.compositions = new Compositions(wsk)
+  return wsk
+}
+
+// management class for compositions
+class Compositions {
+  constructor (wsk) {
+    this.actions = wsk.actions
+  }
+
+  deploy (composition, overwrite) {
+    const actions = (composition.actions || 
[]).concat(conductor.generate(composition))
+    return actions.reduce((promise, action) => promise.then(() => overwrite && 
this.actions.delete(action).catch(() => { }))
+      .then(() => this.actions.create(action)), Promise.resolve())
+      .then(() => actions)
+  }
+}
diff --git a/conductor.js b/conductor.js
index fab979b..0c22f14 100644
--- a/conductor.js
+++ b/conductor.js
@@ -19,68 +19,20 @@
 
 'use strict'
 
-const fs = require('fs')
 const { minify } = require('terser')
-const openwhisk = require('openwhisk')
-const os = require('os')
-const path = require('path')
 
 // read conductor version number
 const version = require('./package.json').version
 
 // synthesize conductor action code from composition
-function synthesize ({ name, composition, ast, version: composer, annotations 
= [] }) {
+function generate ({ name, composition, ast, version: composer, annotations = 
[] }) {
   const code = `// generated by composer v${composer} and conductor 
v${version}\n\nconst composition = ${JSON.stringify(composition, null, 
4)}\n\n// do not edit below this point\n\n` +
     minify(`const main=(${main})(composition)`, { output: { max_line_len: 127 
} }).code
   annotations = annotations.concat([{ key: 'conductor', value: ast }, { key: 
'composerVersion', value: composer }, { key: 'conductorVersion', value: version 
}])
   return { name, action: { exec: { kind: 'nodejs:default', code }, annotations 
} }
 }
 
-// return enhanced openwhisk client capable of deploying compositions
-module.exports = function (options) {
-  // try to extract apihost and key first from whisk property file file and 
then from process.env
-  let apihost
-  let apikey
-  let ignorecerts
-
-  try {
-    const wskpropsPath = process.env.WSK_CONFIG_FILE || 
path.join(os.homedir(), '.wskprops')
-    const lines = fs.readFileSync(wskpropsPath, { encoding: 'utf8' 
}).split('\n')
-
-    for (let line of lines) {
-      let parts = line.trim().split('=')
-      if (parts.length === 2) {
-        if (parts[0] === 'APIHOST') {
-          apihost = parts[1]
-        } else if (parts[0] === 'AUTH') {
-          apikey = parts[1]
-        }
-      }
-    }
-  } catch (error) { }
-
-  if (process.env.__OW_API_HOST) apihost = process.env.__OW_API_HOST
-  if (process.env.__OW_API_KEY) apikey = process.env.__OW_API_KEY
-  if (process.env.__OW_IGNORE_CERTS) ignorecerts = 
process.env.__OW_IGNORE_CERTS
-
-  const wsk = openwhisk(Object.assign({ apihost, api_key: apikey, 
ignore_certs: ignorecerts }, options))
-  wsk.compositions = new Compositions(wsk)
-  return wsk
-}
-
-// management class for compositions
-class Compositions {
-  constructor (wsk) {
-    this.actions = wsk.actions
-  }
-
-  deploy (composition, overwrite) {
-    const actions = (composition.actions || []).concat(synthesize(composition))
-    return actions.reduce((promise, action) => promise.then(() => overwrite && 
this.actions.delete(action).catch(() => { }))
-      .then(() => this.actions.create(action)), Promise.resolve())
-      .then(() => actions)
-  }
-}
+module.exports = { generate }
 
 // runtime code
 function main (composition) {
diff --git a/docs/COMMANDS.md b/docs/COMMANDS.md
index db45108..adfb02e 100644
--- a/docs/COMMANDS.md
+++ b/docs/COMMANDS.md
@@ -39,6 +39,7 @@ Usage:
   compose composition.js [flags]
 Flags:
   --ast                  only output the ast for the composition
+  --js                   output the conductor action code for the composition
   -v, --version          output the composer version
 ```
 The `compose` command takes a Javascript module that exports a composition
@@ -50,6 +51,9 @@ compose demo.js > demo.json
 If the `--ast` option is specified, the `compose` command only outputs a JSON
 representation of the Abstract Syntax Tree for the composition.
 
+If the `--js` option is specified, the `compose` command outputs the conductor
+action code for the composition.
+
 # Deploy
 
 ```
diff --git a/docs/COMPOSITIONS.md b/docs/COMPOSITIONS.md
index 342b4f6..7f72223 100644
--- a/docs/COMPOSITIONS.md
+++ b/docs/COMPOSITIONS.md
@@ -133,3 +133,13 @@ default parameters, limits, blocking invocation, web 
export. Execution
 and
 
[limits](https://github.com/apache/incubator-openwhisk/blob/master/docs/conductors.md#limits)
 of compositions follow from conductor actions.
+
+The conductor action code for a composition may be obtained by means of the
+`generate` method of the `conductor` module or using the `compose` command with
+the `--js` flag. The conductor action code may be deployed using, e.g., the
+OpenWhisk CLI.
+```
+compose demo.js --js > demo-conductor.js
+wsk action create demo demo-conductor.js -a conductor true
+```
+The `conductor` annotation must be set on conductor actions.
diff --git a/docs/README.md b/docs/README.md
index 1abced5..e29a579 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -20,7 +20,10 @@
 # Composer Package
 
 The Composer package consists of:
-* the [composer](../composer.js) Node.js module for authoring compositions,
+* the [composer](../composer.js) module for authoring compositions,
+* the [conductor](../conductor.js) module for generating conductor actions from
+  compositions,
+* the [client](../client.js) module for deploying compositions to openwhisk,
 * the [compose](../bin/compose.js) and [deploy](../bin/deploy.js) commands for
   managing compositions from the command line.
 
diff --git a/package.json b/package.json
index 4069188..d8989eb 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
   },
   "files": [
     "bin/",
+    "client.js",
     "composer.js",
     "conductor.js",
     "fqn.js",
diff --git a/test/conductor.js b/test/conductor.js
index 157d885..9e89f01 100644
--- a/test/conductor.js
+++ b/test/conductor.js
@@ -21,9 +21,8 @@
 
 const assert = require('assert')
 const composer = require('../composer')
-const conductor = require('../conductor')
+const wsk = require('../client')()
 const name = 'TestAction'
-const wsk = conductor()
 
 // deploy action
 const define = action => wsk.actions.delete(action.name).catch(() => { 
}).then(() => wsk.actions.create(action))

Reply via email to