...
Simple Rule
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
Simple Rule Collapse sourceruleentity { name 'POA-EVENT' name indexing { indices 'vnfdefault-namerules' } validation { category useRule 'INVALID_NAME'{ description 'Invalid naming conventionname 'vnf-name' errorText attributes 'Invalid name - attribute does not match xxxxxnnnvbc (where x = alphanumeric and n = numeric)' context-list.sdc.vfList[*].name' } } } rule { name severity 'MINORvnf-name' category attributes 'nameINVALID_NAME' validatedescription 'Invalid naming convention' 'name != null && name.matches("[a-z,0-9]{5}[0-9]{3}vbc")' } |
Complex Rule
The following example defines a rule that :
- accepts two attributes
- uses expandable error text
- uses a triple-quoted
validate
section to allow multiple lines - defines multiple closures
errorText 'Invalid name - attribute does not match xxxxxnnnvbc (where x = alphanumeric and n = numeric)'
severity 'MINOR'
attributes 'name'
validate 'name != null && name.matches("[a-z,0-9]{5}[0-9]{3}vbc")'
} |
Complex Rule
The following example defines a rule that :
- accepts two attributes
- uses expandable error text
- uses a triple-quoted
validate
section to allow multiple lines - defines multiple closures
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
entity {
name 'POA-EVENT'
indexing {
indices 'default-rules'
}
validation {
useRule { | ||||||
Code Block | ||||||
| ||||||
rule { name 'NDCB-AAI-attribute-comparison' category 'Attribute Mismatch' description 'Verify that all attributes in Network-Discovery are the same as in AAI' errorText 'Error found with attribute "{0}"; value "{1}" does not exist in Network-Discovery' severity 'ERROR' attributes 'ndcbItems', 'aaiItems' validate ''' Closure<java.util.Map> getAttributes = { parsedData -> name 'NDCB-AAI-attribute-comparison' java.util.Map attributeMap = new java.util.HashMap() attributes 'context-list.ndcb.vfList[*].vfModuleList[*]', 'context-list.aai.vfList[*].vfModuleList[*]' } def isAttributeDataQualityOk = { attribute -> } } rule { name 'NDCB-AAI-attribute-comparison' category attribute.findResult{ k, v -> if(k.equals("dataQuality") ) {return v.get("status")}}.equals("ok") } def addToMap = { attrKey, attrValue -> java.util.Set values = attributeMap.get("$attrKey")'Attribute Mismatch' description 'Verify that all attributes in Network-Discovery are the same as in AAI' errorText 'Error found with attribute "{0}"; value "{1}" does not exist in Network-Discovery' severity 'ERROR' attributes 'ndcbItems', 'aaiItems' validate ''' Closure<java.util.Map> getAttributes = { if(values == null) {parsedData -> valuesjava.util.Map attributeMap = new java.util.HashSetHashMap() def isAttributeDataQualityOk = attributeMap.put("$attrKey", values){ attribute -> } values.add("$attrValueattribute.findResult{ k, v -> if(k.equals("dataQuality") ) {return v.get("status")}}.equals("ok") } def addAttributeToMapaddToMap = { attrKey, attributeattrValue -> java.util.Set values = if(isAttributeDataQualityOk(attribute)) {attributeMap.get("$attrKey") if(values == String key, valuenull) { attribute.eachvalues {= k, v ->new java.util.HashSet() if(k.equalsattributeMap.put("name$attrKey")) {key = "$v"} , values) } if(kvalues.equalsadd("value$attrValue")) {value = "$v"} } } def addAttributeToMap = { attribute -> addToMap("$key", "$value") if(isAttributeDataQualityOk(attribute)) { } String key, value } def processKeyValue =attribute.each { keyk, valuev -> if(value instanceof java.util.ArrayListk.equals("name")) {key = "$v"} if(keyk.equals("attributeListvalue")) {value = "$v"} } value.each { addToMap("$key", "$value") addAttributeToMap(it) } } def processKeyValue = { } key, value -> } else if(!(value instanceof groovyjava.json.internal.LazyMaputil.ArrayList) { if(key.equals("attributeList")) { // only add key-value.each attributes,{ skip the rest addToMap("$key", "$value") addAttributeToMap(it) } } } else if(!(parsedDatavalue instanceof java.util.ArrayList)groovy.json.internal.LazyMap)) { // only add key-value attributes, skip the rest addToMap("$key", "$value") } } if(parsedData instanceof java.util.ArrayList) { parsedData.each { it.each { key, value -> processKeyValue(key, value) } } } else { parsedData.each { key, value -> processKeyValue(key, value) } } return attributeMap } def slurper = new groovy.json.JsonSlurper() java.util.Map ndcb = getAttributes(slurper.parseText(ndcbItems.toString())) java.util.Map aai = getAttributes(slurper.parseText(aaiItems.toString())) boolean result = true List<String> details = new ArrayList<>(); ndcb.any{ ndcbKey, ndcbValueList -> def aaiValueList = aai.get("$ndcbKey") aaiValueList.each{ aaiValue -> if(!ndcbValueList.any{ it == "$aaiValue" }) { result = false details.add("$ndcbKey") details.add("$aaiValue") } } if(result == false) { // break out of 'any' loop return true } } return new Tuple2(result, details) ''' } |
Data-Dictionary rule
The following example defines a rule that uses the data-dictionary interfaced defined here.
By default, the URI template is configured as "/commonModelElements/{0}~{1}~1.0/validateInstance"
With the arguments used for calling validate() below, the resulting URL would be: [ddict-host:port]/commonModelElements/instance~vfModuleNetworkType~1.0/validateInstance
And the body would be: {"type" : "some-value"
}
Code Block | ||||
---|---|---|---|---|
| ||||
entity { name 'POA-EVENT' parsedData.eachindexing { it.each { key, value -> processKeyValue(key, value)indices 'default-rules' } validation { useRule }{ name 'Data-Dictionary validate VF }type' else { attributes 'context-list.ndcb.vfList[*].vfModuleList[*].networkList[*].type' } parsedData.each { key, value -> processKeyValue(key, value) } } } rule { name 'Data-Dictionary validate VF }type' category 'INVALID_VALUE' return attributeMap description 'Validate all VF type values } against data-dictionary' errorText 'VF def slurper = new groovy.json.JsonSlurper()type [{0}] failed data-dictionary validation: {1}' severity java.util.Map ndcb = getAttributes(slurper.parseText(ndcbItems.toString())) 'ERROR' attributes 'typeList' validate java.util.Map aai = getAttributes(slurper.parseText(aaiItems.toString())) ''' boolean resultsuccess = true List<String> details = new ArrayList<>(); ndcbtypeList.any{ ndcbKey, ndcbValueList -> { def aaiValueList = aai.get("$ndcbKey") if(!success) { aaiValueList.each{ aaiValue -> // break if(!ndcbValueList.any{ it == "$aaiValue" }) { out of 'any' loop result =return false } details.add("$ndcbKey") def result details.add("$aaiValue") = org.onap.aai.validation.ruledriven.rule.builtin.DataDictionary.validate("instance", "vfModuleNetworkType", "type", "$it") } if(!result.isEmpty()) { } if(resultsuccess == false) { // break out of 'any' loop details.add("$it") return true details.add("$result") } } return new Tuple2(resultsuccess, details) ''' } |
Entity Configuration
The entity
configuration element defines which rules are applied to a specific entity type. The configuration is comprised of the following properties:
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
entity { type 'complex' validation { useRule { name 'CLLI' attributes 'physical-location-id' } useRule {name 'complex is related to 1 oam-network' } useRule { name 'if a customer is related to an oam-network then oam-network.network-name must match naming convention' attributes 'relationship-list.relationship[*]' } } } |
...