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.etsisol003adapter.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.so.adapters.etsisol003adapter.lcm.extclients.EtsiPackageProvider;
28 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.AaiHelper;
29 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.AaiServiceProvider;
30 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.OamIpAddressSource;
31 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.OamIpAddressSource.OamIpAddressType;
32 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.VnfmHelper;
33 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.VnfmServiceProvider;
34 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.InlineResponse201;
35 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.InstantiateVnfRequest;
36 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.LccnSubscriptionRequest;
37 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.TerminateVnfRequest;
38 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.TerminateVnfRequest.TerminationTypeEnum;
39 import org.onap.so.adapters.etsisol003adapter.lcm.jobmanagement.JobManager;
40 import org.onap.so.adapters.etsisol003adapter.lcm.rest.exceptions.VnfNotFoundException;
41 import org.onap.so.adapters.etsisol003adapter.lcm.rest.exceptions.VnfmNotFoundException;
42 import org.onap.so.adapters.etsisol003adapter.lcm.rest.exceptions.VnfmRequestFailureException;
43 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfRequest;
44 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.CreateVnfResponse;
45 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.DeleteVnfResponse;
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;
51 import static org.apache.commons.lang3.StringUtils.isNotBlank;
54 * Manages lifecycle operations towards the VNFMs.
57 public class LifecycleManager {
58 private static final Logger logger = LoggerFactory.getLogger(LifecycleManager.class);
59 private final AaiServiceProvider aaiServiceProvider;
60 private final VnfmServiceProvider vnfmServiceProvider;
61 private final AaiHelper aaiHelper;
62 private final VnfmHelper vnfmHelper;
63 private final JobManager jobManager;
64 private final EtsiPackageProvider packageProvider;
67 LifecycleManager(final AaiServiceProvider aaiServiceProvider, final AaiHelper aaiHelper,
68 final VnfmHelper vnfmHelper, final VnfmServiceProvider vnfmServiceProvider, final JobManager jobManager,
69 final EtsiPackageProvider packageProvider) {
70 this.aaiServiceProvider = aaiServiceProvider;
71 this.vnfmServiceProvider = vnfmServiceProvider;
72 this.aaiHelper = aaiHelper;
73 this.vnfmHelper = vnfmHelper;
74 this.jobManager = jobManager;
75 this.packageProvider = packageProvider;
79 * Create a VNF on a VNFM.
81 * @param vnfIdInAai the ID of the VNF in AAI
82 * @param request the create request
83 * @return the response to the request
85 public CreateVnfResponse createVnf(final String vnfIdInAai, final CreateVnfRequest request) {
86 final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
87 EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
88 checkIfVnfAlreadyExistsInVnfm(vnfm, genericVnf);
91 vnfm = aaiHelper.selectVnfm(genericVnf);
92 aaiServiceProvider.invokePutGenericVnfToVnfmRelationship(genericVnf, vnfm.getVnfmId());
94 final InlineResponse201 vnfmResponse = sendCreateRequestToVnfm(request, genericVnf, vnfIdInAai, vnfm);
96 logger.info("Create response: {}", vnfmResponse);
98 genericVnf.setSelflink(getSelfLink(vnfmResponse, vnfm));
100 final GenericVnf genericVnfPatch = new GenericVnf();
101 genericVnfPatch.setVnfId(genericVnf.getVnfId());
102 genericVnfPatch.setSelflink(genericVnf.getSelflink());
103 aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
105 final String vnfIdInVnfm = vnfmResponse.getId();
107 final OamIpAddressSource oamIpAddressSource = extractOamIpAddressSource(request);
108 aaiHelper.setOamIpAddressSource(vnfIdInVnfm, oamIpAddressSource);
110 createNotificationSubscription(vnfm, vnfIdInVnfm);
111 final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request);
113 final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, false);
114 final CreateVnfResponse response = new CreateVnfResponse();
115 response.setJobId(jobId);
119 private String getSelfLink(final InlineResponse201 vnfmResponse, final EsrVnfm vnfm) {
120 if (vnfmResponse.getLinks() != null && vnfmResponse.getLinks().getSelf() != null
121 && vnfmResponse.getLinks().getSelf().getHref() != null) {
122 return vnfmResponse.getLinks().getSelf().getHref();
124 return vnfm.getEsrSystemInfoList().getEsrSystemInfo().iterator().next().getServiceUrl() + "/vnf_instances/"
125 + vnfmResponse.getId();
128 private OamIpAddressSource extractOamIpAddressSource(final CreateVnfRequest request) {
129 final Map<String, String> additionalParams = request.getAdditionalParams();
131 final String sourceType = additionalParams.remove("oamIpAddressSourceType");
132 final String sourceValue = additionalParams.remove("oamIpAddressSourceValue");
133 final OamIpAddressType oamIpAddressType = OamIpAddressType.valueOf(sourceType.toUpperCase());
134 return new OamIpAddressSource(oamIpAddressType, sourceValue);
135 } catch (final NullPointerException | IllegalArgumentException exception) {
136 logger.debug("Additional Params not set for OAM IP address source", exception);
141 private void checkIfVnfAlreadyExistsInVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) {
142 if (genericVnf.getSelflink() != null && !genericVnf.getSelflink().isEmpty() && vnfm != null) {
143 Optional<InlineResponse201> response = Optional.absent();
145 response = vnfmServiceProvider.getVnf(vnfm, genericVnf.getSelflink());
146 } catch (final Exception exception) {
147 logger.debug("Ignoring invalid self link in generic vnf", exception);
149 if (response.isPresent()) {
150 throw new IllegalArgumentException("VNF " + genericVnf.getVnfId()
151 + " is already defined on the VNFM, self link: " + genericVnf.getSelflink());
156 private InlineResponse201 sendCreateRequestToVnfm(final CreateVnfRequest createVnfRequest,
157 final GenericVnf genericVnf, final String vnfIdInAai, final EsrVnfm vnfm) {
158 logger.debug("Sending a create request to SVNFM {}", createVnfRequest);
159 final org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.CreateVnfRequest vnfmRequest =
160 new org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.CreateVnfRequest();
162 final String pkgId = getPackageId(createVnfRequest, genericVnf);
163 final String vnfdId = packageProvider.getVnfdId(pkgId);
164 vnfmRequest.setVnfdId(vnfdId);
165 vnfmRequest.setVnfInstanceName(createVnfRequest.getName().replaceAll(" ", "_"));
166 vnfmRequest.setVnfInstanceDescription(vnfIdInAai);
168 final Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfm, vnfmRequest);
171 return optionalResponse.get();
172 } catch (final Exception exception) {
173 final String errorMessage = "Unable to return response from VNFM";
174 logger.error(errorMessage, exception);
175 throw new VnfmRequestFailureException(errorMessage, exception);
179 private String getPackageId(final CreateVnfRequest createVnfRequest, final GenericVnf genericVnf) {
180 if (isNotBlank(createVnfRequest.getPkgId())) {
181 logger.info("Found createVnfRequest pkgId: {}", createVnfRequest.getPkgId());
182 return createVnfRequest.getPkgId();
184 logger.info("Found genericVnf modelVersionId: {}", genericVnf.getModelVersionId());
185 return genericVnf.getModelVersionId();
188 private void createNotificationSubscription(final EsrVnfm vnfm, final String vnfId) {
190 final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId);
191 vnfmServiceProvider.subscribeForNotifications(vnfm, subscriptionRequest);
192 } catch (final Exception exception) {
193 logger.warn("Subscription for notifications to VNFM: " + vnfm.getVnfmId() + " for VNF " + vnfId
194 + " failed. AAI will not be updated unless the VNFM is configured by other means to send notifications relating to this VNF",
199 private String sendInstantiateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf,
200 final CreateVnfRequest createVnfRequest) {
202 final InstantiateVnfRequest instantiateVnfRequest =
203 vnfmHelper.createInstantiateRequest(createVnfRequest.getTenant(), createVnfRequest,
204 packageProvider.getFlavourId(genericVnf.getModelVersionId()));
205 final String jobId = vnfmServiceProvider.instantiateVnf(vnfm, genericVnf.getSelflink(), instantiateVnfRequest);
207 logger.info("Instantiate VNF request successfully sent to " + genericVnf.getSelflink());
212 * Delete a VNF on a VNFM.
214 * @param vnfIdInAai the ID of the VNF in AAI
215 * @return the response to the request
217 public DeleteVnfResponse deleteVnf(final String vnfIdInAai) {
218 final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
219 final EsrVnfm vnfm = getAssignedVnfm(genericVnf);
221 final String operationId = sendTerminateRequestToVnfm(vnfm, genericVnf);
223 if (operationId.equals(JobManager.ALREADY_COMPLETED_OPERATION_ID)) {
224 sendDeleteRequestToVnfm(genericVnf);
226 final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, true);
228 return new DeleteVnfResponse().jobId(jobId);
231 private String sendTerminateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) {
232 final TerminateVnfRequest terminateVnfRequest = new TerminateVnfRequest();
233 terminateVnfRequest.setTerminationType(TerminationTypeEnum.FORCEFUL);
234 return vnfmServiceProvider.terminateVnf(vnfm, genericVnf.getSelflink(), terminateVnfRequest);
237 private GenericVnf getGenericVnfFromAai(final String vnfIdInAai) {
238 final GenericVnf genericVnf = aaiServiceProvider.invokeGetGenericVnf(vnfIdInAai);
239 if (genericVnf == null) {
240 throw new VnfNotFoundException("VNF not found in AAI: " + vnfIdInAai);
242 logger.debug("Retrieved generic VNF from AAI: " + genericVnf);
246 private EsrVnfm getAssignedVnfm(final GenericVnf genericVnf) {
247 final EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
249 throw new VnfmNotFoundException("No VNFM found in AAI for VNF " + genericVnf.getVnfId());
254 private void sendDeleteRequestToVnfm(final GenericVnf genericVnf) {
256 vnfmServiceProvider.deleteVnf(aaiHelper.getAssignedVnfm(genericVnf), genericVnf.getSelflink());
258 final GenericVnf genericVnfPatch = new GenericVnf();
259 genericVnfPatch.setVnfId(genericVnf.getVnfId());
260 genericVnfPatch.setOrchestrationStatus("Assigned");
261 genericVnfPatch.setSelflink("");
262 aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
264 for (final Relationship relationship : genericVnf.getRelationshipList().getRelationship()) {
265 if (relationship.getRelatedTo().equals("vserver")) {
266 aaiServiceProvider.invokeDeleteVserver(
267 aaiHelper.getRelationshipData(relationship, "cloud-region.cloud-owner"),
268 aaiHelper.getRelationshipData(relationship, "cloud-region.cloud-region-id"),
269 aaiHelper.getRelationshipData(relationship, "tenant.tenant-id"),
270 aaiHelper.getRelationshipData(relationship, "vserver.vserver-id"));