Refactor SOL003 Adapter to organize its modules
[so.git] / adapters / etsi-sol003-adapter / etsi-sol003-lcm / etsi-sol003-lcm-adapter / src / main / java / org / onap / so / adapters / etsisol003adapter / lcm / jobmanagement / JobManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.adapters.etsisol003adapter.lcm.jobmanagement;
22
23 import static org.slf4j.LoggerFactory.getLogger;
24 import java.util.Map;
25 import java.util.UUID;
26 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.AaiServiceProvider;
27 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.VnfmServiceProvider;
28 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.InlineResponse200;
29 import org.onap.so.adapters.etsisol003adapter.lcm.rest.exceptions.JobNotFoundException;
30 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationEnum;
31 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum;
32 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStatusRetrievalStatusEnum;
33 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.QueryJobResponse;
34 import org.onap.so.rest.exceptions.HttpResouceNotFoundException;
35 import org.slf4j.Logger;
36 import org.springframework.beans.factory.annotation.Autowired;
37 import org.springframework.stereotype.Component;
38 import com.google.common.base.Optional;
39 import com.google.common.collect.Maps;
40
41 /**
42  * Manages jobs enabling the status of jobs to be queried. A job is associated with an operation on a VNFM.
43  */
44 @Component
45 public class JobManager {
46     public static final String ALREADY_COMPLETED_OPERATION_ID = "alreadyCompleted";
47     private static final String SEPARATOR = "_";
48     private static Logger logger = getLogger(JobManager.class);
49     private final Map<String, VnfmOperation> mapOfJobIdToVnfmOperation = Maps.newConcurrentMap();
50     private final VnfmServiceProvider vnfmServiceProvider;
51     private final AaiServiceProvider aaiServiceProvider;
52
53     @Autowired
54     JobManager(final VnfmServiceProvider vnfmServiceProvider, final AaiServiceProvider aaiServiceProvider) {
55         this.vnfmServiceProvider = vnfmServiceProvider;
56         this.aaiServiceProvider = aaiServiceProvider;
57     }
58
59     /**
60      * Create a job associated with an operation on a VNFM.
61      *
62      * @param vnfmId the VNFM the operation relates to
63      * @param operationId the ID of the associated VNFM operation
64      * @param waitForNotificationForSuccess if set to <code>true</code> the {@link QueryJobResponse#getOperationState()}
65      *        shall not return {@link org.onap.vnfmadapter.v1.model.OperationStateEnum#COMPLETED} unless a required
66      *        notification has been processed
67      * @return the ID of the job. Can be used to query the job using {@link #getVnfmOperation(String)}
68      */
69     public String createJob(final String vnfmId, final String operationId,
70             final boolean waitForNotificationForSuccess) {
71         final String jobId = vnfmId + SEPARATOR + UUID.randomUUID().toString();
72         final VnfmOperation vnfmOperation = new VnfmOperation(vnfmId, operationId, waitForNotificationForSuccess);
73         mapOfJobIdToVnfmOperation.put(jobId, vnfmOperation);
74         return jobId;
75     }
76
77     /**
78      * Get the operation, associated with the given job ID, from the VNFM.
79      *
80      * @param jobId the job ID
81      * @return the associated operation from the VNFM, or <code>null</code> of no operation is associated with the given
82      *         job ID
83      */
84     public QueryJobResponse getVnfmOperation(final String jobId) {
85         final VnfmOperation vnfmOperation = mapOfJobIdToVnfmOperation.get(jobId);
86         final QueryJobResponse response = new QueryJobResponse();
87
88         if (vnfmOperation == null) {
89             throw new JobNotFoundException("No job found with ID: " + jobId);
90         }
91
92         if (vnfmOperation.getOperationId().equals(ALREADY_COMPLETED_OPERATION_ID)) {
93             response.setOperationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.STATUS_FOUND);
94             return response.operationState(OperationStateEnum.COMPLETED);
95         }
96
97         if (vnfmOperation.isVnfDeleted()) {
98             response.setOperationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.STATUS_FOUND);
99             return response.operationState(getOperationState(vnfmOperation, null));
100         }
101
102         try {
103             final Optional<InlineResponse200> operationOptional = vnfmServiceProvider.getOperation(
104                     aaiServiceProvider.invokeGetVnfm(vnfmOperation.getVnfmId()), vnfmOperation.getOperationId());
105
106             if (!operationOptional.isPresent()) {
107                 return response.operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.OPERATION_NOT_FOUND);
108             }
109             final InlineResponse200 operation = operationOptional.get();
110
111             logger.debug("Job Id: {} operationId: {} operation details: {} ", jobId, operation.getId(), operation);
112
113             if (operation.getOperationState() == null) {
114                 return response.operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.WAITING_FOR_STATUS);
115             }
116
117             response.setOperationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.STATUS_FOUND);
118             response.setId(operation.getId());
119             response.setOperation(OperationEnum.fromValue(operation.getOperation().getValue()));
120             response.setOperationState(getOperationState(vnfmOperation, operation));
121             response.setStartTime(operation.getStartTime());
122             response.setStateEnteredTime(operation.getStateEnteredTime());
123             response.setVnfInstanceId(operation.getVnfInstanceId());
124
125             return response;
126         } catch (final HttpResouceNotFoundException exception) {
127             logger.error("Exception encountered trying to get operation status for operation id "
128                     + vnfmOperation.getOperationId(), exception);
129             return response.operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.WAITING_FOR_STATUS);
130         }
131     }
132
133     private OperationStateEnum getOperationState(final VnfmOperation vnfmOperation,
134             final InlineResponse200 operationResponse) {
135         switch (vnfmOperation.getNotificationStatus()) {
136             case NOTIFICATION_PROCESSING_PENDING:
137                 return org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.PROCESSING;
138             case NOTIFICATION_PROCEESING_SUCCESSFUL:
139                 return org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.COMPLETED;
140             case NOTIFICATION_PROCESSING_FAILED:
141                 return org.onap.so.adapters.etsisol003adapter.lcm.v1.model.OperationStateEnum.FAILED;
142             default:
143                 if (operationResponse == null || operationResponse.getOperationState() == null)
144                     return null;
145                 return OperationStateEnum.fromValue(operationResponse.getOperationState().getValue());
146         }
147     }
148
149     public void notificationProcessedForOperation(final String operationId,
150             final boolean notificationProcessingWasSuccessful) {
151         logger.debug("Notification processed for operation ID {} success?: {}", operationId,
152                 notificationProcessingWasSuccessful);
153         final java.util.Optional<VnfmOperation> relatedOperation = mapOfJobIdToVnfmOperation.values().stream()
154                 .filter(operation -> operation.getOperationId().equals(operationId)).findFirst();
155         if (relatedOperation.isPresent()) {
156             relatedOperation.get().setNotificationProcessed(notificationProcessingWasSuccessful);
157         } else {
158             logger.debug("No operation found for operation ID {} ", operationId);
159
160         }
161     }
162
163     public void vnfDeleted(final String operationId) {
164         logger.debug("VNF deleyed for operation ID {}", operationId);
165         final java.util.Optional<VnfmOperation> relatedOperation = mapOfJobIdToVnfmOperation.values().stream()
166                 .filter(operation -> operation.getOperationId().equals(operationId)).findFirst();
167         if (relatedOperation.isPresent()) {
168             relatedOperation.get().setVnfDeleted();
169         } else {
170             logger.debug("No operation found for operation ID {} ", operationId);
171         }
172     }
173
174 }