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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.so.adapters.etsi.sol003.adapter.lcm.lifecycle;
24 import org.onap.aai.domain.yang.EsrVnfm;
25 import org.onap.aai.domain.yang.GenericVnf;
26 import org.onap.aai.domain.yang.Relationship;
27 import org.onap.etsi.sol003.adapter.lcm.v1.model.CreateVnfRequest;
28 import org.onap.etsi.sol003.adapter.lcm.v1.model.CreateVnfResponse;
29 import org.onap.etsi.sol003.adapter.lcm.v1.model.DeleteVnfResponse;
30 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.SdcPackageProvider;
31 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.aai.AaiHelper;
32 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.aai.AaiServiceProvider;
33 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.aai.OamIpAddressSource;
34 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.aai.OamIpAddressSource.OamIpAddressType;
35 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.VnfmHelper;
36 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.VnfmServiceProvider;
37 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.InlineResponse201;
38 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.InstantiateVnfRequest;
39 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.LccnSubscriptionRequest;
40 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.TerminateVnfRequest;
41 import org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.TerminateVnfRequest.TerminationTypeEnum;
42 import org.onap.so.adapters.etsi.sol003.adapter.lcm.jobmanagement.JobManager;
43 import org.onap.so.adapters.etsi.sol003.adapter.lcm.rest.exceptions.VnfNotFoundException;
44 import org.onap.so.adapters.etsi.sol003.adapter.lcm.rest.exceptions.VnfmNotFoundException;
45 import org.onap.so.adapters.etsi.sol003.adapter.lcm.rest.exceptions.VnfmRequestFailureException;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.stereotype.Component;
50 import com.google.common.base.Optional;
53 * Manages lifecycle operations towards the VNFMs.
56 public class LifecycleManager {
57 private static final Logger logger = LoggerFactory.getLogger(LifecycleManager.class);
58 private final AaiServiceProvider aaiServiceProvider;
59 private final VnfmServiceProvider vnfmServiceProvider;
60 private final AaiHelper aaiHelper;
61 private final VnfmHelper vnfmHelper;
62 private final JobManager jobManager;
63 private final SdcPackageProvider packageProvider;
66 LifecycleManager(final AaiServiceProvider aaiServiceProvider, final AaiHelper aaiHelper,
67 final VnfmHelper vnfmHelper, final VnfmServiceProvider vnfmServiceProvider, final JobManager jobManager,
68 final SdcPackageProvider packageProvider) {
69 this.aaiServiceProvider = aaiServiceProvider;
70 this.vnfmServiceProvider = vnfmServiceProvider;
71 this.aaiHelper = aaiHelper;
72 this.vnfmHelper = vnfmHelper;
73 this.jobManager = jobManager;
74 this.packageProvider = packageProvider;
78 * Create a VNF on a VNFM.
80 * @param vnfIdInAai the ID of the VNF in AAI
81 * @param request the create request
82 * @return the response to the request
84 public CreateVnfResponse createVnf(final String vnfIdInAai, final CreateVnfRequest request) {
85 GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
86 EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
87 checkIfVnfAlreadyExistsInVnfm(vnfm, genericVnf);
90 vnfm = aaiHelper.selectVnfm(genericVnf);
91 aaiServiceProvider.invokePutGenericVnfToVnfmRelationship(genericVnf, vnfm.getVnfmId());
93 final InlineResponse201 vnfmResponse = sendCreateRequestToVnfm(request, genericVnf, vnfIdInAai, vnfm);
95 logger.info("Create response: {}", vnfmResponse);
97 genericVnf.setSelflink(getSelfLink(vnfmResponse, vnfm));
99 GenericVnf genericVnfPatch = new GenericVnf();
100 genericVnfPatch.setVnfId(genericVnf.getVnfId());
101 genericVnfPatch.setSelflink(genericVnf.getSelflink());
102 aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
104 final String vnfIdInVnfm = vnfmResponse.getId();
106 final OamIpAddressSource oamIpAddressSource = extractOamIpAddressSource(request);
107 aaiHelper.setOamIpAddressSource(vnfIdInVnfm, oamIpAddressSource);
109 createNotificationSubscription(vnfm, vnfIdInVnfm);
110 final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request);
112 final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, false);
113 final CreateVnfResponse response = new CreateVnfResponse();
114 response.setJobId(jobId);
118 private String getSelfLink(final InlineResponse201 vnfmResponse, final EsrVnfm vnfm) {
119 if (vnfmResponse.getLinks() != null && vnfmResponse.getLinks().getSelf() != null
120 && vnfmResponse.getLinks().getSelf().getHref() != null) {
121 return vnfmResponse.getLinks().getSelf().getHref();
123 return vnfm.getEsrSystemInfoList().getEsrSystemInfo().iterator().next().getServiceUrl() + "/vnf_instances/"
124 + vnfmResponse.getId();
127 private OamIpAddressSource extractOamIpAddressSource(final CreateVnfRequest request) {
128 final Map<String, String> additionalParams = request.getAdditionalParams();
130 final String sourceType = additionalParams.remove("oamIpAddressSourceType");
131 final String sourceValue = additionalParams.remove("oamIpAddressSourceValue");
132 final OamIpAddressType oamIpAddressType = OamIpAddressType.valueOf(sourceType.toUpperCase());
133 return new OamIpAddressSource(oamIpAddressType, sourceValue);
134 } catch (final NullPointerException | IllegalArgumentException exception) {
135 logger.debug("Additional Params not set for OAM IP address source", exception);
140 private void checkIfVnfAlreadyExistsInVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) {
141 if (genericVnf.getSelflink() != null && !genericVnf.getSelflink().isEmpty() && vnfm != null) {
142 Optional<InlineResponse201> response = Optional.absent();
144 response = vnfmServiceProvider.getVnf(vnfm, genericVnf.getSelflink());
145 } catch (final Exception exception) {
146 logger.debug("Ignoring invalid self link in generic vnf", exception);
148 if (response.isPresent()) {
149 throw new IllegalArgumentException("VNF " + genericVnf.getVnfId()
150 + " is already defined on the VNFM, self link: " + genericVnf.getSelflink());
155 private InlineResponse201 sendCreateRequestToVnfm(final CreateVnfRequest aaiRequest, final GenericVnf genericVnf,
156 final String vnfIdInAai, final EsrVnfm vnfm) {
157 logger.debug("Sending a create request to SVNFM " + aaiRequest);
158 final org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.CreateVnfRequest vnfmRequest =
159 new org.onap.so.adapters.etsi.sol003.adapter.lcm.extclients.vnfm.model.CreateVnfRequest();
161 final String vnfdId = packageProvider.getVnfdId(genericVnf.getModelVersionId());
162 vnfmRequest.setVnfdId(vnfdId);
163 vnfmRequest.setVnfInstanceName(aaiRequest.getName().replaceAll(" ", "_"));
164 vnfmRequest.setVnfInstanceDescription(vnfIdInAai);
166 final Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfm, vnfmRequest);
169 return optionalResponse.get();
170 } catch (final Exception exception) {
171 final String errorMessage = "Unable to return response from VNFM";
172 logger.error(errorMessage, exception);
173 throw new VnfmRequestFailureException(errorMessage, exception);
177 private void createNotificationSubscription(final EsrVnfm vnfm, final String vnfId) {
179 final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId);
180 vnfmServiceProvider.subscribeForNotifications(vnfm, subscriptionRequest);
181 } catch (final Exception exception) {
182 logger.warn("Subscription for notifications to VNFM: " + vnfm.getVnfmId() + " for VNF " + vnfId
183 + " failed. AAI will not be updated unless the VNFM is configured by other means to send notifications relating to this VNF",
188 private String sendInstantiateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf,
189 final CreateVnfRequest createVnfRequest) {
191 final InstantiateVnfRequest instantiateVnfRequest =
192 vnfmHelper.createInstantiateRequest(createVnfRequest.getTenant(), createVnfRequest,
193 packageProvider.getFlavourId(genericVnf.getModelVersionId()));
194 final String jobId = vnfmServiceProvider.instantiateVnf(vnfm, genericVnf.getSelflink(), instantiateVnfRequest);
196 logger.info("Instantiate VNF request successfully sent to " + genericVnf.getSelflink());
201 * Delete a VNF on a VNFM.
203 * @param vnfIdInAai the ID of the VNF in AAI
204 * @return the response to the request
206 public DeleteVnfResponse deleteVnf(final String vnfIdInAai) {
207 final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
208 final EsrVnfm vnfm = getAssignedVnfm(genericVnf);
210 final String operationId = sendTerminateRequestToVnfm(vnfm, genericVnf);
212 if (operationId.equals(JobManager.ALREADY_COMPLETED_OPERATION_ID)) {
213 sendDeleteRequestToVnfm(genericVnf);
215 final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, true);
217 return new DeleteVnfResponse().jobId(jobId);
220 private String sendTerminateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) {
221 final TerminateVnfRequest terminateVnfRequest = new TerminateVnfRequest();
222 terminateVnfRequest.setTerminationType(TerminationTypeEnum.FORCEFUL);
223 return vnfmServiceProvider.terminateVnf(vnfm, genericVnf.getSelflink(), terminateVnfRequest);
226 private GenericVnf getGenericVnfFromAai(final String vnfIdInAai) {
227 final GenericVnf genericVnf = aaiServiceProvider.invokeGetGenericVnf(vnfIdInAai);
228 if (genericVnf == null) {
229 throw new VnfNotFoundException("VNF not found in AAI: " + vnfIdInAai);
231 logger.debug("Retrieved generic VNF from AAI: " + genericVnf);
235 private EsrVnfm getAssignedVnfm(final GenericVnf genericVnf) {
236 final EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
238 throw new VnfmNotFoundException("No VNFM found in AAI for VNF " + genericVnf.getVnfId());
243 private void sendDeleteRequestToVnfm(final GenericVnf genericVnf) {
245 vnfmServiceProvider.deleteVnf(aaiHelper.getAssignedVnfm(genericVnf), genericVnf.getSelflink());
247 final GenericVnf genericVnfPatch = new GenericVnf();
248 genericVnfPatch.setVnfId(genericVnf.getVnfId());
249 genericVnfPatch.setOrchestrationStatus("Assigned");
250 genericVnfPatch.setSelflink("");
251 aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
253 for (final Relationship relationship : genericVnf.getRelationshipList().getRelationship()) {
254 if (relationship.getRelatedTo().equals("vserver")) {
255 aaiServiceProvider.invokeDeleteVserver(
256 aaiHelper.getRelationshipData(relationship, "cloud-region.cloud-owner"),
257 aaiHelper.getRelationshipData(relationship, "cloud-region.cloud-region-id"),
258 aaiHelper.getRelationshipData(relationship, "tenant.tenant-id"),
259 aaiHelper.getRelationshipData(relationship, "vserver.vserver-id"));