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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4ee25af  Adding support for conductor, web sequences, and converting 
to web actions for api gateway (#834)
4ee25af is described below

commit 4ee25af848742c50276b764cac5b6d001891d34f
Author: Priti Desai <[email protected]>
AuthorDate: Mon Apr 2 14:14:18 2018 -0700

    Adding support for conductor, web sequences, and converting to web actions 
for api gateway (#834)
    
    * adding conductor support, web sequence and web action in addition to 
webexport
    
    * converting actions to web action if its not specified with api gateway
    
    * adding newline
    
    * fixing manifest file name
    
    * adding integration on conductor
    
    * adding newline
---
 deployers/manifestreader.go                        |   2 +-
 parsers/manifest_parser.go                         | 159 ++++++++++++---------
 parsers/manifest_parser_test.go                    |  40 +++++-
 parsers/yamlparser.go                              |  12 ++
 ...ata_compose_actions_for_web_and_web_export.yaml |  39 +++++
 tests/dat/manifest_data_compose_api_records.yaml   |   5 -
 tests/src/integration/apigateway/manifest.yml      |   5 -
 .../src/integration/conductor/actions/increment.js |  21 +++
 tests/src/integration/conductor/actions/triple.js  |  21 +++
 .../conductor/actions/tripleAndIncrement.js        |  27 ++++
 tests/src/integration/conductor/conductor_test.go  |  40 ++++++
 tests/src/integration/conductor/manifest.yaml      |  52 +++++++
 tests/src/integration/websequence/manifest.yaml    |  50 +++++++
 tests/src/integration/websequence/src/greeting.js  |  32 +++++
 .../integration/websequence/websequence_test.go    |  43 ++++++
 utils/conductor.go                                 |  29 ++++
 utils/conductor_test.go                            |  37 +++++
 utils/misc.go                                      |  42 +-----
 utils/webaction.go                                 |   9 +-
 wski18n/i18n_ids.go                                |   3 +-
 wski18n/i18n_resources.go                          |   4 +-
 wski18n/resources/en_US.all.json                   |  12 +-
 22 files changed, 559 insertions(+), 125 deletions(-)

diff --git a/deployers/manifestreader.go b/deployers/manifestreader.go
index c9f0268..1f9171d 100644
--- a/deployers/manifestreader.go
+++ b/deployers/manifestreader.go
@@ -78,7 +78,7 @@ func (deployer *ManifestReader) HandleYaml(sdeployer 
*ServiceDeployer, manifestP
                return wskderrors.NewYAMLFileFormatError(manifestName, err)
        }
 
-       sequences, err := 
manifestParser.ComposeSequencesFromAllPackages(deployer.serviceDeployer.ClientConfig.Namespace,
 manifest, managedAnnotations)
+       sequences, err := 
manifestParser.ComposeSequencesFromAllPackages(deployer.serviceDeployer.ClientConfig.Namespace,
 manifest, deployer.serviceDeployer.ManifestPath, managedAnnotations)
        if err != nil {
                return wskderrors.NewYAMLFileFormatError(manifestName, err)
        }
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index 9cfa673..b46f73a 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -142,7 +142,7 @@ func (dm *YAMLParser) composeAnnotations(annotations 
map[string]interface{}) whi
        return listOfAnnotations
 }
 
-func (dm *YAMLParser) ComposeDependenciesFromAllPackages(manifest *YAML, 
projectPath string, filePath string, ma whisk.KeyValue) 
(map[string]utils.DependencyRecord, error) {
+func (dm *YAMLParser) ComposeDependenciesFromAllPackages(manifest *YAML, 
projectPath string, filePath string, managedAnnotations whisk.KeyValue) 
(map[string]utils.DependencyRecord, error) {
        dependencies := make(map[string]utils.DependencyRecord)
        packages := make(map[string]Package)
 
@@ -153,7 +153,7 @@ func (dm *YAMLParser) 
ComposeDependenciesFromAllPackages(manifest *YAML, project
        }
 
        for n, p := range packages {
-               d, err := dm.ComposeDependencies(p, projectPath, filePath, n, 
ma)
+               d, err := dm.ComposeDependencies(p, projectPath, filePath, n, 
managedAnnotations)
                if err == nil {
                        for k, v := range d {
                                dependencies[k] = v
@@ -165,7 +165,7 @@ func (dm *YAMLParser) 
ComposeDependenciesFromAllPackages(manifest *YAML, project
        return dependencies, nil
 }
 
-func (dm *YAMLParser) ComposeDependencies(pkg Package, projectPath string, 
filePath string, packageName string, ma whisk.KeyValue) 
(map[string]utils.DependencyRecord, error) {
+func (dm *YAMLParser) ComposeDependencies(pkg Package, projectPath string, 
filePath string, packageName string, managedAnnotations whisk.KeyValue) 
(map[string]utils.DependencyRecord, error) {
 
        depMap := make(map[string]utils.DependencyRecord)
        for key, dependency := range pkg.Dependencies {
@@ -203,7 +203,7 @@ func (dm *YAMLParser) ComposeDependencies(pkg Package, 
projectPath string, fileP
                annotations := dm.composeAnnotations(dependency.Annotations)
 
                if utils.Flags.Managed || utils.Flags.Sync {
-                       annotations = append(annotations, ma)
+                       annotations = append(annotations, managedAnnotations)
                }
 
                packDir := path.Join(projectPath, 
strings.Title(YAML_KEY_PACKAGES))
@@ -214,7 +214,7 @@ func (dm *YAMLParser) ComposeDependencies(pkg Package, 
projectPath string, fileP
        return depMap, nil
 }
 
-func (dm *YAMLParser) ComposeAllPackages(manifest *YAML, filePath string, ma 
whisk.KeyValue) (map[string]*whisk.Package, error) {
+func (dm *YAMLParser) ComposeAllPackages(manifest *YAML, filePath string, 
managedAnnotations whisk.KeyValue) (map[string]*whisk.Package, error) {
        packages := map[string]*whisk.Package{}
        manifestPackages := make(map[string]Package)
 
@@ -234,7 +234,7 @@ func (dm *YAMLParser) ComposeAllPackages(manifest *YAML, 
filePath string, ma whi
 
        // Compose each package found in manifest
        for n, p := range manifestPackages {
-               s, err := dm.ComposePackage(p, n, filePath, ma)
+               s, err := dm.ComposePackage(p, n, filePath, managedAnnotations)
 
                if err == nil {
                        packages[n] = s
@@ -246,7 +246,7 @@ func (dm *YAMLParser) ComposeAllPackages(manifest *YAML, 
filePath string, ma whi
        return packages, nil
 }
 
-func (dm *YAMLParser) ComposePackage(pkg Package, packageName string, filePath 
string, ma whisk.KeyValue) (*whisk.Package, error) {
+func (dm *YAMLParser) ComposePackage(pkg Package, packageName string, filePath 
string, managedAnnotations whisk.KeyValue) (*whisk.Package, error) {
        pag := &whisk.Package{}
        pag.Name = packageName
        //The namespace for this package is absent, so we use default guest 
here.
@@ -314,7 +314,7 @@ func (dm *YAMLParser) ComposePackage(pkg Package, 
packageName string, filePath s
 
        // add Managed Annotations if this is Managed Deployment
        if utils.Flags.Managed || utils.Flags.Sync {
-               pag.Annotations = append(pag.Annotations, ma)
+               pag.Annotations = append(pag.Annotations, managedAnnotations)
        }
 
        // "default" package is a reserved package name
@@ -336,7 +336,7 @@ func (dm *YAMLParser) ComposePackage(pkg Package, 
packageName string, filePath s
        return pag, nil
 }
 
-func (dm *YAMLParser) ComposeSequencesFromAllPackages(namespace string, mani 
*YAML, ma whisk.KeyValue) ([]utils.ActionRecord, error) {
+func (dm *YAMLParser) ComposeSequencesFromAllPackages(namespace string, mani 
*YAML, manifestFilePath string, managedAnnotations whisk.KeyValue) 
([]utils.ActionRecord, error) {
        var sequences []utils.ActionRecord = make([]utils.ActionRecord, 0)
        manifestPackages := make(map[string]Package)
 
@@ -347,7 +347,7 @@ func (dm *YAMLParser) 
ComposeSequencesFromAllPackages(namespace string, mani *YA
        }
 
        for n, p := range manifestPackages {
-               s, err := dm.ComposeSequences(namespace, p.Sequences, n, ma)
+               s, err := dm.ComposeSequences(namespace, p.Sequences, n, 
manifestFilePath, managedAnnotations)
                if err == nil {
                        sequences = append(sequences, s...)
                } else {
@@ -357,8 +357,9 @@ func (dm *YAMLParser) 
ComposeSequencesFromAllPackages(namespace string, mani *YA
        return sequences, nil
 }
 
-func (dm *YAMLParser) ComposeSequences(namespace string, sequences 
map[string]Sequence, packageName string, ma whisk.KeyValue) 
([]utils.ActionRecord, error) {
+func (dm *YAMLParser) ComposeSequences(namespace string, sequences 
map[string]Sequence, packageName string, manifestFilePath string, 
managedAnnotations whisk.KeyValue) ([]utils.ActionRecord, error) {
        var listOfSequences []utils.ActionRecord = make([]utils.ActionRecord, 0)
+       var errorParser error
 
        for key, sequence := range sequences {
                wskaction := new(whisk.Action)
@@ -389,7 +390,19 @@ func (dm *YAMLParser) ComposeSequences(namespace string, 
sequences map[string]Se
 
                // appending managed annotations if its a managed deployment
                if utils.Flags.Managed || utils.Flags.Sync {
-                       wskaction.Annotations = append(wskaction.Annotations, 
ma)
+                       wskaction.Annotations = append(wskaction.Annotations, 
managedAnnotations)
+               }
+
+               // Web Export
+               // Treat sequence as a web action, a raw HTTP web action, or as 
a standard action based on web-export;
+               // when web-export is set to yes | true, treat sequence as a 
web action,
+               // when web-export is set to raw, treat sequence as a raw HTTP 
web action,
+               // when web-export is set to no | false, treat sequence as a 
standard action
+               if len(sequence.Web) != 0 {
+                       wskaction.Annotations, errorParser = 
utils.WebAction(manifestFilePath, wskaction.Name, sequence.Web, 
wskaction.Annotations, false)
+                       if errorParser != nil {
+                               return nil, errorParser
+                       }
                }
 
                record := utils.ActionRecord{Action: wskaction, Packagename: 
packageName, Filepath: key}
@@ -398,7 +411,7 @@ func (dm *YAMLParser) ComposeSequences(namespace string, 
sequences map[string]Se
        return listOfSequences, nil
 }
 
-func (dm *YAMLParser) ComposeActionsFromAllPackages(manifest *YAML, filePath 
string, ma whisk.KeyValue) ([]utils.ActionRecord, error) {
+func (dm *YAMLParser) ComposeActionsFromAllPackages(manifest *YAML, filePath 
string, managedAnnotations whisk.KeyValue) ([]utils.ActionRecord, error) {
        var actions []utils.ActionRecord = make([]utils.ActionRecord, 0)
        manifestPackages := make(map[string]Package)
 
@@ -409,7 +422,7 @@ func (dm *YAMLParser) 
ComposeActionsFromAllPackages(manifest *YAML, filePath str
        }
 
        for n, p := range manifestPackages {
-               a, err := dm.ComposeActions(filePath, p.Actions, n, ma)
+               a, err := dm.ComposeActions(filePath, p.Actions, n, 
managedAnnotations)
                if err == nil {
                        actions = append(actions, a...)
                } else {
@@ -708,7 +721,15 @@ func (dm *YAMLParser) composeActionLimits(limits Limits) 
*whisk.Limits {
        return nil
 }
 
-func (dm *YAMLParser) ComposeActions(manifestFilePath string, actions 
map[string]Action, packageName string, ma whisk.KeyValue) 
([]utils.ActionRecord, error) {
+func (dm *YAMLParser) validateActionWebFlag(action Action) {
+       if len(action.Web) != 0 && len(action.Webexport) != 0 {
+               warningString := 
wski18n.T(wski18n.ID_WARN_ACTION_WEB_X_action_X,
+                       map[string]interface{}{wski18n.KEY_ACTION: action.Name})
+               wskprint.PrintOpenWhiskWarning(warningString)
+       }
+}
+
+func (dm *YAMLParser) ComposeActions(manifestFilePath string, actions 
map[string]Action, packageName string, managedAnnotations whisk.KeyValue) 
([]utils.ActionRecord, error) {
 
        var errorParser error
        var listOfActions []utils.ActionRecord = make([]utils.ActionRecord, 0)
@@ -762,7 +783,7 @@ func (dm *YAMLParser) ComposeActions(manifestFilePath 
string, actions map[string
 
                // add managed annotations if its marked as managed deployment
                if utils.Flags.Managed || utils.Flags.Sync {
-                       wskaction.Annotations = append(wskaction.Annotations, 
ma)
+                       wskaction.Annotations = append(wskaction.Annotations, 
managedAnnotations)
                }
 
                // Web Export
@@ -770,8 +791,9 @@ func (dm *YAMLParser) ComposeActions(manifestFilePath 
string, actions map[string
                // when web-export is set to yes | true, treat action as a web 
action,
                // when web-export is set to raw, treat action as a raw HTTP 
web action,
                // when web-export is set to no | false, treat action as a 
standard action
-               if len(action.Webexport) != 0 {
-                       wskaction.Annotations, errorParser = 
utils.WebAction(manifestFilePath, action.Name, action.Webexport, 
wskaction.Annotations, false)
+               dm.validateActionWebFlag(action)
+               if len(action.GetWeb()) != 0 {
+                       wskaction.Annotations, errorParser = 
utils.WebAction(manifestFilePath, action.Name, action.GetWeb(), 
wskaction.Annotations, false)
                        if errorParser != nil {
                                return listOfActions, errorParser
                        }
@@ -783,6 +805,10 @@ func (dm *YAMLParser) ComposeActions(manifestFilePath 
string, actions map[string
                                wskaction.Limits = wsklimits
                        }
                }
+               // Conductor Action
+               if action.Conductor {
+                       wskaction.Annotations = append(wskaction.Annotations, 
utils.ConductorAction())
+               }
 
                wskaction.Name = actionName
                pub := false
@@ -796,7 +822,7 @@ func (dm *YAMLParser) ComposeActions(manifestFilePath 
string, actions map[string
 
 }
 
-func (dm *YAMLParser) ComposeTriggersFromAllPackages(manifest *YAML, filePath 
string, ma whisk.KeyValue) ([]*whisk.Trigger, error) {
+func (dm *YAMLParser) ComposeTriggersFromAllPackages(manifest *YAML, filePath 
string, managedAnnotations whisk.KeyValue) ([]*whisk.Trigger, error) {
        var triggers []*whisk.Trigger = make([]*whisk.Trigger, 0)
        manifestPackages := make(map[string]Package)
 
@@ -807,7 +833,7 @@ func (dm *YAMLParser) 
ComposeTriggersFromAllPackages(manifest *YAML, filePath st
        }
 
        for _, p := range manifestPackages {
-               t, err := dm.ComposeTriggers(filePath, p, ma)
+               t, err := dm.ComposeTriggers(filePath, p, managedAnnotations)
                if err == nil {
                        triggers = append(triggers, t...)
                } else {
@@ -817,7 +843,7 @@ func (dm *YAMLParser) 
ComposeTriggersFromAllPackages(manifest *YAML, filePath st
        return triggers, nil
 }
 
-func (dm *YAMLParser) ComposeTriggers(filePath string, pkg Package, ma 
whisk.KeyValue) ([]*whisk.Trigger, error) {
+func (dm *YAMLParser) ComposeTriggers(filePath string, pkg Package, 
managedAnnotations whisk.KeyValue) ([]*whisk.Trigger, error) {
        var errorParser error
        var listOfTriggers []*whisk.Trigger = make([]*whisk.Trigger, 0)
 
@@ -870,7 +896,7 @@ func (dm *YAMLParser) ComposeTriggers(filePath string, pkg 
Package, ma whisk.Key
 
                // add managed annotations if its a managed deployment
                if utils.Flags.Managed || utils.Flags.Sync {
-                       wsktrigger.Annotations = append(wsktrigger.Annotations, 
ma)
+                       wsktrigger.Annotations = append(wsktrigger.Annotations, 
managedAnnotations)
                }
 
                listOfTriggers = append(listOfTriggers, wsktrigger)
@@ -878,7 +904,7 @@ func (dm *YAMLParser) ComposeTriggers(filePath string, pkg 
Package, ma whisk.Key
        return listOfTriggers, nil
 }
 
-func (dm *YAMLParser) ComposeRulesFromAllPackages(manifest *YAML, ma 
whisk.KeyValue) ([]*whisk.Rule, error) {
+func (dm *YAMLParser) ComposeRulesFromAllPackages(manifest *YAML, 
managedAnnotations whisk.KeyValue) ([]*whisk.Rule, error) {
        var rules []*whisk.Rule = make([]*whisk.Rule, 0)
        manifestPackages := make(map[string]Package)
 
@@ -889,7 +915,7 @@ func (dm *YAMLParser) ComposeRulesFromAllPackages(manifest 
*YAML, ma whisk.KeyVa
        }
 
        for n, p := range manifestPackages {
-               r, err := dm.ComposeRules(p, n, ma)
+               r, err := dm.ComposeRules(p, n, managedAnnotations)
                if err == nil {
                        rules = append(rules, r...)
                } else {
@@ -899,7 +925,7 @@ func (dm *YAMLParser) ComposeRulesFromAllPackages(manifest 
*YAML, ma whisk.KeyVa
        return rules, nil
 }
 
-func (dm *YAMLParser) ComposeRules(pkg Package, packageName string, ma 
whisk.KeyValue) ([]*whisk.Rule, error) {
+func (dm *YAMLParser) ComposeRules(pkg Package, packageName string, 
managedAnnotations whisk.KeyValue) ([]*whisk.Rule, error) {
        var rules []*whisk.Rule = make([]*whisk.Rule, 0)
 
        for _, rule := range pkg.GetRuleList() {
@@ -923,7 +949,7 @@ func (dm *YAMLParser) ComposeRules(pkg Package, packageName 
string, ma whisk.Key
 
                // add managed annotations if its a managed deployment
                if utils.Flags.Managed || utils.Flags.Sync {
-                       wskrule.Annotations = append(wskrule.Annotations, ma)
+                       wskrule.Annotations = append(wskrule.Annotations, 
managedAnnotations)
                }
 
                rules = append(rules, wskrule)
@@ -1009,46 +1035,51 @@ func (dm *YAMLParser) ComposeApiRecords(client 
*whisk.Config, packageName string
                                                                        
wski18n.KEY_API:    apiName}))
                                        } else {
                                                // verify that the action is 
defined as web action
-                                               // web-export set to any of 
[true, yes, raw]
-                                               if 
!utils.IsWebAction(pkg.Actions[actionName].Webexport) {
-                                                       return nil, 
wskderrors.NewYAMLFileFormatError(manifestPath,
-                                                               
wski18n.T(wski18n.ID_ERR_API_MISSING_WEB_ACTION_X_action_X_api_X,
-                                                                       
map[string]interface{}{
-                                                                               
wski18n.KEY_ACTION: actionName,
-                                                                               
wski18n.KEY_API:    apiName}))
-                                               } else {
-                                                       request := 
new(whisk.ApiCreateRequest)
-                                                       request.ApiDoc = 
new(whisk.Api)
-                                                       
request.ApiDoc.GatewayBasePath = gatewayBasePath
-                                                       // is API verb is 
valid, it must be one of (GET, PUT, POST, DELETE)
-                                                       
request.ApiDoc.GatewayRelPath = gatewayRelPath
-                                                       if _, ok := 
whisk.ApiVerbs[strings.ToUpper(gatewayMethod)]; !ok {
-                                                               return nil, 
wskderrors.NewInvalidAPIGatewayMethodError(manifestPath,
-                                                                       
gatewayBasePath+gatewayRelPath,
-                                                                       
gatewayMethod,
-                                                                       
dm.getGatewayMethods())
-                                                       }
-                                                       
request.ApiDoc.GatewayMethod = strings.ToUpper(gatewayMethod)
-                                                       
request.ApiDoc.Namespace = client.Namespace
-                                                       request.ApiDoc.ApiName 
= apiName
-                                                       request.ApiDoc.Id = 
strings.Join([]string{API, request.ApiDoc.Namespace, 
request.ApiDoc.GatewayRelPath}, ":")
-                                                       // set action of an API 
Doc
-                                                       request.ApiDoc.Action = 
new(whisk.ApiAction)
-                                                       if packageName == 
DEFAULT_PACKAGE {
-                                                               
request.ApiDoc.Action.Name = actionName
-                                                       } else {
-                                                               
request.ApiDoc.Action.Name = packageName + PATH_SEPARATOR + actionName
+                                               // web or web-export set to any 
of [true, yes, raw]
+                                               a := pkg.Actions[actionName]
+                                               if 
!utils.IsWebAction(a.GetWeb()) {
+                                                       warningString := 
wski18n.T(wski18n.ID_WARN_API_MISSING_WEB_ACTION_X_action_X_api_X,
+                                                               
map[string]interface{}{
+                                                                       
wski18n.KEY_ACTION: actionName,
+                                                                       
wski18n.KEY_API:    apiName})
+                                                       
wskprint.PrintOpenWhiskWarning(warningString)
+                                                       if a.Annotations == nil 
{
+                                                               a.Annotations = 
make(map[string]interface{}, 0)
                                                        }
-                                                       url := []string{HTTPS + 
client.Host, strings.ToLower(API),
-                                                               API_VERSION, 
WEB, client.Namespace, packageName,
-                                                               actionName + 
"." + utils.HTTP_FILE_EXTENSION}
-                                                       
request.ApiDoc.Action.Namespace = client.Namespace
-                                                       
request.ApiDoc.Action.BackendUrl = strings.Join(url, PATH_SEPARATOR)
-                                                       
request.ApiDoc.Action.BackendMethod = gatewayMethod
-                                                       
request.ApiDoc.Action.Auth = client.AuthToken
-                                                       // add a newly created 
ApiCreateRequest object to a list of requests
-                                                       requests = 
append(requests, request)
+                                                       
a.Annotations[utils.WEB_EXPORT_ANNOT] = true
+                                                       pkg.Actions[actionName] 
= a
+                                               }
+                                               request := 
new(whisk.ApiCreateRequest)
+                                               request.ApiDoc = new(whisk.Api)
+                                               request.ApiDoc.GatewayBasePath 
= gatewayBasePath
+                                               // is API verb is valid, it 
must be one of (GET, PUT, POST, DELETE)
+                                               request.ApiDoc.GatewayRelPath = 
gatewayRelPath
+                                               if _, ok := 
whisk.ApiVerbs[strings.ToUpper(gatewayMethod)]; !ok {
+                                                       return nil, 
wskderrors.NewInvalidAPIGatewayMethodError(manifestPath,
+                                                               
gatewayBasePath+gatewayRelPath,
+                                                               gatewayMethod,
+                                                               
dm.getGatewayMethods())
+                                               }
+                                               request.ApiDoc.GatewayMethod = 
strings.ToUpper(gatewayMethod)
+                                               request.ApiDoc.Namespace = 
client.Namespace
+                                               request.ApiDoc.ApiName = apiName
+                                               request.ApiDoc.Id = 
strings.Join([]string{API, request.ApiDoc.Namespace, 
request.ApiDoc.GatewayRelPath}, ":")
+                                               // set action of an API Doc
+                                               request.ApiDoc.Action = 
new(whisk.ApiAction)
+                                               if packageName == 
DEFAULT_PACKAGE {
+                                                       
request.ApiDoc.Action.Name = actionName
+                                               } else {
+                                                       
request.ApiDoc.Action.Name = packageName + PATH_SEPARATOR + actionName
                                                }
+                                               url := []string{HTTPS + 
client.Host, strings.ToLower(API),
+                                                       API_VERSION, WEB, 
client.Namespace, packageName,
+                                                       actionName + "." + 
utils.HTTP_FILE_EXTENSION}
+                                               request.ApiDoc.Action.Namespace 
= client.Namespace
+                                               
request.ApiDoc.Action.BackendUrl = strings.Join(url, PATH_SEPARATOR)
+                                               
request.ApiDoc.Action.BackendMethod = gatewayMethod
+                                               request.ApiDoc.Action.Auth = 
client.AuthToken
+                                               // add a newly created 
ApiCreateRequest object to a list of requests
+                                               requests = append(requests, 
request)
                                        }
                                }
                        }
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index 6c64492..c3d62d4 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -1033,6 +1033,41 @@ func TestComposeActionsForInvalidWebActions(t 
*testing.T) {
        assert.NotNil(t, err, "Expected error for invalid web-export.")
 }
 
+func TestComposeActionsForWebAndWebExport(t *testing.T) {
+       file := 
"../tests/dat/manifest_data_compose_actions_for_web_and_web_export.yaml"
+       p, m, _ := testLoadParseManifest(t, file)
+
+       actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, 
whisk.KeyValue{})
+       assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+       for _, action := range actions {
+               if action.Action.Name == "hello1" || action.Action.Name == 
"hello2" {
+                       for _, a := range action.Action.Annotations {
+                               switch a.Key {
+                               case "web-export":
+                                       assert.True(t, a.Value.(bool), 
"Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+                               }
+                       }
+               } else if action.Action.Name == "hello3" {
+                       for _, a := range action.Action.Annotations {
+                               switch a.Key {
+                               case "web-export":
+                                       assert.False(t, a.Value.(bool), 
"Expected false for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+                               }
+                       }
+               } else if action.Action.Name == "hello4" {
+                       for _, a := range action.Action.Annotations {
+                               switch a.Key {
+                               case "web-export":
+                                       assert.True(t, a.Value.(bool), 
"Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+                               case "raw-http":
+                                       assert.True(t, a.Value.(bool), 
"Expected true for raw but got "+strconv.FormatBool(a.Value.(bool)))
+                               }
+                       }
+               }
+       }
+}
+
 // Test 16: validate manifest_parser.ResolveParameter() method
 func TestResolveParameterForMultiLineParams(t *testing.T) {
        paramName := "name"
@@ -1192,10 +1227,11 @@ func TestComposePackage(t *testing.T) {
 
 func TestComposeSequences(t *testing.T) {
 
-       p, m, _ := testLoadParseManifest(t, 
"../tests/dat/manifest_data_compose_sequences.yaml")
+       file := "../tests/dat/manifest_data_compose_sequences.yaml"
+       p, m, _ := testLoadParseManifest(t, file)
 
        // Note: set first param (namespace) to empty string
-       seqList, err := p.ComposeSequencesFromAllPackages("", m, 
whisk.KeyValue{})
+       seqList, err := p.ComposeSequencesFromAllPackages("", m, file, 
whisk.KeyValue{})
        if err != nil {
                assert.Fail(t, "Failed to compose sequences")
        }
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index c65896f..a4a8b79 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -102,9 +102,11 @@ type Action struct {
        Credential  string                 `yaml:"credential"`
        ExposedUrl  string                 `yaml:"exposedUrl"`
        Webexport   string                 `yaml:"web-export"`
+       Web         string                 `yaml:"web"`
        Main        string                 `yaml:"main"`
        Docker      string                 `yaml:"docker,omitempty"`
        Native      bool                   `yaml:"native,omitempty"`
+       Conductor   bool                   `yaml:"conductor,omitempty"`
        Limits      *Limits                `yaml:"limits"`
        Inputs      map[string]Parameter   `yaml:"inputs"`
        Outputs     map[string]Parameter   `yaml:"outputs"`
@@ -125,6 +127,7 @@ type Limits struct {
 
 type Sequence struct {
        Actions     string                 `yaml:"actions"`
+       Web         string                 `yaml:"web"`
        Annotations map[string]interface{} `yaml:"annotations,omitempty"`
 }
 
@@ -231,6 +234,15 @@ type YAML struct {
        Filepath string             //file path of the yaml file
 }
 
+// function to return web-export or web depending on what is specified
+// in manifest and deployment files
+func (action *Action) GetWeb() string {
+       if len(action.Web) == 0 && len(action.Webexport) != 0 {
+               return action.Webexport
+       }
+       return action.Web
+}
+
 // function to return Project or Application depending on what is specified in
 // manifest and deployment files
 func (yaml *YAML) GetProject() Project {
diff --git 
a/tests/dat/manifest_data_compose_actions_for_web_and_web_export.yaml 
b/tests/dat/manifest_data_compose_actions_for_web_and_web_export.yaml
new file mode 100644
index 0000000..c6eb509
--- /dev/null
+++ b/tests/dat/manifest_data_compose_actions_for_web_and_web_export.yaml
@@ -0,0 +1,39 @@
+#
+# 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.
+#
+
+packages:
+  helloworld:
+    actions:
+      hello1:
+        function: ../src/integration/helloworld/actions/hello.js
+        runtime: nodejs
+        web: true
+        web-export: true
+      hello2:
+        function: ../src/integration/helloworld/actions/hello.js
+        runtime: nodejs
+        web: true
+        web-export: false
+      hello3:
+        function: ../src/integration/helloworld/actions/hello.js
+        runtime: nodejs
+        web: false
+        web-export: true
+      hello4:
+        function: ../src/integration/helloworld/actions/hello.js
+        runtime: nodejs
+        web: raw
+        web-export: true
diff --git a/tests/dat/manifest_data_compose_api_records.yaml 
b/tests/dat/manifest_data_compose_api_records.yaml
index 55cd84e..385c8e9 100644
--- a/tests/dat/manifest_data_compose_api_records.yaml
+++ b/tests/dat/manifest_data_compose_api_records.yaml
@@ -22,19 +22,14 @@ packages:
         web-export: true
       deleteBooks:
         function: ../tests/src/integration/helloworld/actions/hello.js
-        web-export: true
       listMembers:
         function: ../tests/src/integration/helloworld/actions/hello.js
-        web-export: true
       getBooks2:
         function: ../tests/src/integration/helloworld/actions/hello.js
-        web-export: true
       postBooks2:
         function: ../tests/src/integration/helloworld/actions/hello.js
-        web-export: true
       listMembers2:
         function: ../tests/src/integration/helloworld/actions/hello.js
-        web-export: true
     apis:
       book-club:
         club:
diff --git a/tests/src/integration/apigateway/manifest.yml 
b/tests/src/integration/apigateway/manifest.yml
index 407347a..e2b26f5 100644
--- a/tests/src/integration/apigateway/manifest.yml
+++ b/tests/src/integration/apigateway/manifest.yml
@@ -25,19 +25,14 @@ packages:
                 function: src/greeting.js
                 runtime: nodejs:6
             getBooks:
-                web-export: true
                 function: src/get-books.js
             postBooks:
-                web-export: true
                 function: src/post-books.js
             putBooks:
-                web-export: true
                 function: src/put-books.js
             deleteBooks:
-                web-export: true
                 function: src/delete-books.js
             listMembers:
-                web-export: true
                 function: src/list-members.js
         # new top-level key for defining groups of named APIs
         apis:
diff --git a/tests/src/integration/conductor/actions/increment.js 
b/tests/src/integration/conductor/actions/increment.js
new file mode 100644
index 0000000..ef3877d
--- /dev/null
+++ b/tests/src/integration/conductor/actions/increment.js
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/*
+ * Increment input value by 1
+ */
+function main({ value }) { return { value: value + 1 } }
diff --git a/tests/src/integration/conductor/actions/triple.js 
b/tests/src/integration/conductor/actions/triple.js
new file mode 100644
index 0000000..0636d1c
--- /dev/null
+++ b/tests/src/integration/conductor/actions/triple.js
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/*
+ * Return triple of the input value.
+ */
+function main({ value }) { return { value: value * 3 } }
diff --git a/tests/src/integration/conductor/actions/tripleAndIncrement.js 
b/tests/src/integration/conductor/actions/tripleAndIncrement.js
new file mode 100644
index 0000000..db5bcdb
--- /dev/null
+++ b/tests/src/integration/conductor/actions/tripleAndIncrement.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+function main(params) {
+    let step = params.$step || 0
+    delete params.$step
+    package_name = "conductorPackage1"
+    switch (step) {
+        case 0: return { action: package_name+'/triple', params, state: { 
$step: 1 } }
+        case 1: return { action: package_name+'/increment', params, state: { 
$step: 2 } }
+        case 2: return { params }
+    }
+}
diff --git a/tests/src/integration/conductor/conductor_test.go 
b/tests/src/integration/conductor/conductor_test.go
new file mode 100644
index 0000000..162d4f9
--- /dev/null
+++ b/tests/src/integration/conductor/conductor_test.go
@@ -0,0 +1,40 @@
+// +build integration
+
+/*
+ * 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 tests
+
+import (
+       "os"
+       "testing"
+
+       
"github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common"
+       "github.com/stretchr/testify/assert"
+)
+
+const PATH = 
"/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/conductor/"
+
+func TestManagedDeployment(t *testing.T) {
+       manifestPath := os.Getenv("GOPATH") + PATH + "manifest.yaml"
+       wskdeploy := common.NewWskdeploy()
+       _, err := wskdeploy.DeployManifestPathOnly(manifestPath)
+       assert.Equal(t, nil, err, "Failed to deploy based on the manifest 
file.")
+       _, err = wskdeploy.UndeployManifestPathOnly(manifestPath)
+       assert.Equal(t, nil, err, "Failed to deploy based on the manifest 
file.")
+
+}
diff --git a/tests/src/integration/conductor/manifest.yaml 
b/tests/src/integration/conductor/manifest.yaml
new file mode 100644
index 0000000..7e8ce4f
--- /dev/null
+++ b/tests/src/integration/conductor/manifest.yaml
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+project:
+    name: DemoConductor
+    packages:
+        conductorPackage1:
+            actions:
+                triple:
+                    function: actions/triple.js
+                increment:
+                    function: actions/increment.js
+                    runtime: nodejs:6
+                tripleAndIncrement:
+                    function: actions/tripleAndIncrement.js
+                    conductor: true
+        default:
+            actions:
+                triple:
+                    code: |
+                          function main({ value }) { return { value: value * 3 
} }
+                    runtime: nodejs:6
+                increment:
+                    code: |
+                          function main({ value }) { return { value: value + 1 
} }
+                    runtime: nodejs:6
+                tripleAndIncrement:
+                    code: |
+                          function main(params) {
+                              let step = params.$step || 0
+                              delete params.$step
+                              switch (step) {
+                                  case 0: return { action: 'triple', params, 
state: { $step: 1 } }
+                                  case 1: return { action: 'increment', 
params, state: { $step: 2 } }
+                                  case 2: return { params }
+                              }
+                          }
+                    runtime: nodejs:6
+                    conductor: true
+
diff --git a/tests/src/integration/websequence/manifest.yaml 
b/tests/src/integration/websequence/manifest.yaml
new file mode 100644
index 0000000..ebd9767
--- /dev/null
+++ b/tests/src/integration/websequence/manifest.yaml
@@ -0,0 +1,50 @@
+#
+# 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.
+#
+
+packages:
+    IntegrationTestWebSequence:
+        actions:
+            greeting-1:
+                version: 1.0
+                function: src/greeting.js
+                runtime: nodejs:6
+                inputs:
+                    name: string
+                    place: string
+                outputs:
+                    payload: string
+            greeting-2:
+                version: 1.0
+                function: src/greeting.js
+                runtime: nodejs:6
+                inputs:
+                    name: string
+                    place: string
+                outputs:
+                    payload: string
+        sequences:
+            greeting-sequence-1:
+                actions: greeting-1, greeting-2
+                web: true
+            greeting-sequence-2:
+                actions: greeting-1, greeting-2
+                web: raw
+        triggers:
+            webSequenceTrigger:
+        rules:
+            webSequenceRule:
+                trigger: webSequenceTrigger
+                action: greeting-sequence-1
\ No newline at end of file
diff --git a/tests/src/integration/websequence/src/greeting.js 
b/tests/src/integration/websequence/src/greeting.js
new file mode 100644
index 0000000..5c01d98
--- /dev/null
+++ b/tests/src/integration/websequence/src/greeting.js
@@ -0,0 +1,32 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+/**
+ * Return a simple greeting message for someone.
+ *
+ * @param name A person's name.
+ * @param place Where the person is from.
+ */
+function main(params) {
+    var name = params.name || params.payload || 'stranger';
+    var place = params.place || 'somewhere';
+    return {payload:  'Hello, ' + name + ' from ' + place + '!'};
+}
diff --git a/tests/src/integration/websequence/websequence_test.go 
b/tests/src/integration/websequence/websequence_test.go
new file mode 100644
index 0000000..7f6eaef
--- /dev/null
+++ b/tests/src/integration/websequence/websequence_test.go
@@ -0,0 +1,43 @@
+// +build integration
+
+/*
+ * 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 tests
+
+import (
+       "os"
+       "testing"
+
+       
"github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common"
+       "github.com/stretchr/testify/assert"
+)
+
+var wskprops = common.GetWskprops()
+
+func TestWebSequence(t *testing.T) {
+       wskdeploy := common.NewWskdeploy()
+       _, err := wskdeploy.Deploy(manifestPath, deploymentPath)
+       assert.Equal(t, nil, err, "Failed to deploy based on the manifest 
file.")
+       _, err = wskdeploy.Undeploy(manifestPath, deploymentPath)
+       assert.Equal(t, nil, err, "Failed to undeploy based on the manifest 
file.")
+}
+
+var (
+       manifestPath   = os.Getenv("GOPATH") + 
"/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/websequence/manifest.yaml"
+       deploymentPath = ""
+)
diff --git a/utils/conductor.go b/utils/conductor.go
new file mode 100644
index 0000000..8688d81
--- /dev/null
+++ b/utils/conductor.go
@@ -0,0 +1,29 @@
+/*
+ * 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 utils
+
+import "github.com/apache/incubator-openwhisk-client-go/whisk"
+
+const CONDUCTOR_ANNOTATION = "conductor"
+
+func ConductorAction() whisk.KeyValue {
+       return whisk.KeyValue{
+               Key:   CONDUCTOR_ANNOTATION,
+               Value: true,
+       }
+}
diff --git a/utils/conductor_test.go b/utils/conductor_test.go
new file mode 100644
index 0000000..ffaab6b
--- /dev/null
+++ b/utils/conductor_test.go
@@ -0,0 +1,37 @@
+// +build unit
+
+/*
+ * 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 utils
+
+import (
+       "testing"
+
+       "github.com/apache/incubator-openwhisk-client-go/whisk"
+       "github.com/stretchr/testify/assert"
+)
+
+const MSG_ERR_CONDUCTOR_ACTION_INVALID = "Conductor action does not create 
conductor annotation"
+
+func TestConductorAction(t *testing.T) {
+       conductor := ConductorAction()
+       annotation := whisk.KeyValue{Key: CONDUCTOR_ANNOTATION, Value: true}
+       assert.NotNil(t, conductor, MSG_ERR_CONDUCTOR_ACTION_INVALID)
+       assert.NotEqual(t, whisk.KeyValue{}, conductor, 
MSG_ERR_CONDUCTOR_ACTION_INVALID)
+       assert.Equal(t, annotation, conductor, MSG_ERR_CONDUCTOR_ACTION_INVALID)
+}
diff --git a/utils/misc.go b/utils/misc.go
index 3ffe17e..29c7b89 100644
--- a/utils/misc.go
+++ b/utils/misc.go
@@ -19,11 +19,6 @@ package utils
 
 import (
        "archive/zip"
-       "errors"
-       "fmt"
-       "github.com/apache/incubator-openwhisk-client-go/whisk"
-       "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
-       "github.com/hokaccha/go-prettyjson"
        "io"
        "io/ioutil"
        "net/http"
@@ -31,8 +26,10 @@ import (
        "os/user"
        "path"
        "path/filepath"
-       "reflect"
        "strings"
+
+       "github.com/apache/incubator-openwhisk-client-go/whisk"
+       "github.com/hokaccha/go-prettyjson"
 )
 
 const (
@@ -100,15 +97,6 @@ func PrettyJSON(j interface{}) (string, error) {
        return string(bytes), nil
 }
 
-var kindToJSON []string = []string{"", "boolean", "integer", "integer", 
"integer", "integer", "integer", "integer", "integer", "integer",
-       "integer", "integer", "integer", "number", "number", "number", 
"number", "array", "", "", "", "object", "", "", "string", "", ""}
-
-// Gets JSON type name
-func GetJSONType(j interface{}) string {
-       fmt.Print(reflect.TypeOf(j).Kind())
-       return kindToJSON[reflect.TypeOf(j).Kind()]
-}
-
 func NewZipWritter(src, des string) *ZipWritter {
        zw := &ZipWritter{src: src, des: des}
        return zw
@@ -165,28 +153,6 @@ func (zw *ZipWritter) Zip() error {
        return nil
 }
 
-func zipKindError() error {
-       errMsg := wski18n.T("creating an action from a .zip artifact requires 
specifying the action kind explicitly")
-
-       return errors.New(errMsg)
-}
-
-func extensionError(extension string) error {
-       errMsg := wski18n.T(
-               "'{{.name}}' is not a supported action runtime",
-               map[string]interface{}{
-                       "name": extension,
-               })
-
-       return errors.New(errMsg)
-}
-
-func javaEntryError() error {
-       errMsg := wski18n.T("Java actions require --main to specify the 
fully-qualified name of the main class")
-
-       return errors.New(errMsg)
-}
-
 func deleteKey(key string, keyValueArr whisk.KeyValueArr) whisk.KeyValueArr {
        for i := 0; i < len(keyValueArr); i++ {
                if keyValueArr[i].Key == key {
@@ -259,7 +225,7 @@ func (localReader *LocalReader) ReadLocal(path string) 
([]byte, error) {
 }
 
 func Read(url string) ([]byte, error) {
-       if strings.HasPrefix(url, "http") {
+       if strings.HasPrefix(url, HTTP_FILE_EXTENSION) {
                return new(ContentReader).URLReader.ReadUrl(url)
        } else {
                return new(ContentReader).LocalReader.ReadLocal(url)
diff --git a/utils/webaction.go b/utils/webaction.go
index 0d6c9c6..087a773 100644
--- a/utils/webaction.go
+++ b/utils/webaction.go
@@ -24,9 +24,12 @@ import (
 )
 
 //for web action support, code from wsk cli with tiny adjustments
-const WEB_EXPORT_ANNOT = "web-export"
-const RAW_HTTP_ANNOT = "raw-http"
-const FINAL_ANNOT = "final"
+const (
+       WEB_EXPORT_ANNOT = "web-export"
+       RAW_HTTP_ANNOT   = "raw-http"
+       FINAL_ANNOT      = "final"
+       TRUE             = "true"
+)
 
 var webExport map[string]string = map[string]string{
        "TRUE":  "true",
diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go
index 3677f90..1ede72a 100644
--- a/wski18n/i18n_ids.go
+++ b/wski18n/i18n_ids.go
@@ -175,7 +175,6 @@ const (
        ID_ERR_RUNTIME_ACTION_SOURCE_NOT_SUPPORTED_X_ext_X_action_X      = 
"msg_err_runtime_action_source_not_supported"
        ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X                  = 
"msg_err_url_invalid"
        ID_ERR_URL_MALFORMED_X_urltype_X_url_X                           = 
"msg_err_url_malformed"
-       ID_ERR_API_MISSING_WEB_ACTION_X_action_X_api_X                   = 
"msg_err_api_missing_web_action"
        ID_ERR_API_MISSING_ACTION_X_action_X_api_X                       = 
"msg_err_api_missing_action"
        ID_ERR_ACTION_INVALID_X_action_X                                 = 
"msg_err_action_invalid"
        ID_ERR_ACTION_MISSING_RUNTIME_WITH_CODE_X_action_X               = 
"msg_err_action_missing_runtime_with_code"
@@ -206,6 +205,8 @@ const (
        ID_WARN_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X          = 
"msg_warn_deployment_name_not_found"
        ID_WARN_PROJECT_NAME_OVERRIDDEN                           = 
"msg_warn_project_name_overridden"
        ID_WARN_PACKAGE_IS_PUBLIC_X_package_X                     = 
"msg_warn_package_is_public"
+       ID_WARN_ACTION_WEB_X_action_X                             = 
"msg_warn_action_web_export_ignored"
+       ID_WARN_API_MISSING_WEB_ACTION_X_action_X_api_X           = 
"msg_warn_api_missing_web_action"
 
        // Verbose (Debug/Trace) messages
        ID_DEBUG_PROJECT_SEARCH_X_path_X_key_X                = 
"msg_dbg_searching_project_directory"
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 2f6894b..7bc2343 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -97,7 +97,7 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
        return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5b\x6d\x8f\xdb\x36\xf2\x7f\x9f\x4f\x31\x08\xfe\x40\x5a\xc0\x51\xd2\xfe\x71\xc0\x21\x40\x5e\xe4\x9a\xb4\xdd\x6b\x93\x0d\x76\xb3\x17\x14\xb9\x85\x42\x4b\x63\x9b\xb5\x44\x0a\x24\x65\xc7\x35\xfc\xdd\x0f\x33\xa4\x1e\xec\x5d\x4a\x5a\xa7\xbd\xeb\x9b\xf3\x2d\x87\x33\xbf\x79\xe0\x70\x66\xa8\x7c\x7a\x04\xb0\x7f\x04\x00\xf0\x58\xe6\x8f\x5f\xc0\xe3\xd2\x2e\xd3\xca\xe0\x42\x7e\x49\xd1\x18\x6d\x1e\xcf\xfc\xaa\x33
 [...]
+var _wski18nResourcesEn_usAllJson = 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5b\x6d\x8f\xdb\x36\xf2\x7f\x9f\x4f\x31\x08\xfe\x40\x5a\xc0\x51\xd2\xfe\x71\xc0\x21\xc0\xbe\xc8\x75\xd3\x76\xaf\x4d\x36\xd8\xcd\x5e\x50\xe4\x16\x0a\x2d\x8d\x6d\xd6\x12\x29\x90\x94\x1d\x77\xe1\xef\x7e\x98\x21\xf5\x60\xef\x52\xd2\x3a\xed\x5d\xdf\xd4\x09\x87\x33\xbf\x19\x0e\xe7\x89\xca\xa7\x27\x00\x77\x4f\x00\x00\x9e\xca\xfc\xe9\x2b\x78\x5a\xda\x65\x5a\x19\x5c\xc8\x2f\x29\x1a\xa3\xcd\xd3\x99\x5f\x75\x46
 [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
        return bindataRead(
@@ -112,7 +112,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 
13874, mode: os.FileMode(420), modTime: time.Unix(1522158494, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 
14019, mode: os.FileMode(420), modTime: time.Unix(1522283010, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index 9824ddb..b03692a 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -292,10 +292,6 @@
     "translation": "JSON input data Missing 'cmd' key"
   },
   {
-    "id": "msg_err_api_missing_web_action",
-    "translation": "Action [{{.action}}] is not a web action, API [{{.api}}] 
can only be created using web action. Please update manifest file to convert 
[{{.action}}] to web action.\n"
-  },
-  {
     "id": "msg_err_api_missing_action",
     "translation": "Action [{{.action}}] is missing from manifest file, API 
[{{.api}}] can only be created based on the action from manifest file. Please 
update manifest file to include [{{.action}}] as a web action.\n"
   },
@@ -400,6 +396,14 @@
     "translation": "[{{.package}}] is marked as public in manifest file, it 
will be visible and can be accessed by anyone"
   },
   {
+    "id": "msg_warn_action_web_export_ignored",
+    "translation": "[{{.action}}] has both web and web-export specified, only 
reading web, ignoring web-export."
+  },
+  {
+    "id": "msg_warn_api_missing_web_action",
+    "translation": "Action [{{.action}}] is not a web action, API [{{.api}}] 
can only be created using web action. Converting [{{.action}}] to a web 
action.\n"
+  },
+  {
     "id": "DEBUG",
     "translation": "================= DEBUG ==================="
   },

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to