Skip to content

Commit

Permalink
Feature: Apply Inherited data
Browse files Browse the repository at this point in the history
Add the application of inherited data to each component to provide
a simple view of each entity that is consumable without the need to
continuously traverse up and down the hierarchy.
  • Loading branch information
kenjones-cisco committed Oct 25, 2016
1 parent 58b202b commit 93631ad
Show file tree
Hide file tree
Showing 16 changed files with 466 additions and 192 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ This library is an implementation of the TOSCA definition as described in the do
[5]: http://gocover.io/_badge/github.com/CiscoCloud/toscalib
[6]: http://gocover.io/github.com/CiscoCloud/toscalib

## Plans

[ToDo Tasks](TODO.md)

## Normative Types
The normative types definitions are included de facto. The files are embeded using go-bindata.
Expand Down
46 changes: 46 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## To Do
### ``assignment.go``
(line 225) (kenjones): Add support for the evaluation of ConstraintClause


### ``flattener.go``
(line 14) (kenjones): Switch to reflect if possible in the future (if simple)


### ``parser.go``
(line 84) (kenjones): Add hooks as method parameter

(line 139) (kenjones): Does dropping the Imports list really have any impact?


### ``service_template.go``
(line 21) (kenjones): Implement ImportDefinition as it is not always going to be a simple

(line 187) (kenjones): assume the requirement has a node specified, otherwise need to use the


### ``topology.go``
(line 62) (kenjones): Add support for Groups


### ``tosca_namespace_alias.go``
(line 43) (kenjones): Leverage https://github.com/blang/semver to provide Version implementation details.

(line 45) Version.GetMajor

(line 52) Version.GetMinor

(line 59) Version.GetFixVersion

(line 66) Version.GetQualifier

(line 73) Version.GetBuildVersion


### ``tosca_reusable_modeling_definitions.go``
(line 19) : Implement ArtifactDefinition struct

(line 22) : Implement NodeFilter struct

(line 70) : Implement ArtifactType struct

4 changes: 0 additions & 4 deletions attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,3 @@ func newAAValue(val interface{}) *AttributeAssignment {
v.Value = val
return v
}

func newAA(def AttributeDefinition) *AttributeAssignment {
return newAAValue(def.Default)
}
20 changes: 16 additions & 4 deletions capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

package toscalib

// CapabilityDefinition TODO: Appendix 6.1
// CapabilityDefinition Appendix 6.1
type CapabilityDefinition struct {
Type string `yaml:"type" json:"type"` // The required name of the Capability Type the capability definition is based upon.
Description string `yaml:"description,omitempty" jsson:"description,omitempty"` // The optional description of the Capability definition.
Expand Down Expand Up @@ -113,9 +113,7 @@ func (c *CapabilityDefinition) extendFrom(capType CapabilityType) {
}
}

// handle reflecting any new properties as attributes
tmp := reflectDefinitionProps(c.Properties, c.Attributes)
c.Attributes = *tmp
c.reflectProperties()
}

// CapabilityType as described in appendix 6.6
Expand Down Expand Up @@ -146,3 +144,17 @@ func (c *CapabilityAssignment) reflectProperties() {
tmp := reflectAssignmentProps(c.Properties, c.Attributes)
c.Attributes = *tmp
}

func (c *CapabilityAssignment) extendFrom(cd CapabilityDefinition) {
for k, v := range cd.Properties {
if len(c.Properties) == 0 {
c.Properties = make(map[string]PropertyAssignment)
}
if _, ok := c.Properties[k]; !ok {
tmp := newPA(v)
c.Properties[k] = *tmp
}
}

c.reflectProperties()
}
168 changes: 160 additions & 8 deletions flattener.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,80 @@ package toscalib

import "github.com/kenjones-cisco/mergo"

