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