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 requestInfo.setRequestorId("NBI");
258 requestDetails.setRequestInfo(requestInfo);
260 RequestParameters requestParameters = new RequestParameters();
261 requestParameters.setSubscriptionServiceType((String) sdcInfos.get("name"));
262 requestParameters.setUserParams(
263 retrieveUserParamsFromServiceCharacteristics(orderItem.getService().getServiceCharacteristic()));
264 requestParameters.setaLaCarte(true);
265 requestDetails.setRequestParameters(requestParameters);
267 CloudConfiguration cloudConfiguration = new CloudConfiguration(lcpCloudRegionId, tenantId);
268 requestDetails.setCloudConfiguration(cloudConfiguration);
269 return requestDetails;
273 * Build a list of UserParams for the SO request by browsing a list of ServiceCharacteristics from
276 * @param characteristics
279 private List<UserParams> retrieveUserParamsFromServiceCharacteristics(List<ServiceCharacteristic> characteristics) {
280 List<UserParams> userParams = new ArrayList<UserParams>();
282 if (!CollectionUtils.isEmpty(characteristics)) {
283 for (ServiceCharacteristic characteristic : characteristics) {
284 UserParams userParam = new UserParams(characteristic.getName(),
285 characteristic.getValue().getServiceCharacteristicValue());
286 userParams.add(userParam);
295 * Update ServiceOrderItem with SO response by using serviceOrderRepository with the serviceOrderId
297 * @param createServiceInstanceResponse
300 private void updateServiceOrderItem(CreateServiceInstanceResponse createServiceInstanceResponse,
301 ServiceOrderItem orderItem) {
303 if (createServiceInstanceResponse != null && !orderItem.getState().equals(StateType.FAILED)) {
304 orderItem.getService().setId(createServiceInstanceResponse.getRequestReference().getInstanceId());
305 orderItem.setRequestId(createServiceInstanceResponse.getRequestReference().getRequestId());
310 * Update an executionTask in database when it's process with a success
312 * @param executionTask
314 private void updateSuccessTask(ExecutionTask executionTask) {
315 executionTaskRepository.delete(executionTask.getInternalId());
316 executionTaskRepository.updateReliedTaskAfterDelete(executionTask.getInternalId());
320 * @param executionTask
321 * @param serviceOrder
323 private void updateFailedTask(ExecutionTask executionTask, ServiceOrder serviceOrder) {
324 List<ExecutionTask> executionTasksToDelete = findExecutionTasksRecursively(executionTask);
325 for (ExecutionTask taskId : executionTasksToDelete) {
326 executionTaskRepository.delete(taskId);
329 for (ServiceOrderItem item : serviceOrder.getOrderItem()) {
330 for (ExecutionTask taskToDelete : executionTasksToDelete) {
331 if (taskToDelete.getOrderItemId().equals(item.getId())) {
332 item.setState(StateType.FAILED);
339 * @param executionTask
342 private List<ExecutionTask> findExecutionTasksRecursively(ExecutionTask executionTask) {
344 List<ExecutionTask> executionTasks = new ArrayList<>();
346 List<ExecutionTask> tasksReliedToAnOrderItemId =
347 executionTaskRepository.findTasksReliedToAnOrderItemId(executionTask.getInternalId());
349 if (CollectionUtils.isEmpty(tasksReliedToAnOrderItemId)) {
350 return Arrays.asList(executionTask);
352 for (ExecutionTask task : tasksReliedToAnOrderItemId) {
353 executionTasks.addAll(findExecutionTasksRecursively(task));
356 executionTasks.add(executionTask);
357 return executionTasks;