461c15a5120c65f603ae43bad95cc9d882edad94
[so.git] /
1 /*-
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.adapters.vnfmadapter.lifecycle;
22
23 import com.google.common.base.Optional;
24 import java.util.Map;
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;
50
51 /**
52  * Manages lifecycle operations towards the VNFMs.
53  */
54 @Component
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;
63
64     @Autowired
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;
74     }
75
76     /**
77      * Create a VNF on a VNFM.
78      *
79      * @param vnfIdInAai the ID of the VNF in AAI
80      * @param request the create request
81      * @return the response to the request
82      */
83     public CreateVnfResponse createVnf(final String vnfIdInAai, final CreateVnfRequest request) {
84         GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
85         EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
86         checkIfVnfAlreadyExistsInVnfm(vnfm, genericVnf);
87
88         if (vnfm == null) {
89             vnfm = aaiHelper.selectVnfm(genericVnf);
90             aaiServiceProvider.invokePutGenericVnfToVnfmRelationship(genericVnf, vnfm.getVnfmId());
91         }
92         final InlineResponse201 vnfmResponse = sendCreateRequestToVnfm(request, genericVnf, vnfIdInAai, vnfm);
93
94         logger.info("Create response: {}", vnfmResponse);
95
96         genericVnf.setSelflink(getSelfLink(vnfmResponse, vnfm));
97
98         GenericVnf genericVnfPatch = new GenericVnf();
99         genericVnfPatch.setVnfId(genericVnf.getVnfId());
100         genericVnfPatch.setSelflink(genericVnf.getSelflink());
101         aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
102
103         final String vnfIdInVnfm = vnfmResponse.getId();
104
105         final OamIpAddressSource oamIpAddressSource = extractOamIpAddressSource(request);
106         aaiHelper.setOamIpAddressSource(vnfIdInVnfm, oamIpAddressSource);
107
108         createNotificationSubscription(vnfm, vnfIdInVnfm);
109         final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request);
110
111         final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, false);
112         final CreateVnfResponse response = new CreateVnfResponse();
113         response.setJobId(jobId);
114         return response;
115     }
116
117     private String getSelfLink(final InlineResponse201 vnfmResponse, final EsrVnfm vnfm) {
118         if (vnfmResponse.getLinks() != null && vnfmResponse.getLinks().getSelf() != null
119                 && vnfmResponse.getLinks().getSelf().getHref() != null) {
120             return vnfmResponse.getLinks().getSelf().getHref();
121         }
122         return vnfm.getEsrSystemInfoList().getEsrSystemInfo().iterator().next().getServiceUrl() + "/vnf_instances/"
123                 + vnfmResponse.getId();
124     }
125
126     private OamIpAddressSource extractOamIpAddressSource(final CreateVnfRequest request) {
127         final Map<String, String> additionalParams = request.getAdditionalParams();
128         try {
129             final String sourceType = additionalParams.remove("oamIpAddressSourceType");
130             final String sourceValue = additionalParams.remove("oamIpAddressSourceValue");
131             final OamIpAddressType oamIpAddressType = OamIpAddressType.valueOf(sourceType.toUpperCase());
132             return new OamIpAddressSource(oamIpAddressType, sourceValue);
133         } catch (final NullPointerException | IllegalArgumentException exception) {
134             logger.debug("Additional Params not set for OAM IP address source", exception);
135             return null;
136         }
137     }
138
139     private void checkIfVnfAlreadyExistsInVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) {
140         if (genericVnf.getSelflink() != null && !genericVnf.getSelflink().isEmpty() && vnfm != null) {
141             Optional<InlineResponse201> response = Optional.absent();
142             try {
143                 response = vnfmServiceProvider.getVnf(vnfm, genericVnf.getSelflink());
144             } catch (final Exception exception) {
145                 logger.debug("Ignoring invalid self link in generic vnf", exception);
146             }
147             if (response.isPresent()) {
148                 throw new IllegalArgumentException("VNF " + genericVnf.getVnfId()
149                         + " is already defined on the VNFM, self link: " + genericVnf.getSelflink());
150             }
151         }
152     }
153
154     private InlineResponse201 sendCreateRequestToVnfm(final CreateVnfRequest aaiRequest, final GenericVnf genericVnf,
155             final String vnfIdInAai, final EsrVnfm vnfm) {
156         logger.debug("Sending a create request to SVNFM " + aaiRequest);
157         final org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest vnfmRequest =
158                 new org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest();
159
160         final String vnfdId = packageProvider.getVnfdId(genericVnf.getModelVersionId());
161         vnfmRequest.setVnfdId(vnfdId);
162         vnfmRequest.setVnfInstanceName(aaiRequest.getName().replaceAll(" ", "_"));
163         vnfmRequest.setVnfInstanceDescription(vnfIdInAai);
164
165         final Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfm, vnfmRequest);
166
167         try {
168             return optionalResponse.get();
169         } catch (final Exception exception) {
170             final String errorMessage = "Unable to return response from VNFM";
171             logger.error(errorMessage, exception);
172             throw new VnfmRequestFailureException(errorMessage, exception);
173         }
174     }
175
176     private void createNotificationSubscription(final EsrVnfm vnfm, final String vnfId) {
177         try {
178             final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId);
179             vnfmServiceProvider.subscribeForNotifications(vnfm, subscriptionRequest);
180         } catch (final Exception exception) {
181             logger.warn("Subscription for notifications to VNFM: " + vnfm.getVnfmId() + " for VNF " + vnfId
182                     + " failed. AAI will not be updated unless the VNFM is configured by other means to send notifications relating to this VNF",
183                     exception);
184         }
185     }
186
187     private String sendInstantiateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf,
188             final CreateVnfRequest createVnfRequest) {
189
190         final InstantiateVnfRequest instantiateVnfRequest =
191                 vnfmHelper.createInstantiateRequest(createVnfRequest.getTenant(), createVnfRequest,
192                         packageProvider.getFlavourId(genericVnf.getModelVersionId()));
193         final String jobId = vnfmServiceProvider.instantiateVnf(vnfm, genericVnf.getSelflink(), instantiateVnfRequest);
194
195         logger.info("Instantiate VNF request successfully sent to " + genericVnf.getSelflink());
196         return jobId;
197     }
198
199     /**
200      * Delete a VNF on a VNFM.
201      *
202      * @param vnfIdInAai the ID of the VNF in AAI
203      * @return the response to the request
204      */
205     public DeleteVnfResponse deleteVnf(final String vnfIdInAai) {
206         final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
207         final EsrVnfm vnfm = getAssignedVnfm(genericVnf);
208
209         final String operationId = sendTerminateRequestToVnfm(vnfm, genericVnf);
210         final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, true);
211
212         return new DeleteVnfResponse().jobId(jobId);
213     }
214
215     private String sendTerminateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) {
216         final TerminateVnfRequest terminateVnfRequest = new TerminateVnfRequest();
217         terminateVnfRequest.setTerminationType(TerminationTypeEnum.FORCEFUL);
218         return vnfmServiceProvider.terminateVnf(vnfm, genericVnf.getSelflink(), terminateVnfRequest);
219     }
220
221     private GenericVnf getGenericVnfFromAai(final String vnfIdInAai) {
222         final GenericVnf genericVnf = aaiServiceProvider.invokeGetGenericVnf(vnfIdInAai);
223         if (genericVnf == null) {
224             throw new VnfNotFoundException("VNF not found in AAI: " + vnfIdInAai);
225         }
226         logger.debug("Retrieved generic VNF from AAI: " + genericVnf);
227         return genericVnf;
228     }
229
230     private EsrVnfm getAssignedVnfm(final GenericVnf genericVnf) {
231         final EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
232         if (vnfm == null) {
233             throw new VnfmNotFoundException("No VNFM found in AAI for VNF " + genericVnf.getVnfId());
234         }
235         return vnfm;
236     }
237 }