Add junit coverage to RequestInfoBuilder class
[appc.git] / appc-sequence-generator / appc-sequence-generator-bundle / src / main / java / org / onap / appc / seqgen / dgplugin / impl / SequenceGeneratorPluginImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.appc.seqgen.dgplugin.impl;
26
27
28 import com.att.eelf.configuration.EELFLogger;
29 import com.att.eelf.configuration.EELFManager;
30 import com.fasterxml.jackson.core.JsonParser;
31 import com.fasterxml.jackson.databind.DeserializationFeature;
32 import com.fasterxml.jackson.databind.JsonNode;
33 import com.fasterxml.jackson.databind.ObjectMapper;
34 import org.onap.appc.dg.flowbuilder.exception.InvalidDependencyModelException;
35 import org.onap.appc.dg.objects.InventoryModel;
36 import org.onap.appc.dg.objects.Node;
37 import org.onap.appc.dg.objects.VnfcDependencyModel;
38 import org.onap.appc.domainmodel.Vnf;
39 import org.onap.appc.domainmodel.Vnfc;
40 import org.onap.appc.domainmodel.Vserver;
41 import org.onap.appc.domainmodel.lcm.VNFOperation;
42 import org.onap.appc.exceptions.APPCException;
43 import org.onap.appc.seqgen.SequenceGenerator;
44 import org.onap.appc.seqgen.dgplugin.SequenceGeneratorPlugin;
45 import org.onap.appc.seqgen.impl.SequenceGeneratorFactory;
46 import org.onap.appc.seqgen.objects.Constants;
47 import org.onap.appc.seqgen.objects.SequenceGeneratorInput;
48 import org.onap.appc.seqgen.objects.Transaction;
49 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
50
51 import java.io.IOException;
52 import java.util.Map;
53 import java.util.List;
54 import java.util.HashSet;
55 import java.util.Set;
56 import java.util.HashMap;
57 import java.util.LinkedList;
58
59 public class SequenceGeneratorPluginImpl implements SequenceGeneratorPlugin {
60
61     private static final EELFLogger logger = EELFManager.getInstance().getLogger(SequenceGeneratorPluginImpl.class);
62
63     @Override
64     public void generateSequence(Map<String, String> params, SvcLogicContext context) {
65         ObjectMapper objectMapper = new ObjectMapper();
66         String inputJSON = context.getAttribute("inputJSON");
67         logger.debug("Input to Sequence Generator " + inputJSON);
68         try {
69             SequenceGeneratorInput sequenceGeneratorInput = buildSequenceGeneratorInput(inputJSON);
70             List<Transaction> sequence = generateSequence(sequenceGeneratorInput);
71             String output = objectMapper.writeValueAsString(sequence);
72             logger.debug("Sequence Generator Output " + output);
73
74             context.setAttribute("output", output);
75         } catch (Exception e) {
76             logger.error("Error generating sequence", e);
77             context.setAttribute("error-code", "401");
78             context.setAttribute("error-message", "Error generating sequence " + e.getMessage());
79         }
80     }
81
82     private SequenceGeneratorInput buildSequenceGeneratorInput(String inputJson) throws IOException, APPCException {
83         ObjectMapper objectMapper = new ObjectMapper();
84         SequenceGeneratorInput sequenceGeneratorInput ;
85         objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
86         objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
87         sequenceGeneratorInput = objectMapper.readValue(inputJson, SequenceGeneratorInput.class);
88
89         InventoryModel inventoryModel = buildInventoryModel(inputJson);
90         sequenceGeneratorInput.setInventoryModel(inventoryModel);
91
92         VnfcDependencyModel dependencyModel = buildDependencyModel(inputJson);
93         if(dependencyModel!=null){
94             validateInventoryModelWithDependencyModel(dependencyModel,inventoryModel);
95         }
96         sequenceGeneratorInput.setDependencyModel(dependencyModel);
97
98         return sequenceGeneratorInput;
99     }
100     private List<Transaction> generateSequence(SequenceGeneratorInput sequenceGeneratorInput) throws APPCException {
101         if (sequenceGeneratorInput.getRequestInfo() == null) {
102             throw new APPCException("Request info is not provided in the input");
103         }
104         String action = sequenceGeneratorInput.getRequestInfo().getAction();
105         VNFOperation operation = VNFOperation.findByString(action);
106         if (operation == null) {
107             throw new APPCException("Invalid Action " + action);
108         }
109         if(Constants.ActionLevel.findByString(sequenceGeneratorInput.getRequestInfo().getActionLevel().toUpperCase())==null){
110             throw new APPCException("Invalid Action Level " + sequenceGeneratorInput.getRequestInfo().getActionLevel());
111         }
112         SequenceGenerator sequenceGenerator = SequenceGeneratorFactory.getInstance().createSequenceGenerator(operation);
113         return sequenceGenerator.generateSequence(sequenceGeneratorInput);
114     }
115
116     private void validateInventoryModelWithDependencyModel(VnfcDependencyModel dependencyModel, InventoryModel inventoryModel) throws APPCException {
117         Set<String> dependencyModelVnfcSet = new HashSet<>();
118         Set<String> dependencyModelMandatoryVnfcSet = new HashSet<>();
119         Set<String> inventoryModelVnfcsSet = new HashSet<>();
120
121         for (Node<Vnfc> node : dependencyModel.getDependencies()) {
122             dependencyModelVnfcSet.add(node.getChild().getVnfcType().toLowerCase());
123             if (node.getChild().isMandatory()) {
124                 dependencyModelMandatoryVnfcSet.add(node.getChild().getVnfcType().toLowerCase());
125             }
126         }
127
128         for (Vnfc vnfc : inventoryModel.getVnf().getVnfcs()) {
129             inventoryModelVnfcsSet.add(vnfc.getVnfcType().toLowerCase());
130         }
131
132         // if dependency model and inventory model contains same set of VNFCs, validation succeed and hence return
133         if (dependencyModelVnfcSet.equals(inventoryModelVnfcsSet)) {
134             return;
135         }
136
137         if (inventoryModelVnfcsSet.size() >= dependencyModelVnfcSet.size()) {
138             Set<String> difference = new HashSet<>(inventoryModelVnfcsSet);
139             difference.removeAll(dependencyModelVnfcSet);
140             logger.error("Dependency model is missing following vnfc type(s): " + difference);
141             throw new APPCException("Dependency model is missing following vnfc type(s): " + difference);
142         } else {
143             Set<String> difference = new HashSet<>(dependencyModelMandatoryVnfcSet);
144             difference.removeAll(inventoryModelVnfcsSet);
145             if (difference.size() > 0) {
146                 logger.error("Inventory model is missing following mandatory vnfc type(s): " + difference);
147                 throw new APPCException("VMs missing for the mandatory VNFC : " + difference);
148             }
149         }
150     }
151
152     // Dependency model is an optional attribute and may contain null values
153     private VnfcDependencyModel buildDependencyModel(String inputJson) throws IOException, APPCException {
154         Set<Node<Vnfc>> dependency = new HashSet<>();
155         Set<String> parentVnfcs=new HashSet<>();
156         Set<String> allVnfcTypes=new HashSet<>();
157         ObjectMapper objectMapper = new ObjectMapper();
158         objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
159         JsonNode rootNode = objectMapper.readTree(inputJson);
160         JsonNode vnfcs = getVnfcsNode(rootNode);
161         if (vnfcs != null) {
162             for (JsonNode vnfcNode : vnfcs) {
163                 String vnfcType = readVnfcType(vnfcNode);
164                 allVnfcTypes.add(vnfcType);
165                 String mandatory = readMandatory(vnfcNode);
166                 String resilience = readResilience(vnfcNode);
167                 Vnfc vnfc = new Vnfc();
168                 vnfc.setVnfcType(vnfcType);
169                 vnfc.setResilienceType(resilience);
170                 vnfc.setMandatory(Boolean.parseBoolean(mandatory));
171                 Node<Vnfc> currentNode = getNode(dependency, vnfcType);
172                 if (currentNode == null) {
173                     currentNode = new Node<>(vnfc);
174                     dependency.add(currentNode);
175                 } else {
176                     currentNode.getChild().setMandatory(Boolean.valueOf(mandatory));
177                     currentNode.getChild().setResilienceType(resilience);
178                 }
179                 JsonNode parents = vnfcNode.get("parents");
180                 for (JsonNode parent : parents) {
181                     String parentVnfcType = parent.asText();
182                     parentVnfcs.add(parentVnfcType);
183                     Node<Vnfc> parentNode = getNode(dependency, parentVnfcType);
184                     if (parentNode != null) {
185                         currentNode.addParent(parentNode.getChild());
186                     } else {
187                         Vnfc parentVnfc=new Vnfc();
188                         parentVnfc.setVnfcType(parentVnfcType);
189                         parentVnfc.setMandatory(false);
190                         parentNode = new Node<>(parentVnfc);
191                         currentNode.addParent(parentVnfc);
192                         dependency.add(parentNode);
193                     }
194                 }
195
196             }
197             for(String parent:parentVnfcs){
198                 if(!allVnfcTypes.contains(parent)){
199                     throw new APPCException("Dependency model missing vnfc type "+parent);
200                 }
201             }
202             return new VnfcDependencyModel(dependency);
203         }
204         return null;
205     }
206
207     private String readResilience(JsonNode vnfcNode) {
208         String resilience = null;
209         if (vnfcNode.get("resilience") != null) {
210             resilience = vnfcNode.get("resilience").asText();
211         }
212         return resilience;
213     }
214
215     private String readMandatory(JsonNode vnfcNode) {
216         String mandatory ;
217         JsonNode mandatoryNode = vnfcNode.get("mandatory");
218         if (mandatoryNode == null) {
219             mandatory = "false";
220         } else {
221             mandatory = mandatoryNode.asText();
222         }
223         return mandatory;
224     }
225
226     private String readVnfcType(JsonNode vnfcNode) throws APPCException {
227         JsonNode vnfcTypeNode = vnfcNode.get(Constants.VNFC_TYPE);
228         if (vnfcTypeNode == null) {
229             throw new APPCException("vnfc-type is not available in dependency info");
230         }
231         return vnfcTypeNode.asText();
232     }
233
234     private JsonNode getVnfcsNode(JsonNode rootNode) {
235         JsonNode dependencyInfo = rootNode.get("dependency-info");
236         JsonNode vnfcs = null;
237         if (dependencyInfo != null) {
238             vnfcs = dependencyInfo.get("vnfcs");
239         }
240         return vnfcs;
241     }
242
243     private Node<Vnfc> getNode(Set<Node<Vnfc>> dependency, String vnfcType) {
244         for (Node<Vnfc> node : dependency) {
245             if (node.getChild().getVnfcType().equals(vnfcType)) {
246                 return node;
247             }
248         }
249         return null;
250     }
251
252     private InventoryModel buildInventoryModel(String inputJson) throws IOException, APPCException {
253         ObjectMapper objectMapper = new ObjectMapper();
254         JsonNode jsonNode = objectMapper.readTree(inputJson);
255         JsonNode inventoryInfo = jsonNode.get("inventory-info");
256         if (inventoryInfo == null) {
257             throw new APPCException("inventory-info is not provided in the input");
258         }
259         JsonNode vnfInfo = inventoryInfo.get("vnf-info");
260         if (vnfInfo == null) {
261             throw new APPCException("vnf-info is not provided in the input");
262         }
263
264         String vnfId = vnfInfo.get("vnf-id").asText();
265         String vnfType = vnfInfo.get("vnf-type").asText();
266         Vnf vnf =new Vnf();
267         vnf.setVnfId(vnfId);
268         vnf.setVnfType(vnfType);
269         Map<Vnfc, List<Vserver>> vfcs = new HashMap<>();
270         JsonNode vms = vnfInfo.get("vm");
271         if(vms.size()<1){
272             throw new APPCException("vm info not provided in the input");
273         }
274         for (JsonNode vm : vms) {
275             if(vm.get("vserver-id")== null){
276                 throw new APPCException("vserver-id not found ");
277             }
278             String vserverId = vm.get("vserver-id").asText();
279             Vserver vserver = new Vserver();
280             vserver.setId(vserverId);
281             if (vm.get("vnfc")!=null&& vm.get("vnfc").get("vnfc-name") != null && vm.get("vnfc").get("vnfc-type")!= null) {
282                 Vnfc vfc = new Vnfc();
283                 vfc.setVnfcType(vm.get("vnfc").get("vnfc-type").asText());
284                 vfc.setVnfcName(vm.get("vnfc").get("vnfc-name").asText());
285                 vserver.setVnfc(vfc);
286                 List<Vserver> vServers = vfcs.get(vfc);
287                 if (vServers == null) {
288                     vServers = new LinkedList<>();
289                     vfcs.put(vfc, vServers);
290                 }
291                 vServers.add(vserver);
292             }
293             vnf.addVserver(vserver);
294         }
295
296         for (Map.Entry<Vnfc, List<Vserver>> entry : vfcs.entrySet()) {
297             Vnfc vnfc = entry.getKey();
298             List<Vserver> vServers = vfcs.get(vnfc);
299             vnfc.addVservers(vServers);
300         }
301
302         return new InventoryModel(vnf);
303     }
304 }