From 2299aa41af51f45e5110f42ae036e68a87a9ab35 Mon Sep 17 00:00:00 2001 From: Venkata Molluru Date: Thu, 18 Nov 2021 08:19:10 +0000 Subject: [DCAEGEN2] Improvements to kpi-computation-ms Microservice Issue-ID: DCAEGEN2-2972 Change-Id: If2eb842a1d75b0770cd14f4e0c571c7a721327fa Signed-off-by: Venkata Molluru --- components/kpi-computation-ms/Changelog.md | 10 +- .../kpi/computation/BaseKpiComputation.java | 117 +++++++++++++++++++++ .../org/onap/dcaegen2/kpi/computation/Command.java | 12 ++- .../dcaegen2/kpi/computation/CommandHandler.java | 14 ++- .../dcaegen2/kpi/computation/KpiComputation.java | 104 +++++++++++++----- .../kpi/computation/RatioKpiComputation.java | 82 +++++++++++++++ .../kpi/computation/SumKpiComputation.java | 79 +++----------- .../java/org/onap/dcaegen2/kpi/config/Kpi.java | 5 +- .../org/onap/dcaegen2/kpi/config/Operation.java | 6 +- .../org/onap/dcaegen2/kpi/models/KpiOperand.java | 48 +++++++++ .../kpi/computation/KpiComputationTest.java | 17 +++ .../org/onap/dcaegen2/kpi/computation/KpiTest.java | 9 ++ .../src/test/resources/config_all.json | 4 +- .../src/test/resources/kpi/cbs_config1.json | 4 +- .../src/test/resources/kpi/cbs_config2.json | 4 +- .../src/test/resources/kpi/kpi_config.json | 8 +- .../src/test/resources/kpi/kpi_config_ratio.json | 17 +++ 17 files changed, 424 insertions(+), 116 deletions(-) create mode 100755 components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/BaseKpiComputation.java create mode 100644 components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/RatioKpiComputation.java create mode 100644 components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/models/KpiOperand.java create mode 100644 components/kpi-computation-ms/src/test/resources/kpi/kpi_config_ratio.json (limited to 'components') diff --git a/components/kpi-computation-ms/Changelog.md b/components/kpi-computation-ms/Changelog.md index 357ea9d2..a5dfd969 100644 --- a/components/kpi-computation-ms/Changelog.md +++ b/components/kpi-computation-ms/Changelog.md @@ -5,8 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [1.0.1] +## [1.0.2] ### Changed -* Migrating the kpi.policy from app-config file to separate policy module (DCAEGEN2-2835) +* [DCAEGEN2-2972] +1) Ability to define KPIs using multiple PM event fields Operands. +2) Enhance KpiComputation for RATIO operation. +3) Ability to compute each Cell data separately in response to incoming single VesEvents for multiple Cells and trigger multiple events post KpiComputation. +## [1.0.1] +### Changed +* Migrating the kpi.policy from app-config file to separate policy module (DCAEGEN2-2835) diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/BaseKpiComputation.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/BaseKpiComputation.java new file mode 100755 index 00000000..ffd84ec7 --- /dev/null +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/BaseKpiComputation.java @@ -0,0 +1,117 @@ +/*- +* ============LICENSE_START======================================================= +* Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. +* ================================================================================ +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* SPDX-License-Identifier: Apache-2.0 +* ============LICENSE_END========================================================= +*/ + +package org.onap.dcaegen2.kpi.computation; + +import org.onap.dcaegen2.kpi.models.CommonEventHeader; +import org.onap.dcaegen2.kpi.models.MeasDataCollection; +import org.onap.dcaegen2.kpi.models.MeasInfo; +import org.onap.dcaegen2.kpi.models.MeasInfoId; +import org.onap.dcaegen2.kpi.models.MeasResult; +import org.onap.dcaegen2.kpi.models.MeasTypes; +import org.onap.dcaegen2.kpi.models.MeasValues; +import org.onap.dcaegen2.kpi.models.Perf3gppFields; +import org.onap.dcaegen2.kpi.models.PerformanceEvent; +import org.onap.dcaegen2.kpi.models.VesEvent; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** +* RatioKpiComputation. +* +* @author Tarun Agrawal +*/ +public abstract class BaseKpiComputation implements Command { + + /** + * Command Interface. + * + * @param pmEvent PerformanceEvent + * @param measInfoIdValue measInfoIdValue + * @param result result + * @param measType measType + * @return kpi Ves Event + */ + public static VesEvent generateVesEvent(final PerformanceEvent pmEvent, final String measInfoIdValue, + final BigDecimal result, final String measType) { + + // Create ves kpi data + CommonEventHeader commonEventHeader = new CommonEventHeader(); + commonEventHeader.setDomain(pmEvent.getCommonEventHeader().getDomain()); + commonEventHeader.setEventId(UUID.randomUUID().toString()); + commonEventHeader.setSequence(1); + commonEventHeader.setEventName(pmEvent.getCommonEventHeader().getEventName()); + commonEventHeader.setSourceName(pmEvent.getCommonEventHeader().getSourceName()); + commonEventHeader.setReportingEntityName(pmEvent.getCommonEventHeader().getReportingEntityName()); + commonEventHeader.setPriority(pmEvent.getCommonEventHeader().getPriority()); + commonEventHeader.setStartEpochMicrosec(pmEvent.getCommonEventHeader().getStartEpochMicrosec()); + commonEventHeader.setLastEpochMicrosec(pmEvent.getCommonEventHeader().getLastEpochMicrosec()); + commonEventHeader.setVersion(pmEvent.getCommonEventHeader().getVersion()); + commonEventHeader.setVesEventListenerVersion(pmEvent.getCommonEventHeader().getVesEventListenerVersion()); + commonEventHeader.setTimeZoneOffset(pmEvent.getCommonEventHeader().getTimeZoneOffset()); + Perf3gppFields perf3gppFields = new Perf3gppFields(); + perf3gppFields.setPerf3gppFieldsVersion(pmEvent.getPerf3gppFields().getPerf3gppFieldsVersion()); + MeasDataCollection tmpMeasDataCollection = new MeasDataCollection(); + tmpMeasDataCollection + .setGranularityPeriod(pmEvent.getPerf3gppFields().getMeasDataCollection().getGranularityPeriod()); + tmpMeasDataCollection.setMeasuredEntityUserName( + pmEvent.getPerf3gppFields().getMeasDataCollection().getMeasuredEntityUserName()); + tmpMeasDataCollection + .setMeasuredEntityDn(pmEvent.getPerf3gppFields().getMeasDataCollection().getMeasuredEntityDn()); + tmpMeasDataCollection.setMeasuredEntitySoftwareVersion( + pmEvent.getPerf3gppFields().getMeasDataCollection().getMeasuredEntitySoftwareVersion()); + MeasInfoId measInfoId = new MeasInfoId(); + measInfoId.setMeasInfoId(measInfoIdValue); + MeasTypes measTypes = new MeasTypes(); + List measTypesList = new ArrayList<>(); + measTypesList.add(measType); + measTypes.setMeasTypesList(measTypesList); + MeasValues measValue = new MeasValues(); + measValue.setSuspectFlag(false); + List measResults = new ArrayList<>(); + MeasResult measureMent = new MeasResult(); + + measureMent.setPvalue(1); + measureMent.setSvalue(result.toString()); + measResults.add(measureMent); + MeasInfo measInfo = new MeasInfo(); + measValue.setMeasResults(measResults); + List measValuesList = new ArrayList<>(); + measValuesList.add(measValue); + measInfo.setMeasInfoId(measInfoId); + measInfo.setMeasTypes(measTypes); + measInfo.setMeasValuesList(measValuesList); + List measInfoList = new ArrayList<>(); + measInfoList.add(measInfo); + tmpMeasDataCollection.setMeasInfoList(measInfoList); + perf3gppFields.setMeasDataCollection(tmpMeasDataCollection); + VesEvent kpiVesEvent = new VesEvent(); + PerformanceEvent kpiEvent = new PerformanceEvent(); + kpiEvent.setCommonEventHeader(commonEventHeader); + kpiEvent.setPerf3gppFields(perf3gppFields); + kpiVesEvent.setEvent(kpiEvent); + + return kpiVesEvent; + } +} + diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/Command.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/Command.java index 90f1661d..9b0322a1 100644 --- a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/Command.java +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/Command.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2021 China Mobile. + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,11 +28,13 @@ import java.util.Map; import org.onap.dcaegen2.kpi.config.ControlLoopSchemaType; import org.onap.dcaegen2.kpi.models.PerformanceEvent; import org.onap.dcaegen2.kpi.models.VesEvent; +import org.onap.dcaegen2.kpi.models.KpiOperand; /** * Command Type. * * @author Kai Lu + * @author Tarun Agrawal * */ @FunctionalInterface @@ -44,9 +47,10 @@ public interface Command { * @param schemaType schemaType * @param measInfoMap measInfoMap * @param measType measType - * + * @param operands operands list of measurements + * * @return object */ - VesEvent handle(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType, - Map> measInfoMap, String measType); -} \ No newline at end of file + List handle(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType, + Map> measInfoMap, String measType, List operands); +} diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/CommandHandler.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/CommandHandler.java index 5934a2e0..0d393d64 100644 --- a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/CommandHandler.java +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/CommandHandler.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2020-2021 China Mobile. + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +26,7 @@ import java.util.List; import java.util.Map; import org.onap.dcaegen2.kpi.config.ControlLoopSchemaType; +import org.onap.dcaegen2.kpi.models.KpiOperand; import org.onap.dcaegen2.kpi.models.PerformanceEvent; import org.onap.dcaegen2.kpi.models.VesEvent; @@ -32,31 +34,33 @@ import org.onap.dcaegen2.kpi.models.VesEvent; * Get special methods to do computation. * * @author Kai Lu + * @author Tarun Agrawal * */ public class CommandHandler { /** * The method to handle data. - * + * * @param className class name * @param pmEvent pmEvent * @param schemaType schemaType * @param measInfoMap measInfoMap * @param measType measType + * @param operands operands list of measurements * @return VesEvent VesEvent */ - public static VesEvent handle(String className, PerformanceEvent pmEvent, ControlLoopSchemaType schemaType, - Map> measInfoMap, String measType) { + public static List handle(String className, PerformanceEvent pmEvent, ControlLoopSchemaType schemaType, + Map> measInfoMap, String measType, List operands) { try { // Load Command Object Command command = (Command) Class.forName(className).getDeclaredConstructor().newInstance(); - return command.handle(pmEvent, schemaType, measInfoMap, measType); + return command.handle(pmEvent, schemaType, measInfoMap, measType, operands); } catch (Exception e) { e.printStackTrace(); } return null; } -} \ No newline at end of file +} diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/KpiComputation.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/KpiComputation.java index e039b519..d3493528 100644 --- a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/KpiComputation.java +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/KpiComputation.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2021 China Mobile. + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,16 +25,19 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.LinkedList; import java.util.Map; import java.util.Optional; import org.apache.commons.lang.StringUtils; + import org.onap.dcaegen2.kpi.config.ControlLoopSchemaType; import org.onap.dcaegen2.kpi.config.Kpi; import org.onap.dcaegen2.kpi.config.KpiConfig; import org.onap.dcaegen2.kpi.config.KpiJsonConversion; import org.onap.dcaegen2.kpi.config.MethodForKpi; import org.onap.dcaegen2.kpi.config.Operation; + import org.onap.dcaegen2.kpi.exception.KpiComputationException; import org.onap.dcaegen2.kpi.models.CommonEventHeader; import org.onap.dcaegen2.kpi.models.Configuration; @@ -44,6 +48,7 @@ import org.onap.dcaegen2.kpi.models.MeasValues; import org.onap.dcaegen2.kpi.models.Perf3gppFields; import org.onap.dcaegen2.kpi.models.PerformanceEvent; import org.onap.dcaegen2.kpi.models.VesEvent; +import org.onap.dcaegen2.kpi.models.KpiOperand; import org.onap.dcaegen2.kpi.utils.VesJsonConversion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +57,7 @@ import org.slf4j.LoggerFactory; * KPI computation. * * @author Kai Lu + * @author Tarun Agrawal */ public class KpiComputation { @@ -98,10 +104,10 @@ public class KpiComputation { .map(Perf3gppFields::getMeasDataCollection) .orElseThrow(() -> new KpiComputationException("Required Field: MeasData not present")); // Do computation for each KPI - List events = new ArrayList<>(); + List events = new LinkedList<>(); List kpis = methodForKpi.getKpis(); kpis.forEach(k -> { - Map> measInfoMap = getOperands(measDataCollection, k.getOperands()); + Map> measInfoMap = getOperands(measDataCollection, k.getOperands()); if (measInfoMap == null) { logger.info("No kpi need to do computation for {}", k.getOperands()); return; @@ -111,36 +117,84 @@ public class KpiComputation { String measType = k.getMeasType(); Operation operation = k.getOperation(); - VesEvent kpiVesEvent = CommandHandler.handle(operation.value, pmEvent, schemaType, measInfoMap, measType); - events.add(kpiVesEvent); + List kpiVesEvent = CommandHandler.handle(operation.value, pmEvent, schemaType, + measInfoMap, measType, k.getOperands()); + if (kpiVesEvent != null && !kpiVesEvent.isEmpty()) { + events.addAll(kpiVesEvent); + } + }); + return events; } - private Map> getOperands(MeasDataCollection measDataCollection, String operands) { - List kpiOperands = new ArrayList<>(); + private Map> getOperands(MeasDataCollection measDataCollection, List operands) { + Map> measInfoMap = new HashMap<>(); List measInfoList = measDataCollection.getMeasInfoList(); - String[] key = new String[1]; - measInfoList.forEach(m -> { - List measTypesList = m.getMeasTypes().getMeasTypesList(); - String measValue = measTypesList.stream() - .filter(s -> StringUtils.substring(s, 0, operands.length()).equalsIgnoreCase(operands)).findFirst() - .orElse(null); - if (measValue != null) { - key[0] = measValue.substring(operands.length() + 1); - int index = measTypesList.indexOf(measValue); - MeasValues measValues = m.getMeasValuesList().stream().findFirst().orElse(null); - List measResults = measValues.getMeasResults(); - kpiOperands.add(new BigDecimal(measResults.get(index).getSvalue())); - } - }); - if (kpiOperands.size() <= 0) { - logger.info("No measureValues matched"); + boolean flag; + if (operands == null || operands.size() <= 0) { + logger.info("No operands, no need to do computation "); return null; } - Map> measInfoMap = new HashMap<>(); - measInfoMap.put(key[0], kpiOperands); - logger.info("kpi operate: {}", kpiOperands); + + // check all operands part of MeasInfo. else remove them from curated list. + List curatedMeasInfoList = new ArrayList<>(); + for (MeasInfo measInfo : measInfoList) { + flag = false; + for (String operand : operands) { + List measTypesList = measInfo.getMeasTypes().getMeasTypesList(); + String measValue = measTypesList.stream() + .filter(s -> StringUtils.substring(s, 0, operand.length()).equalsIgnoreCase(operand)) + .findFirst() + .orElse(null); + if (measValue == null) { + flag = true; + } + } + if (!flag) { + //add to new list + curatedMeasInfoList.add(measInfo); + } + } + + for (String operand: operands) { + String key = null; + List kpiOperands = new ArrayList<>(); + for (MeasInfo m: curatedMeasInfoList) { + List measTypesList = m.getMeasTypes().getMeasTypesList(); + String measValue = measTypesList.stream() + .filter(s -> StringUtils.substring(s, 0, operand.length()).equalsIgnoreCase(operand)) + .findFirst() + .orElse(null); + if (measValue != null) { + key = new StringBuilder().append(operand).toString(); + int index = measTypesList.indexOf(measValue); + MeasValues measValues = m.getMeasValuesList().stream().findFirst().orElse(null); + List measResults = measValues.getMeasResults(); + String measObjInstId = measValues.getMeasObjInstId(); + MeasResult measResult = measResults.stream() + .filter(v -> v.getPvalue() == (index + 1)) + .findFirst() + .orElse(null); + if (measResult != null) { + KpiOperand newKpiOperand = new KpiOperand(measObjInstId, new BigDecimal(measResult.getSvalue())); + kpiOperands.add(newKpiOperand); + } else { + logger.info("measResults mis-matched - incorrect ves msg construction"); + } + } + } + if (kpiOperands.size() <= 0) { + logger.info("No measureValues matched"); + return null; + } + if(key != null) { + measInfoMap.put(key, kpiOperands); + logger.info("kpi operate: {}", kpiOperands); + } else { + return null; + } + } return measInfoMap; } } diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/RatioKpiComputation.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/RatioKpiComputation.java new file mode 100644 index 00000000..96559a4c --- /dev/null +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/RatioKpiComputation.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.dcaegen2.kpi.computation; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.List; +import java.util.LinkedList; +import java.util.ListIterator; +import java.util.Map; +import java.util.UUID; + +import org.onap.dcaegen2.kpi.config.ControlLoopSchemaType; +import org.onap.dcaegen2.kpi.models.CommonEventHeader; +import org.onap.dcaegen2.kpi.models.KpiOperand; +import org.onap.dcaegen2.kpi.models.MeasDataCollection; +import org.onap.dcaegen2.kpi.models.MeasInfo; +import org.onap.dcaegen2.kpi.models.MeasInfoId; +import org.onap.dcaegen2.kpi.models.MeasResult; +import org.onap.dcaegen2.kpi.models.MeasTypes; +import org.onap.dcaegen2.kpi.models.MeasValues; +import org.onap.dcaegen2.kpi.models.Perf3gppFields; +import org.onap.dcaegen2.kpi.models.PerformanceEvent; +import org.onap.dcaegen2.kpi.models.VesEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * RatioKpiComputation. + * + * @author Tarun Agrawal + */ +public class RatioKpiComputation extends BaseKpiComputation { + + private static Logger logger = LoggerFactory.getLogger(RatioKpiComputation.class); + + @Override + public List handle(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType, + Map > measInfoMap, String measType, List < String > operands) { + + final List < VesEvent > vesEvents = new LinkedList < > (); + if (operands.size() == 2) { + List k1 = measInfoMap.get(operands.get(0)); + List k2 = measInfoMap.get(operands.get(1)); + if (k1.size() != k2.size()) { + return null; + } + ListIterator listIteratorK1 = k1.listIterator(); + ListIterator listIteratorK2 = k2.listIterator(); + while (listIteratorK1.hasNext()) { + final KpiOperand myK1 = listIteratorK1.next(); + final KpiOperand myK2 = listIteratorK2.next(); + if (myK2.getValue().compareTo(BigDecimal.ZERO) != 0) { + final BigDecimal result = myK1.getValue().multiply(new BigDecimal("100")) + .divide(myK2.getValue(), 0, RoundingMode.HALF_UP); + vesEvents.add(generateVesEvent(pmEvent, schemaType.toString(), result, measType)); + } + } + } + return vesEvents; + } +} + diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/SumKpiComputation.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/SumKpiComputation.java index 0fe1c4b6..a25abaad 100644 --- a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/SumKpiComputation.java +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/SumKpiComputation.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2020-2021 China Mobile. + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +24,13 @@ package org.onap.dcaegen2.kpi.computation; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; +import java.util.LinkedList; import java.util.Map; import java.util.UUID; import org.onap.dcaegen2.kpi.config.ControlLoopSchemaType; import org.onap.dcaegen2.kpi.models.CommonEventHeader; +import org.onap.dcaegen2.kpi.models.KpiOperand; import org.onap.dcaegen2.kpi.models.MeasDataCollection; import org.onap.dcaegen2.kpi.models.MeasInfo; import org.onap.dcaegen2.kpi.models.MeasInfoId; @@ -44,81 +47,23 @@ import org.slf4j.LoggerFactory; * SumKpiComputation. * * @author Kai Lu + * @author Tarun Agrawal */ -public class SumKpiComputation implements Command { +public class SumKpiComputation extends BaseKpiComputation { private static Logger logger = LoggerFactory.getLogger(SumKpiComputation.class); @Override - public VesEvent handle(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType, - Map> measInfoMap, String measType) { + public List handle(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType, + Map> measInfoMap, String measType, List operands) { - return generateSumVesEvent(pmEvent, schemaType, measInfoMap, measType); - } - - private VesEvent generateSumVesEvent(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType, - Map> measInfoMap, String measType) { + List k1 = measInfoMap.get(operands.get(0)); - // Create ves kpi data - CommonEventHeader commonEventHeader = new CommonEventHeader(); - commonEventHeader.setDomain(pmEvent.getCommonEventHeader().getDomain()); - commonEventHeader.setEventId(UUID.randomUUID().toString()); - commonEventHeader.setSequence(0); - commonEventHeader.setEventName(pmEvent.getCommonEventHeader().getEventName()); - commonEventHeader.setSourceName(pmEvent.getCommonEventHeader().getSourceName()); - commonEventHeader.setReportingEntityName(pmEvent.getCommonEventHeader().getReportingEntityName()); - commonEventHeader.setPriority(pmEvent.getCommonEventHeader().getPriority()); - commonEventHeader.setStartEpochMicrosec(pmEvent.getCommonEventHeader().getStartEpochMicrosec()); - commonEventHeader.setLastEpochMicrosec(pmEvent.getCommonEventHeader().getLastEpochMicrosec()); - commonEventHeader.setVersion(pmEvent.getCommonEventHeader().getVersion()); - commonEventHeader.setVesEventListenerVersion(pmEvent.getCommonEventHeader().getVesEventListenerVersion()); - commonEventHeader.setTimeZoneOffset(pmEvent.getCommonEventHeader().getTimeZoneOffset()); - Perf3gppFields perf3gppFields = new Perf3gppFields(); - perf3gppFields.setPerf3gppFieldsVersion(pmEvent.getPerf3gppFields().getPerf3gppFieldsVersion()); - MeasDataCollection tmpMeasDataCollection = new MeasDataCollection(); - tmpMeasDataCollection - .setGranularityPeriod(pmEvent.getPerf3gppFields().getMeasDataCollection().getGranularityPeriod()); - tmpMeasDataCollection.setMeasuredEntityUserName( - pmEvent.getPerf3gppFields().getMeasDataCollection().getMeasuredEntityUserName()); - tmpMeasDataCollection - .setMeasuredEntityDn(pmEvent.getPerf3gppFields().getMeasDataCollection().getMeasuredEntityDn()); - tmpMeasDataCollection.setMeasuredEntitySoftwareVersion( - pmEvent.getPerf3gppFields().getMeasDataCollection().getMeasuredEntitySoftwareVersion()); - MeasInfoId measInfoId = new MeasInfoId(); - measInfoId.setMeasInfoId(schemaType.toString()); - MeasTypes measTypes = new MeasTypes(); - List measTypesList = new ArrayList<>(); - String keyOperands = measInfoMap.keySet().stream().findAny().get(); - measTypesList.add(new StringBuilder().append(measType).append(keyOperands).toString()); - measTypes.setMeasTypesList(measTypesList); - MeasValues measValue = new MeasValues(); - measValue.setSuspectFlag(false); - List measResults = new ArrayList<>(); - MeasResult measureMent = new MeasResult(); - List kpiOperands = measInfoMap.values().stream().findAny().get(); - BigDecimal result = kpiOperands.stream().map(i -> i).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal result = k1.stream().map(KpiOperand::getValue).reduce(BigDecimal.ZERO, BigDecimal::add); - measureMent.setPvalue(1); - measureMent.setSvalue(result.toString()); - measResults.add(measureMent); - MeasInfo measInfo = new MeasInfo(); - measValue.setMeasResults(measResults); - List measValuesList = new ArrayList<>(); - measValuesList.add(measValue); - measInfo.setMeasInfoId(measInfoId); - measInfo.setMeasTypes(measTypes); - measInfo.setMeasValuesList(measValuesList); - List measInfoList = new ArrayList<>(); - measInfoList.add(measInfo); - tmpMeasDataCollection.setMeasInfoList(measInfoList); - perf3gppFields.setMeasDataCollection(tmpMeasDataCollection); - VesEvent kpiVesEvent = new VesEvent(); - PerformanceEvent kpiEvent = new PerformanceEvent(); - kpiEvent.setCommonEventHeader(commonEventHeader); - kpiEvent.setPerf3gppFields(perf3gppFields); - kpiVesEvent.setEvent(kpiEvent); - logger.info("kpiVesEvent: {}", kpiVesEvent); - return kpiVesEvent; + final List vesEvents = new LinkedList<>(); + vesEvents.add(generateVesEvent(pmEvent, schemaType.toString(), result, measType)); + return vesEvents; } } diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Kpi.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Kpi.java index 01fc8bc6..e162f985 100644 --- a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Kpi.java +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Kpi.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2021 China Mobile. + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,11 +25,13 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.List; /** * KPI Formula. * * @author Kai Lu + * @author Tarun Agrawal */ @Data @EqualsAndHashCode(callSuper = true) @@ -50,7 +53,7 @@ public class Kpi extends BaseModule { /** * operands. */ - private String operands; + private List operands; /** * condition. diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Operation.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Operation.java index c61b827e..248c3817 100644 --- a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Operation.java +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Operation.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2021 China Mobile. + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +23,8 @@ package org.onap.dcaegen2.kpi.config; public enum Operation { - SUM("org.onap.dcaegen2.kpi.computation.SumKpiComputation"), RATIO("org.onap.dcaegen2.kpi.computation.RATIO"), + SUM("org.onap.dcaegen2.kpi.computation.SumKpiComputation"), + RATIO("org.onap.dcaegen2.kpi.computation.RatioKpiComputation"), MEAN("org.onap.dcaegen2.kpi.computation.MEAN"); public final String value; @@ -34,4 +36,4 @@ public enum Operation { public String value() { return this.value; } -} \ No newline at end of file +} diff --git a/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/models/KpiOperand.java b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/models/KpiOperand.java new file mode 100644 index 00000000..6b709aee --- /dev/null +++ b/components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/models/KpiOperand.java @@ -0,0 +1,48 @@ +/* + * ================================================================================ + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcaegen2.kpi.models; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * Operand Values. + * + * @author curated code + * + */ +@Data +@AllArgsConstructor +public class KpiOperand { + + /** + * measValuesList[0].measObjInstId + */ + private String measObjInstId; + + /** + * measResult.svalue + */ + private BigDecimal value; + +} + diff --git a/components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiComputationTest.java b/components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiComputationTest.java index 0bb3b184..69494ab5 100644 --- a/components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiComputationTest.java +++ b/components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiComputationTest.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2021 China Mobile. + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,10 +32,14 @@ import org.onap.dcaegen2.kpi.computation.KpiComputation; import org.onap.dcaegen2.kpi.models.Configuration; import org.onap.dcaegen2.kpi.models.VesEvent; +import java.math.BigDecimal; +import java.math.RoundingMode; + public class KpiComputationTest { private static final String KPI_CONFIG_FILE = "kpi/kpi_config.json"; private static final String VES_MESSAGE_FILE = "kpi/ves_message.json"; + private static final String KPI_CONFIG_RATIO_FILE = "kpi/kpi_config_ratio.json"; @Test public void testKpiComputation() { @@ -53,4 +58,16 @@ public class KpiComputationTest { .getMeasValuesList().get(0).getMeasResults().get(0).getSvalue(), "40"); } + @Test + public void testKpiComputationRatio() { + String strKpiConfigRatio = FileUtils.getFileContents(KPI_CONFIG_RATIO_FILE); + String vesMessage = FileUtils.getFileContents(VES_MESSAGE_FILE); + Configuration config = mock(Configuration.class); + when(config.getKpiConfig()).thenReturn(strKpiConfigRatio); + List vesList = new KpiComputation().checkAndDoComputation(vesMessage, config); + VesEvent vesEvent = vesList.get(0); + assertEquals(vesEvent.getEvent().getPerf3gppFields().getMeasDataCollection().getMeasInfoList().get(0) + .getMeasValuesList().get(0).getMeasResults().get(0).getSvalue(), "50"); + } + } diff --git a/components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiTest.java b/components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiTest.java index 94aca96a..236a15c4 100644 --- a/components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiTest.java +++ b/components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiTest.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2021 China Mobile. + * Copyright (C) 2021 Deutsche Telekom AG. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +33,7 @@ public class KpiTest { private static final String KPI_CONFIG_FILE = "kpi/kpi_config.json"; private static final String VES_MESSAGE_FILE = "kpi/ves_message.json"; + private static final String KPI_CONFIG_RATIO_FILE = "kpi/kpi_config_ratio.json"; @Test public void testKpiConfigValidate() { @@ -51,4 +53,11 @@ public class KpiTest { assertEquals(vesEvent.getEvent().getCommonEventHeader().getDomain(), "perf3gpp"); } + @Test + public void testKpiConfigRatioValidate() { + String strKpiConfig = FileUtils.getFileContents(KPI_CONFIG_RATIO_FILE); + KpiConfig kpiConfig = KpiJsonConversion.convertKpiConfig(strKpiConfig); + assertEquals(kpiConfig.getDomain(), "measurementsForKpi"); + } + } diff --git a/components/kpi-computation-ms/src/test/resources/config_all.json b/components/kpi-computation-ms/src/test/resources/config_all.json index eb84e0d8..eec10029 100644 --- a/components/kpi-computation-ms/src/test/resources/config_all.json +++ b/components/kpi-computation-ms/src/test/resources/config_all.json @@ -32,7 +32,7 @@ } }, "aafPassword": "demo123456!", - "kpi.policy": "{\"domain\":\"measurementsForKpi\",\"methodForKpi\":[{\"eventName\":\"perf3gpp_CORE-AMF_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"AMFRegNbr\",\"operation\":\"SUM\",\"operands\":\"RM.RegisteredSubNbrMean\"}]},{\"eventName\":\"perf3gpp_AcmeNode-Acme_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"UpstreamThr\",\"operation\":\"SUM\",\"operands\":\"GTP.InDataOctN3UPF\"},{\"measType\":\"DownstreamThr\",\"operation\":\"SUM\",\"operands\":\"GTP.OutDataOctN3UPF\"}]}]}", + "kpi.policy": "{\"domain\":\"measurementsForKpi\",\"methodForKpi\":[{\"eventName\":\"perf3gpp_CORE-AMF_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"AMFRegNbr\",\"operation\":\"SUM\",\"operands\":[\"RM.RegisteredSubNbrMean\"]}]},{\"eventName\":\"perf3gpp_AcmeNode-Acme_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"UpstreamThr\",\"operation\":\"SUM\",\"operands\":[\"GTP.InDataOctN3UPF\"]},{\"measType\":\"DownstreamThr\",\"operation\":\"SUM\",\"operands\":[\"GTP.OutDataOctN3UPF\"]}]}]}", "dmaap.server": ["message-router"] }, "policies": { @@ -86,4 +86,4 @@ } }] } -} \ No newline at end of file +} diff --git a/components/kpi-computation-ms/src/test/resources/kpi/cbs_config1.json b/components/kpi-computation-ms/src/test/resources/kpi/cbs_config1.json index bb763db1..9dea5012 100644 --- a/components/kpi-computation-ms/src/test/resources/kpi/cbs_config1.json +++ b/components/kpi-computation-ms/src/test/resources/kpi/cbs_config1.json @@ -32,7 +32,7 @@ } }, "aafPassword": "demo123456!", - "kpi.policy": "{\"domain\":\"measurementsForKpi\",\"methodForKpi\":[{\"eventName\":\"perf3gpp_CORE-AMF_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"AMFRegNbr\",\"operation\":\"SUM\",\"operands\":\"RM.RegisteredSubNbrMean\"}]},{\"eventName\":\"perf3gpp_AcmeNode-Acme_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"UpstreamThr\",\"operation\":\"SUM\",\"operands\":\"GTP.InDataOctN3UPF\"},{\"measType\":\"DownstreamThr\",\"operation\":\"SUM\",\"operands\":\"GTP.OutDataOctN3UPF\"}]}]}", + "kpi.policy": "{\"domain\":\"measurementsForKpi\",\"methodForKpi\":[{\"eventName\":\"perf3gpp_CORE-AMF_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"AMFRegNbr\",\"operation\":\"SUM\",\"operands\":[\"RM.RegisteredSubNbrMean\"]}]},{\"eventName\":\"perf3gpp_AcmeNode-Acme_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"UpstreamThr\",\"operation\":\"SUM\",\"operands\":[\"GTP.InDataOctN3UPF\"]},{\"measType\":\"DownstreamThr\",\"operation\":\"SUM\",\"operands\":[\"GTP.OutDataOctN3UPF\"]}]}]}", "dmaap.server": ["message-router"] } -} \ No newline at end of file +} diff --git a/components/kpi-computation-ms/src/test/resources/kpi/cbs_config2.json b/components/kpi-computation-ms/src/test/resources/kpi/cbs_config2.json index bb763db1..d69c89c4 100644 --- a/components/kpi-computation-ms/src/test/resources/kpi/cbs_config2.json +++ b/components/kpi-computation-ms/src/test/resources/kpi/cbs_config2.json @@ -32,7 +32,7 @@ } }, "aafPassword": "demo123456!", - "kpi.policy": "{\"domain\":\"measurementsForKpi\",\"methodForKpi\":[{\"eventName\":\"perf3gpp_CORE-AMF_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"AMFRegNbr\",\"operation\":\"SUM\",\"operands\":\"RM.RegisteredSubNbrMean\"}]},{\"eventName\":\"perf3gpp_AcmeNode-Acme_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"UpstreamThr\",\"operation\":\"SUM\",\"operands\":\"GTP.InDataOctN3UPF\"},{\"measType\":\"DownstreamThr\",\"operation\":\"SUM\",\"operands\":\"GTP.OutDataOctN3UPF\"}]}]}", + "kpi.policy": "{\"domain\":\"measurementsForKpi\",\"methodForKpi\":[{\"eventName\":\"perf3gpp_CORE-AMF_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"AMFRegNbr\",\"operation\":\"SUM\",\"operands\":[\"RM.RegisteredSubNbrMean\"]}]},{\"eventName\":\"perf3gpp_AcmeNode-Acme_pmMeasResult\",\"controlLoopSchemaType\":\"SLICE\",\"policyScope\":\"resource=networkSlice;type=configuration\",\"policyName\":\"configuration.dcae.microservice.pm-mapper.xml\",\"policyVersion\":\"v0.0.1\",\"kpis\":[{\"measType\":\"RatioUpstreamDownStream\",\"operation\":\"RATIO\",\"operands\":[\"GTP.InDataOctN3UPF\",\"GTP.OutDataOctN3UPF\"]}]}]}", "dmaap.server": ["message-router"] } -} \ No newline at end of file +} diff --git a/components/kpi-computation-ms/src/test/resources/kpi/kpi_config.json b/components/kpi-computation-ms/src/test/resources/kpi/kpi_config.json index 64e426cf..85487cb5 100644 --- a/components/kpi-computation-ms/src/test/resources/kpi/kpi_config.json +++ b/components/kpi-computation-ms/src/test/resources/kpi/kpi_config.json @@ -9,7 +9,7 @@ "kpis": [{ "measType": "AMFRegNbr", "operation": "SUM", - "operands": "RM.RegisteredSubNbrMean" + "operands": ["RM.RegisteredSubNbrMean"] }] }, { @@ -21,15 +21,15 @@ "kpis": [{ "measType": "UpstreamThr", "operation": "SUM", - "operands": "GTP.InDataOctN3UPF" + "operands": ["GTP.InDataOctN3UPF"] }, { "measType": "DownstreamThr", "operation": "SUM", - "operands": "GTP.OutDataOctN3UPF" + "operands": ["GTP.OutDataOctN3UPF"] } ] } ] -} \ No newline at end of file +} diff --git a/components/kpi-computation-ms/src/test/resources/kpi/kpi_config_ratio.json b/components/kpi-computation-ms/src/test/resources/kpi/kpi_config_ratio.json new file mode 100644 index 00000000..3f6828a9 --- /dev/null +++ b/components/kpi-computation-ms/src/test/resources/kpi/kpi_config_ratio.json @@ -0,0 +1,17 @@ +{ + "domain": "measurementsForKpi", + "methodForKpi": [{ + "eventName": "perf3gpp_AcmeNode-Acme_pmMeasResult", + "controlLoopSchemaType": "SLICE", + "policyScope": "resource=networkSlice;type=configuration", + "policyName": "configuration.dcae.microservice.pm-mapper.xml", + "policyVersion": "v0.0.1", + "kpis": [{ + "measType": "RatioUpstreamDownstream", + "operation": "RATIO", + "operands": ["GTP.InDataOctN3UPF","GTP.OutDataOctN3UPF"] + } + ] + } + ] +} -- cgit 1.2.3-korg