Fix OSGi wiring issues
[ccsdk/features.git] / blueprints-processor / plugin / model-provider / src / main / java / org / onap / ccsdk / features / 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.features.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.features.model.ConfigModelConstant;\r
27 import org.onap.ccsdk.features.model.ConfigModelException;\r
28 import org.onap.ccsdk.features.model.data.CapabilityAssignment;\r
29 import org.onap.ccsdk.features.model.data.NodeTemplate;\r
30 import org.onap.ccsdk.features.model.data.ResourceAssignment;\r
31 import org.onap.ccsdk.features.model.utils.TopologicalSortingUtils;\r
32 import org.onap.ccsdk.features.model.utils.TransformationUtils;\r
33 \r
34 import com.att.eelf.configuration.EELFLogger;\r
35 import com.att.eelf.configuration.EELFManager;\r
36 \r
37 public class ResourceAssignmentValidator {\r
38     private static EELFLogger logger = EELFManager.getInstance().getLogger(ResourceAssignmentValidator.class);\r
39     private List<ResourceAssignment> assignments;\r
40     private Map<String, ResourceAssignment> resourceAssignmentMap = new HashMap<>();\r
41     private StringBuilder validationMessage = new StringBuilder();\r
42 \r
43     public ResourceAssignmentValidator(NodeTemplate nodeTemplate) throws ConfigModelException {\r
44 \r
45         if (nodeTemplate != null && nodeTemplate.getCapabilities() != null) {\r
46             CapabilityAssignment capabilityAssignment =\r
47                     nodeTemplate.getCapabilities().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
48             if (capabilityAssignment != null && capabilityAssignment.getProperties() != null) {\r
49                 Object mappingObject =\r
50                         capabilityAssignment.getProperties().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
51                 if (mappingObject != null) {\r
52                     String mappingContent = TransformationUtils.getJson(mappingObject);\r
53                     if (StringUtils.isNotBlank(mappingContent)) {\r
54                         this.assignments =\r
55                                 TransformationUtils.getListfromJson(mappingContent, ResourceAssignment.class);\r
56                     } else {\r
57                         validationMessage\r
58                                 .append(String.format("Failed to transform Mapping Content (%s) ", mappingContent));\r
59                         throw new ConfigModelException(\r
60                                 String.format("Failed to transform Mapping Content (%s) ", mappingContent));\r
61                     }\r
62                 }\r
63             }\r
64         }\r
65     }\r
66 \r
67     public ResourceAssignmentValidator(List<ResourceAssignment> assignments) {\r
68         this.assignments = assignments;\r
69     }\r
70 \r
71     /**\r
72      * This is a validateResourceAssignment to validate the Topology Template\r
73      *\r
74      * @return boolean\r
75      * @throws ConfigModelException\r
76      */\r
77     public boolean validateResourceAssignment() throws ConfigModelException {\r
78         if (assignments != null && !assignments.isEmpty()) {\r
79             validateDuplicateDictionaryKeys();\r
80             validateCyclicDependencty();\r
81             if (validationMessage.length() > 0) {\r
82                 logger.error("Resourece Assignment Validation : {}", validationMessage);\r
83                 throw new ConfigModelException("Resourece 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.append(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.append(\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 validateCyclicDependencty() {\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.append("Cyclic Dependency :" + graph);\r
134         }\r
135     }\r
136 \r
137     public String getTopologicalGraph(TopologicalSortingUtils<ResourceAssignment> topologySorting) {\r
138         StringBuilder s = new StringBuilder();\r
139         if (topologySorting != null) {\r
140             Map<ResourceAssignment, List<ResourceAssignment>> neighbors = topologySorting.getNeighbors();\r
141 \r
142             neighbors.forEach((v, vs) -> {\r
143                 if (v == null) {\r
144                     s.append("\n    * -> [");\r
145                     List<ResourceAssignment> links = vs;\r
146                     for (ResourceAssignment resourceAssignment : links) {\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                     List<ResourceAssignment> links = vs;\r
154                     for (ResourceAssignment resourceAssignment : links) {\r
155                         s.append("(" + resourceAssignment.getDictionaryName() + ":" + resourceAssignment.getName()\r
156                                 + "),");\r
157                     }\r
158                     s.append("]");\r
159                 }\r
160             });\r
161         }\r
162         return s.toString();\r
163     }\r
164 }\r