c09aa0cd48f6ab36f700122e6330cbd4ac54626a
[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             genericVnf.setOrchestrationStatus("Assigned");
165             genericVnf.setSelflink("");
166             aaiServiceProvider.invokePutGenericVnf(genericVnf);
167         }
168     }
169
170     private void addVservers(final VnfLcmOperationOccurrenceNotification notification, final String vnfId,
171             final List<InlineResponse201VimConnectionInfo> vnfInstancesVimConnectionInfo) {
172         final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo = new HashMap<>();
173         for (final InlineResponse201VimConnectionInfo vimConnectionInfo : vnfInstancesVimConnectionInfo) {
174             vimConnectionIdToVimConnectionInfo.put(vimConnectionInfo.getId(), vimConnectionInfo);
175         }
176
177         for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) {
178             final InlineResponse201VimConnectionInfo vimConnectionInfo =
179                     getVimConnectionInfo(vimConnectionIdToVimConnectionInfo, vnfc);
180             if (ChangeTypeEnum.ADDED.equals(vnfc.getChangeType())) {
181                 final Vserver vserver = aaiHelper.createVserver(vnfc);
182                 aaiHelper.addRelationshipFromVserverVnfToGenericVnf(vserver, vnfId);
183
184                 aaiServiceProvider.invokePutVserver(getCloudOwner(vimConnectionInfo), getCloudRegion(vimConnectionInfo),
185                         getTenant(vimConnectionInfo), vserver);
186             }
187         }
188     }
189
190     private void deleteVservers(final VnfLcmOperationOccurrenceNotification notification, final GenericVnf vnf) {
191         for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) {
192             if (ChangeTypeEnum.REMOVED.equals(vnfc.getChangeType())) {
193
194                 final Relationship relationshipToVserver = aaiHelper.deleteRelationshipWithDataValue(vnf, "vserver",
195                         "vserver.vserver-id", vnfc.getComputeResource().getResourceId());
196
197                 aaiServiceProvider.invokeDeleteVserver(
198                         aaiHelper.getRelationshipData(relationshipToVserver, "cloud-region.cloud-owner"),
199                         aaiHelper.getRelationshipData(relationshipToVserver, "cloud-region.cloud-region-id"),
200                         aaiHelper.getRelationshipData(relationshipToVserver, "tenant.tenant-id"),
201                         vnfc.getComputeResource().getResourceId());
202             }
203         }
204     }
205
206     private InlineResponse201VimConnectionInfo getVimConnectionInfo(
207             final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo,
208             final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc) {
209         final String vimConnectionId = vnfc.getComputeResource().getVimConnectionId();
210         return vimConnectionIdToVimConnectionInfo.get(vimConnectionId);
211     }
212
213     private String getCloudOwner(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
214         final String vimId = vimConnectionInfo.getVimId();
215         return vimId.substring(0, vimId.indexOf("_"));
216     }
217
218     private String getCloudRegion(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
219         final String vimId = vimConnectionInfo.getVimId();
220         return vimId.substring(vimId.indexOf("_") + 1);
221     }
222
223     private String getTenant(final InlineResponse201VimConnectionInfo vimConnectionInfo) {
224         final JSONObject vimConnectionJsonObject = new JSONObject(vimConnectionInfo);
225         return vimConnectionJsonObject.getJSONObject("accessInfo").get("projectId").toString();
226     }
227
228 }