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