Updated SDC listener and dependent bundles
[appc.git] / appc-dg / appc-dg-shared / appc-dg-common / src / main / java / org / onap / appc / dg / common / impl / VnfExecutionFlowImpl.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.dg.common.impl;
26
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29 import com.att.eelf.i18n.EELFResourceManager;
30 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
31 import org.onap.appc.exceptions.APPCException;
32
33 import java.util.*;
34
35 import org.onap.appc.dg.common.VnfExecutionFlow;
36 import org.onap.appc.dg.dependencymanager.DependencyManager;
37 import org.onap.appc.dg.dependencymanager.exception.DependencyModelNotFound;
38 import org.onap.appc.dg.dependencymanager.impl.DependencyModelFactory;
39 import org.onap.appc.dg.flowbuilder.FlowBuilder;
40 import org.onap.appc.dg.flowbuilder.exception.InvalidDependencyModelException;
41 import org.onap.appc.dg.flowbuilder.impl.FlowBuilderFactory;
42 import org.onap.appc.dg.objects.*;
43 import org.onap.appc.domainmodel.Vnf;
44 import org.onap.appc.domainmodel.Vnfc;
45 import org.onap.appc.domainmodel.Vserver;
46 import org.onap.appc.i18n.Msg;
47 import org.onap.appc.metadata.objects.DependencyModelIdentifier;
48
49 public class VnfExecutionFlowImpl implements VnfExecutionFlow {
50
51     private final EELFLogger logger = EELFManager.getInstance().getLogger(VnfExecutionFlowImpl.class);
52     private static final String VNFC_FLOW="vnfcFlow[";
53     private static final String VNF_VNFC="vnf.vnfc[";
54     /**
55      * Constructor
56      * <p>Used through blueprint
57      */
58     public VnfExecutionFlowImpl(){
59         // do nothing
60     }
61
62     @Override
63     public void getVnfExecutionFlowData(Map<String, String> params, SvcLogicContext context) {
64         String dependencyType = params.get(Constants.DEPENDENCY_TYPE);
65         String flowStrategy = params.get(Constants.FLOW_STRATEGY);
66         DependencyModelIdentifier modelIdentifier = readDependencyModelIdentifier(params);
67         VnfcDependencyModel dependencyModel;
68         try {
69             validateInput(dependencyType, flowStrategy, params);
70
71             if (logger.isTraceEnabled()) {
72                 logger.trace("Input received from DG Node : dependencyType = " + dependencyType +
73                         " , flowStrategy = " + flowStrategy +
74                         ", DependencyModelIdentifier = " + modelIdentifier.toString());
75             }
76
77             DependencyManager dependencyManager = DependencyModelFactory.createDependencyManager();
78             dependencyModel = dependencyManager.getVnfcDependencyModel(
79                     modelIdentifier, DependencyTypes.findByString(dependencyType));
80         } catch (DependencyModelNotFound e) {
81             String msg = EELFResourceManager.format(Msg.DEPENDENCY_MODEL_NOT_FOUND,params.get(Constants.VNF_TYPE), e.getMessage());
82             logger.error(msg);
83             context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,msg);
84             context.setAttribute("dependencyModelFound","false");
85             return;
86         } catch (InvalidDependencyModelException e){
87             String msg = EELFResourceManager.format(Msg.INVALID_DEPENDENCY_MODEL,params.get(Constants.VNF_TYPE), e.getMessage());
88             logger.error(msg);
89             context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,msg);
90             throw new RuntimeException(e.getMessage(),e);
91         } catch (APPCException e){
92             logger.error(e.getMessage());
93             context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,e.getMessage());
94             throw new RuntimeException(e.getMessage(),e);
95         }
96         catch (RuntimeException e){
97             logger.error(e.getMessage());
98             context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,e.getMessage());
99             throw e;
100         }
101
102
103         context.setAttribute("dependencyModelFound","true");
104         if(logger.isDebugEnabled()){
105             logger.debug("Dependency Model = " +dependencyModel);
106         }
107         logger.info("Building Inventory Model from DG context");
108         InventoryModel inventoryModel = null;
109         try {
110              inventoryModel = readInventoryModel(context);
111         } catch (APPCException e) {
112             logger.error(e.getMessage());
113             context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,e.getMessage());
114             throw new RuntimeException(e.getMessage(),e);
115         }
116         if(logger.isDebugEnabled()){
117             logger.debug("Inventory Model = " +inventoryModel);
118         }
119
120         if(logger.isDebugEnabled()){
121             logger.debug("Validating inventory model with dependency model");
122         }
123         try {
124             validateInventoryModelWithDependencyModel(dependencyModel, inventoryModel);
125         }
126         catch (APPCException e){
127             logger.error(e.getMessage());
128             context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,e.getMessage());
129             throw new RuntimeException(e.getMessage(),e);
130         }
131         logger.info("Creating flow builder");
132         FlowBuilder flowBuilder = FlowBuilderFactory.getInstance().getFlowBuilder(
133                 FlowStrategies.findByString(flowStrategy));
134
135         logger.info("Building Vnf flow model");
136         VnfcFlowModel flowModel;
137         try{
138             flowModel = flowBuilder.buildFlowModel(dependencyModel,inventoryModel);
139         }
140         catch (InvalidDependencyModelException e){
141             String msg = EELFResourceManager.format(Msg.INVALID_DEPENDENCY_MODEL,params.get(Constants.VNF_TYPE), e.getMessage());
142             logger.error(msg);
143             context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,msg);
144             throw new RuntimeException(e.getMessage(),e);
145         }
146
147         // remove VNFCs from the flow model where vserver list is empty
148         reconcileFlowModel(flowModel);
149         populateContext(flowModel,context);
150         if(logger.isDebugEnabled()){
151             logContext(context);
152         }
153         String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "GetVnfExecutionFlowData","VNF ID " + params.get(Constants.VNF_TYPE));
154         context.setAttribute(org.onap.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
155     }
156
157     private void validateInput(String dependencyType, String flowStrategy, Map<String, String> params) throws APPCException {
158         DependencyTypes dependencyTypes = DependencyTypes.findByString(dependencyType);
159         if(dependencyTypes == null){
160             throw new APPCException("Dependency type from the input : " + dependencyType +" is invalid.");
161         }
162         FlowStrategies flowStrategies = FlowStrategies.findByString(flowStrategy);
163         if(flowStrategies == null){
164             throw new APPCException("Flow Strategy from the input : " + flowStrategy +" is invalid.");
165         }
166         String vnfType = params.get(Constants.VNF_TYPE);
167         if(vnfType ==null || vnfType.length() ==0){
168             throw new APPCException("Vnf Type is not passed in the input");
169         }
170         String vnfVersion = params.get(Constants.VNF_VERION);
171         if(vnfVersion == null || vnfVersion.length() ==0){
172             throw new APPCException("Vnf Version not found");
173         }
174     }
175
176     private void logContext(SvcLogicContext context) {
177         for(String key:context.getAttributeKeySet()){
178             logger.debug(key + " = " + context.getAttribute(key) + "\n" );
179         }
180     }
181
182     private void populateContext(VnfcFlowModel flowModel, SvcLogicContext context) {
183         int flowIndex=0;
184         Iterator<List<Vnfc>> iterator = flowModel.getModelIterator();
185         while (iterator.hasNext()){
186             for(Vnfc vnfc:iterator.next()){
187                 context.setAttribute(VNFC_FLOW+flowIndex+"].vnfcName",vnfc.getVnfcName());
188                 context.setAttribute(VNFC_FLOW+flowIndex+"].vnfcType",vnfc.getVnfcType());
189                 context.setAttribute(VNFC_FLOW+flowIndex+"].resilienceType",vnfc.getResilienceType());
190                 context.setAttribute(VNFC_FLOW+flowIndex+"].vmCount",Integer.toString(vnfc.getVserverList().size()));
191                 int vmIndex =0;
192                 for(Vserver vm :vnfc.getVserverList()){
193                     context.setAttribute(VNFC_FLOW+flowIndex+"].vm["+vmIndex+"].url",vm.getUrl());
194                     vmIndex++;
195                 }
196                 flowIndex++;
197             }
198         }
199         context.setAttribute("vnfcFlowCount",Integer.toString(flowIndex));
200     }
201
202     private InventoryModel readInventoryModel(SvcLogicContext context) throws APPCException {
203         String vnfId = context.getAttribute("input.action-identifiers.vnf-id");
204         String vnfType = context.getAttribute("vnf.type");
205         String vnfVersion = context.getAttribute("vnf.version");
206         String vnfcCountStr = context.getAttribute("vnf.vnfcCount");
207         Integer vnfcCount = Integer.parseInt(vnfcCountStr);
208         Vnf vnf = createVnf(vnfId, vnfType, vnfVersion);
209         for(Integer i=0;i<vnfcCount;i++){
210             String vnfcName = context.getAttribute(VNF_VNFC+ i+"].name");
211             String vnfcType = context.getAttribute(VNF_VNFC+ i+"].type");
212             String vmCountStr = context.getAttribute(VNF_VNFC+ i+"].vm_count");
213             if(vnfcType ==null || vnfcType.length() ==0){
214                 throw new APPCException("Could not retrieve VNFC Type from DG Context for vnf.vnfc["+ i+"].type");
215             }
216             Integer vmCount = Integer.parseInt(vmCountStr);
217             Vnfc vnfc = createVnfc(vnfcName, vnfcType);
218             for(Integer j=0;j<vmCount;j++){
219                 String vmURL = context.getAttribute(VNF_VNFC+i+"].vm["+j+"].url");
220                 Vserver vm = createVserver(vmURL);
221                 vm.setVnfc(vnfc);
222                 vnfc.addVserver(vm);
223                 vnf.addVserver(vm);
224             }
225         }
226         return new InventoryModel(vnf);
227     }
228
229     private Vserver createVserver(String vmURL) {
230         Vserver vserver = new Vserver();
231         vserver.setUrl(vmURL);
232         return vserver;
233     }
234
235     private Vnfc createVnfc(String vnfcName, String vnfcType) {
236         Vnfc vnfc =new Vnfc();
237         vnfc.setVnfcName(vnfcName);
238         vnfc.setVnfcType(vnfcType);
239         return vnfc;
240     }
241
242     private Vnf createVnf(String vnfId, String vnfType, String vnfVersion) {
243         Vnf vnf =new Vnf();
244         vnf.setVnfType(vnfType);
245         vnf.setVnfId(vnfId);
246         vnf.setVnfVersion(vnfVersion);
247         return vnf;
248     }
249
250     private DependencyModelIdentifier readDependencyModelIdentifier(Map<String, String> params) {
251         String vnfType = params.get(Constants.VNF_TYPE);
252         String catalogVersion = params.get(Constants.VNF_VERION);
253         return new DependencyModelIdentifier(vnfType,catalogVersion);
254     }
255
256     private void validateInventoryModelWithDependencyModel(VnfcDependencyModel dependencyModel, InventoryModel inventoryModel) throws APPCException {
257         Set<String> dependencyModelVnfcSet = new HashSet<>();
258         Set<String> dependencyModelMandatoryVnfcSet = new HashSet<>();
259         Set<String> inventoryModelVnfcsSet = new HashSet<>();
260         for (Node<Vnfc> node : dependencyModel.getDependencies()) {
261             dependencyModelVnfcSet.add(node.getChild().getVnfcType().toLowerCase());
262             if (node.getChild().isMandatory()) {
263                 dependencyModelMandatoryVnfcSet.add(node.getChild().getVnfcType().toLowerCase());
264             }
265         }
266         for (Vnfc vnfc : inventoryModel.getVnf().getVnfcs()) {
267             inventoryModelVnfcsSet.add(vnfc.getVnfcType().toLowerCase());
268         }
269         // if dependency model and inventory model contains same set of VNFCs, validation succeed and hence return
270         if (dependencyModelVnfcSet.equals(inventoryModelVnfcsSet)) {
271             return;
272         }
273         if (inventoryModelVnfcsSet.size() >= dependencyModelVnfcSet.size()) {
274             Set<String> difference = new HashSet<>(inventoryModelVnfcsSet);
275             difference.removeAll(dependencyModelVnfcSet);
276             logger.error("Dependency model is missing following vnfc type(s): " + difference);
277             throw new APPCException("Dependency model is missing following vnfc type(s): " + difference);
278         } else {
279             Set<String> difference = new HashSet<>(dependencyModelMandatoryVnfcSet);
280             difference.removeAll(inventoryModelVnfcsSet);
281             if (difference.size() > 0) {
282                 logger.error("Inventory model is missing following mandatory vnfc type(s): " + difference);
283                 throw new APPCException("Inventory model is missing following mandatory vnfc type(s): " + difference);
284             }
285         }
286     }
287
288     private void reconcileFlowModel(VnfcFlowModel flowModel) {
289         Iterator<List<Vnfc>> flowIterator = flowModel.getModelIterator();
290         while (flowIterator.hasNext()) {
291             Iterator<Vnfc> vnfcIterator = flowIterator.next().iterator();
292             while (vnfcIterator.hasNext()) {
293                 Vnfc vnfc = vnfcIterator.next();
294                 if (vnfc.getVserverList().size() == 0) {
295                     if (logger.isDebugEnabled()) {
296                         logger.debug("No vservers present for Vnfc type: " + vnfc.getVnfcType() + ". Hence, removing it from the flow model.");
297                     }
298                     vnfcIterator.remove();
299                 }
300             }
301         }
302     }
303
304 }