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.collections.CollectionUtils
20 import org.apache.commons.lang3.StringUtils
21 import org.apache.commons.lang3.text.StrBuilder
22 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
23 import org.onap.ccsdk.apps.controllerblueprints.core.utils.TopologicalSortingUtils
24 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment
25 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.validator.ResourceAssignmentValidator
26 import org.slf4j.LoggerFactory
27 import java.io.Serializable
30 * ResourceAssignmentValidationService.
32 * @author Brinda Santh
34 interface ResourceAssignmentValidationService : Serializable {
36 @Throws(BluePrintException::class)
37 fun validate(resourceAssignments: List<ResourceAssignment>): Boolean
41 * ResourceAssignmentValidationDefaultService.
43 * @author Brinda Santh
45 open class ResourceAssignmentValidationDefaultService : ResourceAssignmentValidationService {
46 private val log = LoggerFactory.getLogger(ResourceAssignmentValidator::class.java)
47 open var resourceAssignments: List<ResourceAssignment> = arrayListOf()
48 open var resourceAssignmentMap: MutableMap<String, ResourceAssignment> = hashMapOf()
49 open val validationMessage = StrBuilder()
51 override fun validate(resourceAssignments: List<ResourceAssignment>): Boolean {
52 this.resourceAssignments = resourceAssignments
53 validateSources(resourceAssignments)
54 validateDuplicateDictionaryKeys()
55 validateCyclicDependency()
56 if (StringUtils.isNotBlank(validationMessage)) {
57 throw BluePrintException("Resource Assignment Validation :" + validationMessage.toString())
62 open fun validateSources(resourceAssignments: List<ResourceAssignment>) {
63 log.info("validating resource assignment sources")
66 open fun validateDuplicateDictionaryKeys() {
67 val uniqueDictionaryKeys = hashSetOf<String>()
69 this.resourceAssignments.forEach { resourceAssignment ->
70 // Check Duplicate Names
71 if (!resourceAssignmentMap.containsKey(resourceAssignment.name)) {
72 resourceAssignmentMap[resourceAssignment.name] = resourceAssignment
74 validationMessage.appendln(String.format("Duplicate Assignment Template Key (%s) is Present",
75 resourceAssignment.name))
77 // Check duplicate Dictionary Keys
78 if (!uniqueDictionaryKeys.contains(resourceAssignment.dictionaryName!!)) {
79 uniqueDictionaryKeys.add(resourceAssignment.dictionaryName!!)
81 validationMessage.appendln(
82 String.format("Duplicate Assignment Dictionary Key (%s) present with Template Key (%s)",
83 resourceAssignment.dictionaryName, resourceAssignment.name))
88 open fun validateCyclicDependency() {
89 val startResourceAssignment = ResourceAssignment()
90 startResourceAssignment.name = "*"
92 val topologySorting = TopologicalSortingUtils<ResourceAssignment>()
93 this.resourceAssignmentMap.forEach { assignmentKey, assignment ->
94 if (CollectionUtils.isNotEmpty(assignment.dependencies)) {
95 for (dependency in assignment.dependencies!!) {
96 topologySorting.add(resourceAssignmentMap[dependency]!!, assignment)
99 topologySorting.add(startResourceAssignment, assignment)
103 if (!topologySorting.isDag) {
104 val graph = getTopologicalGraph(topologySorting)
105 validationMessage.appendln("Cyclic Dependency :$graph")
109 open fun getTopologicalGraph(topologySorting: TopologicalSortingUtils<ResourceAssignment>): String {
110 val s = StringBuilder()
111 val neighbors = topologySorting.getNeighbors()
113 neighbors.forEach { v, vs ->
115 s.append("\n * -> [")
116 for (resourceAssignment in vs) {
117 s.append("(" + resourceAssignment.dictionaryName + ":" + resourceAssignment.name
122 s.append("\n (" + v.dictionaryName + ":" + v.name + ") -> [")
123 for (resourceAssignment in vs) {
124 s.append("(" + resourceAssignment.dictionaryName + ":" + resourceAssignment.name