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