2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.appc.seqgen.impl;
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;
44 import java.util.HashMap;
45 import java.util.Iterator;
46 import java.util.LinkedList;
47 import java.util.List;
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;;
62 public class StartSequenceGenerator implements SequenceGenerator {
64 private static final EELFLogger logger = EELFManager.getInstance().getLogger(StartSequenceGenerator.class);
66 private List<Transaction> generateSequenceWithOutDependency(SequenceGeneratorInput input) throws APPCException {
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);
90 transactionList.add(transaction);
92 return transactionList;
95 private boolean checkSingleTransaction(List<Vnfc> invVnfcList) {
97 for(Vnfc vnfc : invVnfcList) {
98 List<Vserver> vms = vnfc.getVserverList();
99 vServerCount=vServerCount+vms.size();
101 return vServerCount <= 1;
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);
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<>();
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);
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());
154 List<PreCheckOption> preCheckOptions = buildPreCheckOptions(transactionIds);
155 startAppTransaction.setPreCheckOperator(PreCheckOperator.ANY.getOperator());
156 startAppTransaction.setPrecheckOptions(preCheckOptions);
157 transactionList.add(startAppTransaction);
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());
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);
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);
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);
196 return transactionList;
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);
208 return preCheckOptions;
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;
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);
224 logger.debug("Flow Model " + flowModel);
225 return generateSequenceWithDependencyModel(flowModel, input);
227 else throw new APPCException("Vnfc details is missing in the input");
229 logger.info("Generating sequence without dependency model");
230 return generateSequenceWithOutDependency(input);
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);
239 return flowBuilder.buildFlowModel(dependencyModel, inventoryModel);
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);
250 if (strategy == null)
251 strategy= FlowStrategies.FORWARD;
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));
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));
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;
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);
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;
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;
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);