c9b37c2697869d854821d9e662db21deecb28591
[ccsdk/cds.git] /
1 /*\r
2  * Copyright © 2017-2018 AT&T Intellectual Property.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package org.onap.ccsdk.apps.controllerblueprints.resource.dict.validator;\r
18 \r
19 import org.apache.commons.lang3.StringUtils;\r
20 import org.apache.commons.lang3.text.StrBuilder;\r
21 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
22 import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
23 import org.onap.ccsdk.apps.controllerblueprints.core.data.CapabilityAssignment;\r
24 import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate;\r
25 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
26 import org.onap.ccsdk.apps.controllerblueprints.core.utils.TopologicalSortingUtils;\r
27 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
28 import org.slf4j.Logger;\r
29 import org.slf4j.LoggerFactory;\r
30 \r
31 import java.util.*;\r
32 \r
33 /**\r
34  * ResourceAssignmentValidator.java Purpose:\r
35  *\r
36  * @author Brinda Santh\r
37  */\r
38 public class ResourceAssignmentValidator {\r
39     private static final Logger log = LoggerFactory.getLogger(ResourceAssignmentValidator.class);\r
40     private List<ResourceAssignment> assignments;\r
41     private Map<String, ResourceAssignment> resourceAssignmentMap = new HashMap<>();\r
42     private StrBuilder validationMessage = new StrBuilder();\r
43 \r
44     public ResourceAssignmentValidator(List<ResourceAssignment> assignments) {\r
45         this.assignments = assignments;\r
46     }\r
47 \r
48     public ResourceAssignmentValidator(NodeTemplate nodeTemplate) throws BluePrintException {\r
49 \r
50         if (nodeTemplate != null && nodeTemplate.getCapabilities() != null) {\r
51             CapabilityAssignment capabilityAssignment =\r
52                     nodeTemplate.getCapabilities().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
53             if (capabilityAssignment != null && capabilityAssignment.getProperties() != null) {\r
54                 Object mappingObject =\r
55                         capabilityAssignment.getProperties().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
56                 if (mappingObject != null) {\r
57                     String mappingContent = JacksonUtils.getJson(mappingObject);\r
58                     if (StringUtils.isNotBlank(mappingContent)) {\r
59                         this.assignments =\r
60                                 JacksonUtils.getListFromJson(mappingContent, ResourceAssignment.class);\r
61                     } else {\r
62                         validationMessage\r
63                                 .appendln(String.format("Failed to transform Mapping Content (%s) ", mappingContent));\r
64                         throw new BluePrintException(\r
65                                 String.format("Failed to transform Mapping Content (%s) ", mappingContent));\r
66                     }\r
67                 }\r
68             }\r
69         }\r
70     }\r
71 \r
72     /**\r
73      * This is a validateResourceAssignment to validate the Topology Template\r
74      *\r
75      * @return boolean\r
76      * @throws BluePrintException BluePrintException\r
77      */\r
78     public boolean validateResourceAssignment() throws BluePrintException {\r
79         if (assignments != null && !assignments.isEmpty()) {\r
80             validateDuplicateDictionaryKeys();\r
81             validateCyclicDependency();\r
82             if (validationMessage.length() > 0) {\r
83                 throw new BluePrintException("Resource Assignment Validation :" + validationMessage.toString());\r
84             }\r
85         }\r
86         return true;\r
87     }\r
88 \r
89     @SuppressWarnings("squid:S3776")\r
90     private void validateDuplicateDictionaryKeys() {\r
91         this.assignments.forEach(resourceMapping -> {\r
92             if (resourceMapping != null) {\r
93                 if (!resourceAssignmentMap.containsKey(resourceMapping.getName())) {\r
94                     resourceAssignmentMap.put(resourceMapping.getName(), resourceMapping);\r
95                 } else {\r
96                     validationMessage.appendln(String.format("Duplicate Assignment Template Key (%s) is Present",\r
97                             resourceMapping.getName()));\r
98                 }\r
99             }\r
100         });\r
101 \r
102         if (!assignments.isEmpty()) {\r
103             Set<String> uniqueSet = new HashSet<>();\r
104             for (ResourceAssignment resourceAssignment : assignments) {\r
105                 if (resourceAssignment != null) {\r
106                     boolean added = uniqueSet.add(resourceAssignment.getDictionaryName());\r
107                     if (!added) {\r
108                         validationMessage.appendln(\r
109                                 String.format("Duplicate Assignment Dictionary Key (%s) present with Template Key (%s)",\r
110                                         resourceAssignment.getDictionaryName(), resourceAssignment.getName()));\r
111                     }\r
112                 }\r
113             }\r
114         }\r
115     }\r
116 \r
117     private void validateCyclicDependency() {\r
118         TopologicalSortingUtils<ResourceAssignment> topologySorting = new TopologicalSortingUtils<>();\r
119         this.resourceAssignmentMap.forEach((mappingKey, mapping) -> {\r
120             if (mapping != null) {\r
121                 if (mapping.getDependencies() != null && !mapping.getDependencies().isEmpty()) {\r
122                     for (String dependency : mapping.getDependencies()) {\r
123                         topologySorting.add(resourceAssignmentMap.get(dependency), mapping);\r
124                     }\r
125                 } else {\r
126                     topologySorting.add(null, mapping);\r
127                 }\r
128             }\r
129         });\r
130 \r
131         if (!topologySorting.isDag()) {\r
132             String graph = getTopologicalGraph(topologySorting);\r
133             validationMessage.appendln("Cyclic Dependency :" + graph);\r
134         }\r
135     }\r
136 \r
137 \r
138     public String getTopologicalGraph(TopologicalSortingUtils<ResourceAssignment> topologySorting) {\r
139         StringBuilder s = new StringBuilder();\r
140         if (topologySorting != null) {\r
141             Map<ResourceAssignment, List<ResourceAssignment>> neighbors = topologySorting.getNeighbors();\r
142 \r
143             neighbors.forEach((v, vs) -> {\r
144                 if (v == null) {\r
145                     s.append("\n    * -> [");\r
146                     for (ResourceAssignment resourceAssignment : vs) {\r
147                         s.append("(" + resourceAssignment.getDictionaryName() + ":" + resourceAssignment.getName()\r
148                                 + "),");\r
149                     }\r
150                     s.append("]");\r
151                 } else {\r
152                     s.append("\n    (" + v.getDictionaryName() + ":" + v.getName() + ") -> [");\r
153                     for (ResourceAssignment resourceAssignment : vs) {\r
154                         s.append("(" + resourceAssignment.getDictionaryName() + ":" + resourceAssignment.getName()\r
155                                 + "),");\r
156                     }\r
157                     s.append("]");\r
158                 }\r
159             });\r
160         }\r
161         return s.toString();\r
162     }\r
163 }\r