2 * ============LICENSE_START=======================================================
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * ============LICENSE_END=========================================================
25 package org.onap.appc.seqgen.impl;
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.CapabilityModel;
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;
49 import java.util.HashMap;
50 import java.util.Iterator;
51 import java.util.LinkedList;
52 import java.util.List;
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;;
67 public class StartSequenceGenerator implements SequenceGenerator {
69 private static final EELFLogger logger = EELFManager.getInstance().getLogger(StartSequenceGenerator.class);
71 private List<Transaction> generateSequenceWithOutDependency(SequenceGeneratorInput input) throws Exception {
73 String payload = null;
74 PayloadGenerator payloadGenerator = new PayloadGenerator();
75 List<Transaction> transactionList = new LinkedList<>();
76 Integer transactionId = 1;
77 List<Vserver> vservers = input.getInventoryModel().getVnf().getVservers();
78 List<Integer> transactionIds = new LinkedList<>();
79 for (Vserver vm : vservers) {
80 // check vm-Start-capabilities for this vm's vnfc-function-code (before incrementing transactionId)
81 if (!vmSupportsStart(input, vm)) {
84 Transaction transaction = new Transaction();
85 transaction.setTransactionId(transactionId);
86 transactionIds.add(transactionId++);
87 transaction.setAction(Action.START.getActionType());
88 transaction.setActionLevel(ActionLevel.VM.getAction());
89 ActionIdentifier actionIdentifier = new ActionIdentifier();
90 actionIdentifier.setvServerId(vm.getId());
91 transaction.setActionIdentifier(actionIdentifier);
92 String vmId = vm.getUrl();
93 String url = vm.getUrl();
94 payload = payloadGenerator.getPayload(input, vmId, url);
95 transaction.setPayload(payload);
96 if(vservers.size()>1){
97 Response ignoreResponse = new Response();
98 ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
99 Map<String, String> ignoreAction = new HashMap<>();
100 ignoreAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
101 ignoreResponse.setResponseAction(ignoreAction);
102 transaction.addResponse(ignoreResponse);
104 transactionList.add(transaction);
106 return transactionList;
109 private boolean checkSingleTransaction(List<Vnfc> invVnfcList) {
111 for(Vnfc vnfc : invVnfcList) {
112 List<Vserver> vms = vnfc.getVserverList();
113 vServerCount=vServerCount+vms.size();
115 return vServerCount <= 1;
118 private void updateResponse(Transaction transaction) {
119 Response ignoreResponse = new Response();
120 ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
121 Map<String, String> ignoreAction = new HashMap<>();
122 ignoreAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
123 ignoreResponse.setResponseAction(ignoreAction);
124 transaction.addResponse(ignoreResponse);
127 private List<Transaction> generateSequenceWithDependencyModel(VnfcFlowModel flowModel, SequenceGeneratorInput input) throws APPCException {
128 Integer waitTime = readWaitTime(input);
129 Integer retryCount = readRetryCount(input);
130 List<Transaction> transactionList = new LinkedList<>();
131 Integer transactionId = 1;
132 Iterator<List<Vnfc>> itr = flowModel.getModelIterator();
133 while (itr.hasNext()) {
134 List<Vnfc> vnfcs = itr.next();
135 for (Vnfc vnfc : vnfcs) {
136 List<Vserver> vms = vnfc.getVserverList();
137 List<Integer> transactionIds = new LinkedList<>();
139 for (Vserver vm : vms) {
140 // check vm-Start-capabilities for this vm's vnfc-function-code (before incrementing transactionId)
141 if (!vmSupportsStart(input, vm)) {
144 Transaction transaction = new Transaction();
145 transaction.setTransactionId(transactionId);
146 transactionIds.add(transactionId++);
147 transaction.setAction(Action.START.getActionType());
148 transaction.setActionLevel(ActionLevel.VM.getAction());
149 ActionIdentifier actionIdentifier = new ActionIdentifier();
150 actionIdentifier.setvServerId(vm.getId());
151 transaction.setActionIdentifier(actionIdentifier);
152 transaction.setPayload(input.getRequestInfo().getPayload());
153 Response ignoreResponse = new Response();
154 ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
155 Map<String, String> ignoreAction = new HashMap<>();
156 ignoreAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
157 ignoreResponse.setResponseAction(ignoreAction);
158 transaction.addResponse(ignoreResponse);
159 transactionList.add(transaction);
161 boolean startApplicationSupported = readApplicationStartCapability(input);
162 if (startApplicationSupported) {
163 Transaction startAppTransaction = new Transaction();
164 startAppTransaction.setTransactionId(transactionId++);
165 startAppTransaction.setAction(Action.START_APPLICATION.getActionType());
166 startAppTransaction.setActionLevel(ActionLevel.VNFC.getAction());
167 ActionIdentifier startActionIdentifier = new ActionIdentifier();
168 startActionIdentifier.setVnfcName(vnfc.getVnfcName());
169 startAppTransaction.setActionIdentifier(startActionIdentifier);
170 startAppTransaction.setPayload(input.getRequestInfo().getPayload());
172 List<PreCheckOption> preCheckOptions = buildPreCheckOptions(transactionIds);
173 startAppTransaction.setPreCheckOperator(PreCheckOperator.ANY.getOperator());
174 startAppTransaction.setPrecheckOptions(preCheckOptions);
175 transactionList.add(startAppTransaction);
177 boolean healthCheckSupported = readHealthCheckCapabilites(input.getCapability());
178 if (healthCheckSupported) {
179 Transaction healthCheckTransaction = new Transaction();
180 healthCheckTransaction.setTransactionId(transactionId++);
181 healthCheckTransaction.setAction(Action.HEALTH_CHECK.getActionType());
182 healthCheckTransaction.setActionLevel(ActionLevel.VNFC.getAction());
183 ActionIdentifier healthCheckActionIdentifier = new ActionIdentifier();
184 healthCheckActionIdentifier.setVnfcName(vnfc.getVnfcName());
185 healthCheckTransaction.setActionIdentifier(healthCheckActionIdentifier);
186 healthCheckTransaction.setPayload(input.getRequestInfo().getPayload());
188 Response retryResponse = new Response();
189 retryResponse.setResponseMessage(ResponseMessage.UNHEALTHY.getResponse());
190 Map<String, String> retryAction = new HashMap<>();
191 retryAction.put(ResponseAction.RETRY.getAction(), retryCount.toString());
192 retryAction.put(ResponseAction.WAIT.getAction(), waitTime.toString());
193 retryResponse.setResponseAction(retryAction);
194 healthCheckTransaction.addResponse(retryResponse);
196 Response healthyResponse = new Response();
197 healthyResponse.setResponseMessage(ResponseMessage.HEALTHY.getResponse());
198 Map<String, String> healthyAction = new HashMap<>();
199 healthyAction.put(ResponseAction.CONTINUE.getAction().toLowerCase(), Boolean.TRUE.toString());
200 healthyResponse.setResponseAction(healthyAction);
201 healthCheckTransaction.addResponse(healthyResponse);
203 Response failureResponse = new Response();
204 failureResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
205 Map<String, String> failureResonseAction = new HashMap<>();
206 failureResonseAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
207 failureResponse.setResponseAction(failureResonseAction);
208 healthCheckTransaction.addResponse(failureResponse);
209 transactionList.add(healthCheckTransaction);
214 return transactionList;
217 private List<PreCheckOption> buildPreCheckOptions(List<Integer> transactionIds) {
218 List<PreCheckOption> preCheckOptions = new LinkedList<>();
219 for (Integer vmTransactionId : transactionIds) {
220 PreCheckOption option = new PreCheckOption();
221 option.setPreTransactionId(vmTransactionId);
222 option.setParamName("status");
223 option.setParamValue("success");
224 preCheckOptions.add(option);
226 return preCheckOptions;
230 public List<Transaction> generateSequence(SequenceGeneratorInput input) throws Exception {
231 if (input.getRequestInfo().getActionLevel().equals(ActionLevel.VNF.getAction()) && input.getDependencyModel() != null) {
232 if(isVnfcPresent(input)) {
233 FlowStrategies flowStrategy = readFlowStrategy(input);
234 VnfcFlowModel flowModel = null;
236 flowModel = buildFlowModel(input.getInventoryModel()
237 , input.getDependencyModel(), flowStrategy);
238 } catch (InvalidDependencyModelException invalidDependencyModelException) {
239 logger.error("Error Generating Sequence", invalidDependencyModelException);
240 throw new APPCException(invalidDependencyModelException.getMessage(), invalidDependencyModelException);
242 logger.debug("Flow Model " + flowModel);
243 return generateSequenceWithDependencyModel(flowModel, input);
245 else throw new APPCException("Vnfc details is missing in the input");
247 logger.info("Generating sequence without dependency model");
248 return generateSequenceWithOutDependency(input);
252 private VnfcFlowModel buildFlowModel(InventoryModel inventoryModel, VnfcDependencyModel dependencyModel, FlowStrategies flowStrategy) throws APPCException, InvalidDependencyModelException {
253 FlowBuilder flowBuilder = FlowBuilderFactory.getInstance().getFlowBuilder(flowStrategy);
254 if (flowBuilder == null) {
255 throw new APPCException("Flow Strategy not supported " + flowStrategy);
257 return flowBuilder.buildFlowModel(dependencyModel, inventoryModel);
260 private FlowStrategies readFlowStrategy(SequenceGeneratorInput sequenceGeneratorInput) {
261 Map<String, String> tunableParams = sequenceGeneratorInput.getTunableParams();
262 FlowStrategies strategy=null;
263 String strategyStr = null;
264 if (tunableParams != null) {
265 strategyStr = tunableParams.get(Constants.STRATEGY);
266 strategy = FlowStrategies.findByString(strategyStr);
268 if (strategy == null)
269 strategy= FlowStrategies.FORWARD;
273 private boolean readHealthCheckCapabilites(CapabilityModel capabilities) {
274 if (capabilities == null) {
277 List<String> vnfcCapabilities = capabilities.getVnfcCapabilities();
278 if (vnfcCapabilities != null)
279 return vnfcCapabilities.stream()
280 .anyMatch(p -> Capabilties.HEALTH_CHECK.getCapability().equalsIgnoreCase(p));
285 private boolean readApplicationStartCapability(SequenceGeneratorInput input) {
286 CapabilityModel capability = input.getCapability();
287 if (capability == null)
289 List<String> vnfcCapabilities = capability.getVnfcCapabilities();
290 if (vnfcCapabilities != null)
291 return vnfcCapabilities.stream()
292 .anyMatch(p -> Capabilties.START_APPLICATION.getCapability().equalsIgnoreCase(p));
297 private Integer readRetryCount(SequenceGeneratorInput input) throws APPCException {
298 String paramValStr = input.getTunableParams().get(RETRY_COUNT);
299 if (StringUtils.isEmpty(paramValStr)) {
300 return RETRY_COUNT_VALUE;
303 return Integer.parseInt(paramValStr);
304 } catch (NumberFormatException e) {
305 String message = "Invalid Number for Retry Count " + paramValStr;
306 logger.error(message, e);
307 throw new APPCException(message);
311 private boolean isVnfcPresent(SequenceGeneratorInput input){
312 boolean vnfcPresent=true;
313 List<Vserver> vservers = input.getInventoryModel().getVnf().getVservers();
314 for (Vserver vm : vservers) {
315 if(!(vm.getVnfc()!=null&& vm.getVnfc().getVnfcType()!=null&& vm.getVnfc().getVnfcName()!=null)){
323 private Integer readWaitTime(SequenceGeneratorInput input) throws APPCException {
324 String paramValStr = input.getTunableParams().get(WAIT_TIME);
325 if (StringUtils.isEmpty(paramValStr)) {
326 return WAIT_TIME_VALUE;
329 return Integer.parseInt(paramValStr);
330 } catch (NumberFormatException e) {
331 String message = "Invalid Number for Wait Time " + paramValStr;
332 logger.error(message, e);
333 throw new APPCException(message);
337 private boolean vmSupportsStart(SequenceGeneratorInput input, Vserver vm) {
338 boolean vmSupported = true;
339 if (input.getCapability() == null) {
340 logger.info("vmSupportsStart: " + "Capabilities model is null, returning vmSupported=" + vmSupported);
343 Map<String, List<String>> vmCapabilities = input.getCapability().getVmCapabilities();
344 if (vmCapabilities != null) {
345 if (!vmCapabilities.isEmpty()) {
346 List<String> vmCapsForThisAction = vmCapabilities.get(Action.START.getActionType());
347 if (vmCapsForThisAction != null) {
349 if (!vmCapsForThisAction.isEmpty()) {
350 if (vm.getVnfc() != null) {
351 String vnfcFunctionCode = vm.getVnfc().getVnfcFunctionCode();
352 if (vnfcFunctionCode != null && !vnfcFunctionCode.isEmpty()) {
353 for (String s : vmCapabilities.get(Action.START.getActionType()) ) {
354 if (s.equalsIgnoreCase(vnfcFunctionCode)) {
356 logger.info("vmSupportsStart: vnfcFunctionCode=" + vnfcFunctionCode + " found in vmCapabilities");
361 logger.info("vmSupportsStart: " + "Inventory vnfcFunctionCode is null or empty");
364 logger.info("vmSupportsStart: " + "Inventory vnfc is null or empty");
367 logger.info("vmSupportsStart: " + "Given action in vm entry in Capabilities model is empty");
370 logger.info("vmSupportsStart: " + "Given action in vm entry in Capabilities model is null");
373 logger.info("vmSupportsStart: " + "Vm entry in Capabilities model is empty");
376 logger.info("vmSupportsStart: " + "Vm entry in Capabilities model is null");
379 logger.info("vmSupportsStart: " + "returning vmSupported=" + vmSupported + ", " + ((vmSupported)?"including":"excluding") + " vm=" + vm.getId());