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