Merge "Add the schema service helm charts"
[oom.git] / kubernetes / pomba / charts / pomba-validation-service / resources / bundleconfig / etc / rules / poa-event / default-rules.groovy
1 /*
2  * ============LICENSE_START===================================================
3  * Copyright (c) 2018 Amdocs
4  * ============================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ============LICENSE_END=====================================================
17  */
18
19 entity {
20     name 'POA-EVENT'
21     indexing {
22         indices 'default-rules'
23     }
24   validation {
25
26     // NDCB-AAI comparison: Context level
27     useRule {
28       name 'Attribute-comparison'
29       attributes 'context-list.ndcb', 'context-list.aai'
30     }
31
32     // NDCB-AAI comparison: Service entity
33     useRule {
34       name 'Attribute-comparison'
35       attributes 'context-list.ndcb.service', 'context-list.aai.service'
36     }
37
38     // NDCB-AAI comparison: Context level network list
39     useRule {
40       name 'Attribute-comparison'
41       attributes 'context-list.ndcb.networkList[*]', 'context-list.aai.networkList[*]'
42     }
43         
44     // NDCB-AAI comparison: VNF list
45     useRule {
46       name 'Attribute-comparison'
47       attributes 'context-list.ndcb.vnfList[*]', 'context-list.aai.vnfList[*]'
48     }
49
50     // NDCB-AAI comparison: VNF network list
51     useRule {
52       name 'Attribute-comparison'
53       attributes 'context-list.ndcb.vnfList[*].networkList[*]', 'context-list.aai.vnfList[*].networkList[*]'
54     }
55         
56     // NDCB-AAI comparison: VF-Module list
57     useRule {
58       name 'Attribute-comparison'
59       attributes 'context-list.ndcb.vnfList[*].vfModuleList[*]', 'context-list.aai.vnfList[*].vfModuleList[*]'
60     }
61
62     // NDCB-AAI comparison: VF-Module network list
63     useRule {
64       name 'Attribute-comparison'
65       attributes 'context-list.ndcb.vnfList[*].vfModuleList[*].networkList[*]', 'context-list.aai.vnfList[*].vfModuleList[*].networkList[*]'
66     }
67
68     // NDCB-AAI comparison: VNFC list
69     useRule {
70       name 'Attribute-comparison'
71       attributes 'context-list.ndcb.vnfList[*].vnfcList[*]', 'context-list.aai.vnfList[*].vnfcList[*]'
72     }
73
74     // NDCB-AAI comparison: VM list
75     useRule {
76       name 'Attribute-comparison'
77       attributes 'context-list.ndcb.vnfList[*].vfModuleList[*].vmList[*]', 'context-list.aai.vnfList[*].vfModuleList[*].vmList[*]'
78     }
79         
80         
81     // SDNC-AAI comparison: Context level
82     useRule {
83       name 'Attribute-comparison'
84       attributes 'context-list.sdnc', 'context-list.aai'
85     }
86
87     // SDNC-AAI comparison: Service entity
88     useRule {
89       name 'Attribute-comparison'
90       attributes 'context-list.sdnc.service', 'context-list.aai.service'
91     }
92
93     // SDNC-AAI comparison: Context level network list
94     useRule {
95       name 'Attribute-comparison'
96       attributes 'context-list.sdnc.networkList[*]', 'context-list.aai.networkList[*]'
97     }
98
99     // SDNC-AAI comparison: VNF list
100     useRule {
101       name 'Attribute-comparison'
102       attributes 'context-list.sdnc.vnfList[*]', 'context-list.aai.vnfList[*]'
103     }
104
105     // SDNC-AAI comparison: VNF network list
106     useRule {
107       name 'Attribute-comparison'
108       attributes 'context-list.sdnc.vnfList[*].networkList[*]', 'context-list.aai.vnfList[*].networkList[*]'
109     }
110
111     // SDNC-AAI comparison: VF-Module list
112     useRule {
113       name 'Attribute-comparison'
114       attributes 'context-list.sdnc.vnfList[*].vfModuleList[*]', 'context-list.aai.vnfList[*].vfModuleList[*]'
115     }
116
117     // SDNC-AAI comparison: VF-Module network list
118     useRule {
119       name 'Attribute-comparison'
120       attributes 'context-list.sdnc.vnfList[*].vfModuleList[*].networkList[*]', 'context-list.aai.vnfList[*].vfModuleList[*].networkList[*]'
121     }
122
123     // SDNC-AAI comparison: VNFC list
124     useRule {
125       name 'Attribute-comparison'
126       attributes 'context-list.sdnc.vnfList[*].vnfcList[*]', 'context-list.aai.vnfList[*].vnfcList[*]'
127     }
128
129     // SDNC-AAI comparison: VM list
130     useRule {
131       name 'Attribute-comparison'
132       attributes 'context-list.sdnc.vnfList[*].vfModuleList[*].vmList[*]', 'context-list.aai.vnfList[*].vfModuleList[*].vmList[*]'
133     }
134
135         
136         
137     // SDNC-NDCB comparison: Context level
138     useRule {
139       name 'Attribute-comparison'
140       attributes 'context-list.sdnc', 'context-list.ndcb'
141     }
142
143     // SDNC-NDCB comparison: Service entity
144     useRule {
145       name 'Attribute-comparison'
146       attributes 'context-list.sdnc.service', 'context-list.ndcb.service'
147     }
148
149     // SDNC-NDCB comparison: Context level network list
150     useRule {
151       name 'Attribute-comparison'
152       attributes 'context-list.sdnc.networkList[*]', 'context-list.ndcb.networkList[*]'
153     }
154
155     // SDNC-NDCB comparison: VNF list
156     useRule {
157       name 'Attribute-comparison'
158       attributes 'context-list.sdnc.vnfList[*]', 'context-list.ndcb.vnfList[*]'
159     }
160
161     // SDNC-NDCB comparison: VNF network list
162     useRule {
163       name 'Attribute-comparison'
164       attributes 'context-list.sdnc.vnfList[*].networkList[*]', 'context-list.ndcb.vnfList[*].networkList[*]'
165     }
166
167     // SDNC-NDCB comparison: VF-Module list
168     useRule {
169       name 'Attribute-comparison'
170       attributes 'context-list.sdnc.vnfList[*].vfModuleList[*]', 'context-list.ndcb.vnfList[*].vfModuleList[*]'
171     }
172
173     // SDNC-NDCB comparison: VF-Module network list
174     useRule {
175       name 'Attribute-comparison'
176       attributes 'context-list.sdnc.vnfList[*].vfModuleList[*].networkList[*]', 'context-list.ndcb.vnfList[*].vfModuleList[*].networkList[*]'
177     }
178
179     // SDNC-NDCB comparison: VNFC list
180     useRule {
181       name 'Attribute-comparison'
182       attributes 'context-list.sdnc.vnfList[*].vnfcList[*]', 'context-list.ndcb.vnfList[*].vnfcList[*]'
183     }
184
185     // SDNC-NDCB comparison: VM list
186     useRule {
187       name 'Attribute-comparison'
188       attributes 'context-list.sdnc.vnfList[*].vfModuleList[*].vmList[*]', 'context-list.ndcb.vnfList[*].vfModuleList[*].vmList[*]'
189     }
190
191         
192         
193     // SDC-AAI VNFC type
194     useRule {
195       name 'SDC-AAI-vnfc-type'
196       attributes 'context-list.sdc.vnfList[*].vnfcList[*]', 'context-list.aai.vnfList[*].vnfcList[*]'
197     }
198
199     // SDC-AAI VNFC node count
200     useRule {
201       name 'SDC-AAI-vnfc-node-count'
202       attributes 'context-list.sdc.vnfList[*].vnfcList[*]', 'context-list.aai.vnfList[*].vnfcList[*]'
203     }
204
205     // SDC-AAI VF-Module instance
206     useRule {
207       name 'SDC-AAI-vf-module-instance-check'
208       attributes 'context-list.sdc.vnfList[*].vfModuleList[*]', 'context-list.aai.vnfList[*].vfModuleList[*]'
209     }
210   }
211 }
212
213 rule {
214   name        'SDC-AAI-vnfc-type'
215   category    'VNFC Consistency'
216   description 'Validate that each VNFC instance in AAI conforms to a VNFC type defined in SDC model'
217   errorText   'AAI VNFC instance includes non-specified type in design SDC model'
218   severity    'ERROR'
219   attributes  'sdcList', 'aaiList'
220   validate    '''
221         def getVnfcTypes = { parsedData ->
222           parsedData.collect{ it.findResult{ k, v -> if(k.equals("type")) {return "$v"}}}
223         }
224
225         def slurper = new groovy.json.JsonSlurper()
226         def sdcTypes = getVnfcTypes(slurper.parseText(sdcList.toString()))
227         def aaiTypes = getVnfcTypes(slurper.parseText(aaiList.toString()))
228
229         // each type in AAI must exist in SDC
230         return sdcTypes.containsAll(aaiTypes)
231                 '''
232 }
233
234 rule {
235   name        'SDC-AAI-vnfc-node-count'
236   category    'VNFC Consistency'
237   description 'Validate that for each VNFC node defined in SDC model, there is at least one VNFC instance in AAI'
238   errorText   'Design has specified types but not all of them exist in AAI'
239   severity    'WARNING'
240   attributes  'sdcList', 'aaiList'
241   validate    '''
242         def getVnfcNodes = { parsedData ->
243           parsedData.collect { new Tuple2(
244               it.findResult{ k, v -> if(k.equals("name")) {return "$v"}},
245               it.findResult{ k, v -> if(k.equals("type")) {return "$v"}})
246           }
247         }
248
249         def slurper = new groovy.json.JsonSlurper()
250         def sdcNodes = getVnfcNodes(slurper.parseText(sdcList.toString()))
251         def aaiNodes = getVnfcNodes(slurper.parseText(aaiList.toString()))
252
253         // each node in AAI must exist in SDC
254         return aaiNodes.containsAll(sdcNodes)
255                 '''
256 }
257
258 rule {
259   name        'SDC-AAI-vf-module-instance-check'
260   category    'VF Consistency'
261   description 'Validate that each VF module instance in AAI conforms to a VF module defined in SDC service model'
262   errorText   'One or more AAI VF module instance(s) not defined in SDC model'
263   severity    'CRITICAL'
264   attributes  'sdcList', 'aaiList'
265   validate    '''
266         def getVfModules = { parsedData ->
267           parsedData.collect{ it.findResult{ k, v -> if(k.equals("name")) {return "$v"}}}
268         }
269
270         def slurper = new groovy.json.JsonSlurper()
271         def sdcVfModules = getVfModules(slurper.parseText(sdcList.toString()))
272         def aaiVfModules = getVfModules(slurper.parseText(aaiList.toString()))
273
274         // all VF modules in AAI must exist in SDC
275         return aaiVfModules.containsAll(sdcVfModules)
276                 '''
277 }
278
279 rule {
280   name        'Attribute-comparison'
281   category    'Attribute Mismatch'
282   description 'Determine all discrepancies between values for attributes with matching names from each model'
283   errorText   'Error found with attribute(s) and values: {0}'
284   severity    'ERROR'
285   attributes  'lhsObject', 'rhsObject'
286   validate    '''
287                 // This closure extracts the given object's root level attributes and contents of the attribute list.
288                 // Complex items like lists are excluded.
289                 // Returns a map containing attribute names as keys, mapping to a list of values for each attribute.
290                 Closure<java.util.Map> getAttributes = { parsedData ->
291                         java.util.Map attributeMap = new java.util.HashMap()
292
293                         def isAttributeDataQualityOk = { attribute ->
294                                 attribute.findResult{ k, v -> if(k.equals("dataQuality") ) {return v.get("status")}}.equals("ok")
295                         }
296
297                         def addToMap = { attrKey, attrValue ->
298                                 java.util.Set values = attributeMap.get("$attrKey")
299                                 if(values == null) {
300                                         values = new java.util.HashSet()
301                                         attributeMap.put("$attrKey", values)
302                                 }
303                                 values.add("$attrValue")
304                         }
305
306                         def addAttributeToMap = { attribute ->
307                                 if(isAttributeDataQualityOk(attribute)) {
308                                         String key, value
309                                         attribute.each { k, v ->
310                                                 if(k.equals("name")) {key = "$v"}
311                                                 if(k.equals("value")) {value = "$v"}
312                                         }
313                                         addToMap("$key", "$value")
314                                 }
315                         }
316
317                         def processKeyValue = { key, value ->
318                                 if(value instanceof java.util.ArrayList) {
319                                         if(key.equals("attributeList")) {
320                                                 value.each {
321                                                         addAttributeToMap(it)
322                                                 }
323                                         }
324                                 } else if(!(value instanceof groovy.json.internal.LazyMap)) {
325                                         // only add key-value attributes, skip the rest
326                                         addToMap("$key", "$value")
327                                 }
328                         }
329
330                         if(parsedData instanceof java.util.ArrayList) {
331                                 parsedData.each {
332                                         it.each { key, value -> processKeyValue(key, value) }
333                                 }
334                         } else {
335                                 parsedData.each { key, value -> processKeyValue(key, value) }
336                         }
337                         return attributeMap
338                 }
339
340                 // This closure compares all values for each key from the left map, to values of the same key from the right map.
341                 // Returns a map of attributes with mismatched or missing values (i.e. attribute name mapped to list of failed values).
342                 Closure<java.util.Map> compareAttributes = { java.util.Map left, java.util.Map right ->
343                         java.util.Map violationMap = new java.util.HashMap()
344                         left.each{ leftKey, leftValueList ->
345                                 def rightValueList = right.get("$leftKey")
346                                 rightValueList.each{ rightValue ->
347                                         if(!leftValueList.any{ it == "$rightValue" }) {
348                                                 def existingValues = violationMap.get(leftKey)
349                                                 if(existingValues) {
350                                                         existingValues.add("$rightValue")
351                                                 } else {
352                                                         java.util.Set newValues = new HashSet()
353                                                         newValues.add("$rightValue")
354                                                         violationMap.put("$leftKey", newValues)
355                                                 }
356                                         }
357                                 }
358                         }
359                         return violationMap
360                 }
361
362                 // This closure merges the given maps into a new map.
363                 // Returns a map containing all keys and their values from both maps.
364                 Closure<java.util.Map> mergeMaps = { java.util.Map left, java.util.Map right ->
365                         if(left.isEmpty() && right.isEmpty()) {
366                                 return [:]
367                         } else if(left.isEmpty()) {
368                                 return right
369                         } else if(right.isEmpty()) {
370                                 return left
371                         }
372                         java.util.Map merged = new java.util.HashMap()
373                         merged.putAll(left)
374                         right.each{ rightKey, rightValues ->
375                                 java.util.Set mergedValues = merged.get(rightKey)
376                                 if(mergedValues == null) {
377                                         merged.put(rightKey, rightValues)
378                                 } else {
379                                         mergedValues.addAll(rightValues)
380                                 }
381                         }
382                         return merged
383                 }
384
385                 def slurper = new groovy.json.JsonSlurper()
386                 java.util.Map lhsAttributes = getAttributes(slurper.parseText(lhsObject.toString()))
387                 java.util.Map rhsAttributes = getAttributes(slurper.parseText(rhsObject.toString()))
388
389                 def leftToRight = compareAttributes(lhsAttributes, rhsAttributes)
390                 def rightToLeft = compareAttributes(rhsAttributes, lhsAttributes)
391                 def mergedResults = mergeMaps(leftToRight, rightToLeft)
392
393                 boolean success = true
394                 List<String> details = new ArrayList<>()
395                 if(!mergedResults.isEmpty()) {
396                         success = false
397                         details.add(mergedResults.toString())
398                 }
399                 return new Tuple2(success, details)
400         '''
401 }
402
403 /*
404  * The data-dictionary rule below can be used with this useRule clause:
405  *   useRule {
406  *     name 'Data-Dictionary validate VF type'
407  *     attributes 'context-list.ndcb.vnfList[*].vfModuleList[*].networkList[*].type'
408  *   }
409  */
410 rule {
411     name        'Data-Dictionary validate VF type'
412     category    'INVALID_VALUE'
413     description 'Validate all VF type values against data-dictionary'
414     errorText   'VF type [{0}] failed data-dictionary validation: {1}'
415     severity    'ERROR'
416     attributes  'typeList'
417     validate    '''
418         boolean success = true
419         List<String> details = new ArrayList<>()
420         typeList.any {
421             if(!success) {
422                 // break out of 'any' loop
423                 return false
424             }
425             def result = org.onap.aai.validation.ruledriven.rule.builtin.DataDictionary.validate("instance", "vfModuleNetworkType", "type", "$it")
426             if(!result.isEmpty()) {
427                 success = false
428                 details.add("$it")
429                 details.add("$result")
430             }
431         }
432         return new Tuple2(success, details)
433         '''
434 }