VNFM adapter relationship handling improvements
[so.git] / adapters / mso-vnfm-adapter / mso-vnfm-etsi-adapter / src / main / java / org / onap / so / adapters / vnfmadapter / notificationhandling / NotificationHandler.java
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.notificationhandling;
22
23 import static org.slf4j.LoggerFactory.getLogger;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
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;
45
46 /**
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.
49  */
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;
58
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;
69     }
70
71     @Override
72     public void run() {
73         try {
74             if (vnfLcmOperationOccurrenceNotification.getOperationState().equals(OperationStateEnum.COMPLETED)) {
75                 switch (vnfLcmOperationOccurrenceNotification.getOperation()) {
76                     case INSTANTIATE:
77                         handleVnfInstantiate();
78                         break;
79                     case TERMINATE:
80                         handleVnfTerminate();
81                         break;
82                     default:
83                 }
84             }
85         } catch (final Exception exception) {
86             logger.error("Error encountered handling notification, AAI may not be updated correctly "
87                     + vnfLcmOperationOccurrenceNotification, exception);
88         }
89     }
90
91     private void handleVnfInstantiate() {
92         if (vnfLcmOperationOccurrenceNotification.getOperationState().equals(OperationStateEnum.COMPLETED)) {
93             handleVnfInstantiateCompleted();
94         }
95     }
96
97     private void handleVnfInstantiateCompleted() {
98         final GenericVnf genericVnf = aaiServiceProvider
99                 .invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).getGenericVnf().get(0);
100
101         final GenericVnf genericVnfPatch = new GenericVnf();
102         genericVnfPatch.setVnfId(genericVnf.getVnfId());
103         setOamIpAddress(genericVnfPatch, vnfInstance);
104         genericVnfPatch.setOrchestrationStatus("Created");
105         aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
106
107         addVservers(vnfLcmOperationOccurrenceNotification, genericVnf.getVnfId(), vnfInstance.getVimConnectionInfo());
108
109         logger.debug("Finished handling notification for vnfm: " + vnfInstance.getId());
110     }
111
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");
116             return;
117         }
118         if (oamIpAddressSource.getType().equals(OamIpAddressType.LITERAL)) {
119             genericVnf.setIpv4OamAddress(oamIpAddressSource.getValue());
120         } else {
121             try {
122                 logger.debug("ConfigurableProperties: " + vnfInstance.getVnfConfigurableProperties());
123                 if (vnfInstance.getVnfConfigurableProperties() == null) {
124                     logger.warn("No ConfigurableProperties, cannot set OAM IP Address");
125                 }
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);
130             }
131         }
132     }
133
134     private void handleVnfTerminate() {
135         switch (vnfLcmOperationOccurrenceNotification.getOperationState()) {
136             case COMPLETED:
137                 handleVnfTerminateCompleted();
138                 break;
139             case FAILED:
140             case ROLLING_BACK:
141                 handleVnfTerminateFailed();
142                 break;
143             default:
144         }
145     }
146
147     private void handleVnfTerminateFailed() {
148         final GenericVnf genericVnf = aaiServiceProvider
149                 .invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).getGenericVnf().get(0);
150         deleteVservers(vnfLcmOperationOccurrenceNotification, genericVnf);
151         jobManager.notificationProcessedForOperation(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId(), false);
152     }
153
154     private void handleVnfTerminateCompleted() {
155         final GenericVnf genericVnf = aaiServiceProvider
156                 .invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).getGenericVnf().get(0);
157         deleteVservers(vnfLcmOperationOccurrenceNotification, genericVnf);
158
159         boolean deleteSuccessful = false;
160         try {
161             vnfmServiceProvider.deleteVnf(aaiHelper.getAssignedVnfm(genericVnf), genericVnf.getSelflink());
162             deleteSuccessful = true;
163         } finally {
164             jobManager.notificationProcessedForOperation(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId(),
165                     deleteSuccessful);
166             jobManager.vnfDeleted(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId());
167
168             final GenericVnf genericVnfPatch = new GenericVnf();
169             genericVnfPatch.setVnfId(genericVnf.getVnfId());
170             genericVnfPatch.setOrchestrationStatus("Assigned");
171             genericVnfPatch.setSelflink("");
172             aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
173         }
174     }
175
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);
181         }
182
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);
190
191                 aaiServiceProvider.invokePutVserverToVnfRelationship(getCloudOwner(vimConnectionInfo),
192                         getCloudRegion(vimConnectionInfo), getTenant(vimConnectionInfo), vserver, vnfId);
193             }
194         }
195     }
196
197     private void deleteVservers(final VnfLcmOperationOccurrenceNotification notification, final GenericVnf vnf) {
198         for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) {
199             if (ChangeTypeEnum.REMOVED.equals(vnfc.getChangeType())) {
200
201                 final Relationship relationshipToVserver = aaiHelper.deleteRelationshipWithDataValue(vnf, "vserver",
202                         "vserver.vserver-id", vnfc.getComputeResource().getResourceId());
203
204                 aaiServiceProvider.invokeDeleteVserver(
205                         aaiHelper.getRelationshipData(relationshipToVserver, "cloud-region.cloud-owner"),
206                         aaiHelper.getRelationshipData(relationshipToVserver, "cloud-region.cloud-region-id"),
207                         aaiHelper.getRelationshipData(relationshipToVserver, "tenant.tenant-id"),
208                         vnfc.getComputeResource().getResourceId());
209             }
210         }
211     }
212
213     private InlineResponse201VimConnectionInfo getVimConnectionInfo(
214             final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo,
215             final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc) {
216         final String vimConnectionId = vnfc.getComputeResource().getVimConnectionId();
217         return vimConnectionIdToVimConnectionInfo.get(vimConnectionId);
218     }
219
220     private String getCloudOwner(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
221         final String vimId = vimConnectionInfo.getVimId();
222         return vimId.substring(0, vimId.indexOf("_"));
223     }
224
225     private String getCloudRegion(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
226         final String vimId = vimConnectionInfo.getVimId();
227         return vimId.substring(vimId.indexOf("_") + 1);
228     }
229
230     private String getTenant(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
231         final JSONObject vimConnectionJsonObject = new JSONObject(vimConnectionInfo);
232         return vimConnectionJsonObject.getJSONObject("accessInfo").get("projectId").toString();
233     }
234
235 }