...
Simple Rule
Code Block | |||||
---|---|---|---|---|---|
| rule
| ||||
entity { name 'vnfPOA-nameEVENT' indexing { category indices 'INVALID_NAMEdefault-rules' } description 'Invalidvalidation naming{ convention' useRule errorText{ 'Invalid name - attribute does not match xxxxxnnnvbc (where x = alphanumeric and n = numeric)' severity 'MINOR'name 'vnf-name' attributes 'context-list.sdc.vfList[*].name' } } } rule { name attributes 'vnf-name' validatecategory '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 | ||
---|---|---|
| ||
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 ->'INVALID_NAME' description 'Invalid naming convention' 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' java.util.Map attributeMap = new java.util.HashMap()attributes 'context-list.ndcb.vfList[*].vfModuleList[*]', 'context-list.aai.vfList[*].vfModuleList[*]' } } } defrule isAttributeDataQualityOk{ = { attributename -> '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 ''' if(values == null) { Closure<java.util.Map> getAttributes = { parsedData -> valuesjava.util.Map attributeMap = new java.util.HashSetHashMap() def isAttributeDataQualityOk attributeMap.put("$attrKey", values) = { attribute -> } attribute.findResult{ k, v values.add("$attrValue-> 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 == null) String{ key, value values = attribute.each { k, v ->new java.util.HashSet() attributeMap.put("$attrKey", values) if(k.equals("name")) {key = "$v"} } 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.jsonutil.internal.LazyMap)ArrayList) { if(key.equals("attributeList")) { // only add key-value attributes, skip the restvalue.each { addToMap("$key", "$value")addAttributeToMap(it) } } } if(parsedData instanceof java.util.ArrayList) { parsedData.each } else if(!(value instanceof 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' indexing { indices 'default-rules' } validation { it.each { key, valueuseRule -> processKeyValue(key, value) }{ name 'Data-Dictionary validate VF type' } attributes 'context-list.ndcb.vfList[*].vfModuleList[*].networkList[*].type' } } else} { rule { name parsedData.each { key, value 'Data-> processKeyValue(key, value) }Dictionary validate VF type' category 'INVALID_VALUE' } description 'Validate all VF type values return attributeMap }against data-dictionary' errorText 'VF type def slurper = new groovy.json.JsonSlurper()[{0}] failed data-dictionary validation: {1}' severity java.util.Map ndcb = getAttributes(slurper.parseText(ndcbItems.toString())) 'ERROR' attributes 'typeList' java.util.Mapvalidate 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 out if(!ndcbValueList.any{ it == "$aaiValue" }) {of 'any' loop return false result = false } details.add("$ndcbKey") def result = org.onap.aai.validation.ruledriven.rule.builtin.DataDictionary.validate("instance", details.add("$aaiValue"vfModuleNetworkType", "type", "$it") } if(!result.isEmpty()) { } success = false if(result == false) { // break out of 'any' loopdetails.add("$it") return truedetails.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:
...