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.notificationhandling;
23 import static org.slf4j.LoggerFactory.getLogger;
24 import java.util.HashMap;
25 import java.util.List;
27 import org.json.JSONException;
28 import org.json.JSONObject;
29 import org.onap.aai.domain.yang.GenericVnf;
30 import org.onap.aai.domain.yang.Relationship;
31 import org.onap.aai.domain.yang.Vserver;
32 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.AaiHelper;
33 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.AaiServiceProvider;
34 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.OamIpAddressSource;
35 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.aai.OamIpAddressSource.OamIpAddressType;
36 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.VnfmServiceProvider;
37 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.InlineResponse201;
38 import org.onap.so.adapters.etsisol003adapter.lcm.extclients.vnfm.model.InlineResponse201VimConnectionInfo;
39 import org.onap.so.adapters.etsisol003adapter.lcm.jobmanagement.JobManager;
40 import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs;
41 import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.ChangeTypeEnum;
42 import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.VnfLcmOperationOccurrenceNotification;
43 import org.onap.so.adapters.etsisol003adapter.lcm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationStateEnum;
44 import org.slf4j.Logger;
47 * Performs updates to AAI based on a received notification. The updates are executed in a separate thread so as the
48 * notification response to the VNFM is not delayed.
50 public class NotificationHandler implements Runnable {
51 private static Logger logger = getLogger(NotificationHandler.class);
52 private final VnfLcmOperationOccurrenceNotification vnfLcmOperationOccurrenceNotification;
53 private final AaiHelper aaiHelper;
54 private final AaiServiceProvider aaiServiceProvider;
55 private final VnfmServiceProvider vnfmServiceProvider;
56 private final JobManager jobManager;
57 private final InlineResponse201 vnfInstance;
59 public NotificationHandler(final VnfLcmOperationOccurrenceNotification vnfLcmOperationOccurrenceNotification,
60 final AaiHelper aaiHelper, final AaiServiceProvider aaiServiceProvider,
61 final VnfmServiceProvider vnfmServiceProvider, final JobManager jobManager,
62 final InlineResponse201 vnfInstance) {
63 this.vnfLcmOperationOccurrenceNotification = vnfLcmOperationOccurrenceNotification;
64 this.aaiHelper = aaiHelper;
65 this.aaiServiceProvider = aaiServiceProvider;
66 this.vnfmServiceProvider = vnfmServiceProvider;
67 this.jobManager = jobManager;
68 this.vnfInstance = vnfInstance;
74 if (vnfLcmOperationOccurrenceNotification.getOperationState().equals(OperationStateEnum.COMPLETED)) {
75 switch (vnfLcmOperationOccurrenceNotification.getOperation()) {
77 handleVnfInstantiate();
85 } catch (final Exception exception) {
86 logger.error("Error encountered handling notification, AAI may not be updated correctly "
87 + vnfLcmOperationOccurrenceNotification, exception);
91 private void handleVnfInstantiate() {
92 if (vnfLcmOperationOccurrenceNotification.getOperationState().equals(OperationStateEnum.COMPLETED)) {
93 handleVnfInstantiateCompleted();
97 private void handleVnfInstantiateCompleted() {
98 final GenericVnf genericVnf = aaiServiceProvider
99 .invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).getGenericVnf().get(0);
101 final GenericVnf genericVnfPatch = new GenericVnf();
102 genericVnfPatch.setVnfId(genericVnf.getVnfId());
103 setOamIpAddress(genericVnfPatch, vnfInstance);
104 genericVnfPatch.setOrchestrationStatus("Created");
105 aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
107 addVservers(vnfLcmOperationOccurrenceNotification, genericVnf.getVnfId(), vnfInstance.getVimConnectionInfo());
109 logger.debug("Finished handling notification for vnfm: " + vnfInstance.getId());
112 private void setOamIpAddress(final GenericVnf genericVnf, final InlineResponse201 vnfInstance) {
113 final OamIpAddressSource oamIpAddressSource = aaiHelper.getOamIpAddressSource(vnfInstance.getId());
114 if (oamIpAddressSource == null) {
115 logger.warn("No source indicated for OAM IP address, no value will be set in AAI");
118 if (oamIpAddressSource.getType().equals(OamIpAddressType.LITERAL)) {
119 genericVnf.setIpv4OamAddress(oamIpAddressSource.getValue());
122 logger.debug("ConfigurableProperties: " + vnfInstance.getVnfConfigurableProperties());
123 if (vnfInstance.getVnfConfigurableProperties() == null) {
124 logger.warn("No ConfigurableProperties, cannot set OAM IP Address");
126 final JSONObject properties = new JSONObject((Map) vnfInstance.getVnfConfigurableProperties());
127 genericVnf.setIpv4OamAddress(properties.get(oamIpAddressSource.getValue()).toString());
128 } catch (final JSONException jsonException) {
129 logger.error("Error getting vnfIpAddress", jsonException);
134 private void handleVnfTerminate() {
135 switch (vnfLcmOperationOccurrenceNotification.getOperationState()) {
137 handleVnfTerminateCompleted();
141 handleVnfTerminateFailed();
147 private void handleVnfTerminateFailed() {
149 final GenericVnf genericVnf = aaiServiceProvider
150 .invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).getGenericVnf().get(0);
151 deleteVserversFromAai(vnfLcmOperationOccurrenceNotification, genericVnf);
153 jobManager.notificationProcessedForOperation(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId(),
158 private void handleVnfTerminateCompleted() {
159 GenericVnf genericVnf = null;
160 boolean vServersDeletedFromAai = false;
161 boolean identifierDeletedFromVnfm = false;
162 boolean genericVnfUpdated = false;
164 genericVnf = aaiServiceProvider.invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref())
165 .getGenericVnf().get(0);
166 vServersDeletedFromAai = deleteVserversFromAai(vnfLcmOperationOccurrenceNotification, genericVnf);
167 identifierDeletedFromVnfm = deleteVnfIdentifierOnVnfm(genericVnf);
168 genericVnfUpdated = patchVnfInAai(genericVnf.getVnfId(), "Assigned", identifierDeletedFromVnfm ? "" : null);
170 jobManager.notificationProcessedForOperation(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId(),
171 vServersDeletedFromAai && identifierDeletedFromVnfm && genericVnfUpdated);
172 jobManager.vnfDeleted(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId());
176 private void addVservers(final VnfLcmOperationOccurrenceNotification notification, final String vnfId,
177 final List<InlineResponse201VimConnectionInfo> vnfInstancesVimConnectionInfo) {
178 final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo = new HashMap<>();
179 for (final InlineResponse201VimConnectionInfo vimConnectionInfo : vnfInstancesVimConnectionInfo) {
180 vimConnectionIdToVimConnectionInfo.put(vimConnectionInfo.getId(), vimConnectionInfo);
183 for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) {
184 final InlineResponse201VimConnectionInfo vimConnectionInfo =
185 getVimConnectionInfo(vimConnectionIdToVimConnectionInfo, vnfc);
186 if (ChangeTypeEnum.ADDED.equals(vnfc.getChangeType())) {
187 final Vserver vserver = aaiHelper.createVserver(vnfc);
188 aaiServiceProvider.invokePutVserver(getCloudOwner(vimConnectionInfo), getCloudRegion(vimConnectionInfo),
189 getTenant(vimConnectionInfo), vserver);
191 aaiServiceProvider.invokePutVserverToVnfRelationship(getCloudOwner(vimConnectionInfo),
192 getCloudRegion(vimConnectionInfo), getTenant(vimConnectionInfo), vserver, vnfId);
197 private boolean deleteVserversFromAai(final VnfLcmOperationOccurrenceNotification notification,
198 final GenericVnf vnf) {
200 for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) {
201 if (ChangeTypeEnum.REMOVED.equals(vnfc.getChangeType())) {
203 final Relationship relationshipToVserver = aaiHelper.deleteRelationshipWithDataValue(vnf, "vserver",
204 "vserver.vserver-id", vnfc.getComputeResource().getResourceId());
206 aaiServiceProvider.invokeDeleteVserver(
207 aaiHelper.getRelationshipData(relationshipToVserver, "cloud-region.cloud-owner"),
208 aaiHelper.getRelationshipData(relationshipToVserver, "cloud-region.cloud-region-id"),
209 aaiHelper.getRelationshipData(relationshipToVserver, "tenant.tenant-id"),
210 vnfc.getComputeResource().getResourceId());
214 } catch (final Exception exception) {
216 "Error encountered deleting vservers based on received notification, AAI may not be updated correctly "
217 + vnfLcmOperationOccurrenceNotification,
223 private boolean deleteVnfIdentifierOnVnfm(final GenericVnf genericVnf) {
225 vnfmServiceProvider.deleteVnf(aaiHelper.getAssignedVnfm(genericVnf), genericVnf.getSelflink());
227 } catch (final Exception exception) {
228 logger.error("Exception deleting the identifier " + genericVnf.getSelflink()
229 + " from the VNFM. The VNF has been terminated successfully but the identifier will remain on the VNFM.",
235 private boolean patchVnfInAai(final String vnfId, final String orchestrationStatus, final String selfLink) {
237 final GenericVnf genericVnfPatch = new GenericVnf();
238 genericVnfPatch.setVnfId(vnfId);
239 genericVnfPatch.setOrchestrationStatus(orchestrationStatus);
240 if (selfLink != null) {
241 genericVnfPatch.setSelflink(selfLink);
243 aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
245 } catch (final Exception exception) {
247 "Error encountered setting orchestration status and/or self link based on received notification, AAI may not be updated correctly "
248 + vnfLcmOperationOccurrenceNotification,
254 private InlineResponse201VimConnectionInfo getVimConnectionInfo(
255 final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo,
256 final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc) {
257 final String vimConnectionId = vnfc.getComputeResource().getVimConnectionId();
258 return vimConnectionIdToVimConnectionInfo.get(vimConnectionId);
261 private String getCloudOwner(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
262 final String vimId = vimConnectionInfo.getVimId();
263 return vimId.substring(0, vimId.indexOf("_"));
266 private String getCloudRegion(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
267 final String vimId = vimConnectionInfo.getVimId();
268 return vimId.substring(vimId.indexOf("_") + 1);
271 private String getTenant(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
272 final JSONObject vimConnectionJsonObject = new JSONObject(vimConnectionInfo);
273 return vimConnectionJsonObject.getJSONObject("accessInfo").get("projectId").toString();