/*- * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= */ package org.onap.so.adapters.vfc.rest; import java.util.HashMap; import java.util.Map; import org.onap.so.adapters.vfc.constant.CommonConstant; import org.onap.so.adapters.vfc.constant.CommonConstant.Step; import org.onap.so.adapters.vfc.constant.DriverExceptionID; import org.onap.so.adapters.vfc.constant.HttpCode; import org.onap.so.adapters.vfc.exceptions.ApplicationException; import org.onap.so.adapters.vfc.model.CustomerModel; import org.onap.so.adapters.vfc.model.NSResourceInputParameter; import org.onap.so.adapters.vfc.model.NsCreateReq; import org.onap.so.adapters.vfc.model.NsInstantiateReq; import org.onap.so.adapters.vfc.model.NsOperationKey; import org.onap.so.adapters.vfc.model.NsParameters; import org.onap.so.adapters.vfc.model.NsProgressStatus; import org.onap.so.adapters.vfc.model.NsScaleParameters; import org.onap.so.adapters.vfc.model.ResponseDescriptor; import org.onap.so.adapters.vfc.model.RestfulResponse; import org.onap.so.adapters.vfc.model.VFCScaleData; import org.onap.so.adapters.vfc.util.JsonUtil; import org.onap.so.adapters.vfc.util.RestfulUtil; import org.onap.so.adapters.vfc.util.ValidateUtil; import org.onap.so.db.request.beans.ResourceOperationStatus; import org.onap.so.db.request.data.repository.ResourceOperationStatusRepository; import org.onap.so.requestsdb.RequestsDbConstant; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.data.domain.Example; import org.springframework.stereotype.Component; /** * VF-C Manager
*

*

* * @author * @version ONAP Amsterdam Release 2017-08-28 */ @Component @Primary public class VfcManager { private static final Logger LOGGER = LoggerFactory.getLogger(VfcManager.class); /** * nfvo url map */ private Map nfvoUrlMap; @Autowired private ResourceOperationStatusRepository resourceOperationStatusRepository; @Autowired private RestfulUtil restfulUtil; public VfcManager() { nfvoUrlMap = new HashMap<>(); nfvoUrlMap.put(Step.CREATE, CommonConstant.NFVO_CREATE_URL); nfvoUrlMap.put(Step.INSTANTIATE, CommonConstant.NFVO_INSTANTIATE_URL); nfvoUrlMap.put(Step.TERMINATE, CommonConstant.NFVO_TERMINATE_URL); nfvoUrlMap.put(Step.DELETE, CommonConstant.NFVO_DELETE_URL); nfvoUrlMap.put(Step.QUERY, CommonConstant.NFVO_QUERY_URL); nfvoUrlMap.put(Step.SCALE, CommonConstant.NFVO_SCALE_URL); } /** * create network service
* * @param segInput input parameters for current node from http request * @return * @since ONAP Amsterdam Release */ public RestfulResponse createNs(NSResourceInputParameter segInput) throws ApplicationException { // Step1: get service template by node type String csarId = segInput.getNsServiceModelUUID(); // nsdId for NFVO is "id" in the response, while for SDNO is "servcice template id" LOGGER.info("serviceTemplateId is {}, id is {}", csarId, csarId); LOGGER.info("create ns -> begin"); // Step2: Prepare url and method type String url = getUrl(null, CommonConstant.Step.CREATE); String methodType = CommonConstant.MethodType.POST; // Step3: Prepare restful parameters and options NsCreateReq oRequest = new NsCreateReq(); oRequest.setCsarId(csarId); oRequest.setNsName(segInput.getNsServiceName()); oRequest.setDescription(segInput.getNsServiceDescription()); CustomerModel context = new CustomerModel(); context.setGlobalCustomerId(segInput.getNsOperationKey().getGlobalSubscriberId()); context.setServiceType(segInput.getNsOperationKey().getServiceType()); oRequest.setContext(context); String createReq = JsonUtil.marshal(oRequest); // Step4: Call NFVO or SDNO lcm to create ns RestfulResponse createRsp = restfulUtil.send(url, methodType, createReq); ValidateUtil.assertObjectNotNull(createRsp); LOGGER.info("create ns response status is : {}", createRsp.getStatus()); LOGGER.info("create ns response content is : {}", createRsp.getResponseContent()); // Step 5: save resource operation information ResourceOperationStatus status = new ResourceOperationStatus(segInput.getNsOperationKey().getServiceId(), segInput.getNsOperationKey().getOperationId(), segInput.getNsOperationKey().getNodeTemplateUUID()); status.setStatus(RequestsDbConstant.Status.PROCESSING); status = resourceOperationStatusRepository.save(status); if (!HttpCode.isSucess(createRsp.getStatus())) { LOGGER.error("update segment operation status : fail to create ns"); status.setProgress("40"); status.setStatusDescription("NS is created"); status.setStatus(RequestsDbConstant.Status.ERROR); status.setErrorCode(String.valueOf(createRsp.getStatus())); resourceOperationStatusRepository.save(status); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_CREATE_NS); } @SuppressWarnings("unchecked") Map rsp = JsonUtil.unMarshal(createRsp.getResponseContent(), Map.class); String nsInstanceId = rsp.get(CommonConstant.NS_INSTANCE_ID); if (ValidateUtil.isStrEmpty(nsInstanceId)) { LOGGER.error("Invalid instanceId from create operation"); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.INVALID_RESPONSEE_FROM_CREATE_OPERATION); } LOGGER.info("create ns -> end"); LOGGER.info("save segment and operaton info -> begin"); // Step 6: add relation between service and NS AaiUtil.addRelation(segInput.getNsOperationKey().getGlobalSubscriberId(), segInput.getNsOperationKey().getServiceType(), segInput.getNsOperationKey().getServiceId(), nsInstanceId); LOGGER.info("save segment and operation info -> end"); return createRsp; } /** * delete network service
* * @param nsOperationKey The operation key of the NS resource * @param nsInstanceId The NS instance id * @return * @since ONAP Amsterdam Release */ public RestfulResponse deleteNs(NsOperationKey nsOperationKey, String nsInstanceId) throws ApplicationException { LOGGER.info("delete ns -> begin"); // Step1: prepare url and methodType String url = getUrl(nsInstanceId, CommonConstant.Step.DELETE); String methodType = CommonConstant.MethodType.DELETE; // Step2: prepare restful parameters and options RestfulResponse deleteRsp = restfulUtil.send(url, methodType, ""); ValidateUtil.assertObjectNotNull(deleteRsp); LOGGER.info("delete ns response status is : {}", deleteRsp.getStatus()); LOGGER.info("delete ns response content is : {}", deleteRsp.getResponseContent()); LOGGER.info("delete ns -> end"); ResourceOperationStatus status = new ResourceOperationStatus(nsOperationKey.getServiceId(), nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID()); if (!HttpCode.isSucess(deleteRsp.getStatus())) { LOGGER.error("fail to delete ns"); status.setStatus(RequestsDbConstant.Status.ERROR); status.setErrorCode(String.valueOf(deleteRsp.getStatus())); status.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED); resourceOperationStatusRepository.save(status); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_DELETE_NS); } // Step3: remove relation info between service and ns AaiUtil.removeRelation(nsOperationKey.getGlobalSubscriberId(), nsOperationKey.getServiceType(), nsOperationKey.getServiceId(), nsInstanceId); LOGGER.info("delete segment information -> end"); // Step4: update service segment operation status status.setStatus(RequestsDbConstant.Status.FINISHED); status.setErrorCode(String.valueOf(deleteRsp.getStatus())); status.setProgress("100"); status.setStatusDescription("VFC resource deletion finished"); resourceOperationStatusRepository.save(status); LOGGER.info("update segment operaton status for delete -> end"); return deleteRsp; } /** * instantiate network service
* * @param nsInstanceId The NS instance id * @param segInput input parameters for current node from http request * @return * @since ONAP Amsterdam Release */ public RestfulResponse instantiateNs(String nsInstanceId, NSResourceInputParameter segInput) throws ApplicationException { // Call the NFVO or SDNO service to instantiate service LOGGER.info("instantiate ns -> begin"); // Step1: Prepare restful parameters and options NsInstantiateReq oRequest = new NsInstantiateReq(); oRequest.setNsInstanceId(nsInstanceId); NsParameters nsParameters = segInput.getNsParameters(); oRequest.setLocationConstraints(nsParameters.getLocationConstraints()); oRequest.setAdditionalParamForNs(nsParameters.getAdditionalParamForNs()); String instReq = JsonUtil.marshal(oRequest); // Step2: prepare url and String url = getUrl(nsInstanceId, CommonConstant.Step.INSTANTIATE); String methodType = CommonConstant.MethodType.POST; RestfulResponse instRsp = restfulUtil.send(url, methodType, instReq); ResourceOperationStatus status = new ResourceOperationStatus(segInput.getNsOperationKey().getServiceId(), segInput.getNsOperationKey().getOperationId(), segInput.getNsOperationKey().getNodeTemplateUUID()); ValidateUtil.assertObjectNotNull(instRsp); if (!HttpCode.isSucess(instRsp.getStatus())) { LOGGER.error("update segment operation status : fail to instantiate ns"); status.setStatus(RequestsDbConstant.Status.ERROR); status.setErrorCode(String.valueOf(instRsp.getStatus())); status.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED); resourceOperationStatusRepository.save(status); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_INSTANTIATE_NS); } LOGGER.info("instantiate ns response status is : {}", instRsp.getStatus()); LOGGER.info("instantiate ns response content is : {}", instRsp.getResponseContent()); ValidateUtil.assertObjectNotNull(instRsp.getResponseContent()); @SuppressWarnings("unchecked") Map rsp = JsonUtil.unMarshal(instRsp.getResponseContent(), Map.class); String jobId = rsp.get(CommonConstant.JOB_ID); if (ValidateUtil.isStrEmpty(jobId)) { LOGGER.error("Invalid jobId from instantiate operation"); status.setStatus(RequestsDbConstant.Status.ERROR); status.setErrorCode(String.valueOf(instRsp.getStatus())); status.setStatusDescription(CommonConstant.StatusDesc.INSTANTIATE_NS_FAILED); resourceOperationStatusRepository.save(status); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.INVALID_RESPONSE_FROM_INSTANTIATE_OPERATION); } LOGGER.info("instantiate ns -> end"); // Step 3: update segment operation job id LOGGER.info("update resource operation status job id -> begin"); status.setJobId(jobId); status.setProgress("100"); status.setStatusDescription("NS initiation completed."); resourceOperationStatusRepository.save(status); LOGGER.info("update segment operation job id -> end"); return instRsp; } /** * terminate network service
* * @param nsOperationKey The operation key for NS resource * @param nsInstanceId The NS instance id * @return * @since ONAP Amsterdam Release */ public RestfulResponse terminateNs(NsOperationKey nsOperationKey, String nsInstanceId) throws ApplicationException { // Step1: save segment operation info for delete process LOGGER.info("save segment operation for delete process"); ResourceOperationStatus status = new ResourceOperationStatus(nsOperationKey.getServiceId(), nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID()); status.setStatus(RequestsDbConstant.Status.PROCESSING); resourceOperationStatusRepository.save(status); LOGGER.info("terminate ns -> begin"); // Step2: prepare url and method type String url = getUrl(nsInstanceId, CommonConstant.Step.TERMINATE); String methodType = CommonConstant.MethodType.POST; // Step3: prepare restful parameters and options Map reqBody = new HashMap<>(); reqBody.put("nsInstanceId", nsInstanceId); reqBody.put("terminationType", "graceful"); reqBody.put("gracefulTerminationTimeout", "60"); // Step4: Call the NFVO or SDNO service to terminate service RestfulResponse terminateRsp = restfulUtil.send(url, methodType, JsonUtil.marshal(reqBody)); ValidateUtil.assertObjectNotNull(terminateRsp); LOGGER.info("terminate ns response status is : {}", terminateRsp.getStatus()); LOGGER.info("terminate ns response content is : {}", terminateRsp.getResponseContent()); // Step 3: update segment operation if (!HttpCode.isSucess(terminateRsp.getStatus())) { LOGGER.error("fail to instantiate ns"); status.setStatus(RequestsDbConstant.Status.ERROR); status.setErrorCode(String.valueOf(terminateRsp.getStatus())); status.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED); resourceOperationStatusRepository.save(status); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_TERMINATE_NS); } @SuppressWarnings("unchecked") Map rsp = JsonUtil.unMarshal(terminateRsp.getResponseContent(), Map.class); String jobId = rsp.get(CommonConstant.JOB_ID); if (ValidateUtil.isStrEmpty(jobId)) { LOGGER.error("Invalid jobId from terminate operation"); status.setStatus(RequestsDbConstant.Status.ERROR); status.setErrorCode(String.valueOf(terminateRsp.getStatus())); status.setStatusDescription(CommonConstant.StatusDesc.TERMINATE_NS_FAILED); resourceOperationStatusRepository.save(status); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.INVALID_RESPONSE_FROM_TERMINATE_OPERATION); } LOGGER.info("terminate ns -> end"); LOGGER.info("update segment job id -> begin"); status.setProgress("60"); status.setStatusDescription("NS is termination completed"); status.setJobId(jobId); resourceOperationStatusRepository.save(status); LOGGER.info("update segment job id -> end"); return terminateRsp; } /** * get ns progress by job Id
* * @param nsOperationKey The OperationKey for NS resource * @param jobId the job id * @return * @since ONAP Amsterdam Release */ public RestfulResponse getNsProgress(NsOperationKey nsOperationKey, String jobId) throws ApplicationException { ValidateUtil.assertObjectNotNull(jobId); // Step 1: query the current resource operation status ResourceOperationStatus status = new ResourceOperationStatus(nsOperationKey.getServiceId(), nsOperationKey.getOperationId(), nsOperationKey.getNodeTemplateUUID()); status = resourceOperationStatusRepository.findOne(Example.of(status)) .orElseThrow(() -> new ApplicationException(404, "Cannot Find Operation Status")); // Step 2: start query LOGGER.info("query ns status -> begin"); String url = getUrl(jobId, CommonConstant.Step.QUERY); String methodType = CommonConstant.MethodType.GET; // prepare restful parameters and options RestfulResponse rsp = restfulUtil.send(url, methodType, ""); ValidateUtil.assertObjectNotNull(rsp); LOGGER.info("query ns progress response status is : {}", rsp.getStatus()); LOGGER.info("query ns progress response content is : {}", rsp.getResponseContent()); // Step 3:check the response staus if (!HttpCode.isSucess(rsp.getStatus())) { LOGGER.info("fail to query job status"); status.setErrorCode(String.valueOf(rsp.getStatus())); status.setStatus(RequestsDbConstant.Status.ERROR); status.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED); resourceOperationStatusRepository.save(status); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_QUERY_JOB_STATUS); } // Step 4: Process Network Service Instantiate Response NsProgressStatus nsProgress = JsonUtil.unMarshal(rsp.getResponseContent(), NsProgressStatus.class); ResponseDescriptor rspDesc = nsProgress.getResponseDescriptor(); // Step 5: update segment operation progress status.setProgress(rspDesc.getProgress()); status.setStatusDescription(rspDesc.getStatusDescription()); resourceOperationStatusRepository.save(status); // Step 6: update segment operation status if (RequestsDbConstant.Progress.ONE_HUNDRED.equals(rspDesc.getProgress()) && RequestsDbConstant.Status.FINISHED.equals(rspDesc.getStatus())) { LOGGER.info("job result is succeeded, operType is {}", status.getOperType()); status.setErrorCode(String.valueOf(rsp.getStatus())); status.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED); if (RequestsDbConstant.OperationType.CREATE.equalsIgnoreCase(status.getOperType()) || "createInstance".equalsIgnoreCase(status.getOperType())) { status.setStatus(RequestsDbConstant.Status.FINISHED); } resourceOperationStatusRepository.save(status); } else if (RequestsDbConstant.Status.ERROR.equals(rspDesc.getStatus())) { LOGGER.error("job result is failed, operType is {}", status.getOperType()); status.setErrorCode(String.valueOf(rsp.getStatus())); status.setStatusDescription(CommonConstant.StatusDesc.QUERY_JOB_STATUS_FAILED); status.setStatus(RequestsDbConstant.Status.ERROR); resourceOperationStatusRepository.save(status); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.JOB_STATUS_ERROR); } else { LOGGER.error("unexcepted response status"); } LOGGER.info("query ns status -> end"); return rsp; } /** * Scale NS instance
* * @param nsInstanceId The NS instance id * @param segInput input parameters for current node from http request * @return * @since ONAP Amsterdam Release */ public RestfulResponse scaleNs(String nsInstanceId, NSResourceInputParameter segInput) throws ApplicationException { // Call the NFVO to scale service LOGGER.info("scale ns -> begin"); // Step1: Prepare restful parameters and options VFCScaleData oRequest = new VFCScaleData(); oRequest.setNsInstanceId(nsInstanceId); NsScaleParameters nsScaleParameters = segInput.getNsScaleParameters(); oRequest.setScaleType(nsScaleParameters.getScaleType()); oRequest.setScaleNsData(nsScaleParameters.getScaleNsByStepsData()); String scaleReq = JsonUtil.marshal(oRequest); // Step2: prepare url and method type String url = getUrl(nsInstanceId, CommonConstant.Step.SCALE); String methodType = CommonConstant.MethodType.POST; LOGGER.info("scale ns request is {}", scaleReq); // Step3: Call NFVO lcm to scale ns RestfulResponse scaleRsp = restfulUtil.send(url, methodType, scaleReq); ResourceOperationStatus status = new ResourceOperationStatus(segInput.getNsOperationKey().getServiceId(), segInput.getNsOperationKey().getOperationId(), segInput.getNsOperationKey().getNodeTemplateUUID()); ResourceOperationStatus nsOperInfo = resourceOperationStatusRepository.findOne(Example.of(status)) .orElseThrow(() -> new ApplicationException(404, "Cannot Find Operation Status")); ValidateUtil.assertObjectNotNull(scaleRsp); if (!HttpCode.isSucess(scaleRsp.getStatus())) { LOGGER.error("update segment operation status : fail to scale ns"); nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR); nsOperInfo.setErrorCode(String.valueOf(scaleRsp.getStatus())); nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.SCALE_NS_FAILED); resourceOperationStatusRepository.save(nsOperInfo); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.FAIL_TO_SCALE_NS); } LOGGER.info("scale ns response status is {}", scaleRsp.getStatus()); LOGGER.info("scale ns response content is {}", scaleRsp.getResponseContent()); ValidateUtil.assertObjectNotNull(scaleRsp.getResponseContent()); @SuppressWarnings("unchecked") Map rsp = JsonUtil.unMarshal(scaleRsp.getResponseContent(), Map.class); String jobId = rsp.get(CommonConstant.JOB_ID); if (ValidateUtil.isStrEmpty(jobId)) { LOGGER.error("Invalid jobId from scale operation"); nsOperInfo.setStatus(RequestsDbConstant.Status.ERROR); nsOperInfo.setErrorCode(String.valueOf(scaleRsp.getStatus())); nsOperInfo.setStatusDescription(CommonConstant.StatusDesc.SCALE_NS_FAILED); resourceOperationStatusRepository.save(nsOperInfo); throw new ApplicationException(HttpCode.INTERNAL_SERVER_ERROR, DriverExceptionID.INVALID_RESPONSE_FROM_SCALE_OPERATION); } LOGGER.info("update resource operation status job id -> begin"); // Step 4: update segment operation job id nsOperInfo.setJobId(jobId); resourceOperationStatusRepository.save(nsOperInfo); LOGGER.info("update segment operation job id -> end"); LOGGER.info("scale ns -> end"); return scaleRsp; } /** * get url for the operation
* * @param variable variable should be put in the url * @param step step of the operation (terminate,query,delete) * @return * @since ONAP Amsterdam Release */ private String getUrl(String variable, String step) { String url; String originalUrl; originalUrl = nfvoUrlMap.get(step); url = String.format(originalUrl, variable); return url; } }