[DCAEGEN2] Improvements to kpi-computation-ms Microservice 55/125655/6
authorVenkata Molluru <venkatamuralimohanreddy.molluru@techmahindra.com>
Thu, 18 Nov 2021 08:19:10 +0000 (08:19 +0000)
committerVenkata Molluru <venkatamuralimohanreddy.molluru@techmahindra.com>
Thu, 18 Nov 2021 08:19:10 +0000 (08:19 +0000)
Issue-ID: DCAEGEN2-2972
Change-Id: If2eb842a1d75b0770cd14f4e0c571c7a721327fa
Signed-off-by: Venkata Molluru <venkatamuralimohanreddy.molluru@techmahindra.com>
17 files changed:
components/kpi-computation-ms/Changelog.md
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/BaseKpiComputation.java [new file with mode: 0755]
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/Command.java
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/CommandHandler.java
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/KpiComputation.java
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/RatioKpiComputation.java [new file with mode: 0644]
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/computation/SumKpiComputation.java
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Kpi.java
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/config/Operation.java
components/kpi-computation-ms/src/main/java/org/onap/dcaegen2/kpi/models/KpiOperand.java [new file with mode: 0644]
components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiComputationTest.java
components/kpi-computation-ms/src/test/java/org/onap/dcaegen2/kpi/computation/KpiTest.java
components/kpi-computation-ms/src/test/resources/config_all.json
components/kpi-computation-ms/src/test/resources/kpi/cbs_config1.json
components/kpi-computation-ms/src/test/resources/kpi/cbs_config2.json
components/kpi-computation-ms/src/test/resources/kpi/kpi_config.json
components/kpi-computation-ms/src/test/resources/kpi/kpi_config_ratio.json [new file with mode: 0644]

index 357ea9d..a5dfd96 100644 (file)
@@ -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 (executable)
index 0000000..ffd84ec
--- /dev/null
@@ -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<String> measTypesList = new ArrayList<>();
+        measTypesList.add(measType);
+        measTypes.setMeasTypesList(measTypesList);
+        MeasValues measValue = new MeasValues();
+        measValue.setSuspectFlag(false);
+        List<MeasResult> 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<MeasValues> measValuesList = new ArrayList<>();
+        measValuesList.add(measValue);
+        measInfo.setMeasInfoId(measInfoId);
+        measInfo.setMeasTypes(measTypes);
+        measInfo.setMeasValuesList(measValuesList);
+        List<MeasInfo> 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;
+    }
+}
+
index 90f1661..9b0322a 100644 (file)
@@ -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<String, List<BigDecimal>> measInfoMap, String measType);
-}
\ No newline at end of file
+    List<VesEvent> handle(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType,
+            Map<String, List<KpiOperand>> measInfoMap, String measType, List<String> operands);
+}
index 5934a2e..0d393d6 100644 (file)
@@ -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<String, List<BigDecimal>> measInfoMap, String measType) {
+    public static List<VesEvent> handle(String className, PerformanceEvent pmEvent, ControlLoopSchemaType schemaType,
+            Map<String, List<KpiOperand>> measInfoMap, String measType, List<String> 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
+}
index e039b51..d349352 100644 (file)
@@ -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<VesEvent> events = new ArrayList<>();
+        List<VesEvent> events = new LinkedList<>();
         List<Kpi> kpis = methodForKpi.getKpis();
         kpis.forEach(k -> {
-            Map<String, List<BigDecimal>> measInfoMap = getOperands(measDataCollection, k.getOperands());
+            Map<String, List<KpiOperand>> 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<VesEvent> kpiVesEvent = CommandHandler.handle(operation.value, pmEvent, schemaType,
+                                                  measInfoMap, measType, k.getOperands());
+            if (kpiVesEvent != null && !kpiVesEvent.isEmpty()) {
+                events.addAll(kpiVesEvent);
+            }
+
         });
+
         return events;
     }
 
