8c24fe24cb81c272d31451ae1a7338ae90413f9b
[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.Constants;
43 import org.onap.appc.seqgen.objects.PreCheckOption;
44 import org.onap.appc.seqgen.objects.Response;
45 import org.onap.appc.seqgen.objects.SequenceGeneratorInput;
46 import org.onap.appc.seqgen.objects.Transaction;
47
48 import java.util.HashMap;
49 import java.util.Iterator;
50 import java.util.LinkedList;
51 import java.util.List;
52 import java.util.Map;
53
54 import static org.onap.appc.seqgen.objects.Constants.Action;
55 import static org.onap.appc.seqgen.objects.Constants.ActionLevel;
56 import static org.onap.appc.seqgen.objects.Constants.ResponseAction;
57 import static org.onap.appc.seqgen.objects.Constants.ResponseMessage;
58 import static org.onap.appc.seqgen.objects.Constants.PreCheckOperator;
59 import static org.onap.appc.seqgen.objects.Constants.Capabilties;
60 import static org.onap.appc.seqgen.objects.Constants.CapabilityLevel;
61 import static org.onap.appc.seqgen.objects.Constants.RETRY_COUNT_VALUE;
62 import static org.onap.appc.seqgen.objects.Constants.WAIT_TIME;
63 import static org.onap.appc.seqgen.objects.Constants.RETRY_COUNT;
64 import static org.onap.appc.seqgen.objects.Constants.WAIT_TIME_VALUE;;
65
66 public class StartSequenceGenerator implements SequenceGenerator {
67
68     private static final EELFLogger logger = EELFManager.getInstance().getLogger(StartSequenceGenerator.class);
69
70     private List<Transaction> generateSequenceWithOutDependency(SequenceGeneratorInput input) throws Exception {
71
72         String payload = null;
73         PayloadGenerator payloadGenerator = new PayloadGenerator();
74         List<Transaction> transactionList = new LinkedList<>();
75         Integer transactionId = 1;
76         List<Vserver> vservers = input.getInventoryModel().getVnf().getVservers();
77         List<Integer> transactionIds = new LinkedList<>();
78         for (Vserver vm : vservers) {
79             Transaction transaction = new Transaction();
80             transaction.setTransactionId(transactionId);
81             transactionIds.add(transactionId++);
82             transaction.setAction(Action.START.getActionType());
83             transaction.setActionLevel(ActionLevel.VM.getAction());
84             ActionIdentifier actionIdentifier = new ActionIdentifier();
85             actionIdentifier.setvServerId(vm.getId());
86             transaction.setActionIdentifier(actionIdentifier);
87             String vmId = vm.getUrl();
88             String url = vm.getUrl();
89             payload = payloadGenerator.getPayload(input, vmId, url);
90             transaction.setPayload(payload);
91             if(vservers.size()>1){
92                 Response ignoreResponse = new Response();
93                 ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
94                 Map<String, String> ignoreAction = new HashMap<>();
95                 ignoreAction.put(ResponseAction.IGNORE.getAction(), Boolean.TRUE.toString());
96                 ignoreResponse.setResponseAction(ignoreAction);
97                 transaction.addResponse(ignoreResponse);
98             }
99             transactionList.add(transaction);
100         }
101         return transactionList;
102     }
103
104     private boolean checkSingleTransaction(List<Vnfc> invVnfcList) {
105         int vServerCount=0;
106         for(Vnfc vnfc : invVnfcList) {
107             List<Vserver> vms = vnfc.getVserverList();
108             vServerCount=vServerCount+vms.size();
109         }
110         return vServerCount <= 1;
111     }
112
113     private void updateResponse(Transaction transaction) {
114         Response ignoreResponse = new Response();
115         ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
116         Map<String, String> ignoreAction = new HashMap<>();
117         ignoreAction.put(ResponseAction.IGNORE.getAction(), Boolean.TRUE.toString());
118         ignoreResponse.setResponseAction(ignoreAction);
119         transaction.addResponse(ignoreResponse);
120     }
121
122     private List<Transaction> generateSequenceWithDependencyModel(VnfcFlowModel flowModel, SequenceGeneratorInput input) throws APPCException {
123         Integer waitTime = readWaitTime(input);
124         Integer retryCount = readRetryCount(input);
125         List<Transaction> transactionList = new LinkedList<>();
126         Integer transactionId = 1;
127         Iterator<List<Vnfc>> itr = flowModel.getModelIterator();
128         while (itr.hasNext()) {
129             List<Vnfc> vnfcs = itr.next();
130             for (Vnfc vnfc : vnfcs) {
131                 List<Vserver> vms = vnfc.getVserverList();
132                 List<Integer> transactionIds = new LinkedList<>();
133                 if(!vms.isEmpty()) {
134                     for (Vserver vm : vms) {
135                         Transaction transaction = new Transaction();
136                         transaction.setTransactionId(transactionId);
137                         transactionIds.add(transactionId++);
138                         transaction.setAction(Action.START.getActionType());
139                         transaction.setActionLevel(ActionLevel.VM.getAction());
140                         ActionIdentifier actionIdentifier = new ActionIdentifier();
141                         actionIdentifier.setvServerId(vm.getId());
142                         transaction.setActionIdentifier(actionIdentifier);
143                         transaction.setPayload(input.getRequestInfo().getPayload());
144                         Response ignoreResponse = new Response();
145                         ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
146                         Map<String, String> ignoreAction = new HashMap<>();
147                         ignoreAction.put(ResponseAction.IGNORE.getAction(), Boolean.TRUE.toString());
148                         ignoreResponse.setResponseAction(ignoreAction);
149                         transaction.addResponse(ignoreResponse);
150                         transactionList.add(transaction);
151                     }
152                     boolean startApplicationSupported = readApplicationStartCapability(input);
153                     if (startApplicationSupported) {
154                         Transaction startAppTransaction = new Transaction();
155                         startAppTransaction.setTransactionId(transactionId++);
156                         startAppTransaction.setAction(Action.START_APPLICATION.getActionType());
157                         startAppTransaction.setActionLevel(ActionLevel.VNFC.getAction());
158                         ActionIdentifier startActionIdentifier = new ActionIdentifier();
159                         startActionIdentifier.setVnfcName(vnfc.getVnfcName());
160                         startAppTransaction.setActionIdentifier(startActionIdentifier);
161                         startAppTransaction.setPayload(input.getRequestInfo().getPayload());
162
163                         List<PreCheckOption> preCheckOptions = buildPreCheckOptions(transactionIds);
164                         startAppTransaction.setPreCheckOperator(PreCheckOperator.ANY.getOperator());
165                         startAppTransaction.setPrecheckOptions(preCheckOptions);
166                         transactionList.add(startAppTransaction);
167                     }
168                     boolean healthCheckSupported = readHealthCheckCapabilites(input.getCapability());
169                     if (healthCheckSupported) {
170                         Transaction healthCheckTransaction = new Transaction();
171                         healthCheckTransaction.setTransactionId(transactionId++);
172                         healthCheckTransaction.setAction(Action.HEALTH_CHECK.getActionType());
173                         healthCheckTransaction.setActionLevel(ActionLevel.VNFC.getAction());
174                         ActionIdentifier healthCheckActionIdentifier = new ActionIdentifier();
175                         healthCheckActionIdentifier.setVnfcName(vnfc.getVnfcName());
176                         healthCheckTransaction.setActionIdentifier(healthCheckActionIdentifier);
177                         healthCheckTransaction.setPayload(input.getRequestInfo().getPayload());
178
179                         Response retryResponse = new Response();
180                         retryResponse.setResponseMessage(ResponseMessage.UNHEALTHY.getResponse());
181                         Map<String, String> retryAction = new HashMap<>();
182                         retryAction.put(ResponseAction.RETRY.getAction(), retryCount.toString());
183                         retryAction.put(ResponseAction.WAIT.getAction(), waitTime.toString());
184                         retryResponse.setResponseAction(retryAction);
185                         healthCheckTransaction.addResponse(retryResponse);
186
187                         Response healthyResponse = new Response();
188                         healthyResponse.setResponseMessage(ResponseMessage.HEALTHY.getResponse());
189                         Map<String, String> healthyAction = new HashMap<>();
190                         healthyAction.put(ResponseAction.CONTINUE.getAction().toLowerCase(), Boolean.TRUE.toString());
191                         healthyResponse.setResponseAction(healthyAction);
192                         healthCheckTransaction.addResponse(healthyResponse);
193
194                         Response failureResponse = new Response();
195                         failureResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
196                         Map<String, String> failureResonseAction = new HashMap<>();
197                         failureResonseAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
198                         failureResponse.setResponseAction(failureResonseAction);
199                         healthCheckTransaction.addResponse(failureResponse);
200                         transactionList.add(healthCheckTransaction);
201                     }
202                 }
203             }
204         }
205         return transactionList;
206     }
207
208     private List<PreCheckOption> buildPreCheckOptions(List<Integer> transactionIds) {
209         List<PreCheckOption> preCheckOptions = new LinkedList<>();
210         for (Integer vmTransactionId : transactionIds) {
211             PreCheckOption option = new PreCheckOption();
212             option.setPreTransactionId(vmTransactionId);
213             option.setParamName("status");
214             option.setParamValue("success");
215             preCheckOptions.add(option);
216         }
217         return preCheckOptions;
218     }
219
220     @Override
221     public List<Transaction> generateSequence(SequenceGeneratorInput input) throws Exception {
222             if (input.getRequestInfo().getActionLevel().equals(ActionLevel.VNF.getAction()) && input.getDependencyModel() != null) {
223                 if(isVnfcPresent(input)) {
224                     FlowStrategies flowStrategy = readFlowStrategy(input);
225                     VnfcFlowModel flowModel = null;
226                     try {
227                         flowModel = buildFlowModel(input.getInventoryModel()
228                                 , input.getDependencyModel(), flowStrategy);
229                     } catch (InvalidDependencyModelException invalidDependencyModelException) {
230                         logger.error("Error Generating Sequence", invalidDependencyModelException);
231                         throw  new APPCException(invalidDependencyModelException.getMessage(), invalidDependencyModelException);
232                     }
233                     logger.debug("Flow Model " + flowModel);
234                     return generateSequenceWithDependencyModel(flowModel, input);
235                 }
236                  else throw new APPCException("Vnfc details is missing in the input");
237             } else {
238                 logger.info("Generating sequence without dependency model");
239                 return generateSequenceWithOutDependency(input);
240             }
241     }
242
243     private VnfcFlowModel buildFlowModel(InventoryModel inventoryModel, VnfcDependencyModel dependencyModel, FlowStrategies flowStrategy) throws APPCException, InvalidDependencyModelException {
244         FlowBuilder flowBuilder = FlowBuilderFactory.getInstance().getFlowBuilder(flowStrategy);
245         if (flowBuilder == null) {
246             throw new APPCException("Flow Strategy not supported " + flowStrategy);
247         }
248         return flowBuilder.buildFlowModel(dependencyModel, inventoryModel);
249     }
250
251     private FlowStrategies readFlowStrategy(SequenceGeneratorInput sequenceGeneratorInput) {
252         Map<String, String> tunableParams = sequenceGeneratorInput.getTunableParams();
253         FlowStrategies strategy=null;
254         String strategyStr = null;
255         if (tunableParams != null) {
256             strategyStr = tunableParams.get(Constants.STRATEGY);
257             strategy = FlowStrategies.findByString(strategyStr);
258         }
259         if (strategy == null)
260             strategy= FlowStrategies.FORWARD;
261         return strategy;
262     }
263
264     private boolean readHealthCheckCapabilites(Map<String, List<String>> capabilities) {
265         if (capabilities != null) {
266             List<String> vnfcCapabilities = capabilities.get(CapabilityLevel.VNFC.getLevel());
267             if (vnfcCapabilities != null)
268                 return vnfcCapabilities.stream()
269                         .anyMatch(p -> Capabilties.HEALTH_CHECK.getCapability().equalsIgnoreCase(p));
270         }
271         return false;
272     }
273
274     private boolean readApplicationStartCapability(SequenceGeneratorInput input) {
275         Map<String, List<String>> capability = input.getCapability();
276         if (capability != null) {
277             List<String> vnfcCapabilities = capability.get(CapabilityLevel.VNFC.getLevel());
278             if (vnfcCapabilities != null)
279                 return vnfcCapabilities.stream().anyMatch(p -> Capabilties.START_APPLICATION.getCapability().equalsIgnoreCase(p));
280         }
281         return false;
282     }
283
284     private Integer readRetryCount(SequenceGeneratorInput input) throws APPCException {
285         String paramValStr = input.getTunableParams().get(RETRY_COUNT);
286         if (StringUtils.isEmpty(paramValStr)) {
287             return RETRY_COUNT_VALUE;
288         }
289         try {
290             return Integer.parseInt(paramValStr);
291         } catch (NumberFormatException e) {
292             String message = "Invalid Number for Retry Count " + paramValStr;
293             logger.error(message, e);
294             throw new APPCException(message);
295         }
296     }
297
298     private boolean isVnfcPresent(SequenceGeneratorInput input){
299         boolean vnfcPresent=true;
300         List<Vserver> vservers = input.getInventoryModel().getVnf().getVservers();
301         for (Vserver vm : vservers) {
302             if(!(vm.getVnfc()!=null&& vm.getVnfc().getVnfcType()!=null&& vm.getVnfc().getVnfcName()!=null)){
303                 vnfcPresent=false;break;
304             }
305         }
306         return vnfcPresent;
307     }
308
309     private Integer readWaitTime(SequenceGeneratorInput input) throws APPCException {
310         String paramValStr = input.getTunableParams().get(WAIT_TIME);
311         if (StringUtils.isEmpty(paramValStr)) {
312             return WAIT_TIME_VALUE;
313         }
314         try {
315             return Integer.parseInt(paramValStr);
316         } catch (NumberFormatException e) {
317             String message = "Invalid Number for Wait Time " + paramValStr;
318             logger.error(message, e);
319             throw new APPCException(message);
320         }
321     }
322 }