2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.so.adapters.vfc.rest;
23 import java.util.HashMap;
25 import org.onap.so.adapters.vfc.constant.CommonConstant;
26 import org.onap.so.adapters.vfc.constant.CommonConstant.Step;
27 import org.onap.so.adapters.vfc.constant.DriverExceptionID;
28 import org.onap.so.adapters.vfc.constant.HttpCode;
29 import org.onap.so.adapters.vfc.exceptions.ApplicationException;
30 import org.onap.so.adapters.vfc.model.CustomerModel;
31 import org.onap.so.adapters.vfc.model.NSResourceInputParameter;
32 import org.onap.so.adapters.vfc.model.NsCreateReq;
33 import org.onap.so.adapters.vfc.model.NsInstantiateReq;
34 import org.onap.so.adapters.vfc.model.NsOperationKey;
35 import org.onap.so.adapters.vfc.model.NsParameters;
36 import org.onap.so.adapters.vfc.model.NsProgressStatus;
37 import org.onap.so.adapters.vfc.model.NsScaleParameters;
38 import org.onap.so.adapters.vfc.model.ResponseDescriptor;
39 import org.onap.so.adapters.vfc.model.RestfulResponse;
40 import org.onap.so.adapters.vfc.model.VFCScaleData;
41 import org.onap.so.adapters.vfc.util.JsonUtil;
42 import org.onap.so.adapters.vfc.util.RestfulUtil;
43 import org.onap.so.adapters.vfc.util.ValidateUtil;
44 import org.onap.so.db.request.beans.ResourceOperationStatus;
45 import org.onap.so.db.request.data.repository.ResourceOperationStatusRepository;
46 import org.onap.so.requestsdb.RequestsDbConstant;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49 import org.springframework.beans.factory.annotation.Autowired;
50 import org.springframework.context.annotation.Primary;
51 import org.springframework.data.domain.Example;
52 import org.springframework.stereotype.Component;
60 * @version ONAP Amsterdam Release 2017-08-28
64 public class VfcManager {
66 private static final Logger LOGGER = LoggerFactory.getLogger(VfcManager.class);
71 private Map<String, String> nfvoUrlMap;
74 private ResourceOperationStatusRepository resourceOperationStatusRepository;
77 private RestfulUtil restfulUtil;
81 nfvoUrlMap = new HashMap<>();
82 nfvoUrlMap.put(Step.CREATE, CommonConstant.NFVO_CREATE_URL);
83 nfvoUrlMap.put(Step.INSTANTIATE, CommonConstant.NFVO_INSTANTIATE_URL);
84 nfvoUrlMap.put(Step.TERMINATE, CommonConstant.NFVO_TERMINATE_URL);
85 nfvoUrlMap.put(Step.DELETE, CommonConstant.NFVO_DELETE_URL);
86 nfvoUrlMap.put(Step.QUERY, CommonConstant.NFVO_QUERY_URL);
87 nfvoUrlMap.put(Step.SCALE, CommonConstant.NFVO_SCALE_URL);
91 * create network service <br>
93 * @param segInput input parameters for current node from http request
95 * @since ONAP Amsterdam Release
97 public RestfulResponse createNs(NSResourceInputParameter segInput) throws ApplicationException {
99 // Step1: get service template by node type
100 String csarId = segInput.getNsServiceModelUUID();
101 // nsdId for NFVO is "id" in the response, while for SDNO is "servcice template id"
102 LOGGER.info("serviceTemplateId is {}, id is {}", csarId, csarId);
104 LOGGER.info("create ns -> begin");
105 // Step2: Prepare url and method type
106 String url = getUrl(null, CommonConstant.Step.CREATE);
107 String methodType = CommonConstant.MethodType.POST;
109 // Step3: Prepare restful parameters and options
110 NsCreateReq oRequest = new NsCreateReq();
111 oRequest.setCsarId(csarId);
112 oRequest.setNsName(segInput.getNsServiceName());
113 oRequest.setDescription(segInput.getNsServiceDescription());
114 CustomerModel context = new CustomerModel();
115 context.setGlobalCustomerId(segInput.getNsOperationKey().getGlobalSubscriberId());
116 context.setServiceType(segInput.getNsOperationKey().getServiceType());
117 oRequest.setContext(context);
118 String createReq = JsonUtil.marshal(oRequest);
120 // Step4: Call NFVO or SDNO lcm to create ns
121 RestfulResponse createRsp = restfulUtil.send(url, methodType, createReq);
122 ValidateUtil.assertObjectNotNull(createRsp);
123 LOGGER.info("create ns response status is : {}", createRsp.getStatus());
124 LOGGER.info("create ns response content is : {}", createRsp.getResponseContent());
126 // Step 5: save resource operation information
127 ResourceOperationStatus status = new ResourceOperationStatus(segInput.getNsOperationKey().getServiceId(),
128 segInput.getNsOperationKey().getOperationId(), segInput.getNsOperationKey().getNodeTemplateUUID());
129 status.setStatus(RequestsDbConstant.Status.PROCESSING);
130 status = resourceOperationStatusRepository.save(status);
131 if (!HttpCode.isSucess(createRsp.getStatus())) {
132 LOGGER.error("update segment operation status : fail to create ns");
133 status.setProgress("40");
134 status.setStatusDescription("NS is created");
135 status.setStatus(RequestsDbConstant.Status.ERROR);
136 status.setErrorCode(String.valueOf(createRsp.getStatus()));
137 resourceOperationStatusRepository.save(status);
138 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_CREATE_NS);
140 @SuppressWarnings("unchecked")
141 Map<String, String> rsp = JsonUtil.unMarshal(createRsp.getResponseContent(), Map.class);
142 String nsInstanceId = rsp.get(CommonConstant.NS_INSTANCE_ID);
143 if (ValidateUtil.isStrEmpty(nsInstanceId)) {
144 LOGGER.error("Invalid instanceId from create operation");
145 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
146 DriverExceptionID.INVALID_RESPONSEE_FROM_CREATE_OPERATION);
148 LOGGER.info("create ns -> end");
149 LOGGER.info("save segment and operaton info -> begin");
150 // Step 6: add relation between service and NS
151 AaiUtil.addRelation(segInput.getNsOperationKey().getGlobalSubscriberId(),
152 segInput.getNsOperationKey().getServiceType(), segInput.getNsOperationKey().getServiceId(),
154 LOGGER.info("save segment and operation info -> end");
159 * delete network service <br>
161 * @param nsOperationKey The operation key of the NS resource
162 * @param nsInstanceId The NS instance id
164 * @since ONAP Amsterdam Release
166 public RestfulResponse deleteNs(NsOperationKey nsOperationKey, String nsInstanceId) throws ApplicationException {
167 LOGGER.info("delete ns -> begin");
168 // Step1: prepare url and methodType
169 String url = getUrl(nsInstanceId, CommonConstant.Step.DELETE);
170 String methodType = CommonConstant.MethodType.DELETE;
172 // Step2: prepare restful parameters and options
173 RestfulResponse deleteRsp = restfulUtil.send(url, methodType, "");
174 ValidateUtil.assertObjectNotNull(deleteRsp);
175 LOGGER.info("delete ns response status is : {}", deleteRsp.getStatus());
176 LOGGER.info("delete ns response content is : {}", deleteRsp.getResponseContent());
177 LOGGER.info("delete ns -> end");
179 ResourceOperationStatus status = new ResourceOperationStatus(nsOperationKey.getServiceId(),
180 nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
181 if (!HttpCode.isSucess(deleteRsp.getStatus())) {
182 LOGGER.error("fail to delete ns");
184 status.setStatus(RequestsDbConstant.Status.ERROR);
185 status.setErrorCode(String.valueOf(deleteRsp.getStatus()));
186 status.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
187 resourceOperationStatusRepository.save(status);
188 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_DELETE_NS);
191 // Step3: remove relation info between service and ns
192 AaiUtil.removeRelation(nsOperationKey.getGlobalSubscriberId(), nsOperationKey.getServiceType(),
193 nsOperationKey.getServiceId(), nsInstanceId);
194 LOGGER.info("delete segment information -> end");
196 // Step4: update service segment operation status
197 status.setStatus(RequestsDbConstant.Status.FINISHED);
198 status.setErrorCode(String.valueOf(deleteRsp.getStatus()));
199 status.setProgress("100");
200 status.setStatusDescription("VFC resource deletion finished");
201 resourceOperationStatusRepository.save(status);
202 LOGGER.info("update segment operaton status for delete -> end");
209 * instantiate network service <br>
211 * @param nsInstanceId The NS instance id
212 * @param segInput input parameters for current node from http request
214 * @since ONAP Amsterdam Release
216 public RestfulResponse instantiateNs(String nsInstanceId, NSResourceInputParameter segInput)
217 throws ApplicationException {
218 // Call the NFVO or SDNO service to instantiate service
219 LOGGER.info("instantiate ns -> begin");
221 // Step1: Prepare restful parameters and options
222 NsInstantiateReq oRequest = new NsInstantiateReq();
223 oRequest.setNsInstanceId(nsInstanceId);
224 NsParameters nsParameters = segInput.getNsParameters();
225 oRequest.setLocationConstraints(nsParameters.getLocationConstraints());
226 oRequest.setAdditionalParamForNs(nsParameters.getAdditionalParamForNs());
227 String instReq = JsonUtil.marshal(oRequest);
228 // Step2: prepare url and
229 String url = getUrl(nsInstanceId, CommonConstant.Step.INSTANTIATE);
230 String methodType = CommonConstant.MethodType.POST;
232 RestfulResponse instRsp = restfulUtil.send(url, methodType, instReq);
233 ResourceOperationStatus status = new ResourceOperationStatus(segInput.getNsOperationKey().getServiceId(),
234 segInput.getNsOperationKey().getOperationId(), segInput.getNsOperationKey().getNodeTemplateUUID());
235 ValidateUtil.assertObjectNotNull(instRsp);
236 if (!HttpCode.isSucess(instRsp.getStatus())) {
237 LOGGER.error("update segment operation status : fail to instantiate ns");
238 status.setStatus(RequestsDbConstant.Status.ERROR);
239 status.setErrorCode(String.valueOf(instRsp.getStatus()));
240 status.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED);
241 resourceOperationStatusRepository.save(status);
242 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_INSTANTIATE_NS);
244 LOGGER.info("instantiate ns response status is : {}", instRsp.getStatus());
245 LOGGER.info("instantiate ns response content is : {}", instRsp.getResponseContent());
246 ValidateUtil.assertObjectNotNull(instRsp.getResponseContent());
247 @SuppressWarnings("unchecked")
248 Map<String, String> rsp = JsonUtil.unMarshal(instRsp.getResponseContent(), Map.class);
249 String jobId = rsp.get(CommonConstant.JOB_ID);
250 if (ValidateUtil.isStrEmpty(jobId)) {
251 LOGGER.error("Invalid jobId from instantiate operation");
252 status.setStatus(RequestsDbConstant.Status.ERROR);
253 status.setErrorCode(String.valueOf(instRsp.getStatus()));
254 status.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED);
255 resourceOperationStatusRepository.save(status);
256 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
257 DriverExceptionID.INVALID_RESPONSE_FROM_INSTANTIATE_OPERATION);
259 LOGGER.info("instantiate ns -> end");
260 // Step 3: update segment operation job id
261 LOGGER.info("update resource operation status job id -> begin");
262 status.setJobId(jobId);
263 status.setProgress("100");
264 status.setStatusDescription("NS initiation completed.");
265 resourceOperationStatusRepository.save(status);
266 LOGGER.info("update segment operation job id -> end");
272 * terminate network service <br>
274 * @param nsOperationKey The operation key for NS resource
275 * @param nsInstanceId The NS instance id
277 * @since ONAP Amsterdam Release
279 public RestfulResponse terminateNs(NsOperationKey nsOperationKey, String nsInstanceId) throws ApplicationException {
280 // Step1: save segment operation info for delete process
281 LOGGER.info("save segment operation for delete process");
282 ResourceOperationStatus status = new ResourceOperationStatus(nsOperationKey.getServiceId(),
283 nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
284 status.setStatus(RequestsDbConstant.Status.PROCESSING);
285 resourceOperationStatusRepository.save(status);
287 LOGGER.info("terminate ns -> begin");
288 // Step2: prepare url and method type
289 String url = getUrl(nsInstanceId, CommonConstant.Step.TERMINATE);
290 String methodType = CommonConstant.MethodType.POST;
292 // Step3: prepare restful parameters and options
293 Map<String, String> reqBody = new HashMap<>();
294 reqBody.put("nsInstanceId", nsInstanceId);
295 reqBody.put("terminationType", "graceful");
296 reqBody.put("gracefulTerminationTimeout", "60");
298 // Step4: Call the NFVO or SDNO service to terminate service
299 RestfulResponse terminateRsp = restfulUtil.send(url, methodType, JsonUtil.marshal(reqBody));
300 ValidateUtil.assertObjectNotNull(terminateRsp);
301 LOGGER.info("terminate ns response status is : {}", terminateRsp.getStatus());
302 LOGGER.info("terminate ns response content is : {}", terminateRsp.getResponseContent());
303 // Step 3: update segment operation
304 if (!HttpCode.isSucess(terminateRsp.getStatus())) {
305 LOGGER.error("fail to instantiate ns");
306 status.setStatus(RequestsDbConstant.Status.ERROR);
307 status.setErrorCode(String.valueOf(terminateRsp.getStatus()));
308 status.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
309 resourceOperationStatusRepository.save(status);
311 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_TERMINATE_NS);
313 @SuppressWarnings("unchecked")
314 Map<String, String> rsp = JsonUtil.unMarshal(terminateRsp.getResponseContent(), Map.class);
315 String jobId = rsp.get(CommonConstant.JOB_ID);
316 if (ValidateUtil.isStrEmpty(jobId)) {
317 LOGGER.error("Invalid jobId from terminate operation");
318 status.setStatus(RequestsDbConstant.Status.ERROR);
319 status.setErrorCode(String.valueOf(terminateRsp.getStatus()));
320 status.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED);
321 resourceOperationStatusRepository.save(status);
322 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
323 DriverExceptionID.INVALID_RESPONSE_FROM_TERMINATE_OPERATION);
325 LOGGER.info("terminate ns -> end");
327 LOGGER.info("update segment job id -> begin");
328 status.setProgress("60");
329 status.setStatusDescription("NS is termination completed");
330 status.setJobId(jobId);
331 resourceOperationStatusRepository.save(status);
332 LOGGER.info("update segment job id -> end");
338 * get ns progress by job Id <br>
340 * @param nsOperationKey The OperationKey for NS resource
341 * @param jobId the job id
343 * @since ONAP Amsterdam Release
345 public RestfulResponse getNsProgress(NsOperationKey nsOperationKey, String jobId) throws ApplicationException {
347 ValidateUtil.assertObjectNotNull(jobId);
348 // Step 1: query the current resource operation status
349 ResourceOperationStatus status = new ResourceOperationStatus(nsOperationKey.getServiceId(),
350 nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID());
351 status = resourceOperationStatusRepository.findOne(Example.of(status))
352 .orElseThrow(() -> new ApplicationException(404, "Cannot Find Operation Status"));
353 // Step 2: start query
354 LOGGER.info("query ns status -> begin");
355 String url = getUrl(jobId, CommonConstant.Step.QUERY);
356 String methodType = CommonConstant.MethodType.GET;
357 // prepare restful parameters and options
358 RestfulResponse rsp = restfulUtil.send(url, methodType, "");
359 ValidateUtil.assertObjectNotNull(rsp);
360 LOGGER.info("query ns progress response status is : {}", rsp.getStatus());
361 LOGGER.info("query ns progress response content is : {}", rsp.getResponseContent());
362 // Step 3:check the response staus
363 if (!HttpCode.isSucess(rsp.getStatus())) {
364 LOGGER.info("fail to query job status");
365 status.setErrorCode(String.valueOf(rsp.getStatus()));
366 status.setStatus(RequestsDbConstant.Status.ERROR);
367 status.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
368 resourceOperationStatusRepository.save(status);
369 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_QUERY_JOB_STATUS);
371 // Step 4: Process Network Service Instantiate Response
372 NsProgressStatus nsProgress = JsonUtil.unMarshal(rsp.getResponseContent(), NsProgressStatus.class);
373 ResponseDescriptor rspDesc = nsProgress.getResponseDescriptor();
374 // Step 5: update segment operation progress
376 status.setProgress(rspDesc.getProgress());
377 status.setStatusDescription(rspDesc.getStatusDescription());
378 resourceOperationStatusRepository.save(status);
380 // Step 6: update segment operation status
381 if (RequestsDbConstant.Progress.ONE_HUNDRED.equals(rspDesc.getProgress())
382 && RequestsDbConstant.Status.FINISHED.equals(rspDesc.getStatus())) {
383 LOGGER.info("job result is succeeded, operType is {}", status.getOperType());
384 status.setErrorCode(String.valueOf(rsp.getStatus()));
385 status.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
387 if (RequestsDbConstant.OperationType.CREATE.equalsIgnoreCase(status.getOperType())
388 || "createInstance".equalsIgnoreCase(status.getOperType())) {
389 status.setStatus(RequestsDbConstant.Status.FINISHED);
391 resourceOperationStatusRepository.save(status);
392 } else if (RequestsDbConstant.Status.ERROR.equals(rspDesc.getStatus())) {
393 LOGGER.error("job result is failed, operType is {}", status.getOperType());
394 status.setErrorCode(String.valueOf(rsp.getStatus()));
395 status.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED);
396 status.setStatus(RequestsDbConstant.Status.ERROR);
397 resourceOperationStatusRepository.save(status);
398 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.JOB_STATUS_ERROR);
400 LOGGER.error("unexcepted response status");
402 LOGGER.info("query ns status -> end");
408 * Scale NS instance <br>
410 * @param nsInstanceId The NS instance id
411 * @param segInput input parameters for current node from http request
413 * @since ONAP Amsterdam Release
415 public RestfulResponse scaleNs(String nsInstanceId, NSResourceInputParameter segInput) throws ApplicationException {
416 // Call the NFVO to scale service
417 LOGGER.info("scale ns -> begin");
419 // Step1: Prepare restful parameters and options
420 VFCScaleData oRequest = new VFCScaleData();
421 oRequest.setNsInstanceId(nsInstanceId);
422 NsScaleParameters nsScaleParameters = segInput.getNsScaleParameters();
423 oRequest.setScaleType(nsScaleParameters.getScaleType());
424 oRequest.setScaleNsData(nsScaleParameters.getScaleNsByStepsData());
425 String scaleReq = JsonUtil.marshal(oRequest);
427 // Step2: prepare url and method type
428 String url = getUrl(nsInstanceId, CommonConstant.Step.SCALE);
429 String methodType = CommonConstant.MethodType.POST;
430 LOGGER.info("scale ns request is {}", scaleReq);
431 // Step3: Call NFVO lcm to scale ns
432 RestfulResponse scaleRsp = restfulUtil.send(url, methodType, scaleReq);
434 ResourceOperationStatus status = new ResourceOperationStatus(segInput.getNsOperationKey().getServiceId(),
435 segInput.getNsOperationKey().getOperationId(), segInput.getNsOperationKey().getNodeTemplateUUID());
436 ResourceOperationStatus nsOperInfo = resourceOperationStatusRepository.findOne(Example.of(status))
437 .orElseThrow(() -> new ApplicationException(404, "Cannot Find Operation Status"));
438 ValidateUtil.assertObjectNotNull(scaleRsp);
439 if (!HttpCode.isSucess(scaleRsp.getStatus())) {
440 LOGGER.error("update segment operation status : fail to scale ns");
441 nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
442 nsOperInfo.setErrorCode(String.valueOf(scaleRsp.getStatus()));
443 nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.SCALE_NS_FAILED);
444 resourceOperationStatusRepository.save(nsOperInfo);
445 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_SCALE_NS);
447 LOGGER.info("scale ns response status is {}", scaleRsp.getStatus());
448 LOGGER.info("scale ns response content is {}", scaleRsp.getResponseContent());
450 ValidateUtil.assertObjectNotNull(scaleRsp.getResponseContent());
451 @SuppressWarnings("unchecked")
452 Map<String, String> rsp = JsonUtil.unMarshal(scaleRsp.getResponseContent(), Map.class);
453 String jobId = rsp.get(CommonConstant.JOB_ID);
454 if (ValidateUtil.isStrEmpty(jobId)) {
455 LOGGER.error("Invalid jobId from scale operation");
456 nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR);
457 nsOperInfo.setErrorCode(String.valueOf(scaleRsp.getStatus()));
458 nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.SCALE_NS_FAILED);
459 resourceOperationStatusRepository.save(nsOperInfo);
460 throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR,
461 DriverExceptionID.INVALID_RESPONSE_FROM_SCALE_OPERATION);
464 LOGGER.info("update resource operation status job id -> begin");
465 // Step 4: update segment operation job id
466 nsOperInfo.setJobId(jobId);
467 resourceOperationStatusRepository.save(nsOperInfo);
468 LOGGER.info("update segment operation job id -> end");
469 LOGGER.info("scale ns -> end");
475 * get url for the operation <br>
477 * @param variable variable should be put in the url
478 * @param step step of the operation (terminate,query,delete)
480 * @since ONAP Amsterdam Release
482 private String getUrl(String variable, String step) {
486 originalUrl = nfvoUrlMap.get(step);
487 url = String.format(originalUrl, variable);