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.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.vnfmadapter.extclients.aai.AaiHelper;
33 import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiServiceProvider;
34 import org.onap.so.adapters.vnfmadapter.extclients.aai.OamIpAddressSource;
35 import org.onap.so.adapters.vnfmadapter.extclients.aai.OamIpAddressSource.OamIpAddressType;
36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmServiceProvider;
37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs;
38 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.ChangeTypeEnum;
39 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification;
40 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationStateEnum;
41 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201;
42 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201VimConnectionInfo;
43 import org.onap.so.adapters.vnfmadapter.jobmanagement.JobManager;
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);
100 setOamIpAddress(genericVnf, vnfInstance);
101 genericVnf.setOrchestrationStatus("Created");
103 aaiServiceProvider.invokePutGenericVnf(genericVnf);
105 addVservers(vnfLcmOperationOccurrenceNotification, genericVnf.getVnfId(), vnfInstance.getVimConnectionInfo());
107 logger.debug("Finished handling notification for vnfm: " + vnfInstance.getId());
110 private void setOamIpAddress(final GenericVnf genericVnf, final InlineResponse201 vnfInstance) {
111 final OamIpAddressSource oamIpAddressSource = aaiHelper.getOamIpAddressSource(vnfInstance.getId());
112 if (oamIpAddressSource == null) {
113 logger.warn("No source indicated for OAM IP address, no value will be set in AAI");
116 if (oamIpAddressSource.getType().equals(OamIpAddressType.LITERAL)) {
117 genericVnf.setIpv4OamAddress(oamIpAddressSource.getValue());
120 logger.debug("ConfigurableProperties: " + vnfInstance.getVnfConfigurableProperties());
121 if (vnfInstance.getVnfConfigurableProperties() == null) {
122 logger.warn("No ConfigurableProperties, cannot set OAM IP Address");
124 final JSONObject properties = new JSONObject((Map) vnfInstance.getVnfConfigurableProperties());
125 genericVnf.setIpv4OamAddress(properties.get(oamIpAddressSource.getValue()).toString());
126 } catch (final JSONException jsonException) {
127 logger.error("Error getting vnfIpAddress", jsonException);
132 private void handleVnfTerminate() {
133 switch (vnfLcmOperationOccurrenceNotification.getOperationState()) {
135 handleVnfTerminateCompleted();
139 handleVnfTerminateFailed();
145 private void handleVnfTerminateFailed() {
146 final GenericVnf genericVnf = aaiServiceProvider
147 .invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).getGenericVnf().get(0);
148 deleteVservers(vnfLcmOperationOccurrenceNotification, genericVnf);
149 jobManager.notificationProcessedForOperation(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId(), false);
152 private void handleVnfTerminateCompleted() {
153 final GenericVnf genericVnf = aaiServiceProvider
154 .invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).getGenericVnf().get(0);
155 deleteVservers(vnfLcmOperationOccurrenceNotification, genericVnf);
157 boolean deleteSuccessful = false;
159 vnfmServiceProvider.deleteVnf(genericVnf.getSelflink());
160 deleteSuccessful = true;
162 jobManager.notificationProcessedForOperation(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId(),
164 jobManager.vnfDeleted(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId());
165 genericVnf.setOrchestrationStatus("Assigned");
166 genericVnf.setSelflink("");
167 aaiServiceProvider.invokePutGenericVnf(genericVnf);
171 private void addVservers(final VnfLcmOperationOccurrenceNotification notification, final String vnfId,
172 final List<InlineResponse201VimConnectionInfo> vnfInstancesVimConnectionInfo) {
173 final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo = new HashMap<>();
174 for (final InlineResponse201VimConnectionInfo vimConnectionInfo : vnfInstancesVimConnectionInfo) {
175 vimConnectionIdToVimConnectionInfo.put(vimConnectionInfo.getId(), vimConnectionInfo);
178 for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) {
179 final InlineResponse201VimConnectionInfo vimConnectionInfo =
180 getVimConnectionInfo(vimConnectionIdToVimConnectionInfo, vnfc);
181 if (ChangeTypeEnum.ADDED.equals(vnfc.getChangeType())) {
182 final Vserver vserver = aaiHelper.createVserver(vnfc);
183 aaiHelper.addRelationshipFromVserverVnfToGenericVnf(vserver, vnfId);
185 aaiServiceProvider.invokePutVserver(getCloudOwner(vimConnectionInfo), getCloudRegion(vimConnectionInfo),
186 getTenant(vimConnectionInfo), vserver);
191 private void deleteVservers(final VnfLcmOperationOccurrenceNotification notification, final GenericVnf vnf) {
192 for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) {
193 if (ChangeTypeEnum.REMOVED.equals(vnfc.getChangeType())) {
195 final Relationship relationshipToVserver = aaiHelper.deleteRelationshipWithDataValue(vnf, "vserver",
196 "vserver.vserver-id", vnfc.getComputeResource().getResourceId());
198 aaiServiceProvider.invokeDeleteVserver(
199 aaiHelper.getRelationshipData(relationshipToVserver, "cloud-region.cloud-owner"),
200 aaiHelper.getRelationshipData(relationshipToVserver, "cloud-region.cloud-region-id"),
201 aaiHelper.getRelationshipData(relationshipToVserver, "tenant.tenant-id"),
202 vnfc.getComputeResource().getResourceId());
207 private InlineResponse201VimConnectionInfo getVimConnectionInfo(
208 final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo,
209 final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc) {
210 final String vimConnectionId = vnfc.getComputeResource().getVimConnectionId();
211 return vimConnectionIdToVimConnectionInfo.get(vimConnectionId);
214 private String getCloudOwner(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
215 final String vimId = vimConnectionInfo.getVimId();
216 return vimId.substring(0, vimId.indexOf("_"));
219 private String getCloudRegion(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
220 final String vimId = vimConnectionInfo.getVimId();
221 return vimId.substring(vimId.indexOf("_") + 1);
224 private String getTenant(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
225 final JSONObject vimConnectionJsonObject = new JSONObject(vimConnectionInfo);
226 return vimConnectionJsonObject.getJSONObject("accessInfo").get("projectId").toString();