You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by mr...@apache.org on 2017/10/03 21:37:10 UTC

[incubator-openwhisk-wskdeploy] branch master updated: Add the support of the key 'packages' in deployment.yaml (#580)

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 eab6a7b  Add the support of the key 'packages' in deployment.yaml (#580)
eab6a7b is described below

commit eab6a7bb05b54dbf4f79152a4f8131ac0a7086be
Author: Vincent <sh...@us.ibm.com>
AuthorDate: Tue Oct 3 17:37:08 2017 -0400

    Add the support of the key 'packages' in deployment.yaml (#580)
    
    Closes #572
---
 cmd/root.go                                        |   3 +
 deployers/deploymentreader.go                      |  43 ++++-
 deployers/deploymentreader_test.go                 |  69 ++++++++
 deployers/servicedeployer.go                       |  32 +++-
 parsers/deploy_parser.go                           |   7 +-
 parsers/deploy_parser_test.go                      |  43 ++++-
 parsers/manifest_parser.go                         | 188 +++++++++++++--------
 parsers/yamlparser.go                              |   5 +-
 .../deployment-deploymentreader-test-package.yml   |  16 ++
 .../deployment-deploymentreader-test-packages.yml  |  16 ++
 tests/dat/deployment_data_package.yaml             |   7 +
 tests/dat/deployment_data_packages.yaml            |   7 +
 tests/src/integration/flagstests/manifest.yaml     |   2 +-
 wski18n/i18n_resources.go                          |   4 +-
 wski18n/resources/en_US.all.json                   |   5 +
 15 files changed, 359 insertions(+), 88 deletions(-)

diff --git a/cmd/root.go b/cmd/root.go
index acdfbf7..03ab905 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -314,6 +314,9 @@ func Undeploy() error {
 		setSupportedRuntimes(clientConfig.Host)
 
 		verifiedPlan, err := deployer.ConstructUnDeploymentPlan()
+        if err != nil {
+            return err
+        }
 		err = deployer.UnDeploy(verifiedPlan)
 		if err != nil {
 			return err
diff --git a/deployers/deploymentreader.go b/deployers/deploymentreader.go
index dc96a6c..7d8f8b1 100644
--- a/deployers/deploymentreader.go
+++ b/deployers/deploymentreader.go
@@ -63,10 +63,21 @@ func (reader *DeploymentReader) bindPackageInputsAndAnnotations() {
 
 	packMap := make(map[string]parsers.Package)
 
-	if reader.DeploymentDescriptor.Application.Packages == nil {
+    if reader.DeploymentDescriptor.Application.Packages == nil {
 		// a single package is specified in deployment YAML file with "package" key
-		packMap[reader.DeploymentDescriptor.Application.Package.Packagename] = reader.DeploymentDescriptor.Application.Package
-        utils.PrintOpenWhiskOutputln("WARNING: The package YAML key in deployment file will soon be deprecated. Please use packages instead as described in specifications.")
+        if len(reader.DeploymentDescriptor.Application.Package.Packagename) != 0 {
+            packMap[reader.DeploymentDescriptor.Application.Package.Packagename] = reader.DeploymentDescriptor.Application.Package
+            utils.PrintOpenWhiskOutputln("WARNING: The package YAML key in deployment file will soon be deprecated. Please use packages instead as described in specifications.")
+        } else {
+            if reader.DeploymentDescriptor.Packages != nil {
+                for packName, depPacks := range reader.DeploymentDescriptor.Packages {
+                    depPacks.Packagename = packName
+                    packMap[packName] = depPacks
+                }
+            } else {
+                packMap[reader.DeploymentDescriptor.Package.Packagename] = reader.DeploymentDescriptor.Package
+            }
+        }
 	} else {
 		for packName, depPacks := range reader.DeploymentDescriptor.Application.Packages {
 			depPacks.Packagename = packName
@@ -134,7 +145,18 @@ func (reader *DeploymentReader) bindActionInputsAndAnnotations() {
 
 	if reader.DeploymentDescriptor.Application.Packages == nil {
 		// a single package is specified in deployment YAML file with "package" key
-		packMap[reader.DeploymentDescriptor.Application.Package.Packagename] = reader.DeploymentDescriptor.Application.Package
+        if len(reader.DeploymentDescriptor.Application.Package.Packagename) != 0 {
+            packMap[reader.DeploymentDescriptor.Application.Package.Packagename] = reader.DeploymentDescriptor.Application.Package
+        } else {
+            if reader.DeploymentDescriptor.Packages != nil {
+                for packName, depPacks := range reader.DeploymentDescriptor.Packages {
+                    depPacks.Packagename = packName
+                    packMap[packName] = depPacks
+                }
+            } else {
+                packMap[reader.DeploymentDescriptor.Package.Packagename] = reader.DeploymentDescriptor.Package
+            }
+        }
 	} else {
 		for packName, depPacks := range reader.DeploymentDescriptor.Application.Packages {
 			depPacks.Packagename = packName
@@ -206,7 +228,18 @@ func (reader *DeploymentReader) bindTriggerInputsAndAnnotations() {
 	packMap := make(map[string]parsers.Package)
 
 	if reader.DeploymentDescriptor.Application.Packages == nil {
-		packMap[reader.DeploymentDescriptor.Application.Package.Packagename] = reader.DeploymentDescriptor.Application.Package
+        if len(reader.DeploymentDescriptor.Application.Package.Packagename) != 0 {
+            packMap[reader.DeploymentDescriptor.Application.Package.Packagename] = reader.DeploymentDescriptor.Application.Package
+        } else {
+            if reader.DeploymentDescriptor.Packages != nil {
+                for packName, depPacks := range reader.DeploymentDescriptor.Packages {
+                    depPacks.Packagename = packName
+                    packMap[packName] = depPacks
+                }
+            } else {
+                packMap[reader.DeploymentDescriptor.Package.Packagename] = reader.DeploymentDescriptor.Package
+            }
+        }
 	} else {
 		for packName, depPacks := range reader.DeploymentDescriptor.Application.Packages {
 			depPacks.Packagename = packName
diff --git a/deployers/deploymentreader_test.go b/deployers/deploymentreader_test.go
index c3e92aa..458ebe2 100644
--- a/deployers/deploymentreader_test.go
+++ b/deployers/deploymentreader_test.go
@@ -85,3 +85,72 @@ func TestDeploymentReader_bindTrigger(t *testing.T) {
 		}
 	}
 }
+
+func TestDeploymentReader_bindTrigger_packages(t *testing.T) {
+    //init variables
+    sDeployer := NewServiceDeployer()
+    sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test-packages.yml"
+    sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger)
+
+    //parse deployment and bind triggers input and annotation
+    dReader := NewDeploymentReader(sDeployer)
+    dReader.HandleYaml()
+    dReader.bindTriggerInputsAndAnnotations()
+
+    trigger := sDeployer.Deployment.Triggers["locationUpdate"]
+    for _, param := range trigger.Parameters {
+        switch param.Key {
+        case "name":
+            assert.Equal(t, "Bernie", param.Value, "Failed to set inputs")
+        case "place":
+            assert.Equal(t, "DC", param.Value, "Failed to set inputs")
+        default:
+            assert.Fail(t, "Failed to get inputs key")
+
+        }
+    }
+    for _, annos := range trigger.Annotations {
+        switch annos.Key {
+        case "bbb":
+            assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations")
+        default:
+            assert.Fail(t, "Failed to get annotation key")
+
+        }
+    }
+}
+
+func TestDeploymentReader_bindTrigger_package(t *testing.T) {
+    //init variables
+    sDeployer := NewServiceDeployer()
+    sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test-package.yml"
+    sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger)
+
+    //parse deployment and bind triggers input and annotation
+    dReader := NewDeploymentReader(sDeployer)
+    dReader.HandleYaml()
+    dReader.bindTriggerInputsAndAnnotations()
+
+    assert.Equal(t, "triggerrule", dReader.DeploymentDescriptor.Package.Packagename)
+    trigger := sDeployer.Deployment.Triggers["locationUpdate"]
+    for _, param := range trigger.Parameters {
+        switch param.Key {
+        case "name":
+            assert.Equal(t, "Bernie", param.Value, "Failed to set inputs")
+        case "place":
+            assert.Equal(t, "DC", param.Value, "Failed to set inputs")
+        default:
+            assert.Fail(t, "Failed to get inputs key")
+
+        }
+    }
+    for _, annos := range trigger.Annotations {
+        switch annos.Key {
+        case "bbb":
+            assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations")
+        default:
+            assert.Fail(t, "Failed to get annotation key")
+
+        }
+    }
+}
diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go
index c52f377..a5b099f 100644
--- a/deployers/servicedeployer.go
+++ b/deployers/servicedeployer.go
@@ -138,13 +138,29 @@ func (deployer *ServiceDeployer) ConstructDeploymentPlan() error {
 		return err
 	}
 
+    applicationName := ""
+    if len(manifest.Application.Packages) != 0 {
+        applicationName = manifest.Application.Name
+    }
+
 	// process deploymet file
 	if utils.FileExists(deployer.DeploymentPath) {
 		var deploymentReader = NewDeploymentReader(deployer)
 		err = deploymentReader.HandleYaml()
+
 		if err != nil {
 			return err
 		}
+        // compare the name of the application
+        if len(deploymentReader.DeploymentDescriptor.Application.Packages) != 0 && len(applicationName) != 0 {
+            appNameDeploy := deploymentReader.DeploymentDescriptor.Application.Name
+            if appNameDeploy != applicationName {
+                errorString := wski18n.T("The name of the application {{.appNameDeploy}} in deployment file at [{{.deploymentFile}}] does not match the name of the application {{.appNameManifest}}} in manifest file at [{{.manifestFile}}].",
+                    map[string]interface{}{"appNameDeploy": appNameDeploy, "deploymentFile": deployer.DeploymentPath,
+                        "appNameManifest": applicationName,  "manifestFile": deployer.ManifestPath })
+                return utils.NewInputYamlFormatError(errorString)
+            }
+        }
 
 		deploymentReader.BindAssets()
 	}
@@ -186,6 +202,11 @@ func (deployer *ServiceDeployer) ConstructUnDeploymentPlan() (*DeploymentApplica
 		return deployer.Deployment, err
 	}
 
+    applicationName := ""
+    if len(manifest.Application.Packages) != 0 {
+        applicationName = manifest.Application.Name
+    }
+
 	// process deployment file
 	if utils.FileExists(deployer.DeploymentPath) {
 		var deploymentReader = NewDeploymentReader(deployer)
@@ -193,7 +214,16 @@ func (deployer *ServiceDeployer) ConstructUnDeploymentPlan() (*DeploymentApplica
 		if err != nil {
 			return deployer.Deployment, err
 		}
-
+        // compare the name of the application
+        if len(deploymentReader.DeploymentDescriptor.Application.Packages) != 0 && len(applicationName) != 0 {
+            appNameDeploy := deploymentReader.DeploymentDescriptor.Application.Name
+            if appNameDeploy != applicationName {
+                errorString := wski18n.T("The name of the application {{.appNameDeploy}} in deployment file at [{{.deploymentFile}}] does not match the name of the application {{.appNameManifest}}} in manifest file at [{{.manifestFile}}].",
+                    map[string]interface{}{"appNameDeploy": appNameDeploy, "deploymentFile": deployer.DeploymentPath,
+                        "appNameManifest": applicationName,  "manifestFile": deployer.ManifestPath })
+                return deployer.Deployment, utils.NewInputYamlFormatError(errorString)
+            }
+        }
 		deploymentReader.BindAssets()
 	}
 
diff --git a/parsers/deploy_parser.go b/parsers/deploy_parser.go
index 2c89083..60b0c3f 100644
--- a/parsers/deploy_parser.go
+++ b/parsers/deploy_parser.go
@@ -49,11 +49,8 @@ func (dm *YAMLParser) ParseDeployment(deploymentPath string) (*DeploymentYAML, e
     }
 	err = dm.UnmarshalDeployment(content, &dplyyaml)
     if err != nil {
-        if err != nil {
-
-            lines, msgs := dm.convertErrorToLinesMsgs(err.Error())
-            return &dplyyaml, utils.NewParserErr(deploymentPath, lines, msgs)
-        }
+        lines, msgs := dm.convertErrorToLinesMsgs(err.Error())
+        return &dplyyaml, utils.NewParserErr(deploymentPath, lines, msgs)
     }
 	dplyyaml.Filepath = deploymentPath
 	return &dplyyaml, nil
diff --git a/parsers/deploy_parser_test.go b/parsers/deploy_parser_test.go
index 3ab06e3..86ed25a 100644
--- a/parsers/deploy_parser_test.go
+++ b/parsers/deploy_parser_test.go
@@ -106,7 +106,7 @@ func TestParseDeploymentYAML_Application(t *testing.T) {
 	assert.Equal(t, "172.17.0.1", deployment.Application.ApiHost, "Get application api host failed.")
 }
 
-func TestParseDeploymentYAML_Package(t *testing.T) {
+func TestParseDeploymentYAML_Application_Package(t *testing.T) {
 	//var deployment utils.DeploymentYAML
 	mm := NewYAMLParser()
 	deployment, _ := mm.ParseDeployment("../tests/dat/deployment_data_application_package.yaml")
@@ -126,6 +126,47 @@ func TestParseDeploymentYAML_Package(t *testing.T) {
 	}
 }
 
+func TestParseDeploymentYAML_Packages(t *testing.T) {
+    //var deployment utils.DeploymentYAML
+    mm := NewYAMLParser()
+    deployment, _ := mm.ParseDeployment("../tests/dat/deployment_data_packages.yaml")
+
+    assert.Equal(t, 0, len(deployment.Application.Packages), "Packages under application are empty.")
+    assert.Equal(t, 0, len(deployment.Application.Package.Packagename), "Package name is empty.")
+    assert.Equal(t, 1, len(deployment.Packages), "Packages are available.")
+    for pkg_name := range deployment.Packages {
+        assert.Equal(t, "test_package", pkg_name, "Get package name failed.")
+        var pkg = deployment.Packages[pkg_name]
+        assert.Equal(t, "/wskdeploy/samples/test", pkg.Namespace, "Get package namespace failed.")
+        assert.Equal(t, "12345678ABCDEF", pkg.Credential, "Get package credential failed.")
+        assert.Equal(t, 1, len(pkg.Inputs), "Get package input list failed.")
+        //get and verify inputs
+        for param_name, param := range pkg.Inputs {
+            assert.Equal(t, "value", param.Value, "Get input value failed.")
+            assert.Equal(t, "param", param_name, "Get input param name failed.")
+        }
+    }
+}
+
+func TestParseDeploymentYAML_Package(t *testing.T) {
+    //var deployment utils.DeploymentYAML
+    mm := NewYAMLParser()
+    deployment, _ := mm.ParseDeployment("../tests/dat/deployment_data_package.yaml")
+
+    assert.Equal(t, 0, len(deployment.Application.Packages), "Get package list failed.")
+    assert.Equal(t, 0, len(deployment.Application.Package.Packagename), "Package name is empty.")
+    assert.Equal(t, 0, len(deployment.Packages), "Get package list failed.")
+    assert.Equal(t, "test_package", deployment.Package.Packagename, "Get package name failed.")
+    assert.Equal(t, "/wskdeploy/samples/test", deployment.Package.Namespace, "Get package namespace failed.")
+    assert.Equal(t, "12345678ABCDEF", deployment.Package.Credential, "Get package credential failed.")
+    assert.Equal(t, 1, len(deployment.Package.Inputs), "Get package input list failed.")
+    //get and verify inputs
+    for param_name, param := range deployment.Package.Inputs {
+        assert.Equal(t, "value", param.Value, "Get input value failed.")
+        assert.Equal(t, "param", param_name, "Get input param name failed.")
+    }
+}
+
 func TestParseDeploymentYAML_Action(t *testing.T) {
 	mm := NewYAMLParser()
     deployment, _ := mm.ParseDeployment("../tests/dat/deployment_data_application_package.yaml")
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index 0b0ead8..e6a2023 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -103,20 +103,26 @@ func (dm *YAMLParser) ParseManifest(manifestPath string) (*ManifestYAML, error)
 
 func (dm *YAMLParser) ComposeDependenciesFromAllPackages(manifest *ManifestYAML, projectPath string, filePath string) (map[string]utils.DependencyRecord, error) {
 	dependencies := make(map[string]utils.DependencyRecord)
+    packages := make(map[string]Package)
 	if manifest.Package.Packagename != "" {
 		return dm.ComposeDependencies(manifest.Package, projectPath, filePath, manifest.Package.Packagename)
-	} else if manifest.Packages != nil {
-		for n, p := range manifest.Packages {
-			d, err := dm.ComposeDependencies(p, projectPath, filePath, n)
-			if err == nil {
-				for k, v := range d {
-					dependencies[k] = v
-				}
-			} else {
-				return nil, err
-			}
-		}
-	}
+	} else {
+        if manifest.Packages != nil {
+            packages = manifest.Packages
+        } else {
+            packages = manifest.Application.Packages
+        }
+    }
+    for n, p := range packages {
+        d, err := dm.ComposeDependencies(p, projectPath, filePath, n)
+        if err == nil {
+            for k, v := range d {
+                dependencies[k] = v
+            }
+        } else {
+            return nil, err
+        }
+    }
 	return dependencies, nil
 }
 
@@ -186,6 +192,7 @@ func (dm *YAMLParser) ComposeDependencies(pkg Package, projectPath string, fileP
 
 func (dm *YAMLParser) ComposeAllPackages(manifest *ManifestYAML, filePath string) (map[string]*whisk.Package, error) {
 	packages := map[string]*whisk.Package{}
+    manifestPackages := make(map[string]Package)
 	if manifest.Package.Packagename != "" {
 		fmt.Println("WARNING: using package inside of manifest file will soon be deprecated, please use packages instead.")
 		s, err := dm.ComposePackage(manifest.Package, manifest.Package.Packagename, filePath)
@@ -194,16 +201,23 @@ func (dm *YAMLParser) ComposeAllPackages(manifest *ManifestYAML, filePath string
 		} else {
 			return nil, err
 		}
-	} else if manifest.Packages != nil {
-		for n, p := range manifest.Packages {
-			s, err := dm.ComposePackage(p, n, filePath)
-			if err == nil {
-				packages[n] = s
-			} else {
-				return nil, err
-			}
-		}
-	}
+	} else {
+        if manifest.Packages != nil {
+            manifestPackages = manifest.Packages
+        } else {
+            manifestPackages = manifest.Application.Packages
+        }
+    }
+
+    for n, p := range manifestPackages {
+        s, err := dm.ComposePackage(p, n, filePath)
+        if err == nil {
+            packages[n] = s
+        } else {
+            return nil, err
+        }
+    }
+
 	return packages, nil
 }
 
@@ -265,18 +279,24 @@ func (dm *YAMLParser) ComposePackage(pkg Package, packageName string, filePath s
 
 func (dm *YAMLParser) ComposeSequencesFromAllPackages(namespace string, mani *ManifestYAML) ([]utils.ActionRecord, error) {
 	var s1 []utils.ActionRecord = make([]utils.ActionRecord, 0)
+    manifestPackages := make(map[string]Package)
 	if mani.Package.Packagename != "" {
 		return dm.ComposeSequences(namespace, mani.Package.Sequences, mani.Package.Packagename)
-	} else if mani.Packages != nil {
-		for n, p := range mani.Packages {
-			s, err := dm.ComposeSequences(namespace, p.Sequences, n)
-			if err == nil {
-				s1 = append(s1, s...)
-			} else {
-				return nil, err
-			}
-		}
-	}
+	} else {
+        if mani.Packages != nil {
+            manifestPackages = mani.Packages
+        } else {
+            manifestPackages = mani.Application.Packages
+        }
+    }
+    for n, p := range manifestPackages {
+        s, err := dm.ComposeSequences(namespace, p.Sequences, n)
+        if err == nil {
+            s1 = append(s1, s...)
+        } else {
+            return nil, err
+        }
+    }
 	return s1, nil
 }
 
@@ -324,18 +344,24 @@ func (dm *YAMLParser) ComposeSequences(namespace string, sequences map[string]Se
 
 func (dm *YAMLParser) ComposeActionsFromAllPackages(manifest *ManifestYAML, filePath string) ([]utils.ActionRecord, error) {
 	var s1 []utils.ActionRecord = make([]utils.ActionRecord, 0)
+    manifestPackages := make(map[string]Package)
 	if manifest.Package.Packagename != "" {
 		return dm.ComposeActions(filePath, manifest.Package.Actions, manifest.Package.Packagename)
-	} else if manifest.Packages != nil {
-		for n, p := range manifest.Packages {
-			a, err := dm.ComposeActions(filePath, p.Actions, n)
-			if err == nil {
-				s1 = append(s1, a...)
-			} else {
-				return nil, err
-			}
-		}
-	}
+	} else {
+        if manifest.Packages != nil {
+            manifestPackages = manifest.Packages
+        } else {
+            manifestPackages = manifest.Application.Packages
+        }
+    }
+    for n, p := range manifestPackages {
+        a, err := dm.ComposeActions(filePath, p.Actions, n)
+        if err == nil {
+            s1 = append(s1, a...)
+        } else {
+            return nil, err
+        }
+    }
 	return s1, nil
 }
 
@@ -511,18 +537,24 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 
 func (dm *YAMLParser) ComposeTriggersFromAllPackages(manifest *ManifestYAML, filePath string) ([]*whisk.Trigger, error) {
 	var triggers []*whisk.Trigger = make([]*whisk.Trigger, 0)
+    manifestPackages := make(map[string]Package)
 	if manifest.Package.Packagename != "" {
 		return dm.ComposeTriggers(filePath, manifest.Package)
-	} else if manifest.Packages != nil {
-		for _, p := range manifest.Packages {
-			t, err := dm.ComposeTriggers(filePath, p)
-			if err == nil {
-				triggers = append(triggers, t...)
-			} else {
-				return nil, err
-			}
-		}
-	}
+	} else {
+        if manifest.Packages != nil {
+            manifestPackages = manifest.Packages
+        } else {
+            manifestPackages = manifest.Application.Packages
+        }
+    }
+    for _, p := range manifestPackages {
+        t, err := dm.ComposeTriggers(filePath, p)
+        if err == nil {
+            triggers = append(triggers, t...)
+        } else {
+            return nil, err
+        }
+    }
 	return triggers, nil
 }
 
@@ -584,18 +616,24 @@ func (dm *YAMLParser) ComposeTriggers(filePath string, pkg Package) ([]*whisk.Tr
 
 func (dm *YAMLParser) ComposeRulesFromAllPackages(manifest *ManifestYAML) ([]*whisk.Rule, error) {
 	var rules []*whisk.Rule = make([]*whisk.Rule, 0)
+    manifestPackages := make(map[string]Package)
 	if manifest.Package.Packagename != "" {
 		return dm.ComposeRules(manifest.Package, manifest.Package.Packagename)
-	} else if manifest.Packages != nil {
-		for n, p := range manifest.Packages {
-			r, err := dm.ComposeRules(p, n)
-			if err == nil {
-				rules = append(rules, r...)
-			} else {
-				return nil, err
-			}
-		}
-	}
+	} else {
+        if manifest.Packages != nil {
+            manifestPackages = manifest.Packages
+        } else {
+            manifestPackages = manifest.Application.Packages
+        }
+    }
+    for n, p := range manifestPackages {
+        r, err := dm.ComposeRules(p, n)
+        if err == nil {
+            rules = append(rules, r...)
+        } else {
+            return nil, err
+        }
+    }
 	return rules, nil
 }
 
@@ -616,18 +654,24 @@ func (dm *YAMLParser) ComposeRules(pkg Package, packageName string) ([]*whisk.Ru
 
 func (dm *YAMLParser) ComposeApiRecordsFromAllPackages(manifest *ManifestYAML) ([]*whisk.ApiCreateRequest, error) {
 	var requests []*whisk.ApiCreateRequest = make([]*whisk.ApiCreateRequest, 0)
+    manifestPackages := make(map[string]Package)
 	if manifest.Package.Packagename != "" {
 		return dm.ComposeApiRecords(manifest.Package)
-	} else if manifest.Packages != nil {
-		for _, p := range manifest.Packages {
-			r, err := dm.ComposeApiRecords(p)
-			if err == nil {
-				requests = append(requests, r...)
-			} else {
-				return nil, err
-			}
-		}
-	}
+	} else {
+        if manifest.Packages != nil {
+            manifestPackages = manifest.Packages
+        } else {
+            manifestPackages = manifest.Application.Packages
+        }
+    }
+    for _, p := range manifestPackages {
+        r, err := dm.ComposeApiRecords(p)
+        if err == nil {
+            requests = append(requests, r...)
+        } else {
+            return nil, err
+        }
+    }
 	return requests, nil
 }
 
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index b6c8950..ff0cf99 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -178,7 +178,9 @@ type Application struct {
 }
 
 type DeploymentYAML struct {
-	Application Application `yaml:"application"` //used in deployment.yaml
+	Application Application       `yaml:"application"` //used in deployment.yaml
+    Packages   map[string]Package `yaml:"packages"` //used in deployment.yaml
+    Package    Package            `yaml:"package"`
 	Filepath    string      //file path of the yaml file
 }
 
@@ -186,6 +188,7 @@ type ManifestYAML struct {
 	Package  Package `yaml:"package"` //used in both manifest.yaml and deployment.yaml
 	Packages map[string]Package `yaml:"packages"`
 	Filepath string  //file path of the yaml file
+    Application Application       `yaml:"application"` //used in manifest.yaml
 }
 
 //********************Trigger functions*************************//
diff --git a/tests/dat/deployment-deploymentreader-test-package.yml b/tests/dat/deployment-deploymentreader-test-package.yml
new file mode 100644
index 0000000..cbae8d8
--- /dev/null
+++ b/tests/dat/deployment-deploymentreader-test-package.yml
@@ -0,0 +1,16 @@
+package:
+      name: triggerrule
+      actions:
+        greeting:
+          inputs:
+            name: Amy
+            place: Paris
+          annotations:
+            aaa: this is an annotation
+      triggers:
+        locationUpdate:
+          inputs:
+            name: Bernie
+            place: DC
+          annotations:
+            bbb: this is an annotation
diff --git a/tests/dat/deployment-deploymentreader-test-packages.yml b/tests/dat/deployment-deploymentreader-test-packages.yml
new file mode 100644
index 0000000..d45ecfa
--- /dev/null
+++ b/tests/dat/deployment-deploymentreader-test-packages.yml
@@ -0,0 +1,16 @@
+packages:
+    triggerrule:
+      actions:
+        greeting:
+          inputs:
+            name: Amy
+            place: Paris
+          annotations:
+            aaa: this is an annotation
+      triggers:
+        locationUpdate:
+          inputs:
+            name: Bernie
+            place: DC
+          annotations:
+            bbb: this is an annotation
diff --git a/tests/dat/deployment_data_package.yaml b/tests/dat/deployment_data_package.yaml
new file mode 100644
index 0000000..e1b2d86
--- /dev/null
+++ b/tests/dat/deployment_data_package.yaml
@@ -0,0 +1,7 @@
+package:
+    name: test_package
+    namespace: /wskdeploy/samples/test
+    credential: 12345678ABCDEF
+    inputs:
+      param: value
+
diff --git a/tests/dat/deployment_data_packages.yaml b/tests/dat/deployment_data_packages.yaml
new file mode 100644
index 0000000..a9b8738
--- /dev/null
+++ b/tests/dat/deployment_data_packages.yaml
@@ -0,0 +1,7 @@
+packages:
+  test_package:
+    namespace: /wskdeploy/samples/test
+    credential: 12345678ABCDEF
+    inputs:
+      param: value
+
diff --git a/tests/src/integration/flagstests/manifest.yaml b/tests/src/integration/flagstests/manifest.yaml
index a998688..f67ff2f 100644
--- a/tests/src/integration/flagstests/manifest.yaml
+++ b/tests/src/integration/flagstests/manifest.yaml
@@ -1,5 +1,5 @@
 packages:
-  helloWorldFlags:
+    helloWorldFlags:
       version: 1.0
       license: Apache-2.0
       actions:
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index c810e27..d3c127f 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -114,7 +114,7 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
     return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x41\x6f\xdb\x3c\x12\xbd\xe7\x57\x0c\x72\xf1\x25\xd0\xb6\x5d\x2c\xb0\xe8\x2d\x68\xbb\x6d\xd0\x36\x0d\x92\x6c\x8b\xa2\x5b\x20\x8c\x34\xb2\x58\x53\xa4\x40\x52\x0e\x5c\xc1\xff\x7d\x41\x51\xb2\x9d\x84\xa2\x28\x59\xf6\x76\x81\x2f\x27\xc7\xe6\xbc\xf7\x66\x48\x0e\x67\x24\xfe\x38\x01\xa8\x4e\x00\x00\x4e\x69\x72\xfa\x1a\x4e\x3f\x20\x63\xe2\xf4\xcc\x7e\xa5\x25\xe1\x8a\x11\x4d\x05\x37\xbf\x9d\x73\x38\xbf\xba [...]
+var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x5d\x6f\xdb\x3a\x12\x7d\xcf\xaf\x18\xe4\xc5\x2f\x81\xb6\xbd\x8b\x05\x16\x7d\x0b\x6e\xbf\x82\xb6\x69\x90\x64\x5b\x14\xdd\x02\x61\xc4\xb1\xc5\x9a\x22\x05\x92\x72\xe0\x1a\xfe\xef\x0b\x8a\x92\xed\x24\x14\x45\xc9\xb2\xb7\xbb\xb8\x7d\x72\x6c\xce\x39\x67\x86\xe4\x70\x46\x62\xbf\x9f\x00\xac\x4e\x00\x00\x4e\x19\x3d\x7d\x05\xa7\xef\x91\x73\x79\x7a\xe6\xbe\x32\x8a\x08\xcd\x89\x61\x52\xd8\xdf\xce\x05\x9c\x5f [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
     return bindataRead(
@@ -129,7 +129,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 13189, mode: os.FileMode(420), modTime: time.Unix(1506953492, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 13627, mode: os.FileMode(420), modTime: time.Unix(1507040831, 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 72b0ca7..34a6be1 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -330,5 +330,10 @@
   {
     "id": "path of the .cert file",
     "translation": "path of the .cert file"
+  },
+  {
+    "id": "The name of the application {{.appNameDeploy}} in deployment file at [{{.deploymentFile}}] does not match the name of the application {{.appNameManifest}}} in manifest file at [{{.manifestFile}}].",
+    "translation": "The name of the application {{.appNameDeploy}} in deployment file at [{{.deploymentFile}}] does not match the name of the application {{.appNameManifest}}} in manifest file at [{{.manifestFile}}]."
   }
+
 ]

-- 
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].