func (s *ServiceTemplateDefinition) flattenCapType(name string) CapabilityType {
type flatTypes struct {
Capabilities map[string]CapabilityType
Interfaces map[string]InterfaceType
Relationships map[string]RelationshipType
Nodes map[string]NodeType
Groups map[string]GroupType
Policies map[string]PolicyType
}

// TODO(kenjones): Switch to reflect if possible in the future (if simple)

func flattenCapType(name string, s ServiceTemplateDefinition) CapabilityType {
if ct, ok := s.CapabilityTypes[name]; ok {
if ct.DerivedFrom != "" {
parent := s.flattenCapType(ct.DerivedFrom)
parent := flattenCapType(ct.DerivedFrom, s)
// mergo does not handle merging Slices so the rt items
// will wipe away, capture the values here.
sources := parent.ValidSources

_ = mergo.MergeWithOverwrite(&parent, ct)

// now copy them back in using append, if the child type had
// any previously, otherwise it will duplicate the parents.
if len(ct.ValidSources) > 0 {
parent.ValidSources = append(parent.ValidSources, sources...)
}
return parent
}
return ct
}
return CapabilityType{}
}

func (s *ServiceTemplateDefinition) flattenNodeType(name string) NodeType {
func flattenIntfType(name string, s ServiceTemplateDefinition) InterfaceType {
if it, ok := s.InterfaceTypes[name]; ok {
if it.DerivedFrom != "" {
parent := flattenIntfType(it.DerivedFrom, s)
_ = mergo.MergeWithOverwrite(&parent, it)
return parent
}
return it
}
return InterfaceType{}
}

func flattenRelType(name string, s ServiceTemplateDefinition) RelationshipType {
if rt, ok := s.RelationshipTypes[name]; ok {
if rt.DerivedFrom != "" {
parent := flattenRelType(rt.DerivedFrom, s)
// mergo does not handle merging Slices so the rt items
// will wipe away, capture the values here.
targets := parent.ValidTarget

_ = mergo.MergeWithOverwrite(&parent, rt)

// now copy them back in using append, if the child type had
// any previously, otherwise it will duplicate the parents.
if len(rt.ValidTarget) > 0 {
parent.ValidTarget = append(parent.ValidTarget, targets...)
}
return parent
}
return rt
}
return RelationshipType{}
}

func flattenNodeType(name string, s ServiceTemplateDefinition) NodeType {
if nt, ok := s.NodeTypes[name]; ok {
if nt.DerivedFrom != "" {
parent := s.flattenNodeType(nt.DerivedFrom)
parent := flattenNodeType(nt.DerivedFrom, s)
// mergo does not handle merging Slices so the nt items
// will wipe away, capture the values here.
reqs := parent.Requirements
arts := parent.Artifacts

_ = mergo.MergeWithOverwrite(&parent, nt)

Expand All @@ -30,12 +84,110 @@ func (s *ServiceTemplateDefinition) flattenNodeType(name string) NodeType {
if len(nt.Requirements) > 0 {
parent.Requirements = append(parent.Requirements, reqs...)
}
if len(nt.Artifacts) > 0 {
parent.Artifacts = append(parent.Artifacts, arts...)
}
return parent
}
return nt
}
return NodeType{}
}

func flattenGroupType(name string, s ServiceTemplateDefinition) GroupType {
if gt, ok := s.GroupTypes[name]; ok {
if gt.DerivedFrom != "" {
parent := flattenGroupType(gt.DerivedFrom, s)
// mergo does not handle merging Slices so the nt items
// will wipe away, capture the values here.
reqs := parent.Requirements
members := parent.Members

_ = mergo.MergeWithOverwrite(&parent, gt)

// now copy them back in using append, if the child type had
// any previously, otherwise it will duplicate the parents.
if len(gt.Requirements) > 0 {
parent.Requirements = append(parent.Requirements, reqs...)
}
if len(gt.Members) > 0 {
parent.Members = append(parent.Members, members...)
}
return parent
}
return gt
}
return GroupType{}
}

func flattenPolicyType(name string, s ServiceTemplateDefinition) PolicyType {
if pt, ok := s.PolicyTypes[name]; ok {
if pt.DerivedFrom != "" {
parent := flattenPolicyType(pt.DerivedFrom, s)
// mergo does not handle merging Slices so the items
// will wipe away, capture the values here.
targets := parent.Targets

_ = mergo.MergeWithOverwrite(&parent, pt)

// now copy them back in using append, if the child type had
// any previously, otherwise it will duplicate the parents.
if len(pt.Targets) > 0 {
parent.Targets = append(parent.Targets, targets...)
}
return parent
}
return pt
}
return PolicyType{}
}

func flattenHierarchy(s ServiceTemplateDefinition) flatTypes {
var flats flatTypes

flats.Capabilities = make(map[string]CapabilityType)
for name := range s.CapabilityTypes {
flats.Capabilities[name] = flattenCapType(name, s)
}

flats.Interfaces = make(map[string]InterfaceType)
for name := range s.InterfaceTypes {
flats.Interfaces[name] = flattenIntfType(name, s)
}

flats.Relationships = make(map[string]RelationshipType)
for name := range s.RelationshipTypes {
flats.Relationships[name] = flattenRelType(name, s)
}

flats.Nodes = make(map[string]NodeType)
for name := range s.NodeTypes {
flats.Nodes[name] = flattenNodeType(name, s)
}

for k, v := range flats.Nodes {
for name, capDef := range v.Capabilities {
capDef.extendFrom(flats.Capabilities[capDef.Type])
v.Capabilities[name] = capDef
}
for name, iDef := range v.Interfaces {
// during merge the Type is not always properly inherited, so set it
// from the parent.
if iDef.Type == "" {
iDef.Type = flats.Nodes[v.DerivedFrom].Interfaces[name].Type
}
iDef.extendFrom(flats.Interfaces[iDef.Type])
v.Interfaces[name] = iDef
}
flats.Nodes[k] = v
}

flats.Groups = make(map[string]GroupType)
for name := range s.GroupTypes {
flats.Groups[name] = flattenGroupType(name, s)
}

flats.Policies = make(map[string]PolicyType)
for name := range s.PolicyTypes {
flats.Policies[name] = flattenPolicyType(name, s)
}

return flats
}
Loading

0 comments on commit 93631ad

Please sign in to comment.