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.vnfmadapter.lifecycle;
23 import com.google.common.base.Optional;
25 import org.onap.aai.domain.yang.EsrVnfm;
26 import org.onap.aai.domain.yang.GenericVnf;
27 import org.onap.so.adapters.vnfmadapter.extclients.SdcPackageProvider;
28 import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiHelper;
29 import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiServiceProvider;
30 import org.onap.so.adapters.vnfmadapter.extclients.aai.OamIpAddressSource;
31 import org.onap.so.adapters.vnfmadapter.extclients.aai.OamIpAddressSource.OamIpAddressType;
32 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmHelper;
33 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmServiceProvider;
34 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201;
35 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest;
36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest;
37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest;
38 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest.TerminationTypeEnum;
39 import org.onap.so.adapters.vnfmadapter.jobmanagement.JobManager;
40 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfNotFoundException;
41 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmNotFoundException;
42 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmRequestFailureException;
43 import org.onap.vnfmadapter.v1.model.CreateVnfRequest;
44 import org.onap.vnfmadapter.v1.model.CreateVnfResponse;
45 import org.onap.vnfmadapter.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;
52 * Manages lifecycle operations towards the VNFMs.
55 public class LifecycleManager {
56 private static final Logger logger = LoggerFactory.getLogger(LifecycleManager.class);
57 private final AaiServiceProvider aaiServiceProvider;
58 private final VnfmServiceProvider vnfmServiceProvider;
59 private final AaiHelper aaiHelper;
60 private final VnfmHelper vnfmHelper;
61 private final JobManager jobManager;
62 private final SdcPackageProvider packageProvider;
65 LifecycleManager(final AaiServiceProvider aaiServiceProvider, final AaiHelper aaiHelper,
66 final VnfmHelper vnfmHelper, final VnfmServiceProvider vnfmServiceProvider, final JobManager jobManager,
67 final SdcPackageProvider packageProvider) {
68 this.aaiServiceProvider = aaiServiceProvider;
69 this.vnfmServiceProvider = vnfmServiceProvider;
70 this.aaiHelper = aaiHelper;
71 this.vnfmHelper = vnfmHelper;
72 this.jobManager = jobManager;
73 this.packageProvider = packageProvider;
77 * Create a VNF on a VNFM.
79 * @param vnfIdInAai the ID of the VNF in AAI
80 * @param request the create request
81 * @return the response to the request
83 public CreateVnfResponse createVnf(final String vnfIdInAai, final CreateVnfRequest request) {
84 final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
85 checkIfVnfAlreadyExistsInVnfm(genericVnf);
87 EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
89 vnfm = aaiHelper.selectVnfm(genericVnf);
90 aaiHelper.addRelationshipFromGenericVnfToVnfm(genericVnf, vnfm.getVnfmId());
92 aaiHelper.addRelationshipFromGenericVnfToTenant(genericVnf, request.getTenant());
93 final InlineResponse201 vnfmResponse =
94 sendCreateRequestToVnfm(request, genericVnf, vnfIdInAai, vnfm.getVnfmId());
96 logger.info("Create response: {}", vnfmResponse);
98 genericVnf.setSelflink(vnfmResponse.getLinks().getSelf().getHref());
99 aaiServiceProvider.invokePutGenericVnf(genericVnf);
100 final String vnfIdInVnfm = vnfmResponse.getId();
102 final OamIpAddressSource oamIpAddressSource = extractOamIpAddressSource(request);
103 aaiHelper.setOamIpAddressSource(vnfIdInVnfm, oamIpAddressSource);
105 createNotificationSubscription(vnfm.getVnfmId(), vnfIdInVnfm);
106 final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request, vnfIdInAai, vnfIdInVnfm);
108 final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, false);
109 final CreateVnfResponse response = new CreateVnfResponse();
110 response.setJobId(jobId);
114 private OamIpAddressSource extractOamIpAddressSource(final CreateVnfRequest request) {
115 final Map<String, String> additionalParams = request.getAdditionalParams();
117 final String sourceType = additionalParams.remove("oamIpAddressSourceType");
118 final String sourceValue = additionalParams.remove("oamIpAddressSourceValue");
119 final OamIpAddressType oamIpAddressType = OamIpAddressType.valueOf(sourceType.toUpperCase());
120 return new OamIpAddressSource(oamIpAddressType, sourceValue);
121 } catch (final NullPointerException | IllegalArgumentException exception) {
122 logger.debug("Additional Params not set for OAM IP address source", exception);
127 private void checkIfVnfAlreadyExistsInVnfm(final GenericVnf genericVnf) {
128 if (genericVnf.getSelflink() != null && !genericVnf.getSelflink().isEmpty()) {
129 Optional<InlineResponse201> response = Optional.absent();
131 response = vnfmServiceProvider.getVnf(genericVnf.getSelflink());
132 } catch (final Exception exception) {
133 logger.debug("Ignoring invalid self link in generic vnf", exception);
135 if (response.isPresent()) {
136 throw new IllegalArgumentException("VNF " + genericVnf.getVnfId()
137 + " is already defined on the VNFM, self link: " + genericVnf.getSelflink());
142 private InlineResponse201 sendCreateRequestToVnfm(final CreateVnfRequest aaiRequest, final GenericVnf genericVnf,
143 final String vnfIdInAai, final String vnfmId) {
144 logger.debug("Sending a create request to SVNFM " + aaiRequest);
145 final org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest vnfmRequest =
146 new org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest();
148 final String vnfdId = packageProvider.getVnfdId(genericVnf.getModelVersionId());
149 vnfmRequest.setVnfdId(vnfdId);
150 vnfmRequest.setVnfInstanceName(aaiRequest.getName().replaceAll(" ", "_"));
151 vnfmRequest.setVnfInstanceDescription(vnfIdInAai);
153 final Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfmId, vnfmRequest);
156 return optionalResponse.get();
157 } catch (final Exception exception) {
158 final String errorMessage = "Unable to return response from VNFM";
159 logger.error(errorMessage, exception);
160 throw new VnfmRequestFailureException(errorMessage, exception);
164 private void createNotificationSubscription(final String vnfmId, final String vnfId) {
166 final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId);
167 vnfmServiceProvider.subscribeForNotifications(vnfmId, subscriptionRequest);
168 } catch (final Exception exception) {
169 logger.warn("Subscription for notifications to VNFM: " + vnfmId + " for VNF " + vnfId
170 + " failed. AAI will not be updated unless the VNFM is configured by other means to send notifications relating to this VNF",
175 private String sendInstantiateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf,
176 final CreateVnfRequest createVnfRequest, final String vnfIdInAai, final String vnfIdInVnfm) {
178 final InstantiateVnfRequest instantiateVnfRequest =
179 vnfmHelper.createInstantiateRequest(createVnfRequest.getTenant(), createVnfRequest,
180 packageProvider.getFlavourId(genericVnf.getModelVersionId()));
181 final String jobId = vnfmServiceProvider.instantiateVnf(genericVnf.getSelflink(), instantiateVnfRequest);
183 logger.info("Instantiate VNF request successfully sent to " + genericVnf.getSelflink());
188 * Delete a VNF on a VNFM.
190 * @param vnfIdInAai the ID of the VNF in AAI
191 * @return the response to the request
193 public DeleteVnfResponse deleteVnf(final String vnfIdInAai) {
194 final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
195 final String vnfmId = getIdOfAssignedVnfm(genericVnf);
197 final String operationId = sendTerminateRequestToVnfm(genericVnf);
198 final String jobId = jobManager.createJob(vnfmId, operationId, true);
200 return new DeleteVnfResponse().jobId(jobId);
203 private String sendTerminateRequestToVnfm(final GenericVnf genericVnf) {
204 final TerminateVnfRequest terminateVnfRequest = new TerminateVnfRequest();
205 terminateVnfRequest.setTerminationType(TerminationTypeEnum.FORCEFUL);
206 return vnfmServiceProvider.terminateVnf(genericVnf.getSelflink(), terminateVnfRequest);
209 private GenericVnf getGenericVnfFromAai(final String vnfIdInAai) {
210 final GenericVnf genericVnf = aaiServiceProvider.invokeGetGenericVnf(vnfIdInAai);
211 if (genericVnf == null) {
212 throw new VnfNotFoundException("VNF not found in AAI: " + vnfIdInAai);
214 logger.debug("Retrieved generic VNF from AAI: " + genericVnf);
218 private String getIdOfAssignedVnfm(final GenericVnf genericVnf) {
219 final String vnfmId = aaiHelper.getIdOfAssignedVnfm(genericVnf);
220 if (vnfmId == null) {
221 throw new VnfmNotFoundException("No VNFM found in AAI for VNF " + genericVnf.getVnfId());