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.Constants;
43 import org.onap.appc.seqgen.objects.PreCheckOption;
44 import org.onap.appc.seqgen.objects.Response;
45 import org.onap.appc.seqgen.objects.SequenceGeneratorInput;
46 import org.onap.appc.seqgen.objects.Transaction;
48 import java.util.HashMap;
49 import java.util.Iterator;
50 import java.util.LinkedList;
51 import java.util.List;
54 import static org.onap.appc.seqgen.objects.Constants.Action;
55 import static org.onap.appc.seqgen.objects.Constants.ActionLevel;
56 import static org.onap.appc.seqgen.objects.Constants.ResponseAction;
57 import static org.onap.appc.seqgen.objects.Constants.ResponseMessage;
58 import static org.onap.appc.seqgen.objects.Constants.PreCheckOperator;
59 import static org.onap.appc.seqgen.objects.Constants.Capabilties;
60 import static org.onap.appc.seqgen.objects.Constants.CapabilityLevel;
61 import static org.onap.appc.seqgen.objects.Constants.RETRY_COUNT_VALUE;
62 import static org.onap.appc.seqgen.objects.Constants.WAIT_TIME;
63 import static org.onap.appc.seqgen.objects.Constants.RETRY_COUNT;
64 import static org.onap.appc.seqgen.objects.Constants.WAIT_TIME_VALUE;;
66 public class StartSequenceGenerator implements SequenceGenerator {
68 private static final EELFLogger logger = EELFManager.getInstance().getLogger(StartSequenceGenerator.class);
70 private List<Transaction> generateSequenceWithOutDependency(SequenceGeneratorInput input) throws Exception {
72 String payload = null;
73 PayloadGenerator payloadGenerator = new PayloadGenerator();
74 List<Transaction> transactionList = new LinkedList<>();
75 Integer transactionId = 1;
76 List<Vserver> vservers = input.getInventoryModel().getVnf().getVservers();
77 List<Integer> transactionIds = new LinkedList<>();
78 for (Vserver vm : vservers) {
79 Transaction transaction = new Transaction();
80 transaction.setTransactionId(transactionId);
81 transactionIds.add(transactionId++);
82 transaction.setAction(Action.START.getActionType());
83 transaction.setActionLevel(ActionLevel.VM.getAction());
84 ActionIdentifier actionIdentifier = new ActionIdentifier();
85 actionIdentifier.setvServerId(vm.getId());
86 transaction.setActionIdentifier(actionIdentifier);
87 String vmId = vm.getUrl();
88 String url = vm.getUrl();
89 payload = payloadGenerator.getPayload(input, vmId, url);
90 transaction.setPayload(payload);
91 if(vservers.size()>1){
92 Response ignoreResponse = new Response();
93 ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
94 Map<String, String> ignoreAction = new HashMap<>();
95 ignoreAction.put(ResponseAction.IGNORE.getAction(), Boolean.TRUE.toString());
96 ignoreResponse.setResponseAction(ignoreAction);
97 transaction.addResponse(ignoreResponse);
99 transactionList.add(transaction);
101 return transactionList;
104 private boolean checkSingleTransaction(List<Vnfc> invVnfcList) {
106 for(Vnfc vnfc : invVnfcList) {
107 List<Vserver> vms = vnfc.getVserverList();
108 vServerCount=vServerCount+vms.size();
110 return vServerCount <= 1;
113 private void updateResponse(Transaction transaction) {
114 Response ignoreResponse = new Response();
115 ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
116 Map<String, String> ignoreAction = new HashMap<>();
117 ignoreAction.put(ResponseAction.IGNORE.getAction(), Boolean.TRUE.toString());
118 ignoreResponse.setResponseAction(ignoreAction);
119 transaction.addResponse(ignoreResponse);
122 private List<Transaction> generateSequenceWithDependencyModel(VnfcFlowModel flowModel, SequenceGeneratorInput input) throws APPCException {
123 Integer waitTime = readWaitTime(input);
124 Integer retryCount = readRetryCount(input);
125 List<Transaction> transactionList = new LinkedList<>();
126 Integer transactionId = 1;
127 Iterator<List<Vnfc>> itr = flowModel.getModelIterator();
128 while (itr.hasNext()) {
129 List<Vnfc> vnfcs = itr.next();
130 for (Vnfc vnfc : vnfcs) {
131 List<Vserver> vms = vnfc.getVserverList();
132 List<Integer> transactionIds = new LinkedList<>();
134 for (Vserver vm : vms) {
135 Transaction transaction = new Transaction();
136 transaction.setTransactionId(transactionId);
137 transactionIds.add(transactionId++);
138 transaction.setAction(Action.START.getActionType());
139 transaction.setActionLevel(ActionLevel.VM.getAction());
140 ActionIdentifier actionIdentifier = new ActionIdentifier();
141 actionIdentifier.setvServerId(vm.getId());
142 transaction.setActionIdentifier(actionIdentifier);
143 transaction.setPayload(input.getRequestInfo().getPayload());
144 Response ignoreResponse = new Response();
145 ignoreResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
146 Map<String, String> ignoreAction = new HashMap<>();
147 ignoreAction.put(ResponseAction.IGNORE.getAction(), Boolean.TRUE.toString());
148 ignoreResponse.setResponseAction(ignoreAction);
149 transaction.addResponse(ignoreResponse);
150 transactionList.add(transaction);
152 boolean startApplicationSupported = readApplicationStartCapability(input);
153 if (startApplicationSupported) {
154 Transaction startAppTransaction = new Transaction();
155 startAppTransaction.setTransactionId(transactionId++);
156 startAppTransaction.setAction(Action.START_APPLICATION.getActionType());
157 startAppTransaction.setActionLevel(ActionLevel.VNFC.getAction());
158 ActionIdentifier startActionIdentifier = new ActionIdentifier();
159 startActionIdentifier.setVnfcName(vnfc.getVnfcName());
160 startAppTransaction.setActionIdentifier(startActionIdentifier);
161 startAppTransaction.setPayload(input.getRequestInfo().getPayload());
163 List<PreCheckOption> preCheckOptions = buildPreCheckOptions(transactionIds);
164 startAppTransaction.setPreCheckOperator(PreCheckOperator.ANY.getOperator());
165 startAppTransaction.setPrecheckOptions(preCheckOptions);
166 transactionList.add(startAppTransaction);
168 boolean healthCheckSupported = readHealthCheckCapabilites(input.getCapability());
169 if (healthCheckSupported) {
170 Transaction healthCheckTransaction = new Transaction();
171 healthCheckTransaction.setTransactionId(transactionId++);
172 healthCheckTransaction.setAction(Action.HEALTH_CHECK.getActionType());
173 healthCheckTransaction.setActionLevel(ActionLevel.VNFC.getAction());
174 ActionIdentifier healthCheckActionIdentifier = new ActionIdentifier();
175 healthCheckActionIdentifier.setVnfcName(vnfc.getVnfcName());
176 healthCheckTransaction.setActionIdentifier(healthCheckActionIdentifier);
177 healthCheckTransaction.setPayload(input.getRequestInfo().getPayload());
179 Response retryResponse = new Response();
180 retryResponse.setResponseMessage(ResponseMessage.UNHEALTHY.getResponse());
181 Map<String, String> retryAction = new HashMap<>();
182 retryAction.put(ResponseAction.RETRY.getAction(), retryCount.toString());
183 retryAction.put(ResponseAction.WAIT.getAction(), waitTime.toString());
184 retryResponse.setResponseAction(retryAction);
185 healthCheckTransaction.addResponse(retryResponse);
187 Response healthyResponse = new Response();
188 healthyResponse.setResponseMessage(ResponseMessage.HEALTHY.getResponse());
189 Map<String, String> healthyAction = new HashMap<>();
190 healthyAction.put(ResponseAction.CONTINUE.getAction().toLowerCase(), Boolean.TRUE.toString());
191 healthyResponse.setResponseAction(healthyAction);
192 healthCheckTransaction.addResponse(healthyResponse);
194 Response failureResponse = new Response();
195 failureResponse.setResponseMessage(ResponseMessage.FAILURE.getResponse());
196 Map<String, String> failureResonseAction = new HashMap<>();
197 failureResonseAction.put(ResponseAction.STOP.getAction(), Boolean.TRUE.toString());
198 failureResponse.setResponseAction(failureResonseAction);
199 healthCheckTransaction.addResponse(failureResponse);
200 transactionList.add(healthCheckTransaction);
205 return transactionList;
208 private List<PreCheckOption> buildPreCheckOptions(List<Integer> transactionIds) {
209 List<PreCheckOption> preCheckOptions = new LinkedList<>();
210 for (Integer vmTransactionId : transactionIds) {
211 PreCheckOption option = new PreCheckOption();
212 option.setPreTransactionId(vmTransactionId);
213 option.setParamName("status");
214 option.setParamValue("success");
215 preCheckOptions.add(option);
217 return preCheckOptions;
221 public List<Transaction> generateSequence(SequenceGeneratorInput input) throws Exception {
222 if (input.getRequestInfo().getActionLevel().equals(ActionLevel.VNF.getAction()) && input.getDependencyModel() != null) {
223 if(isVnfcPresent(input)) {
224 FlowStrategies flowStrategy = readFlowStrategy(input);
225 VnfcFlowModel flowModel = null;
227 flowModel = buildFlowModel(input.getInventoryModel()
228 , input.getDependencyModel(), flowStrategy);
229 } catch (InvalidDependencyModelException invalidDependencyModelException) {
230 logger.error("Error Generating Sequence", invalidDependencyModelException);
231 throw new APPCException(invalidDependencyModelException.getMessage(), invalidDependencyModelException);
233 logger.debug("Flow Model " + flowModel);
234 return generateSequenceWithDependencyModel(flowModel, input);
236 else throw new APPCException("Vnfc details is missing in the input");
238 logger.info("Generating sequence without dependency model");
239 return generateSequenceWithOutDependency(input);
243 private VnfcFlowModel buildFlowModel(InventoryModel inventoryModel, VnfcDependencyModel dependencyModel, FlowStrategies flowStrategy) throws APPCException, InvalidDependencyModelException {
244 FlowBuilder flowBuilder = FlowBuilderFactory.getInstance().getFlowBuilder(flowStrategy);
245 if (flowBuilder == null) {
246 throw new APPCException("Flow Strategy not supported " + flowStrategy);
248 return flowBuilder.buildFlowModel(dependencyModel, inventoryModel);
251 private FlowStrategies readFlowStrategy(SequenceGeneratorInput sequenceGeneratorInput) {
252 Map<String, String> tunableParams = sequenceGeneratorInput.getTunableParams();
253 FlowStrategies strategy=null;
254 String strategyStr = null;
255 if (tunableParams != null) {
256 strategyStr = tunableParams.get(Constants.STRATEGY);
257 strategy = FlowStrategies.findByString(strategyStr);
259 if (strategy == null)
260 strategy= FlowStrategies.FORWARD;
264 private boolean readHealthCheckCapabilites(Map<String, List<String>> capabilities) {
265 if (capabilities != null) {
266 List<String> vnfcCapabilities = capabilities.get(CapabilityLevel.VNFC.getLevel());
267 if (vnfcCapabilities != null)
268 return vnfcCapabilities.stream()
269 .anyMatch(p -> Capabilties.HEALTH_CHECK.getCapability().equalsIgnoreCase(p));
274 private boolean readApplicationStartCapability(SequenceGeneratorInput input) {
275 Map<String, List<String>> capability = input.getCapability();
276 if (capability != null) {
277 List<String> vnfcCapabilities = capability.get(CapabilityLevel.VNFC.getLevel());
278 if (vnfcCapabilities != null)
279 return vnfcCapabilities.stream().anyMatch(p -> Capabilties.START_APPLICATION.getCapability().equalsIgnoreCase(p));
284 private Integer readRetryCount(SequenceGeneratorInput input) throws APPCException {
285 String paramValStr = input.getTunableParams().get(RETRY_COUNT);
286 if (StringUtils.isEmpty(paramValStr)) {
287 return RETRY_COUNT_VALUE;
290 return Integer.parseInt(paramValStr);
291 } catch (NumberFormatException e) {
292 String message = "Invalid Number for Retry Count " + paramValStr;
293 logger.error(message, e);
294 throw new APPCException(message);
298 private boolean isVnfcPresent(SequenceGeneratorInput input){
299 boolean vnfcPresent=true;
300 List<Vserver> vservers = input.getInventoryModel().getVnf().getVservers();
301 for (Vserver vm : vservers) {
302 if(!(vm.getVnfc()!=null&& vm.getVnfc().getVnfcType()!=null&& vm.getVnfc().getVnfcName()!=null)){
303 vnfcPresent=false;break;
309 private Integer readWaitTime(SequenceGeneratorInput input) throws APPCException {
310 String paramValStr = input.getTunableParams().get(WAIT_TIME);
311 if (StringUtils.isEmpty(paramValStr)) {
312 return WAIT_TIME_VALUE;
315 return Integer.parseInt(paramValStr);
316 } catch (NumberFormatException e) {
317 String message = "Invalid Number for Wait Time " + paramValStr;
318 logger.error(message, e);
319 throw new APPCException(message);