...
Simple Rule
Code Block | ||||
---|---|---|---|---|
| ||||
entitySimple Rule Collapse sourcerule { 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 {
name 'NDCB-AAI-attribute-comparison'
attributes 'context-list.ndcb.vfList[*].vfModuleList[*]', 'context-list.aai.vfList[*].vfModuleList[*]'
}
}
}
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 '''
| ||||
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 -> java.util.Map attributeMap = new java.util.HashMap() def isAttributeDataQualityOk = { attribute -> attribute.findResult{ k, v -> if(k.equals("dataQuality") ) {return v.get("status")}}.equals("ok") } def addToMap = { attrKey, attrValue -> javaClosure<java.util.SetMap> valuesgetAttributes = attributeMap.get("$attrKey") { parsedData -> java.util.Map attributeMap if(values == null) {= new java.util.HashMap() def isAttributeDataQualityOk = { valuesattribute =-> new java.util.HashSet() attribute.findResult{ k, v -> attributeMapif(k.putequals("$attrKeydataQuality",) values) {return v.get("status")}}.equals("ok") } def addToMap values.add("$attrValue") = { attrKey, attrValue -> } def addAttributeToMap = { attribute ->java.util.Set values = attributeMap.get("$attrKey") if(isAttributeDataQualityOk(attribute)values == null) { Stringvalues key,= value new java.util.HashSet() attribute.each { k, v -> attributeMap.put("$attrKey", values) } if(kvalues.equalsadd("name$attrValue")) {key = "$v"} } def addAttributeToMap = { if(k.equals("value")) {value = "$v"}attribute -> if(isAttributeDataQualityOk(attribute)) { } String addToMap("$key"key, "$value")value } attribute.each { k, v -> } def processKeyValue = if(k.equals("name")) { key, value -> if(value instanceof java.util.ArrayList) { = "$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.LazyMap)util.ArrayList) { // only add key-value attributes, skip the rest if(key.equals("attributeList")) { value.each { 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[*]' } } } |
...