Skip to content

Commit

Permalink
Merge pull request #7 from ystia/hotfix/operations-with-implem-artifact
Browse files Browse the repository at this point in the history
Hotfix: operations with implem artifact
  • Loading branch information
loicalbertin committed Mar 8, 2018
2 parents 728adcd + c19e593 commit 86350b0
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 59 deletions.
23 changes: 16 additions & 7 deletions deployments/definition_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,12 +551,12 @@ func storeTypes(ctx context.Context, topology tosca.Topology, topologyPrefix, im
} else {
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/primary", path.Join(importPath, operationDef.Implementation.Primary))
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/dependencies", strings.Join(operationDef.Implementation.Dependencies, ","))
if operationDef.Implementation.OperationHost != "" {
if err := checkOperationHost(operationDef.Implementation.OperationHost, false); err != nil {
return err
}
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/operation_host", strings.ToUpper(operationDef.Implementation.OperationHost))
}
if operationDef.Implementation.OperationHost != "" {
if err := checkOperationHost(operationDef.Implementation.OperationHost, false); err != nil {
return err
}
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/operation_host", strings.ToUpper(operationDef.Implementation.OperationHost))
}
}
}
Expand Down Expand Up @@ -659,8 +659,17 @@ func storeRelationshipTypes(ctx context.Context, topology tosca.Topology, topolo
return err
}
}
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/primary", path.Join(importPath, operationDef.Implementation.Primary))
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/dependencies", strings.Join(operationDef.Implementation.Dependencies, ","))
if operationDef.Implementation.Artifact != (tosca.ArtifactDefinition{}) {
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/file", operationDef.Implementation.Artifact.File)
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/type", operationDef.Implementation.Artifact.Type)
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/repository", operationDef.Implementation.Artifact.Repository)
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/description", operationDef.Implementation.Artifact.Description)
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/deploy_path", operationDef.Implementation.Artifact.DeployPath)

} else {
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/primary", path.Join(importPath, operationDef.Implementation.Primary))
consulStore.StoreConsulKeyAsString(operationPrefix+"/implementation/dependencies", strings.Join(operationDef.Implementation.Dependencies, ","))
}
if operationDef.Implementation.OperationHost != "" {
if err := checkOperationHost(operationDef.Implementation.OperationHost, true); err != nil {
return err
Expand Down
102 changes: 70 additions & 32 deletions deployments/definition_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ package deployments
import (
"context"
"path"
"testing"

"github.com/ystia/yorc/helper/consulutil"
"github.com/ystia/yorc/prov"

"strings"
"testing"

"github.com/hashicorp/consul/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ystia/yorc/helper/consulutil"
"github.com/ystia/yorc/prov"
"github.com/ystia/yorc/testutil"
)

func testDefinitionStore(t *testing.T, kv *api.KV) {
Expand All @@ -40,6 +40,9 @@ func testDefinitionStore(t *testing.T, kv *api.KV) {
t.Run("TestValueAssignments", func(t *testing.T) {
testValueAssignments(t, kv)
})
t.Run("TestOperationImplementationArtifact(", func(t *testing.T) {
testOperationImplementationArtifact(t, kv)
})
})
}

Expand Down Expand Up @@ -688,36 +691,36 @@ func testValueAssignments(t *testing.T, kv *api.KV) {
wantFound bool
want string
}{
// {"OutputValueLiteral", topoOutputArgs{"literal", nil}, false, true, `literalOutput`},
// {"OutputValueLiteralDefault", topoOutputArgs{"literalDefault", nil}, false, true, `1`},
// {"OutputValueComplexDTLiteral", topoOutputArgs{"complex", []string{"literal"}}, false, true, `11`},
// {"OutputValueComplexDTLiteral", topoOutputArgs{"complex", []string{"literalDefault"}}, false, true, `OutputLitDef`},
// {"OutputValueComplexDTLiteralDefault", topoOutputArgs{"complex", []string{"literalDefault"}}, false, true, `OutputLitDef`},
// {"OutputValueComplexDTAll", topoOutputArgs{"complex", []string{}}, false, true, `{"literal":"11","literalDefault":"OutputLitDef"}`},
// {"OutputValueComplexDefaultDTAll", topoOutputArgs{"complexDef", nil}, false, true, `{"literal":"1","literalDefault":"ComplexDataTypeDefault"}`},
// {"OutputValueComplexDefaultFromDT", topoOutputArgs{"complexDef", []string{"literalDefault"}}, false, true, `ComplexDataTypeDefault`},
// {"OutputValueBaseComplexDTNestedListOfString", topoOutputArgs{"baseComplex", []string{"nestedType", "listofstring"}}, false, true, `["OutputL1","OutputL2"]`},
// {"OutputValueBaseComplexDTNestedSubComplexLiteral", topoOutputArgs{"baseComplex", []string{"nestedType", "subcomplex", "literal"}}, false, true, `2`},
// {"OutputValueBaseComplexDTNestedSubComplexLiteralDefault", topoOutputArgs{"baseComplex", []string{"nestedType", "subcomplex", "literalDefault"}}, false, true, `ComplexDataTypeDefault`},
// {"OutputValueBaseComplexDTNestedSubComplexAll", topoOutputArgs{"baseComplex", []string{"nestedType", "subcomplex"}}, false, true, `{"literal":"2","literalDefault":"ComplexDataTypeDefault"}`},
// {"OutputValueBaseComplexDTNestedListOfComplex0Literal", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "0", "literal"}}, false, true, `2`},
// {"OutputValueBaseComplexDTNestedListOfComplex0MyMap", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "0", "mymap"}}, false, true, `{"Output":"1"}`},
// {"OutputValueBaseComplexDTNestedListOfComplex0All", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "0"}}, false, true, `{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"1"}}`},
// {"OutputValueBaseComplexDTNestedListOfComplex1Literal", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "1", "literal"}}, false, true, `3`},
// {"OutputValueBaseComplexDTNestedListOfComplex1MyMap", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "1", "mymap"}}, false, true, `{"Output":"2"}`},
// {"OutputValueBaseComplexDTNestedListOfComplex1All", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "1"}}, false, true, `{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"2"}}`},
// {"OutputValueBaseComplexDTNestedListOfComplexAll", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex"}}, false, true, `[{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"1"}},{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"2"}}]`},
// {"OutputValueBaseComplexDTNestedMapOfComplex1Literal", topoOutputArgs{"baseComplex", []string{"nestedType", "mapofcomplex", "m1", "literal"}}, false, true, `4`},
// {"OutputValueBaseComplexDTNestedMapOfComplex1MyMap", topoOutputArgs{"baseComplex", []string{"nestedType", "mapofcomplex", "m1", "mymap"}}, false, true, `{"Output":"3"}`},
// {"OutputValueBaseComplexDTNestedMapOfComplex1All", topoOutputArgs{"baseComplex", []string{"nestedType", "mapofcomplex", "m1"}}, false, true, `{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"3"}}`},
// {"OutputValueBaseComplexDTNestedMapOfComplexAll", topoOutputArgs{"baseComplex", []string{"nestedType", "mapofcomplex"}}, false, true, `{"m1":{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"3"}}}`},
// {"OutputValueBaseComplexDTNestedAll", topoOutputArgs{"baseComplex", []string{"nestedType"}}, false, true, `{"listofcomplex":[{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"1"}},{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"2"}}],"listofstring":["OutputL1","OutputL2"],"mapofcomplex":{"m1":{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"3"}}},"subcomplex":{"literal":"2","literalDefault":"ComplexDataTypeDefault"}}`},
// {"OutputValueBaseComplexDTAll", topoOutputArgs{"baseComplex", nil}, false, true, `{"nestedType":{"listofcomplex":[{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"1"}},{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"2"}}],"listofstring":["OutputL1","OutputL2"],"mapofcomplex":{"m1":{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"3"}}},"subcomplex":{"literal":"2","literalDefault":"ComplexDataTypeDefault"}}}`},
{"OutputValueLiteral", topoOutputArgs{"literal", nil}, false, true, `literalOutput`},
{"OutputValueLiteralDefault", topoOutputArgs{"literalDefault", nil}, false, true, `1`},
{"OutputValueComplexDTLiteral", topoOutputArgs{"complex", []string{"literal"}}, false, true, `11`},
{"OutputValueComplexDTLiteral", topoOutputArgs{"complex", []string{"literalDefault"}}, false, true, `OutputLitDef`},
{"OutputValueComplexDTLiteralDefault", topoOutputArgs{"complex", []string{"literalDefault"}}, false, true, `OutputLitDef`},
{"OutputValueComplexDTAll", topoOutputArgs{"complex", []string{}}, false, true, `{"literal":"11","literalDefault":"OutputLitDef"}`},
{"OutputValueComplexDefaultDTAll", topoOutputArgs{"complexDef", nil}, false, true, `{"literal":"1","literalDefault":"ComplexDataTypeDefault"}`},
{"OutputValueComplexDefaultFromDT", topoOutputArgs{"complexDef", []string{"literalDefault"}}, false, true, `ComplexDataTypeDefault`},
{"OutputValueBaseComplexDTNestedListOfString", topoOutputArgs{"baseComplex", []string{"nestedType", "listofstring"}}, false, true, `["OutputL1","OutputL2"]`},
{"OutputValueBaseComplexDTNestedSubComplexLiteral", topoOutputArgs{"baseComplex", []string{"nestedType", "subcomplex", "literal"}}, false, true, `2`},
{"OutputValueBaseComplexDTNestedSubComplexLiteralDefault", topoOutputArgs{"baseComplex", []string{"nestedType", "subcomplex", "literalDefault"}}, false, true, `ComplexDataTypeDefault`},
{"OutputValueBaseComplexDTNestedSubComplexAll", topoOutputArgs{"baseComplex", []string{"nestedType", "subcomplex"}}, false, true, `{"literal":"2","literalDefault":"ComplexDataTypeDefault"}`},
{"OutputValueBaseComplexDTNestedListOfComplex0Literal", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "0", "literal"}}, false, true, `2`},
{"OutputValueBaseComplexDTNestedListOfComplex0MyMap", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "0", "mymap"}}, false, true, `{"Output":"1"}`},
{"OutputValueBaseComplexDTNestedListOfComplex0All", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "0"}}, false, true, `{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"1"}}`},
{"OutputValueBaseComplexDTNestedListOfComplex1Literal", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "1", "literal"}}, false, true, `3`},
{"OutputValueBaseComplexDTNestedListOfComplex1MyMap", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "1", "mymap"}}, false, true, `{"Output":"2"}`},
{"OutputValueBaseComplexDTNestedListOfComplex1All", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex", "1"}}, false, true, `{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"2"}}`},
{"OutputValueBaseComplexDTNestedListOfComplexAll", topoOutputArgs{"baseComplex", []string{"nestedType", "listofcomplex"}}, false, true, `[{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"1"}},{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"2"}}]`},
{"OutputValueBaseComplexDTNestedMapOfComplex1Literal", topoOutputArgs{"baseComplex", []string{"nestedType", "mapofcomplex", "m1", "literal"}}, false, true, `4`},
{"OutputValueBaseComplexDTNestedMapOfComplex1MyMap", topoOutputArgs{"baseComplex", []string{"nestedType", "mapofcomplex", "m1", "mymap"}}, false, true, `{"Output":"3"}`},
{"OutputValueBaseComplexDTNestedMapOfComplex1All", topoOutputArgs{"baseComplex", []string{"nestedType", "mapofcomplex", "m1"}}, false, true, `{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"3"}}`},
{"OutputValueBaseComplexDTNestedMapOfComplexAll", topoOutputArgs{"baseComplex", []string{"nestedType", "mapofcomplex"}}, false, true, `{"m1":{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"3"}}}`},
{"OutputValueBaseComplexDTNestedAll", topoOutputArgs{"baseComplex", []string{"nestedType"}}, false, true, `{"listofcomplex":[{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"1"}},{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"2"}}],"listofstring":["OutputL1","OutputL2"],"mapofcomplex":{"m1":{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"3"}}},"subcomplex":{"literal":"2","literalDefault":"ComplexDataTypeDefault"}}`},
{"OutputValueBaseComplexDTAll", topoOutputArgs{"baseComplex", nil}, false, true, `{"nestedType":{"listofcomplex":[{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"1"}},{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"2"}}],"listofstring":["OutputL1","OutputL2"],"mapofcomplex":{"m1":{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"Output":"3"}}},"subcomplex":{"literal":"2","literalDefault":"ComplexDataTypeDefault"}}}`},

// Test functions
// {"OutputFunctionLiteral", topoOutputArgs{"node1Lit", nil}, false, true, `myLiteral`},
{"OutputFunctionLiteral", topoOutputArgs{"node1Lit", nil}, false, true, `myLiteral`},
{"OutputFunctionNode2BaseComplexPropAll", topoOutputArgs{"node2BaseComplexPropAll", nil}, false, true, `{"nestedType":{"listofcomplex":[{"literal":"2","literalDefault":"ComplexDataTypeDefault","mymap":{"VANode2":"1"}},{"literal":"3","literalDefault":"ComplexDataTypeDefault","mymap":{"VANode2":"2"}}],"listofstring":["VANode2L1","VANode2L2"],"mapofcomplex":{"m1":{"literal":"4","literalDefault":"ComplexDataTypeDefault","mymap":{"VANode2":"3"}}},"subcomplex":{"literal":"2","literalDefault":"ComplexDataTypeDefault"}}}`},
// {"OutputFunctionNode2BaseComplexPropNestedSubComplexLiteral", topoOutputArgs{"node2BaseComplexPropNestedSubComplexLiteral", nil}, false, true, `2`},
{"OutputFunctionNode2BaseComplexPropNestedSubComplexLiteral", topoOutputArgs{"node2BaseComplexPropNestedSubComplexLiteral", nil}, false, true, `2`},
}
for _, tt := range topoOutputTests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -922,3 +925,38 @@ func testImportTopologyTemplate(t *testing.T, kv *api.KV) {
assert.Equal(t, string(kvp.Value), expectedValue, "Wrong value for key %s", key)
}
}

