afea05c2bb9a29efeb13f2f4629cf4aa6cd9ba49
[so.git] / adapters / mso-vfc-adapter / src / main / java / org / openecomp / mso / adapters / vfc / VfcManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.mso.adapters.vfc;
21
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import org.openecomp.mso.adapters.vfc.constant.CommonConstant;
26 import org.openecomp.mso.adapters.vfc.constant.CommonConstant.Step;
27 import org.openecomp.mso.adapters.vfc.constant.DriverExceptionID;
28 import org.openecomp.mso.adapters.vfc.constant.HttpCode;
29 import org.openecomp.mso.adapters.vfc.exceptions.ApplicationException;
30 import org.openecomp.mso.adapters.vfc.model.NSResourceInputParameter;
31 import org.openecomp.mso.adapters.vfc.model.NsCreateReq;
32 import org.openecomp.mso.adapters.vfc.model.NsInstantiateReq;
33 import org.openecomp.mso.adapters.vfc.model.NsOperationKey;
34 import org.openecomp.mso.adapters.vfc.model.NsParameters;
35 import org.openecomp.mso.adapters.vfc.model.NsProgressStatus;
36 import org.openecomp.mso.adapters.vfc.model.ResponseDescriptor;
37 import org.openecomp.mso.adapters.vfc.model.RestfulResponse;
38 import org.openecomp.mso.adapters.vfc.util.JsonUtil;
39 import org.openecomp.mso.adapters.vfc.util.RestfulUtil;
40 import org.openecomp.mso.adapters.vfc.util.ValidateUtil;
41 import org.openecomp.mso.requestsdb.RequestsDatabase;
42 import org.openecomp.mso.requestsdb.RequestsDbConstant;
43 import org.openecomp.mso.requestsdb.ResourceOperationStatus;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 /**
48  * VF-C Manager
49  * <br>
50  * <p>
51  * </p>
52  * 
53  * @author
54  * @version     ONAP Amsterdam Release  2017-08-28
55  */
56 public class VfcManager {
57
58     private static final Logger LOGGER = LoggerFactory.getLogger(VfcManager.class);
59
60     /**
61      * nfvo url map
62      */
63     private static Map<String, String> nfvoUrlMap;
64
65     static {
66         nfvoUrlMap = new HashMap<String, String>();
67         nfvoUrlMap.put(Step.CREATE, CommonConstant.NFVO_CREATE_URL);
68         nfvoUrlMap.put(Step.INSTANTIATE, CommonConstant.NFVO_INSTANTIATE_URL);
69         nfvoUrlMap.put(Step.TERMINATE, CommonConstant.NFVO_TERMINATE_URL);
70         nfvoUrlMap.put(Step.DELETE, CommonConstant.NFVO_DELETE_URL);
71         nfvoUrlMap.put(Step.QUERY, CommonConstant.NFVO_QUERY_URL);
72     }
73
74     /**
75      * create network service
76      * <br>
77      * 
78      * @param segInput input parameters for current node from http request 
79      * @return
80      * @since ONAP Amsterdam Release
81      */
82     public RestfulResponse createNs(NSResourceInputParameter segInput) {
83
84         // Step1: get service template by node type
85         String nsdId = segInput.getNsOperationKey().getNodeTemplateId();
86         // nsdId for NFVO is "id" in the response, while for SDNO is "servcice template id"
87         LOGGER.info("serviceTemplateId is {}, id is {}", nsdId);
88
89         LOGGER.info("create ns -> begin");
90         // Step2: Prepare url and method type
91         String url = getUrl(null, CommonConstant.Step.CREATE);
92         String methodType = CommonConstant.MethodType.POST;
93
94         // Step3: Prepare restful parameters and options
95         NsCreateReq oRequest = new NsCreateReq();
96         oRequest.setNsdId(nsdId);
97         oRequest.setNsName(segInput.getSubServiceName());
98         oRequest.setDescription(segInput.getSubServiceDesc());
99         String createReq = JsonUtil.marshal(oRequest);
100
101         // Step4: Call NFVO or SDNO lcm to create ns
102         RestfulResponse createRsp = RestfulUtil.send(url, methodType, createReq);
103         ValidateUtil.assertObjectNotNull(createRsp);
104         LOGGER.info("create ns response status is : {}", createRsp.getStatus());
105         LOGGER.info("create ns response content is : {}", createRsp.getResponseContent());
106         @SuppressWarnings("unchecked")
107         Map<String, String> rsp = JsonUtil.unMarshal(createRsp.getResponseContent(), Map.class);
108         String nsInstanceId = rsp.get(CommonConstant.NS_INSTANCE_ID);
109         if(ValidateUtil.isStrEmpty(nsInstanceId)) {
110             LOGGER.error("Invalid instanceId from create operation");
111             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
112                     DriverExceptionID.INVALID_RESPONSEE_FROM_CREATE_OPERATION);
113         }
114         LOGGER.info("create ns -> end");
115         LOGGER.info("save segment and operaton info -> begin");
116         // Step 5: add relation between service and NS
117         AaiUtil.addRelation(segInput.getNsOperationKey().getServiceId(), nsInstanceId);
118
119         // Step 6: save resource operation information
120         ResourceOperationStatus nsOperInfo = RequestsDatabase.getResourceOperationStatus(
121                 segInput.getNsOperationKey().getServiceId(), segInput.getNsOperationKey().getOperationId(),
122                 segInput.getNsOperationKey().getNodeTemplateId());
123         nsOperInfo.setStatus(RequestsDbConstant.Status.PROCESSING);
124         RequestsDatabase.updateResOperStatus(nsOperInfo);
125
126         if(!HttpCode.isSucess(createRsp.getStatus())) {
127             LOGGER.error("update segment operation status : fail to create ns");
128             nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
129             nsOperInfo.setErrorCode(String.valueOf(createRsp.getStatus()));
130             RequestsDatabase.updateResOperStatus(nsOperInfo);
131             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_CREATE_NS);
132         }
133         LOGGER.info("save segment and operation info -> end");
134         return createRsp;
135     }
136
137     /**
138      * delete network service
139      * <br>
140      * 
141      * @param nsOperationKey The operation key of the NS resource
142      * @param nsInstanceId The NS instance id
143      * @return
144      * @since ONAP Amsterdam Release
145      */
146     public RestfulResponse deleteNs(NsOperationKey nsOperationKey, String nsInstanceId) {
147         LOGGER.info("delete ns -> begin");
148         // Step1: prepare url and methodType
149         String url = getUrl(nsInstanceId, CommonConstant.Step.DELETE);
150         String methodType = CommonConstant.MethodType.DELETE;
151
152         // Step2: prepare restful parameters and options
153         RestfulResponse deleteRsp = RestfulUtil.send(url, methodType, "");
154         ValidateUtil.assertObjectNotNull(deleteRsp);
155         LOGGER.info("delete ns response status is : {}", deleteRsp.getStatus());
156         LOGGER.info("delete ns response content is : {}", deleteRsp.getResponseContent());
157         LOGGER.info("delete ns -> end");
158         ResourceOperationStatus nsOperInfo = RequestsDatabase.getResourceOperationStatus(nsOperationKey.getServiceId(),
159                 nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateId());
160         if(!HttpCode.isSucess(deleteRsp.getStatus())) {
161             LOGGER.error("fail to delete ns");
162
163             nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
164             nsOperInfo.setErrorCode(String.valueOf(deleteRsp.getStatus()));
165             nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
166             RequestsDatabase.updateResOperStatus(nsOperInfo);
167             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_DELETE_NS);
168         }
169
170         // Step3: remove relation info between service and ns
171         AaiUtil.removeRelation(nsOperationKey.getServiceId(), nsInstanceId);
172         LOGGER.info("delete segment information -> end");
173
174         // Step4: update service segment operation status
175         nsOperInfo.setStatus(RequestsDbConstant.Status.FINISHED);
176         nsOperInfo.setErrorCode(String.valueOf(deleteRsp.getStatus()));
177         RequestsDatabase.updateResOperStatus(nsOperInfo);
178         LOGGER.info("update segment operaton status for delete -> end");
179
180         return deleteRsp;
181
182     }
183
184     /**
185      * instantiate network service
186      * <br>
187      * 
188      * @param nsInstanceId The NS instance id 
189      * @param segInput input parameters for current node from http request
190      * @return
191      * @since ONAP Amsterdam Release
192      */
193     public RestfulResponse instantiateNs(String nsInstanceId, NSResourceInputParameter segInput) {
194         // Call the NFVO or SDNO service to instantiate service
195         LOGGER.info("instantiate ns -> begin");
196
197         // Step1: Prepare restful parameters and options
198         NsInstantiateReq oRequest = new NsInstantiateReq();
199         oRequest.setNsInstanceId(nsInstanceId);
200         NsParameters nsParameters = segInput.getNsParameters();
201         oRequest.setLocationConstraints(nsParameters.getLocationConstraints());
202         oRequest.setAdditionalParamForNs(nsParameters.getAdditionalParamForNs());
203         String instReq = JsonUtil.marshal(oRequest);
204         // Step2: prepare url and
205         String url = getUrl(nsInstanceId, CommonConstant.Step.INSTANTIATE);
206         String methodType = CommonConstant.MethodType.POST;
207
208         RestfulResponse instRsp = RestfulUtil.send(url, methodType, instReq);
209         ValidateUtil.assertObjectNotNull(instRsp);
210         LOGGER.info("instantiate ns response status is : {}", instRsp.getStatus());
211         LOGGER.info("instantiate ns response content is : {}", instRsp.getResponseContent());
212         ValidateUtil.assertObjectNotNull(instRsp.getResponseContent());
213         @SuppressWarnings("unchecked")
214         Map<String, String> rsp = JsonUtil.unMarshal(instRsp.getResponseContent(), Map.class);
215         String jobId = rsp.get(CommonConstant.JOB_ID);
216         ResourceOperationStatus nsOperInfo = RequestsDatabase.getResourceOperationStatus(
217                 segInput.getNsOperationKey().getServiceId(), segInput.getNsOperationKey().getOperationId(),
218                 segInput.getNsOperationKey().getNodeTemplateId());
219         if(ValidateUtil.isStrEmpty(jobId)) {
220             LOGGER.error("Invalid jobId from instantiate operation");
221             nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
222             nsOperInfo.setErrorCode(String.valueOf(instRsp.getStatus()));
223             nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED);
224             RequestsDatabase.updateResOperStatus(nsOperInfo);
225             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
226                     DriverExceptionID.INVALID_RESPONSE_FROM_INSTANTIATE_OPERATION);
227         }
228         LOGGER.info("instantiate ns -> end");
229
230         if(!HttpCode.isSucess(instRsp.getStatus())) {
231             LOGGER.error("update segment operation status : fail to instantiate ns");
232             nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
233             nsOperInfo.setErrorCode(String.valueOf(instRsp.getStatus()));
234             nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED);
235             RequestsDatabase.updateResOperStatus(nsOperInfo);
236             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_INSTANTIATE_NS);
237         }
238
239         // Step 3: update segment operation job id
240         LOGGER.info("update resource operation status job id -> begin");
241         nsOperInfo.setJobId(jobId);
242         RequestsDatabase.updateResOperStatus(nsOperInfo);
243         LOGGER.info("update segment operation job id -> end");
244
245         return instRsp;
246     }
247
248     /**
249      * terminate network service
250      * <br>
251      * 
252      * @param nsOperationKey The operation key for NS resource
253      * @param nsInstanceId The NS instance id
254      * @return
255      * @since ONAP Amsterdam Release
256      */
257     public RestfulResponse terminateNs(NsOperationKey nsOperationKey, String nsInstanceId) {
258         // Step1: save segment operation info for delete process
259         LOGGER.info("save segment operation for delete process");
260         ResourceOperationStatus nsOperInfo = RequestsDatabase.getResourceOperationStatus(nsOperationKey.getServiceId(),
261                 nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateId());
262         nsOperInfo.setStatus(RequestsDbConstant.Status.PROCESSING);
263         RequestsDatabase.updateResOperStatus(nsOperInfo);
264
265         LOGGER.info("terminate ns -> begin");
266         // Step2: prepare url and method type
267         String url = getUrl(nsInstanceId, CommonConstant.Step.TERMINATE);
268         String methodType = CommonConstant.MethodType.POST;
269
270         // Step3: prepare restful parameters and options
271         Map<String, String> reqBody = new HashMap<>();
272         reqBody.put("nsInstanceId", nsInstanceId);
273         reqBody.put("terminationType", "graceful");
274         reqBody.put("gracefulTerminationTimeout", "60");
275
276         // Step4: Call the NFVO or SDNO service to terminate service
277         RestfulResponse terminateRsp = RestfulUtil.send(url, methodType, JsonUtil.marshal(reqBody));
278         ValidateUtil.assertObjectNotNull(terminateRsp);
279         LOGGER.info("terminate ns response status is : {}", terminateRsp.getStatus());
280         LOGGER.info("terminate ns response content is : {}", terminateRsp.getResponseContent());
281         @SuppressWarnings("unchecked")
282         Map<String, String> rsp = JsonUtil.unMarshal(terminateRsp.getResponseContent(), Map.class);
283         String jobId = rsp.get(CommonConstant.JOB_ID);
284         if(ValidateUtil.isStrEmpty(jobId)) {
285             LOGGER.error("Invalid jobId from terminate operation");
286             nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
287             nsOperInfo.setErrorCode(String.valueOf(terminateRsp.getStatus()));
288             nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
289             RequestsDatabase.updateResOperStatus(nsOperInfo);
290             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
291                     DriverExceptionID.INVALID_RESPONSE_FROM_TERMINATE_OPERATION);
292         }
293         LOGGER.info("terminate ns -> end");
294
295         // Step 3: update segment operation
296         if(!HttpCode.isSucess(terminateRsp.getStatus())) {
297             LOGGER.error("fail to instantiate ns");
298             nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
299             nsOperInfo.setErrorCode(String.valueOf(terminateRsp.getStatus()));
300             nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
301             RequestsDatabase.updateResOperStatus(nsOperInfo);
302
303             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_TERMINATE_NS);
304         }
305         LOGGER.info("update segment job id -> begin");
306         nsOperInfo.setJobId(jobId);
307         RequestsDatabase.updateResOperStatus(nsOperInfo);
308         LOGGER.info("update segment job id -> end");
309
310         return terminateRsp;
311     }
312
313     /**
314      * get ns progress by job Id
315      * <br>
316      * 
317      * @param nsOperationKey The OperationKey for NS resource
318      * @param jobId the job id
319      * @return
320      * @since ONAP Amsterdam Release
321      */
322     public RestfulResponse getNsProgress(NsOperationKey nsOperationKey, String jobId) {
323
324         ValidateUtil.assertObjectNotNull(jobId);
325         // Step 1: query the current resource operation status
326         ResourceOperationStatus nsOperInfo = RequestsDatabase.getResourceOperationStatus(nsOperationKey.getServiceId(),
327                 nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateId());
328
329         // Step 2: start query
330         LOGGER.info("query ns status -> begin");
331         String url = getUrl(jobId, CommonConstant.Step.QUERY);
332         String methodType = CommonConstant.MethodType.GET;
333         // prepare restful parameters and options
334         RestfulResponse rsp = RestfulUtil.send(url, methodType, "");
335         ValidateUtil.assertObjectNotNull(rsp);
336         LOGGER.info("query ns progress response status is : {}", rsp.getStatus());
337         LOGGER.info("query ns progress response content is : {}", rsp.getResponseContent());
338         //Step 3:check the response staus
339         if(!HttpCode.isSucess(rsp.getStatus())) {
340             LOGGER.info("fail to query job status");
341             nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
342             nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
343             nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
344             RequestsDatabase.updateResOperStatus(nsOperInfo);
345             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_QUERY_JOB_STATUS);
346         }
347         // Step 4: Process Network Service Instantiate Response
348         NsProgressStatus nsProgress = JsonUtil.unMarshal(rsp.getResponseContent(), NsProgressStatus.class);
349         ResponseDescriptor rspDesc = nsProgress.getResponseDescriptor();
350         // Step 5: update segment operation progress
351
352         nsOperInfo.setProgress(rspDesc.getProgress());
353         nsOperInfo.setStatusDescription(rspDesc.getStatusDescription());
354         RequestsDatabase.updateResOperStatus(nsOperInfo);
355
356         // Step 6: update segment operation status
357         if(RequestsDbConstant.Progress.ONE_HUNDRED.equals(rspDesc.getProgress())
358                 && RequestsDbConstant.Status.FINISHED.equals(rspDesc.getStatus())) {
359             LOGGER.info("job result is succeeded, operType is {}", nsOperInfo.getOperType());
360             nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
361             nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
362
363             if(RequestsDbConstant.OperationType.CREATE.equals(nsOperInfo.getOperType())) {
364                 nsOperInfo.setStatus(RequestsDbConstant.Status.FINISHED);
365             }
366             RequestsDatabase.updateResOperStatus(nsOperInfo);
367         } else if(RequestsDbConstant.Status.ERROR.equals(rspDesc.getStatus())) {
368             LOGGER.error("job result is failed, operType is {}", nsOperInfo.getOperType());
369             nsOperInfo.setErrorCode(String.valueOf(rsp.getStatus()));
370             nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
371             nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
372             RequestsDatabase.updateResOperStatus(nsOperInfo);
373             throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.JOB_STATUS_ERROR);
374         } else {
375             LOGGER.error("unexcepted response status");
376         }
377         LOGGER.info("query ns status -> end");
378
379         return rsp;
380     }
381
382     /**
383      * get url for the operation
384      * <br>
385      * 
386      * @param variable variable should be put in the url
387      * @param step step of the operation (terminate,query,delete)
388      * @return
389      * @since ONAP Amsterdam Release
390      */
391     private String getUrl(String variable, String step) {
392
393         String url = CommonConstant.STR_EMPTY;
394         String originalUrl;
395         originalUrl = (String)nfvoUrlMap.get(step);
396         url = String.format(originalUrl, variable);
397         return url;
398
399     }
400
401 }