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);
 
 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(GenericVnf genericVnf) {
 
 225             vnfmServiceProvider.deleteVnf(aaiHelper.getAssignedVnfm(genericVnf), genericVnf.getSelflink());
 
 227         } catch (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();