Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use equivalent item values to find existing property GUIDs #503

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ can be found in [Pivotal Documentation](docs.pivotal.io/platform-automation).
## 6.2.0

### Features
- `configure-product`'s _decorating collection with guid based on `name` logical key_ logic has been extended to also use `key` or fields ending in `name` as logical keys. Resolves [#207](https://github.com/pivotal-cf/om/issues/207)
- `configure-product`'s _decorating collection with guid_ logic has been extended to associate existing collection item guids based on (in order)
- equivalent item values
- equal logical keys (in order; ie. 'name' will be used over 'Filename' if both exist)
- `name`
- `key`
- fields ending in `name` (eg: `sqlServerName`)

This addresses [#207](https://github.com/pivotal-cf/om/issues/207); improving GitOps style workflows

## 6.1.0

Expand Down
85 changes: 50 additions & 35 deletions api/staged_products_property_collection_guid_assigner.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,31 @@ func (item updatedPropertyCollectionItem) setFieldValue(fieldName string, value
item.Data[fieldName] = value
}

func (item updatedPropertyCollectionItem) getSortedFieldNames() []string {
sortedFieldNames := make([]string, 0, len(item.Data))
for k := range item.Data {
sortedFieldNames = append(sortedFieldNames, fmt.Sprintf("%v", k))
}
sort.Strings(sortedFieldNames)

return sortedFieldNames
}

func (item updatedPropertyCollectionItem) findLogicalKeyField() (string, bool) {
//search order is important; 'name' should be found before 'ending-with-name'
regexes := []string{"^name$", "^key$", "(?i)name$"}
for _, regex := range regexes {
compiledRegex := regexp.MustCompile(regex)
for _, fieldName := range item.getSortedFieldNames() {
if compiledRegex.MatchString(fieldName) {
return fieldName, true
}
}
}

return "", false
}

func parseUpdatedPropertyCollection(updatedProperty interface{}) (updatedPropertyCollection, error) {
var collection updatedPropertyCollection

Expand Down Expand Up @@ -83,49 +108,29 @@ func (item responsePropertyCollectionItem) getFieldValue(fieldName string) strin
return ""
}

func (item responsePropertyCollectionItem) getSortedFieldNames() []string {
sortedFieldNames := make([]string, 0, len(item.Data))
for k := range item.Data {
sortedFieldNames = append(sortedFieldNames, fmt.Sprintf("%v", k))
}
sort.Strings(sortedFieldNames)

return sortedFieldNames
}
func (item responsePropertyCollectionItem) getFieldValuesExceptGUID() map[interface{}]interface{} {
extractedValues := make(map[interface{}]interface{})

func (item responsePropertyCollectionItem) findLogicalKeyField() (string, bool) {
//search order is important; 'name' should be found before 'ending-with-name'
regexes := []string{"^name$", "^key$", "(?i)name$"}
for _, regex := range regexes {
compiledRegex := regexp.MustCompile(regex)
for _, fieldName := range item.getSortedFieldNames() {
if compiledRegex.MatchString(fieldName) {
return fieldName, true
}
for key, valueObj := range item.Data {
if key == "guid" {
continue
}
extractedValues[key] = valueObj.(map[interface{}]interface{})["value"]
}

return "", false
return extractedValues
}

func assignExistingGUIDUsingLogicalKey(updatedCollection updatedPropertyCollection, existingCollection responsePropertyCollection) bool {
//since all collection items have the same structure; only need to find the logical key from the first one
logicalKeyFieldName, found := existingCollection[0].findLogicalKeyField()
if !found {
return false
}
func (existingCollection responsePropertyCollection) findGUIDForEquivalentlItem(updatedProperty updatedPropertyCollectionItem) (string, bool) {

for _, updatedCollectionItem := range updatedCollection {
updatedCollectionItemLogicalKeyValue := updatedCollectionItem.getFieldValue(logicalKeyFieldName)
for _, existingCollectionItem := range existingCollection {
if updatedCollectionItemLogicalKeyValue == existingCollectionItem.getFieldValue(logicalKeyFieldName) {
updatedCollectionItem.setFieldValue("guid", existingCollectionItem.getFieldValue("guid"))
break //move onto the next updatedCollectionItem
}
for _, existingCollectionItem := range existingCollection {
//use the fact that fmt prints maps in order (see: https://tip.golang.org/doc/go1.12#fmt) to check for equivalence
if fmt.Sprintf("%+v", updatedProperty.Data) == fmt.Sprintf("%+v", existingCollectionItem.getFieldValuesExceptGUID()) {
return existingCollectionItem.getFieldValue("guid"), true
}
}

return true
return "", false
}

func associateExistingCollectionGUIDs(updatedProperty interface{}, existingProperty ResponseProperty) error {
Expand All @@ -138,8 +143,18 @@ func associateExistingCollectionGUIDs(updatedProperty interface{}, existingPrope
return err
}

if assignExistingGUIDUsingLogicalKey(updatedCollection, existingCollection) {
return nil
for _, updatedCollectionItem := range updatedCollection {
if guid, ok := existingCollection.findGUIDForEquivalentlItem(updatedCollectionItem); ok {
updatedCollectionItem.setFieldValue("guid", guid)
} else if logicalKeyFieldName, ok := updatedCollectionItem.findLogicalKeyField(); ok {
updatedCollectionItemLogicalKeyValue := updatedCollectionItem.getFieldValue(logicalKeyFieldName)
for _, existingCollectionItem := range existingCollection {
if updatedCollectionItemLogicalKeyValue == existingCollectionItem.getFieldValue(logicalKeyFieldName) {
updatedCollectionItem.setFieldValue("guid", existingCollectionItem.getFieldValue("guid"))
}
}
}

}

return nil
Expand Down
Loading