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