Implement adaptive SON functionality
[dcaegen2/services/son-handler.git] / src / main / java / org / onap / dcaegen2 / services / sonhms / child / ChildThreadUtils.java
1 /*******************************************************************************
2  *  ============LICENSE_START=======================================================
3  *  son-handler
4  *  ================================================================================
5  *   Copyright (C) 2019-2020 Wipro Limited.
6  *   ==============================================================================
7  *     Licensed under the Apache License, Version 2.0 (the "License");
8  *     you may not use this file except in compliance with the License.
9  *     You may obtain a copy of the License at
10  *  
11  *          http://www.apache.org/licenses/LICENSE-2.0
12  *  
13  *     Unless required by applicable law or agreed to in writing, software
14  *     distributed under the License is distributed on an "AS IS" BASIS,
15  *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *     See the License for the specific language governing permissions and
17  *     limitations under the License.
18  *     ============LICENSE_END=========================================================
19  *  
20  *******************************************************************************/
21
22 package org.onap.dcaegen2.services.sonhms.child;
23
24 import com.fasterxml.jackson.annotation.JsonInclude.Include;
25 import com.fasterxml.jackson.core.JsonProcessingException;
26 import com.fasterxml.jackson.databind.ObjectMapper;
27
28 import fj.data.Either;
29
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.UUID;
34
35 import org.onap.dcaegen2.services.sonhms.ConfigPolicy;
36 import org.onap.dcaegen2.services.sonhms.Configuration;
37 import org.onap.dcaegen2.services.sonhms.HoMetricsComponent;
38 import org.onap.dcaegen2.services.sonhms.dao.SonRequestsRepository;
39 import org.onap.dcaegen2.services.sonhms.dmaap.PolicyDmaapClient;
40 import org.onap.dcaegen2.services.sonhms.entity.SonRequests;
41 import org.onap.dcaegen2.services.sonhms.exceptions.ConfigDbNotFoundException;
42 import org.onap.dcaegen2.services.sonhms.model.CellConfig;
43 import org.onap.dcaegen2.services.sonhms.model.CellPciPair;
44 import org.onap.dcaegen2.services.sonhms.model.Common;
45 import org.onap.dcaegen2.services.sonhms.model.Configurations;
46 import org.onap.dcaegen2.services.sonhms.model.Data;
47 import org.onap.dcaegen2.services.sonhms.model.FapService;
48 import org.onap.dcaegen2.services.sonhms.model.HoDetails;
49 import org.onap.dcaegen2.services.sonhms.model.Lte;
50 import org.onap.dcaegen2.services.sonhms.model.LteCell;
51 import org.onap.dcaegen2.services.sonhms.model.NeighborListInUse;
52 import org.onap.dcaegen2.services.sonhms.model.Payload;
53 import org.onap.dcaegen2.services.sonhms.model.PolicyNotification;
54 import org.onap.dcaegen2.services.sonhms.model.Ran;
55 import org.onap.dcaegen2.services.sonhms.model.X0005b9Lte;
56 import org.onap.dcaegen2.services.sonhms.restclient.AsyncResponseBody;
57 import org.onap.dcaegen2.services.sonhms.restclient.SdnrRestClient;
58 import org.onap.dcaegen2.services.sonhms.restclient.Solutions;
59 import org.onap.dcaegen2.services.sonhms.utils.BeanUtil;
60 import org.slf4j.Logger;
61
62 public class ChildThreadUtils {
63
64     private static final Logger log = org.slf4j.LoggerFactory.getLogger(ChildThreadUtils.class);
65     private ConfigPolicy configPolicy;
66     private PnfUtils pnfUtils;
67     private PolicyDmaapClient policyDmaapClient;
68     private HoMetricsComponent hoMetricsComponent;
69
70     /**
71      * Parameterized constructor.
72      */
73     public ChildThreadUtils(ConfigPolicy configPolicy, PnfUtils pnfUtils, PolicyDmaapClient policyDmaapClient,
74             HoMetricsComponent hoMetricsComponent) {
75         this.configPolicy = configPolicy;
76         this.pnfUtils = pnfUtils;
77         this.policyDmaapClient = policyDmaapClient;
78         this.hoMetricsComponent = hoMetricsComponent;
79     }
80
81     /**
82      * Save request.
83      */
84     public void saveRequest(String transactionId, long childThreadId) {
85         SonRequestsRepository sonRequestsRepository = BeanUtil.getBean(SonRequestsRepository.class);
86
87         SonRequests sonRequest = new SonRequests();
88         sonRequest.setTransactionId(transactionId);
89         sonRequest.setChildThreadId(childThreadId);
90         sonRequestsRepository.save(sonRequest);
91     }
92
93     /**
94      * Determines whether to trigger Oof or wait for notifications.
95      */
96     public Boolean triggerOrWait(Map<String, ArrayList<Integer>> collisionConfusionResult) {
97         // determine collision or confusion
98
99         Configuration configuration = Configuration.getInstance();
100         int collisionSum = 0;
101         int confusionSum = 0;
102
103         for (Map.Entry<String, ArrayList<Integer>> entry : collisionConfusionResult.entrySet()) {
104
105             ArrayList<Integer> arr;
106             arr = entry.getValue();
107             // check for 0 collision and confusion
108             if (!arr.isEmpty()) {
109                 collisionSum = collisionSum + arr.get(0);
110                 confusionSum = confusionSum + arr.get(1);
111             }
112         }
113         return ((collisionSum >= configuration.getMinCollision()) && (confusionSum >= configuration.getMinConfusion()));
114
115     }
116
117     /**
118      * get policy notification string from oof result.
119      *
120      */
121     public String getNotificationString(String pnfName, String requestId, String payloadString, Long alarmStartTime,
122             String action) {
123
124         String closedLoopControlName = "";
125         if (action.equals("ModifyConfig")) {
126             closedLoopControlName = "ControlLoop-vPCI-fb41f388-a5f2-11e8-98d0-529269fb1459";
127             try {
128                 closedLoopControlName = (String) configPolicy.getConfig().get("PCI_MODCONFIG_POLICY_NAME");
129             } catch (NullPointerException e) {
130                 log.error("Config policy not found, Using default");
131             }
132         }
133         else {
134             closedLoopControlName = "ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61";
135             try {
136                 closedLoopControlName = (String) configPolicy.getConfig().get("PCI_MODCONFIGANR_POLICY_NAME");
137             } catch (NullPointerException e) {
138                 log.error("Config policy not found, Using default");
139             }
140         }
141
142         PolicyNotification policyNotification = new PolicyNotification(closedLoopControlName, requestId, alarmStartTime,
143                 pnfName, action);
144
145         policyNotification.setClosedLoopControlName(closedLoopControlName);
146         policyNotification.setPayload(payloadString);
147         ObjectMapper mapper = new ObjectMapper();
148         mapper.setSerializationInclusion(Include.NON_NULL);
149
150         String notification = "";
151         try {
152             notification = mapper.writeValueAsString(policyNotification);
153         } catch (JsonProcessingException e1) {
154             log.debug("JSON processing exception: {}", e1);
155         }
156         return notification;
157     }
158
159     /**
160      * Sends Dmaap notification to Policy.
161      *
162      * @throws ConfigDbNotFoundException
163      *             when config db is unreachable
164      */
165     public Boolean sendToPolicy(AsyncResponseBody async) throws ConfigDbNotFoundException {
166
167         if (log.isDebugEnabled()) {
168             log.debug(async.toString());
169         }
170
171         Solutions solutions;
172         solutions = async.getSolutions();
173         if (!solutions.getPciSolutions().isEmpty()) {
174             Map<String, List<CellPciPair>> pnfs = pnfUtils.getPnfs(solutions);
175             for (Map.Entry<String, List<CellPciPair>> entry : pnfs.entrySet()) {
176                 String pnfName = entry.getKey();
177                 List<CellPciPair> cellPciPairs = entry.getValue();
178                 ArrayList<Configurations> configurations = new ArrayList<>();
179                 for (CellPciPair cellPciPair : cellPciPairs) {
180                     String cellId = cellPciPair.getCellId();
181                     int pci = cellPciPair.getPhysicalCellId();
182                     Configurations configuration = new Configurations(new Data(new FapService(cellId,
183                             new X0005b9Lte(pci, pnfName), new CellConfig(new Lte(new Ran(new Common(cellId), null))))),
184                             null);
185                     configurations.add(configuration);
186                 }
187
188                 Payload payload = new Payload(configurations);
189                 ObjectMapper mapper = new ObjectMapper();
190                 mapper.setSerializationInclusion(Include.NON_NULL);
191                 String payloadString = "";
192                 try {
193                     payloadString = mapper.writeValueAsString(payload);
194                 } catch (JsonProcessingException e) {
195                     log.debug("JSON processing exception: {}", e);
196                 }
197
198                 String requestId = UUID.randomUUID().toString();
199
200                 String notification = getNotificationString(pnfName, requestId, payloadString,
201                         System.currentTimeMillis(), "ModifyConfig");
202                 log.info("Policy Notification: {}", notification);
203                 boolean status = policyDmaapClient.sendNotificationToPolicy(notification);
204                 log.debug("sent Message: {}", status);
205                 if (status) {
206                     log.debug("Message sent to policy");
207                 } else {
208                     log.debug("Sending notification to policy failed");
209                 }
210             }
211         }
212         if (!solutions.getAnrSolutions().isEmpty()) {
213             Map<String, List<Map<String, List<String>>>> anrPnfs;
214             List<Configurations> configurations = new ArrayList<>();
215             anrPnfs = pnfUtils.getPnfsForAnrSolutions(solutions.getAnrSolutions());
216             for (Map.Entry<String, List<Map<String, List<String>>>> entry : anrPnfs.entrySet()) {
217                 String pnfName = entry.getKey();
218                 for (Map<String, List<String>> cellRemNeighborsPair : anrPnfs.get(pnfName)) {
219                     for (Map.Entry<String, List<String>> entry1 : cellRemNeighborsPair.entrySet()) {
220                         String cellId = entry1.getKey();
221                         List<LteCell> lteCellList = new ArrayList<>();
222                         for (String removeableNeighbor : entry1.getValue()) {
223                             LteCell lteCell = new LteCell();
224                             lteCell.setBlacklisted("true");
225                             lteCell.setPlmnId(solutions.getNetworkId());
226                             lteCell.setCid(removeableNeighbor);
227                             int pci = SdnrRestClient.getPci(cellId);
228                             lteCell.setPhyCellId(pci);
229                             lteCell.setPnfName(pnfName);
230                             lteCellList.add(lteCell);
231                         }
232                         Configurations configuration = new Configurations(new Data(new FapService(cellId, null,
233                                 new CellConfig(new Lte(new Ran(new Common(cellId), new NeighborListInUse(null,
234                                         lteCellList, String.valueOf(lteCellList.size()))))))),
235                                 null);
236                         configurations.add(configuration);
237                         Either<List<HoDetails>, Integer> hoMetrics = hoMetricsComponent.getHoMetrics(cellId);
238                         if (hoMetrics.isLeft()) {
239                             List<HoDetails> hoDetailsList = hoMetrics.left().value();
240                             for (LteCell lteCell : lteCellList) {
241                                 String removedNbr = lteCell.getCid();
242                                 for (HoDetails hoDetail : hoDetailsList) {
243                                     if (removedNbr.equals(hoDetail.getDstCellId())) {
244                                         hoDetailsList.remove(hoDetail);
245                                         break;
246                                     }
247                                 }
248                             }
249                             String hoDetailsString = null;
250                             ObjectMapper mapper = new ObjectMapper();
251                             try {
252                                 hoDetailsString = mapper.writeValueAsString(hoDetailsList);
253                             } catch (Exception e) {
254                                 log.error("Error in writing handover metrics json ", e);
255                                 return false;
256                             }
257                             hoMetricsComponent.update(hoDetailsString, cellId);
258                         }
259
260                     }
261                     Payload payload = new Payload(configurations);
262                     ObjectMapper mapper = new ObjectMapper();
263                     mapper.setSerializationInclusion(Include.NON_NULL);
264                     String payloadString = null;
265                     try {
266                         payloadString = mapper.writeValueAsString(payload);
267                     } catch (JsonProcessingException e) {
268                         log.error("Exception in writing anrupdate string", e);
269                     }
270                     String requestId = UUID.randomUUID().toString();
271                     String notification = getNotificationString(pnfName, requestId, payloadString,
272                             System.currentTimeMillis(), "ModifyConfigANR");
273                     log.info("Policy Notification: {}", notification);
274                     Boolean result = policyDmaapClient.sendNotificationToPolicy(notification);
275                     log.info("send notification to policy result {} ", result);
276                 }
277
278             }
279
280         }
281         return true;
282     }
283
284 }