2 * Copyright © 2017-2018 AT&T Intellectual Property.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.ccsdk.apps.controllerblueprints.resource.dict.service
19 import org.apache.commons.lang3.text.StrBuilder
20 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
21 import org.onap.ccsdk.apps.controllerblueprints.core.utils.TopologicalSortingUtils
22 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment
23 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.validator.ResourceAssignmentValidator
24 import org.slf4j.LoggerFactory
25 import org.apache.commons.collections.CollectionUtils
26 import org.apache.commons.lang3.StringUtils
27 import java.io.Serializable
29 * ResourceAssignmentValidationService.
31 * @author Brinda Santh
33 interface ResourceAssignmentValidationService : Serializable {
35 @Throws(BluePrintException::class)
36 fun validate(resourceAssignments: List<ResourceAssignment>): Boolean
40 * ResourceAssignmentValidationDefaultService.
42 * @author Brinda Santh
44 open class ResourceAssignmentValidationDefaultService : ResourceAssignmentValidationService {
45 private val log = LoggerFactory.getLogger(ResourceAssignmentValidator::class.java)
46 open var resourceAssignments: List<ResourceAssignment> = arrayListOf()
47 open var resourceAssignmentMap: MutableMap<String, ResourceAssignment> = hashMapOf()
48 open val validationMessage = StrBuilder()
50 override fun validate(resourceAssignments: List<ResourceAssignment>): Boolean {
51 this.resourceAssignments = resourceAssignments
52 validateSources(resourceAssignments)
53 validateDuplicateDictionaryKeys()
54 validateCyclicDependency()
55 if (StringUtils.isNotBlank(validationMessage)) {
56 throw BluePrintException("Resource Assignment Validation :" + validationMessage.toString())
61 open fun validateSources(resourceAssignments: List<ResourceAssignment>) {
62 log.info("validating resource assignment sources")
65 open fun validateDuplicateDictionaryKeys() {
66 val uniqueDictionaryKeys = hashSetOf<String>()
68 this.resourceAssignments.forEach { resourceAssignment ->
69 // Check Duplicate Names
70 if (!resourceAssignmentMap.containsKey(resourceAssignment.name)) {
71 resourceAssignmentMap[resourceAssignment.name] = resourceAssignment
73 validationMessage.appendln(String.format("Duplicate Assignment Template Key (%s) is Present",
74 resourceAssignment.name))
76 // Check duplicate Dictionary Keys
77 if (!uniqueDictionaryKeys.contains(resourceAssignment.dictionaryName!!)) {
78 uniqueDictionaryKeys.add(resourceAssignment.dictionaryName!!)
80 validationMessage.appendln(
81 String.format("Duplicate Assignment Dictionary Key (%s) present with Template Key (%s)",
82 resourceAssignment.dictionaryName, resourceAssignment.name))
87 open fun validateCyclicDependency() {
88 val startResourceAssignment = ResourceAssignment()
89 startResourceAssignment.name = "*"
91 val topologySorting = TopologicalSortingUtils<ResourceAssignment>()
92 this.resourceAssignmentMap.forEach { assignmentKey, assignment ->
93 if (CollectionUtils.isNotEmpty(assignment.dependencies)) {
94 for (dependency in assignment.dependencies!!) {
95 topologySorting.add(resourceAssignmentMap[dependency]!!, assignment)
98 topologySorting.add(startResourceAssignment, assignment)
102 if (!topologySorting.isDag) {
103 val graph = getTopologicalGraph(topologySorting)
104 validationMessage.appendln("Cyclic Dependency :$graph")
108 open fun getTopologicalGraph(topologySorting: TopologicalSortingUtils<ResourceAssignment>): String {
109 val s = StringBuilder()
110 val neighbors = topologySorting.getNeighbors()
112 neighbors.forEach { v, vs ->
114 s.append("\n * -> [")
115 for (resourceAssignment in vs) {
116 s.append("(" + resourceAssignment.dictionaryName + ":" + resourceAssignment.name
121 s.append("\n (" + v.dictionaryName + ":" + v.name + ") -> [")
122 for (resourceAssignment in vs) {
123 s.append("(" + resourceAssignment.dictionaryName + ":" + resourceAssignment.name