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