2 * Copyright (c) 2018 Orange
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
14 package org.onap.nbi.apis.serviceorder.workflow;
16 import org.onap.nbi.apis.serviceorder.SoClient;
17 import org.onap.nbi.apis.serviceorder.model.ServiceCharacteristic;
18 import org.onap.nbi.apis.serviceorder.model.ServiceOrder;
19 import org.onap.nbi.apis.serviceorder.model.ServiceOrderItem;
20 import org.onap.nbi.apis.serviceorder.model.StateType;
21 import org.onap.nbi.apis.serviceorder.model.consumer.*;
22 import org.onap.nbi.apis.serviceorder.model.orchestrator.ExecutionTask;
23 import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderInfo;
24 import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderInfoJson;
25 import org.onap.nbi.apis.serviceorder.repositories.ExecutionTaskRepository;
26 import org.onap.nbi.apis.serviceorder.repositories.ServiceOrderRepository;
27 import org.onap.nbi.apis.serviceorder.utils.JsonEntityConverter;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.beans.factory.annotation.Autowired;
31 import org.springframework.beans.factory.annotation.Value;
32 import org.springframework.http.HttpStatus;
33 import org.springframework.http.ResponseEntity;
34 import org.springframework.stereotype.Service;
35 import org.springframework.util.CollectionUtils;
37 import java.io.IOException;
41 public class SOTaskProcessor {
43 @Value("${nbi.callForVNF}")
44 private boolean enableCallForVNF;
46 @Value("${onap.lcpCloudRegionId}")
47 private String lcpCloudRegionId;
49 @Value("${onap.tenantId}")
50 private String tenantId;
53 private ServiceOrderRepository serviceOrderRepository;
56 private ExecutionTaskRepository executionTaskRepository;
59 private SoClient soClient;
62 private static final Logger LOGGER = LoggerFactory.getLogger(SOTaskProcessor.class);
65 * Run the ServiceOrchestrator processing for a serviceOrderItem which with any sub relations
67 * @throws InterruptedException
69 public void processOrderItem(ExecutionTask executionTask) throws InterruptedException {
72 ServiceOrderInfoJson serviceOrderInfoJson = executionTask.getServiceOrderInfoJson();
73 ServiceOrder serviceOrder = serviceOrderRepository.findOne(serviceOrderInfoJson.getServiceOrderId());
74 ServiceOrderItem serviceOrderItem = null;
75 for (ServiceOrderItem item : serviceOrder.getOrderItem()) {
76 if (item.getId().equals(executionTask.getOrderItemId())) {
77 serviceOrderItem = item;
81 ServiceOrderInfo serviceOrderInfo = null;
84 JsonEntityConverter.convertJsonToServiceOrderInfo(serviceOrderInfoJson.getServiceOrderInfoJson());
85 } catch (IOException e) {
86 LOGGER.warn("Unable to read ServiceOrderInfo Json for serviceOrderId " + serviceOrder.getId(), e);
89 if (serviceOrderItem != null && StateType.ACKNOWLEDGED == serviceOrderItem.getState()) {
91 ResponseEntity<CreateServiceInstanceResponse> response = null;
93 response = postSORequest(serviceOrderItem, serviceOrderInfo);
94 } catch (NullPointerException e) {
95 LOGGER.warn("Enable to create service instance for serviceOrderItem.id=" + serviceOrderItem.getId(), e);
99 if (response == null) {
100 LOGGER.warn("response=null for serviceOrderItem.id=" + serviceOrderItem.getId());
101 serviceOrderItem.setState(StateType.FAILED);
103 updateServiceOrderItem(response.getBody(), serviceOrderItem);
105 if (response.getStatusCode() != HttpStatus.CREATED || response.getBody() == null
106 || response.getBody().getRequestReference() == null) {
107 serviceOrderItem.setState(StateType.FAILED);
109 serviceOrderItem.setState(StateType.INPROGRESS);
114 if (executionTask.getNbRetries() > 0) {
115 // TODO lancer en asynchrone
116 pollSoRequestStatus(serviceOrderItem);
117 if (serviceOrderItem.getState().equals(StateType.COMPLETED)) {
118 updateSuccessTask(executionTask);
120 int nbRetries = executionTask.getNbRetries();
121 executionTask.setNbRetries(--nbRetries);
122 executionTask.setLastAttemptDate(new Date());
123 executionTaskRepository.save(executionTask);
126 updateFailedTask(executionTask, serviceOrder);
130 updateServiceOrder(serviceOrder);
133 private ResponseEntity<CreateServiceInstanceResponse> postSORequest(ServiceOrderItem serviceOrderItem,
134 ServiceOrderInfo serviceOrderInfo) {
135 RequestDetails requestDetails = buildSoRequest(serviceOrderItem,
136 serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId()).getCatalogResponse(),
137 serviceOrderInfo.getSubscriberInfo());
138 MSOPayload msoPayload = new MSOPayload(requestDetails);
139 ResponseEntity<CreateServiceInstanceResponse> response = null;
141 switch (serviceOrderItem.getAction()) {
143 response = soClient.callCreateServiceInstance(msoPayload);
146 response = soClient.callDeleteServiceInstance(msoPayload, serviceOrderItem.getService().getId());
154 private void updateServiceOrder(ServiceOrder serviceOrder) {
155 boolean atLeastOneCompleted = false;
156 boolean atLeastOneNotFinished = false;
157 boolean atLeastOneFailed = false;
160 for (ServiceOrderItem serviceOrderItem : serviceOrder.getOrderItem()) {
161 switch (serviceOrderItem.getState()) {
163 atLeastOneCompleted = true;
167 atLeastOneNotFinished = true;
170 atLeastOneFailed = true;
178 if (atLeastOneNotFinished) {
179 serviceOrder.setState(StateType.INPROGRESS);
181 serviceOrder.setCompletionDateTime(new Date());
182 if (atLeastOneFailed) {
183 if (!atLeastOneCompleted) {
184 serviceOrder.setState(StateType.FAILED);
186 serviceOrder.setState(StateType.PARTIAL);
189 serviceOrder.setState(StateType.COMPLETED);
192 serviceOrderRepository.save(serviceOrder);
199 * @throws InterruptedException
201 private void pollSoRequestStatus(ServiceOrderItem orderItem) throws InterruptedException {
202 boolean stopPolling = false;
203 String requestId = orderItem.getRequestId();
204 GetRequestStatusResponse response = null;
207 while (!stopPolling) {
208 response = soClient.callGetRequestStatus(requestId);
209 if (response != null) {
210 if (response.getRequest().getRequestStatus().getPercentProgress() != 100) {
212 orderItem.setState(StateType.INPROGRESS);
214 } else if (RequestState.COMPLETE != response.getRequest().getRequestStatus().getRequestState()) {
215 orderItem.setState(StateType.FAILED);
218 orderItem.setState(StateType.COMPLETED);
222 orderItem.setState(StateType.INPROGRESS);
225 if (nbRetries == 3) {
232 * Build SO CREATE request from the ServiceOrder and catalog informations from SDC
236 * @param subscriberInfo
239 private RequestDetails buildSoRequest(ServiceOrderItem orderItem, LinkedHashMap<String, Object> sdcInfos,
240 SubscriberInfo subscriberInfo) {
241 RequestDetails requestDetails = new RequestDetails();
243 requestDetails.setSubscriberInfo(subscriberInfo);
245 ModelInfo modelInfo = new ModelInfo();
246 modelInfo.setModelType("service");
247 modelInfo.setModelInvariantId((String) sdcInfos.get("invariantUUID"));
248 modelInfo.setModelNameVersionId(orderItem.getService().getServiceSpecification().getId());
249 modelInfo.setModelName((String) sdcInfos.get("name"));
250 modelInfo.setModelVersion((String) sdcInfos.get("version"));
251 requestDetails.setModelInfo(modelInfo);
253 RequestInfo requestInfo = new RequestInfo();
254 requestInfo.setInstanceName(orderItem.getService().getName());
255 requestInfo.setSource("VID");
256 requestInfo.setSuppressRollback(false);
257 requestDetails.setRequestInfo(requestInfo);
259 RequestParameters requestParameters = new RequestParameters();
260 requestParameters.setSubscriptionServiceType((String) sdcInfos.get("name"));
261 requestParameters.setUserParams(
262 retrieveUserParamsFromServiceCharacteristics(orderItem.getService().getServiceCharacteristic()));
263 requestParameters.setaLaCarte(true);
264 requestDetails.setRequestParameters(requestParameters);
266 CloudConfiguration cloudConfiguration = new CloudConfiguration(lcpCloudRegionId, tenantId);
267 requestDetails.setCloudConfiguration(cloudConfiguration);
268 return requestDetails;
272 * Build a list of UserParams for the SO request by browsing a list of ServiceCharacteristics from
275 * @param characteristics
278 private List<UserParams> retrieveUserParamsFromServiceCharacteristics(List<ServiceCharacteristic> characteristics) {
279 List<UserParams> userParams = new ArrayList<UserParams>();
281 if (!CollectionUtils.isEmpty(characteristics)) {
282 for (ServiceCharacteristic characteristic : characteristics) {
283 UserParams userParam = new UserParams(characteristic.getName(),
284 characteristic.getValue().getServiceCharacteristicValue());
285 userParams.add(userParam);
294 * Update ServiceOrderItem with SO response by using serviceOrderRepository with the serviceOrderId
296 * @param createServiceInstanceResponse
299 private void updateServiceOrderItem(CreateServiceInstanceResponse createServiceInstanceResponse,
300 ServiceOrderItem orderItem) {
302 if (createServiceInstanceResponse != null && !orderItem.getState().equals(StateType.FAILED)) {
303 orderItem.getService().setId(createServiceInstanceResponse.getRequestReference().getInstanceId());
304 orderItem.setRequestId(createServiceInstanceResponse.getRequestReference().getRequestId());
309 * Update an executionTask in database when it's process with a success
311 * @param executionTask
313 private void updateSuccessTask(ExecutionTask executionTask) {
314 executionTaskRepository.delete(executionTask.getInternalId());
315 executionTaskRepository.updateReliedTaskAfterDelete(executionTask.getInternalId());
319 * @param executionTask
320 * @param serviceOrder
322 private void updateFailedTask(ExecutionTask executionTask, ServiceOrder serviceOrder) {
323 List<ExecutionTask> executionTasksToDelete = findExecutionTasksRecursively(executionTask);
324 for (ExecutionTask taskId : executionTasksToDelete) {
325 executionTaskRepository.delete(taskId);
328 for (ServiceOrderItem item : serviceOrder.getOrderItem()) {
329 for (ExecutionTask taskToDelete : executionTasksToDelete) {
330 if (taskToDelete.getOrderItemId().equals(item.getId())) {
331 item.setState(StateType.FAILED);
338 * @param executionTask
341 private List<ExecutionTask> findExecutionTasksRecursively(ExecutionTask executionTask) {
343 List<ExecutionTask> executionTasks = new ArrayList<>();
345 List<ExecutionTask> tasksReliedToAnOrderItemId =
346 executionTaskRepository.findTasksReliedToAnOrderItemId(executionTask.getInternalId());
348 if (CollectionUtils.isEmpty(tasksReliedToAnOrderItemId)) {
349 return Arrays.asList(executionTask);
351 for (ExecutionTask task : tasksReliedToAnOrderItemId) {
352 executionTasks.addAll(findExecutionTasksRecursively(task));
355 executionTasks.add(executionTask);
356 return executionTasks;