-    private Map<String, List<BigDecimal>> getOperands(MeasDataCollection measDataCollection, String operands) {
-        List<BigDecimal> kpiOperands = new ArrayList<>();
+    private Map<String, List<KpiOperand>> getOperands(MeasDataCollection measDataCollection, List<String> operands) {
+        Map<String, List<KpiOperand>> measInfoMap = new HashMap<>();
         List<MeasInfo> measInfoList = measDataCollection.getMeasInfoList();
-        String[] key = new String[1];
-        measInfoList.forEach(m -> {
-            List<String> 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<MeasResult> 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<String, List<BigDecimal>> 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<MeasInfo> curatedMeasInfoList = new ArrayList<>();
+        for (MeasInfo measInfo : measInfoList) {
+            flag = false;
+            for (String operand : operands) {
+                List<String> 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<KpiOperand> kpiOperands = new ArrayList<>();
+            for (MeasInfo m: curatedMeasInfoList) {
+                List<String> 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<MeasResult> 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 (file)
index 0000000..96559a4
--- /dev/null
@@ -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 <VesEvent> handle(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType,
+           Map <String,List <KpiOperand>> measInfoMap, String measType, List < String > operands) {
+
+        final List < VesEvent > vesEvents = new LinkedList < > ();
+        if (operands.size() == 2) {
+            List <KpiOperand> k1 = measInfoMap.get(operands.get(0));
+            List <KpiOperand> k2 = measInfoMap.get(operands.get(1));
+            if (k1.size() != k2.size()) {
+                return null;
+            }
+            ListIterator <KpiOperand> listIteratorK1 = k1.listIterator();
+            ListIterator <KpiOperand> 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;
+    }
+}
+
index 0fe1c4b..a25abaa 100644 (file)
@@ -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<String, List<BigDecimal>> measInfoMap, String measType) {
+    public List<VesEvent> handle(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType,
+            Map<String, List<KpiOperand>> measInfoMap, String measType, List<String> operands) {
 
-        return generateSumVesEvent(pmEvent, schemaType, measInfoMap, measType);
-    }
-
-    private VesEvent generateSumVesEvent(PerformanceEvent pmEvent, ControlLoopSchemaType schemaType,
-            Map<String, List<BigDecimal>> measInfoMap, String measType) {
+        List<KpiOperand> 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<String> 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<MeasResult> measResults = new ArrayList<>();
-        MeasResult measureMent = new MeasResult();
-        List<BigDecimal> 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<MeasValues> measValuesList = new ArrayList<>();
-        measValuesList.add(measValue);
-        measInfo.setMeasInfoId(measInfoId);
-        measInfo.setMeasTypes(measTypes);
-        measInfo.setMeasValuesList(measValuesList);
-        List<MeasInfo> 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<VesEvent> vesEvents = new LinkedList<>();
+        vesEvents.add(generateVesEvent(pmEvent, schemaType.toString(), result, measType));
+        return vesEvents;
     }
 
 }
index 01fc8bc..e162f98 100644 (file)
@@ -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<String> operands;
 
     /**
      * condition.
index c61b827..248c381 100644 (file)
@@ -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 (file)
index 0000000..6b709ae
--- /dev/null
@@ -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;
+
+}
+
index 0bb3b18..69494ab 100644 (file)
@@ -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<VesEvent> 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");
+    }
+
 }
index 94aca96..236a15c 100644 (file)
@@ -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");
+    }
+
 }
index eb84e0d..eec1002 100644 (file)
@@ -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
+}
index bb763db..9dea501 100644 (file)
@@ -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
+}
index bb763db..d69c89c 100644 (file)
@@ -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
+}
index 64e426c..85487cb 100644 (file)
@@ -9,7 +9,7 @@
             "kpis": [{
                 "measType": "AMFRegNbr",
                 "operation": "SUM",
-                "operands": "RM.RegisteredSubNbrMean"
+                "operands": ["RM.RegisteredSubNbrMean"]
             }]
         },
         {
             "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 (file)
index 0000000..3f6828a
--- /dev/null
@@ -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"]
+                }
+            ]
+        }
+    ]
+}