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;
24 import org.onap.aai.domain.yang.EsrVnfm;
25 import org.onap.aai.domain.yang.GenericVnf;
26 import org.onap.so.adapters.vnfmadapter.extclients.SdcPackageProvider;
27 import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiHelper;
28 import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiServiceProvider;
29 import org.onap.so.adapters.vnfmadapter.extclients.aai.OamIpAddressSource;
30 import org.onap.so.adapters.vnfmadapter.extclients.aai.OamIpAddressSource.OamIpAddressType;
31 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmHelper;
32 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmServiceProvider;
33 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201;
34 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest;
35 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest;
36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest;
37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest.TerminationTypeEnum;
38 import org.onap.so.adapters.vnfmadapter.jobmanagement.JobManager;
39 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfNotFoundException;
40 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmNotFoundException;
41 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmRequestFailureException;
42 import org.onap.vnfmadapter.v1.model.CreateVnfRequest;
43 import org.onap.vnfmadapter.v1.model.CreateVnfResponse;
44 import org.onap.vnfmadapter.v1.model.DeleteVnfResponse;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.springframework.beans.factory.annotation.Autowired;
48 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 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 InlineResponse201 vnfmResponse = sendCreateRequestToVnfm(request, genericVnf, vnfIdInAai, vnfm.getVnfmId());
94 genericVnf.setSelflink(vnfmResponse.getLinks().getSelf().getHref());
95 aaiServiceProvider.invokePutGenericVnf(genericVnf);
96 final String vnfIdInVnfm = vnfmResponse.getId();
98 final OamIpAddressSource oamIpAddressSource = extractOamIpAddressSource(request);
99 aaiHelper.setOamIpAddressSource(vnfIdInVnfm, oamIpAddressSource);
101 createNotificationSubscription(vnfm.getVnfmId(), vnfIdInVnfm);
102 final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request, vnfIdInAai, vnfIdInVnfm);
104 final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, false);
105 final CreateVnfResponse response = new CreateVnfResponse();
106 response.setJobId(jobId);
110 private OamIpAddressSource extractOamIpAddressSource(final CreateVnfRequest request) {
111 final Map<String, String> additionalParams = request.getAdditionalParams();
113 final String sourceType = additionalParams.remove("oamIpAddressSourceType");
114 final String sourceValue = additionalParams.remove("oamIpAddressSourceValue");
115 final OamIpAddressType oamIpAddressType = OamIpAddressType.valueOf(sourceType.toUpperCase());
116 return new OamIpAddressSource(oamIpAddressType, sourceValue);
117 } catch (final NullPointerException | IllegalArgumentException exception) {
118 logger.debug("Additional Params not set for OAM IP address source", exception);
123 private void checkIfVnfAlreadyExistsInVnfm(final GenericVnf genericVnf) {
124 if (genericVnf.getSelflink() != null && !genericVnf.getSelflink().isEmpty()) {
125 Optional<InlineResponse201> response = Optional.absent();
127 response = vnfmServiceProvider.getVnf(genericVnf.getSelflink());
128 } catch (final Exception exception) {
129 logger.debug("Ignoring invalid self link in generic vnf", exception);
131 if (response.isPresent()) {
132 throw new IllegalArgumentException("VNF " + genericVnf.getVnfId()
133 + " is already defined on the VNFM, self link: " + genericVnf.getSelflink());
138 private InlineResponse201 sendCreateRequestToVnfm(CreateVnfRequest aaiRequest, GenericVnf genericVnf,
139 String vnfIdInAai, String vnfmId) {
140 logger.debug("Sending a create request to SVNFM " + aaiRequest);
141 org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest vnfmRequest =
142 new org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest();
144 String vnfdId = packageProvider.getVnfdId(genericVnf.getModelVersionId());
145 vnfmRequest.setVnfdId(vnfdId);
146 vnfmRequest.setVnfInstanceName(aaiRequest.getName().replaceAll(" ", "_"));
147 vnfmRequest.setVnfInstanceDescription(vnfIdInAai);
149 Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfmId, vnfmRequest);
152 return optionalResponse.get();
153 } catch (final Exception exception) {
154 final String errorMessage = "Unable to return response from VNFM";
155 logger.error(errorMessage, exception);
156 throw new VnfmRequestFailureException(errorMessage, exception);
160 private void createNotificationSubscription(final String vnfmId, final String vnfId) {
162 final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId);
163 vnfmServiceProvider.subscribeForNotifications(vnfmId, subscriptionRequest);
164 } catch (final Exception exception) {
165 logger.warn("Subscription for notifications to VNFM: " + vnfmId + " for VNF " + vnfId
166 + " failed. AAI will not be updated unless the VNFM is configured by other means to send notifications relating to this VNF",
171 private String sendInstantiateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf,
172 final CreateVnfRequest createVnfRequest, final String vnfIdInAai, final String vnfIdInVnfm) {
174 final InstantiateVnfRequest instantiateVnfRequest =
175 vnfmHelper.createInstantiateRequest(createVnfRequest.getTenant(), createVnfRequest,
176 packageProvider.getFlavourId(genericVnf.getModelVersionId()));
177 final String jobId = vnfmServiceProvider.instantiateVnf(genericVnf.getSelflink(), instantiateVnfRequest);
179 logger.info("Instantiate VNF request successfully sent to " + genericVnf.getSelflink());
184 * Delete a VNF on a VNFM.
186 * @param vnfIdInAai the ID of the VNF in AAI
187 * @return the response to the request
189 public DeleteVnfResponse deleteVnf(final String vnfIdInAai) {
190 final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
191 final String vnfmId = getIdOfAssignedVnfm(genericVnf);
193 final String operationId = sendTerminateRequestToVnfm(genericVnf);
194 final String jobId = jobManager.createJob(vnfmId, operationId, true);
196 return new DeleteVnfResponse().jobId(jobId);
199 private String sendTerminateRequestToVnfm(final GenericVnf genericVnf) {
200 final TerminateVnfRequest terminateVnfRequest = new TerminateVnfRequest();
201 terminateVnfRequest.setTerminationType(TerminationTypeEnum.FORCEFUL);
202 return vnfmServiceProvider.terminateVnf(genericVnf.getSelflink(), terminateVnfRequest);
205 private GenericVnf getGenericVnfFromAai(final String vnfIdInAai) {
206 final GenericVnf genericVnf = aaiServiceProvider.invokeGetGenericVnf(vnfIdInAai);
207 if (genericVnf == null) {
208 throw new VnfNotFoundException("VNF not found in AAI: " + vnfIdInAai);
210 logger.debug("Retrieved generic VNF from AAI: " + genericVnf);
214 private String getIdOfAssignedVnfm(final GenericVnf genericVnf) {
215 final String vnfmId = aaiHelper.getIdOfAssignedVnfm(genericVnf);
216 if (vnfmId == null) {
217 throw new VnfmNotFoundException("No VNFM found in AAI for VNF " + genericVnf.getVnfId());