func testOperationImplementationArtifact(t *testing.T, kv *api.KV) {
deploymentID := testutil.BuildDeploymentID(t)
err := StoreDeploymentDefinition(context.Background(), kv, deploymentID, "testdata/operation_implementation_artifact.yaml")
require.NoError(t, err, "Failed to store test topology deployment definition")

type args struct {
typeName string
operation string
}
type checks struct {
implementationType string
primary string
}
oiaTests := []struct {
name string
args args
want checks
}{
{"TestBashOnNodeType", args{"yorc.tests.nodes.OpImplementationArtifact", "standard.create"}, checks{"tosca.artifacts.Implementation.Bash", "scripts/create.sh"}},
{"TestBashOnRelType", args{"yorc.tests.relationships.OpImplementationArtifact", "configure.pre_configure_source"}, checks{"tosca.artifacts.Implementation.Bash", "something"}},
}

for _, tt := range oiaTests {
t.Run(tt.name, func(t *testing.T) {
implType, err := GetOperationImplementationType(kv, deploymentID, tt.args.typeName, tt.args.operation)
require.NoError(t, err)
assert.Equal(t, tt.want.implementationType, implType)
_, primary, err := GetOperationPathAndPrimaryImplementationForNodeType(kv, deploymentID, tt.args.typeName, tt.args.operation)
require.NoError(t, err)
assert.Equal(t, tt.want.primary, primary)
})
}

}
56 changes: 36 additions & 20 deletions deployments/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ func GetOperationPathAndPrimaryImplementationForNodeType(kv *api.KV, deploymentI
return operationPath, string(kvp.Value), nil
}

