1 /*******************************************************************************
2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 *******************************************************************************/
22 package org.onap.dcaegen2.services.sonhms;
24 import com.fasterxml.jackson.annotation.JsonInclude.Include;
25 import com.fasterxml.jackson.databind.ObjectMapper;
27 import fj.data.Either;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.List;
33 import java.util.UUID;
35 import org.onap.dcaegen2.services.sonhms.child.ChildThreadUtils;
36 import org.onap.dcaegen2.services.sonhms.child.PnfUtils;
37 import org.onap.dcaegen2.services.sonhms.dao.HandOverMetricsRepository;
38 import org.onap.dcaegen2.services.sonhms.dmaap.PolicyDmaapClient;
39 import org.onap.dcaegen2.services.sonhms.entity.HandOverMetrics;
40 import org.onap.dcaegen2.services.sonhms.model.AdditionalMeasurements;
41 import org.onap.dcaegen2.services.sonhms.model.CellConfig;
42 import org.onap.dcaegen2.services.sonhms.model.Common;
43 import org.onap.dcaegen2.services.sonhms.model.Configurations;
44 import org.onap.dcaegen2.services.sonhms.model.Data;
45 import org.onap.dcaegen2.services.sonhms.model.FapService;
46 import org.onap.dcaegen2.services.sonhms.model.Flag;
47 import org.onap.dcaegen2.services.sonhms.model.HoDetails;
48 import org.onap.dcaegen2.services.sonhms.model.Lte;
49 import org.onap.dcaegen2.services.sonhms.model.LteCell;
50 import org.onap.dcaegen2.services.sonhms.model.NeighborListInUse;
51 import org.onap.dcaegen2.services.sonhms.model.Payload;
52 import org.onap.dcaegen2.services.sonhms.model.PmNotification;
53 import org.onap.dcaegen2.services.sonhms.model.Ran;
54 import org.onap.dcaegen2.services.sonhms.utils.BeanUtil;
55 import org.onap.dcaegen2.services.sonhms.utils.DmaapUtils;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
59 public class PmNotificationHandler {
61 private static Logger log = LoggerFactory.getLogger(PmNotificationHandler.class);
62 PolicyDmaapClient policyDmaapClient;
64 public PmNotificationHandler() {
68 public PmNotificationHandler(PolicyDmaapClient policyDmaapClient) {
69 this.policyDmaapClient = policyDmaapClient;
73 * handle PM notifications.
75 public Boolean handlePmNotifications(PmNotification pmNotification, int badThreshold, int poorThreshold,
76 int badCountThreshold) {
78 Boolean newEntryFlag = false;
80 List<HoDetails> hoDetailsList = new ArrayList<>();
81 List<LteCell> lteCellList = new ArrayList<>();
82 String srcCellId = pmNotification.getEvent().getCommonEventHeader().getSourceName();
84 * check whether entry already exists if yes : read the hometrics and update it
85 * with latest info else store the current data
87 HoMetricsComponent hoMetricsComponent = new HoMetricsComponent();
88 Either<List<HoDetails>, Integer> hoMetrics = hoMetricsComponent.getHoMetrics(srcCellId);
89 Map<String, Integer> dstCellIdPcPair = new HashMap<>();
90 Map<String, Integer> dstCellIdBcPair = new HashMap<>();
91 if (hoMetrics.isLeft()) {
92 List<HoDetails> oldHoDetailsList = hoMetrics.left().value();
93 for (HoDetails hodetail : oldHoDetailsList) {
94 dstCellIdBcPair.put(hodetail.getDstCellId(), hodetail.getBadCount());
95 dstCellIdPcPair.put(hodetail.getDstCellId(), hodetail.getPoorCount());
98 } else if (hoMetrics.right().value() == 404) {
100 log.info("no history of srcCell found");
102 for (AdditionalMeasurements additionalMeasurements : pmNotification.getEvent().getMeasurementFields()
103 .getAdditionalMeasurements()) {
104 int attemptsCount = Integer.parseInt(additionalMeasurements.getHashMap().get("InterEnbOutAtt_X2HO"));
105 int successCount = Integer.parseInt(additionalMeasurements.getHashMap().get("InterEnbOutSucc_X2HO"));
106 float successRate = ((float) successCount / attemptsCount) * 100;
108 if (successRate >= badThreshold && successRate <= poorThreshold) { // poor neighbor
109 HoDetails hoDetails = new HoDetails();
110 hoDetails.setDstCellId(additionalMeasurements.getName());
111 hoDetails.setAttemptsCount(attemptsCount);
112 hoDetails.setSuccessCount(successCount);
113 hoDetails.setSuccessRate(successRate);
116 if (dstCellIdPcPair.containsKey(additionalMeasurements.getName())) {
117 pc = dstCellIdPcPair.get(additionalMeasurements.getName()) + 1;
119 hoDetails.setBadCount(bc);
120 hoDetails.setPoorCount(pc);
121 hoDetailsList.add(hoDetails);
122 log.info("poor neighbor {}", additionalMeasurements.getName());
123 } else if (successRate < badThreshold) { // bad neighbor
124 log.info(" bad neighbor {}", additionalMeasurements.getName());
125 HoDetails hoDetails = new HoDetails();
126 hoDetails.setDstCellId(additionalMeasurements.getName());
127 hoDetails.setAttemptsCount(attemptsCount);
128 hoDetails.setSuccessCount(successCount);
129 hoDetails.setSuccessRate(successRate);
132 if (dstCellIdBcPair.containsKey(additionalMeasurements.getName())) {
133 bc = dstCellIdBcPair.get(additionalMeasurements.getName()) + 1;
135 if (dstCellIdPcPair.containsKey(additionalMeasurements.getName())) {
136 pc = dstCellIdPcPair.get(additionalMeasurements.getName());
138 hoDetails.setBadCount(bc);
139 hoDetails.setPoorCount(pc);
140 hoDetailsList.add(hoDetails);
141 if (bc >= badCountThreshold) {
142 LteCell lteCell = new LteCell();
143 lteCell.setBlacklisted("true");
144 lteCell.setCid(additionalMeasurements.getName());
145 lteCell.setPlmnId(additionalMeasurements.getHashMap().get("networkId"));
146 lteCell.setPnfName(pmNotification.getEvent().getCommonEventHeader().getReportingEntityName());
147 lteCellList.add(lteCell);
148 hoDetailsList.remove(hoDetails);
151 } else if (successRate > poorThreshold) { // good neighbor
152 HoDetails hoDetails = new HoDetails();
153 hoDetails.setDstCellId(additionalMeasurements.getName());
154 hoDetails.setAttemptsCount(attemptsCount);
155 hoDetails.setSuccessCount(successCount);
156 hoDetails.setSuccessRate(successRate);
159 hoDetails.setBadCount(bc);
160 hoDetails.setPoorCount(pc);
161 hoDetailsList.add(hoDetails);
162 log.info("good neighbor {}", additionalMeasurements.getName());
165 if (!lteCellList.isEmpty()) {
166 log.info("triggering policy to remove bad neighbors");
167 Flag policyTriggerFlag = BeanUtil.getBean(Flag.class);
169 while (policyTriggerFlag.getHolder().equals("CHILD")) {
173 policyTriggerFlag.setHolder("PM");
174 result = sendAnrUpdateToPolicy(pmNotification, lteCellList);
175 log.info("Sent ANR update to policy {}", result);
176 policyTriggerFlag.setHolder("NONE");
178 if (!hoDetailsList.isEmpty() && newEntryFlag) {
179 result = saveToHandOverMetrics(hoDetailsList, srcCellId);
180 log.debug("save HO metrics result {} ", result);
182 } else if (!hoDetailsList.isEmpty()) {
183 String hoDetailsString = null;
184 ObjectMapper mapper = new ObjectMapper();
186 hoDetailsString = mapper.writeValueAsString(hoDetailsList);
187 } catch (Exception e) {
188 log.error("Error in writing handover metrics json ", e);
191 hoMetricsComponent.update(hoDetailsString, srcCellId);
194 } catch (Exception e) {
195 log.error("Error in handlePmNotifications ", e);
202 private Boolean sendAnrUpdateToPolicy(PmNotification pmNotification, List<LteCell> lteCellList) {
203 ObjectMapper mapper = new ObjectMapper();
205 mapper.setSerializationInclusion(Include.NON_NULL);
206 ArrayList<Configurations> configurations = new ArrayList<>();
207 String cellId = pmNotification.getEvent().getCommonEventHeader().getSourceName();
208 Configurations configuration = new Configurations(
209 new Data(new FapService(cellId, null,
210 new CellConfig(new Lte(new Ran(new Common(cellId),
211 new NeighborListInUse(null, lteCellList, String.valueOf(lteCellList.size()))))))),
213 configurations.add(configuration);
214 Payload payload = new Payload(configurations);
215 log.info("payload : {}", payload);
216 String anrUpdateString = mapper.writeValueAsString(payload);
217 ChildThreadUtils childUtils = new ChildThreadUtils(ConfigPolicy.getInstance(), new PnfUtils(),
218 new PolicyDmaapClient(new DmaapUtils(), Configuration.getInstance()), new HoMetricsComponent());
219 String requestId = UUID.randomUUID().toString();
220 String notification = childUtils.getNotificationString(
221 pmNotification.getEvent().getCommonEventHeader().getReportingEntityName(), requestId,
222 anrUpdateString, System.currentTimeMillis(), "ModifyConfigANR");
223 log.info("Policy Notification: {}", notification);
224 Boolean result = policyDmaapClient.sendNotificationToPolicy(notification);
225 log.info("send notification to policy result {} ", result);
227 } catch (Exception e) {
228 log.error("Exception in sending Anr update to policy ", e);
234 private Boolean saveToHandOverMetrics(List<HoDetails> hoDetailsList, String srcCellId) {
235 ObjectMapper mapper = new ObjectMapper();
236 String hoDetailsString = null;
238 hoDetailsString = mapper.writeValueAsString(hoDetailsList);
239 } catch (Exception e) {
240 log.error("Error in writing handover metrics json ", e);
243 HandOverMetrics handOverMetrics = new HandOverMetrics();
244 handOverMetrics.setHoDetails(hoDetailsString);
245 handOverMetrics.setSrcCellId(srcCellId);
246 HandOverMetricsRepository handOverMetricsRepository = BeanUtil.getBean(HandOverMetricsRepository.class);
247 handOverMetricsRepository.save(handOverMetrics);