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