// then check operation file
kvp, _, err = kv.Get(path.Join(operationPath, "implementation/file"), nil)
if err != nil {
return "", "", errors.Wrapf(err, "Failed to retrieve primary implementation for operation %q on type %q", operationName, nodeType)
}
if kvp != nil && len(kvp.Value) > 0 {
return operationPath, string(kvp.Value), nil
}

// Not found here check the type hierarchy
parentType, err := GetParentType(kv, deploymentID, nodeType)
if err != nil || parentType == "" {
Expand Down Expand Up @@ -181,11 +190,30 @@ func GetOperationImplementationType(kv *api.KV, deploymentID, nodeType, operatio
return "", errors.Wrap(err, "Fail to get the type of operation implementation")
}

if kvp == nil {
return "", errors.Errorf("Operation type not found for %q", operationName)
if kvp != nil && len(kvp.Value) > 0 {
return string(kvp.Value), nil
}

return string(kvp.Value), nil
kvp, _, err = kv.Get(path.Join(operationPath, "implementation/primary"), nil)
if err != nil {
return "", errors.Wrap(err, "Fail to get the type of operation primary implementation")
}
if kvp == nil || len(kvp.Value) == 0 {
return "", errors.Errorf("Failed to resolve implementation for operation %q in node %q", operationName, nodeType)
}

primary := string(kvp.Value)
primarySlice := strings.Split(primary, ".")
ext := primarySlice[len(primarySlice)-1]
artImpl, err := GetImplementationArtifactForExtension(kv, deploymentID, ext)
if err != nil {
return "", err
}
if artImpl == "" {
return "", errors.Errorf("Failed to resolve implementation artifact for type %q, operation %q, implementation %q and extension %q", nodeType, operationName, primary, ext)
}
return artImpl, nil

}

// GetOperationImplementationFile allows you when the implementation of an operation is an artifact to retrieve the file of this artifact
Expand Down Expand Up @@ -301,29 +329,17 @@ func GetImplementationArtifactForOperation(kv *api.KV, deploymentID, nodeName, o
return "", err
}

// TODO keep in mind that with Alien we may have a an implementation artifact directly in the operation. This part is currently under development in the Kubernetes branch
// and we should take this into account when it will be merged.
_, primary, err := GetOperationPathAndPrimaryImplementationForNodeType(kv, deploymentID, nodeOrRelType, operationName)
implementedIn, err := GetTypeImplementingAnOperation(kv, deploymentID, nodeOrRelType, operationName)
if err != nil {
return "", err
}
if primary == "" {
implType, err := GetOperationImplementationType(kv, deploymentID, nodeOrRelType, operationName)
if err != nil {
return "", err
}
return implType, nil
}
primarySlice := strings.Split(primary, ".")
ext := primarySlice[len(primarySlice)-1]
artImpl, err := GetImplementationArtifactForExtension(kv, deploymentID, ext)

implType, err := GetOperationImplementationType(kv, deploymentID, implementedIn, operationName)
if err != nil {
return "", err
}
if artImpl == "" {
return "", errors.Errorf("Failed to resolve implementation artifact for type %q, operation %q, implementation %q and extension %q", nodeOrRelType, operationName, primary, ext)
}
return artImpl, nil
return implType, nil

}

// GetOperationInputs returns the list of inputs names for a given operation
Expand Down

0 comments on commit 86350b0

Please sign in to comment.