105173f33811c7d3ae513671a2b1ce553fe6a1f5
[appc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017-2018 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  * ============LICENSE_END=========================================================
22  */
23
24
25 package org.onap.appc.seqgen.impl;
26
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29 import org.apache.commons.lang3.StringUtils;
30 import org.onap.appc.dg.flowbuilder.FlowBuilder;
31 import org.onap.appc.dg.flowbuilder.exception.InvalidDependencyModelException;
32 import org.onap.appc.dg.flowbuilder.impl.FlowBuilderFactory;
33 import org.onap.appc.dg.objects.FlowStrategies;
34 import org.onap.appc.dg.objects.InventoryModel;
35 import org.onap.appc.dg.objects.VnfcDependencyModel;
36 import org.onap.appc.dg.objects.VnfcFlowModel;
37 import org.onap.appc.domainmodel.Vnfc;
38 import org.onap.appc.domainmodel.Vserver;
39 import org.onap.appc.exceptions.APPCException;
40 import org.onap.appc.seqgen.SequenceGenerator;
41 import org.onap.appc.seqgen.objects.ActionIdentifier;
42 import org.onap.appc.seqgen.objects.CapabilityModel;
43 import org.onap.appc.seqgen.objects.Constants;
44 import org.onap.appc.seqgen.objects.PreCheckOption;
45 import org.onap.appc.seqgen.objects.Response;
46 import org.onap.appc.seqgen.objects.SequenceGeneratorInput;
47 import org.onap.appc.seqgen.objects.Transaction;
48
49 import java.util.HashMap;
50 import java.util.Iterator;
51 import java.util.LinkedList;
52 import java.util.List;
53 import java.util.Map;
54
55 import static org.onap.appc.seqgen.objects.Constants.Action;
56 import static org.onap.appc.seqgen.objects.Constants.ActionLevel;
57 import static org.onap.appc.seqgen.objects.Constants.ResponseAction;
58 import static org.onap.appc.seqgen.objects.Constants.ResponseMessage;
59 import static org.onap.appc.seqgen.objects.Constants.PreCheckOperator;
60 import static org.onap.appc.seqgen.objects.Constants.Capabilties;
61 import static org.onap.appc.seqgen.objects.Constants.CapabilityLevel;
62 import static org.onap.appc.seqgen.objects.Constants.RETRY_COUNT_VALUE;
63 import static org.onap.appc.seqgen.objects.Constants.WAIT_TIME;
64 import static org.onap.appc.seqgen.objects.Constants.RETRY_COUNT;
65 import static org.onap.appc.seqgen.objects.Constants.WAIT_TIME_VALUE;;
66
67 public class StartSequenceGenerator implements SequenceGenerator {
68
69     private static final EELFLogger logger = EELFManager.getInstance().getLogger(StartSequenceGenerator.class);
70
71     private List<Transaction> generateSequenceWithOutDependency(SequenceGeneratorInput input) throws Exception {
72
73         String payload = null;
74         PayloadGenerator payloadGenerator = new PayloadGenerator();
75         List<Transaction> transactionList = new LinkedList<>();
76         Integer transactionId = 1;
77         List<Vserver> vservers = input.getInventoryModel().getVnf().getVservers();
78         List<Integer> transactionIds = new LinkedList<>();
79         for (Vserver vm : vservers) {
80             // check vm-Start-capabilities for this vm's vnfc-function-code (before incrementing transactionId)
81             String vmVnfcFunctionCode = vm.getVnfc().getVnfcFunctionCode();
82             if (!vmSupportsStart(input, vmVnfcFunctionCode)) {
83                 continue;
84             }
85             Transaction transaction = new Transaction();
86             transaction.setTransactionId(transactionId);
87             transactionIds.add(transactionId++);
88             transaction.setAction(Action.START.getActionType());
89             transaction.setActionLevel(ActionLevel.VM.getAction());
90             ActionIdentifier actionIdentifier = new ActionIdentifier();
91             actionIdentifier.setvServerId(vm.getId());
92             transaction.setActionIdentifier(actionIdentifier);
93             String vmId = vm.getUrl();
94             String url = vm.getUrl();
95             payload = payloadGenerator.getPayload(input, vmId, url);
96             transaction.setPayload(payload);
97             if(vservers.size()>1){
98                 Response ignoreResponse = new Response();
99                 ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
100                 Map<String, String> ignoreAction = new HashMap<>();
101                 ignoreAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
102                 ignoreResponse.setResponseAction(ignoreAction);
103                 transaction.addResponse(ignoreResponse);
104             }
105             transactionList.add(transaction);
106         }
107         return transactionList;
108     }
109
110     private boolean checkSingleTransaction(List<Vnfc> invVnfcList) {
111         int vServerCount=0;
112         for(Vnfc vnfc : invVnfcList) {
113             List<Vserver> vms = vnfc.getVserverList();
114             vServerCount=vServerCount+vms.size();
115         }
116         return vServerCount <= 1;
117     }
118
119     private void updateResponse(Transaction transaction) {
120         Response ignoreResponse = new Response();
121         ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
122         Map<String, String> ignoreAction = new HashMap<>();
123         ignoreAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
124         ignoreResponse.setResponseAction(ignoreAction);
125         transaction.addResponse(ignoreResponse);
126     }
127
128     private List<Transaction> generateSequenceWithDependencyModel(VnfcFlowModel flowModel, SequenceGeneratorInput input) throws APPCException {
129         Integer waitTime = readWaitTime(input);
130         Integer retryCount = readRetryCount(input);
131         List<Transaction> transactionList = new LinkedList<>();
132         Integer transactionId = 1;
133         Iterator<List<Vnfc>> itr = flowModel.getModelIterator();
134         while (itr.hasNext()) {
135             List<Vnfc> vnfcs = itr.next();
136             for (Vnfc vnfc : vnfcs) {
137                 List<Vserver> vms = vnfc.getVserverList();
138                 List<Integer> transactionIds = new LinkedList<>();
139                 if(!vms.isEmpty()) {
140                     for (Vserver vm : vms) {
141                         // check vm-Start-capabilities for this vm's vnfc-function-code (before incrementing transactionId)
142                         String vmVnfcFunctionCode = vm.getVnfc().getVnfcFunctionCode();
143                         if (!vmSupportsStart(input, vmVnfcFunctionCode)) {
144                             continue;
145                         }
146                         Transaction transaction = new Transaction();
147                         transaction.setTransactionId(transactionId);
148                         transactionIds.add(transactionId++);
149                         transaction.setAction(Action.START.getActionType());
150                         transaction.setActionLevel(ActionLevel.VM.getAction());
151                         ActionIdentifier actionIdentifier = new ActionIdentifier();
152                         actionIdentifier.setvServerId(vm.getId());
153                         transaction.setActionIdentifier(actionIdentifier);
154                         transaction.setPayload(input.getRequestInfo().getPayload());
155                         Response ignoreResponse = new Response();
156                         ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
157                         Map<String, String> ignoreAction = new HashMap<>();
158                         ignoreAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
159                         ignoreResponse.setResponseAction(ignoreAction);
160                         transaction.addResponse(ignoreResponse);
161                         transactionList.add(transaction);
162                     }
163                     boolean startApplicationSupported = readApplicationStartCapability(input);
164                     if (startApplicationSupported) {
165                         Transaction startAppTransaction = new Transaction();
166                         startAppTransaction.setTransactionId(transactionId++);
167                         startAppTransaction.setAction(Action.START_APPLICATION.getActionType());
168                         startAppTransaction.setActionLevel(ActionLevel.VNFC.getAction());
169                         ActionIdentifier startActionIdentifier = new ActionIdentifier();
170                         startActionIdentifier.setVnfcName(vnfc.getVnfcName());
171                         startAppTransaction.setActionIdentifier(startActionIdentifier);
172                         startAppTransaction.setPayload(input.getRequestInfo().getPayload());
173
174                         List<PreCheckOption> preCheckOptions = buildPreCheckOptions(transactionIds);
175                         startAppTransaction.setPreCheckOperator(PreCheckOperator.ANY.getOperator());
176                         startAppTransaction.setPrecheckOptions(preCheckOptions);
177                         transactionList.add(startAppTransaction);
178                     }
179                     boolean healthCheckSupported = readHealthCheckCapabilites(input.getCapability());
180                     if (healthCheckSupported) {
181                         Transaction healthCheckTransaction = new Transaction();
182                         healthCheckTransaction.setTransactionId(transactionId++);
183                         healthCheckTransaction.setAction(Action.HEALTH_CHECK.getActionType());
184                         healthCheckTransaction.setActionLevel(ActionLevel.VNFC.getAction());
185                         ActionIdentifier healthCheckActionIdentifier = new ActionIdentifier();
186                         healthCheckActionIdentifier.setVnfcName(vnfc.getVnfcName());
187                         healthCheckTransaction.setActionIdentifier(healthCheckActionIdentifier);
188                         healthCheckTransaction.setPayload(input.getRequestInfo().getPayload());
189
190                         Response retryResponse = new Response();
191                         retryResponse.setResponseMessage(ResponseMessage.UNHEALTHY.getResponse());
192                         Map<String, String> retryAction = new HashMap<>();
193                         retryAction.put(ResponseAction.RETRY.getAction(), retryCount.toString());
194                         retryAction.put(ResponseAction.WAIT.getAction(), waitTime.toString());
195                         retryResponse.setResponseAction(retryAction);
196                         healthCheckTransaction.addResponse(retryResponse);
197
198                         Response healthyResponse = new Response();
199                         healthyResponse.setResponseMessage(ResponseMessage.HEALTHY.getResponse());
200                         Map<String, String> healthyAction = new HashMap<>();
201                         healthyAction.put(ResponseAction.CONTINUE.getAction().toLowerCase(), Boolean.TRUE.toString());
202                         healthyResponse.setResponseAction(healthyAction);
203                         healthCheckTransaction.addResponse(healthyResponse);
204
205                         Response failureResponse = new Response();
206                         failureResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
207                         Map<String, String> failureResonseAction = new HashMap<>();
208                         failureResonseAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
209                         failureResponse.setResponseAction(failureResonseAction);
210                         healthCheckTransaction.addResponse(failureResponse);
211                         transactionList.add(healthCheckTransaction);
212                     }
213                 }
214             }
215         }
216         return transactionList;
217     }
218
219     private List<PreCheckOption> buildPreCheckOptions(List<Integer> transactionIds) {
220         List<PreCheckOption> preCheckOptions = new LinkedList<>();
221         for (Integer vmTransactionId : transactionIds) {
222             PreCheckOption option = new PreCheckOption();
223             option.setPreTransactionId(vmTransactionId);
224             option.setParamName("status");
225             option.setParamValue("success");
226             preCheckOptions.add(option);
227         }
228         return preCheckOptions;
229     }
230
231     @Override
232     public List<Transaction> generateSequence(SequenceGeneratorInput input) throws Exception {
233             if (input.getRequestInfo().getActionLevel().equals(ActionLevel.VNF.getAction()) && input.getDependencyModel() != null) {
234                 if(isVnfcPresent(input)) {
235                     FlowStrategies flowStrategy = readFlowStrategy(input);
236                     VnfcFlowModel flowModel = null;
237                     try {
238                         flowModel = buildFlowModel(input.getInventoryModel()
239                                 , input.getDependencyModel(), flowStrategy);
240                     } catch (InvalidDependencyModelException invalidDependencyModelException) {
241                         logger.error("Error Generating Sequence", invalidDependencyModelException);
242                         throw  new APPCException(invalidDependencyModelException.getMessage(), invalidDependencyModelException);
243                     }
244                     logger.debug("Flow Model " + flowModel);
245                     return generateSequenceWithDependencyModel(flowModel, input);
246                 }
247                  else throw new APPCException("Vnfc details is missing in the input");
248             } else {
249                 logger.info("Generating sequence without dependency model");
250                 return generateSequenceWithOutDependency(input);
251             }
252     }
253
254     private VnfcFlowModel buildFlowModel(InventoryModel inventoryModel, VnfcDependencyModel dependencyModel, FlowStrategies flowStrategy) throws APPCException, InvalidDependencyModelException {
255         FlowBuilder flowBuilder = FlowBuilderFactory.getInstance().getFlowBuilder(flowStrategy);
256         if (flowBuilder == null) {
257             throw new APPCException("Flow Strategy not supported " + flowStrategy);
258         }
259         return flowBuilder.buildFlowModel(dependencyModel, inventoryModel);
260     }
261
262     private FlowStrategies readFlowStrategy(SequenceGeneratorInput sequenceGeneratorInput) {
263         Map<String, String> tunableParams = sequenceGeneratorInput.getTunableParams();
264         FlowStrategies strategy=null;
265         String strategyStr = null;
266         if (tunableParams != null) {
267             strategyStr = tunableParams.get(Constants.STRATEGY);
268             strategy = FlowStrategies.findByString(strategyStr);
269         }
270         if (strategy == null)
271             strategy= FlowStrategies.FORWARD;
272         return strategy;
273     }
274
275     private boolean readHealthCheckCapabilites(CapabilityModel capabilities) {
276         if (capabilities == null) {
277             return true;
278         }
279         List<String> vnfcCapabilities = capabilities.getVnfcCapabilities();
280         if (vnfcCapabilities != null)
281             return vnfcCapabilities.stream()
282                     .anyMatch(p -> Capabilties.HEALTH_CHECK.getCapability().equalsIgnoreCase(p));
283
284         return false;
285     }
286
287     private boolean readApplicationStartCapability(SequenceGeneratorInput input) {
288         CapabilityModel capability = input.getCapability();
289         if (capability == null)
290             return true;
291         List<String> vnfcCapabilities = capability.getVnfcCapabilities();
292         if (vnfcCapabilities != null)
293             return vnfcCapabilities.stream()
294                     .anyMatch(p -> Capabilties.START_APPLICATION.getCapability().equalsIgnoreCase(p));
295
296         return false;
297     }
298
299     private Integer readRetryCount(SequenceGeneratorInput input) throws APPCException {
300         String paramValStr = input.getTunableParams().get(RETRY_COUNT);
301         if (StringUtils.isEmpty(paramValStr)) {
302             return RETRY_COUNT_VALUE;
303         }
304         try {
305             return Integer.parseInt(paramValStr);
306         } catch (NumberFormatException e) {
307             String message = "Invalid Number for Retry Count " + paramValStr;
308             logger.error(message, e);
309             throw new APPCException(message);
310         }
311     }
312
313     private boolean isVnfcPresent(SequenceGeneratorInput input){
314         boolean vnfcPresent=true;
315         List<Vserver> vservers = input.getInventoryModel().getVnf().getVservers();
316         for (Vserver vm : vservers) {
317             if(!(vm.getVnfc()!=null&& vm.getVnfc().getVnfcType()!=null&& vm.getVnfc().getVnfcName()!=null)){
318                 vnfcPresent=false;
319                 break;
320             }
321         }
322         return vnfcPresent;
323     }
324
325     private Integer readWaitTime(SequenceGeneratorInput input) throws APPCException {
326         String paramValStr = input.getTunableParams().get(WAIT_TIME);
327         if (StringUtils.isEmpty(paramValStr)) {
328             return WAIT_TIME_VALUE;
329         }
330         try {
331             return Integer.parseInt(paramValStr);
332         } catch (NumberFormatException e) {
333             String message = "Invalid Number for Wait Time " + paramValStr;
334             logger.error(message, e);
335             throw new APPCException(message);
336         }
337     }
338
339     private boolean vmSupportsStart(SequenceGeneratorInput input, String vnfcFunctionCode) {
340         boolean vmSupported = true;
341         if (input.getCapability() == null) {
342             logger.info("vmSupportsStart: " + "Capabilities model is null, returning vmSupported=" + vmSupported);
343             return vmSupported;
344         }
345         Map<String, List<String>> vmCapabilities = input.getCapability().getVmCapabilities();
346         logger.info("vmSupportsStart: vnfcFunctionCode=" + vnfcFunctionCode + ", vmCapabilities=" + vmCapabilities);
347         if (vmCapabilities != null) {
348             if (!vmCapabilities.isEmpty()) {
349                 vmSupported = false;
350                 if (vmCapabilities.get(Action.START.getActionType()) != null) {
351                     if (vnfcFunctionCode != null && !vnfcFunctionCode.isEmpty()) {
352                         for (String enabledFuncCode : vmCapabilities.get(Action.START.getActionType()) ) {
353                             if (enabledFuncCode.equalsIgnoreCase(vnfcFunctionCode)) {
354                                 vmSupported = true;
355                                 logger.info("vmSupportsStart: vnfcFunctionCode=" + vnfcFunctionCode + " found in vmCapabilties");
356                                 break;
357                             }
358                         }
359                     } else {
360                         logger.info("vmSupportsStart: " + "Inventory vnfcFunctionCode is null or empty");
361                     }
362                 } else {
363                     logger.info("vmSupportsStart: " + "Given action in vm entry in Capabilities model is null");
364                 }
365             } else {
366                 logger.info("vmSupportsStart: " + "Vm entry in Capabilities model is empty");
367             }
368         } else {
369             logger.info("vmSupportsStart: " + "Vm entry in Capabilities model is null");
370         }
371
372         logger.info("vmSupportsStart: " + "returning vmSupported=" + vmSupported);
373         return vmSupported;
374     }
375 }