VNFM adapter handle getOperation after VNF delete
[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         setOamIpAddress(genericVnf, vnfInstance);
101         genericVnf.setOrchestrationStatus("Created");
102
103         aaiServiceProvider.invokePutGenericVnf(genericVnf);
104
105         addVservers(vnfLcmOperationOccurrenceNotification, genericVnf.getVnfId(), vnfInstance.getVimConnectionInfo());
106
107         logger.debug("Finished handling notification for vnfm: " + vnfInstance.getId());
108     }
109
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");
114             return;
115         }
116         if (oamIpAddressSource.getType().equals(OamIpAddressType.LITERAL)) {
117             genericVnf.setIpv4OamAddress(oamIpAddressSource.getValue());
118         } else {
119             try {
120                 logger.debug("ConfigurableProperties: " + vnfInstance.getVnfConfigurableProperties());
121                 if (vnfInstance.getVnfConfigurableProperties() == null) {
122                     logger.warn("No ConfigurableProperties, cannot set OAM IP Address");
123                 }
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);
128             }
129         }
130     }
131
132     private void handleVnfTerminate() {
133         switch (vnfLcmOperationOccurrenceNotification.getOperationState()) {
134             case COMPLETED:
135                 handleVnfTerminateCompleted();
136                 break;
137             case FAILED:
138             case ROLLING_BACK:
139                 handleVnfTerminateFailed();
140                 break;
141             default:
142         }
143     }
144
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);
150     }
151
152     private void handleVnfTerminateCompleted() {
153         final GenericVnf genericVnf = aaiServiceProvider
154                 .invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).getGenericVnf().get(0);
155         deleteVservers(vnfLcmOperationOccurrenceNotification, genericVnf);
156
157         boolean deleteSuccessful = false;
158         try {
159             vnfmServiceProvider.deleteVnf(genericVnf.getSelflink());
160             deleteSuccessful = true;
161         } finally {
162             jobManager.notificationProcessedForOperation(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId(),
163                     deleteSuccessful);
164             jobManager.vnfDeleted(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId());
165             genericVnf.setOrchestrationStatus("Assigned");
166             genericVnf.setSelflink("");
167             aaiServiceProvider.invokePutGenericVnf(genericVnf);
168         }
169     }
170
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);
176         }
177
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);
184
185                 aaiServiceProvider.invokePutVserver(getCloudOwner(vimConnectionInfo), getCloudRegion(vimConnectionInfo),
186                         getTenant(vimConnectionInfo), vserver);
187             }
188         }
189     }
190
191     private void deleteVservers(final VnfLcmOperationOccurrenceNotification notification, final GenericVnf vnf) {
192         for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) {
193             if (ChangeTypeEnum.REMOVED.equals(vnfc.getChangeType())) {
194
195                 final Relationship relationshipToVserver = aaiHelper.deleteRelationshipWithDataValue(vnf, "vserver",
196                         "vserver.vserver-id", vnfc.getComputeResource().getResourceId());
197
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());
203             }
204         }
205     }
206
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);
212     }
213
214     private String getCloudOwner(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
215         final String vimId = vimConnectionInfo.getVimId();
216         return vimId.substring(0, vimId.indexOf("_"));
217     }
218
219     private String getCloudRegion(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
220         final String vimId = vimConnectionInfo.getVimId();
221         return vimId.substring(vimId.indexOf("_") + 1);
222     }
223
224     private String getTenant(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
225         final JSONObject vimConnectionJsonObject = new JSONObject(vimConnectionInfo);
226         return vimConnectionJsonObject.getJSONObject("accessInfo").get("projectId").toString();
227     }
228
229 }