summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pom.xml1
-rw-r--r--sleepingcelldetector/README.md200
-rw-r--r--sleepingcelldetector/pom.xml55
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/SleepingCellDetectorApplication.java36
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/A1Properties.java31
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/DataCollectorProperties.java31
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorConfiguration.java63
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorProperties.java27
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/MeasurementConfiguration.java32
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/RicConfiguration.java31
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/ServiceRegistrationPayload.java33
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/pm/PMData.java28
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/pm/PMEntity.java29
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/A1PolicyEvent.java31
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/PolicyInstance.java35
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Preference.java23
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Resources.java33
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Scope.java31
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/ue/UEInfo.java26
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CallbackController.java35
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceHandler.java109
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceVerifierScheduler.java60
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/DataCollectorClient.java61
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/JsonHelper.java46
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyAgentClient.java163
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceBuilder.java43
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceManager.java79
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/RicConfigurationHolder.java37
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/RicConfigurationManager.java95
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/ServiceLifeCycleManager.java59
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/CalculationUtil.java63
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/SleepingCellDetectorService.java131
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Condition.java18
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/ConditionEnum.java25
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/ConditionFactory.java41
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Equal.java22
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Less.java22
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/LessOrEqual.java22
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/More.java22
-rw-r--r--sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/MoreOrEqual.java22
-rw-r--r--sleepingcelldetector/src/main/resources/application.yml21
-rw-r--r--sleepingcelldetector/src/main/resources/tca.json16
-rw-r--r--sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorConfigurationTest.java66
-rw-r--r--sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceHandlerTest.java177
-rw-r--r--sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/JsonHelperTest.java102
-rw-r--r--sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyAgentClientTest.java110
-rw-r--r--sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceBuilderTest.java61
-rw-r--r--sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceManagerTest.java110
-rw-r--r--sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/scd/CalculationUtilTest.java68
-rw-r--r--sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/scd/SleepingCellDetectorServiceTest.java144
50 files changed, 2826 insertions, 0 deletions
diff --git a/pom.xml b/pom.xml
index 3c9ee03..0a2de84 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,7 @@
<name>rapp</name>
<description>rapp applications</description>
<modules>
+ <module>sleepingcelldetector</module>
<module>datacollector</module>
</modules>
diff --git a/sleepingcelldetector/README.md b/sleepingcelldetector/README.md
new file mode 100644
index 0000000..1a7b432
--- /dev/null
+++ b/sleepingcelldetector/README.md
@@ -0,0 +1,200 @@
+# SleepingCellDetector R-APP
+
+SleepingCellDetector R-APP is a Java SpringBoot application for reading Aggregated PM Metrics from DataCollector R-APP
+and make sleeping cell prediction based on PM data
+
+## Use of SleepingCellDetector R-APP
+
+SleepingCellDetector R-APP needs several parameters to be defined before start.
+
+TCA Algorithm configuration situated in `resources/tca.json` file, example:
+
+```json
+[
+ {
+ "name": "latency",
+ "condition": "MORE_OR_EQUAL",
+ "averageThresholdValue": 400,
+ "latestThresholdValue": 150,
+ "latestSize": 2
+ },
+ {
+ "name": "throughput",
+ "condition": "LESS_OR_EQUAL",
+ "averageThresholdValue": 10,
+ "latestThresholdValue": 10,
+ "latestSize": 2
+ }
+]
+```
+
+File contains information about names of performance measurement parameters, conditions and values of thresholds for
+them.
+`"averageThresholdValue"`- is a threshold of performance signal average
+`"latestThresholdValue"` - is a threshold of last slots of performance signal (number defined in "
+latestThresholdValue"). Needed to detect correction of performance signal. Conditions available: "LESS", "LESS_OR_EQUAL"
+, "EQUAL", "MORE_OR_EQUAL", "MORE"'
+
+Actually DataCollector R-APP returns Aggregated Metrics of "latency" and "throughput" parameters, example:
+
+```json
+{
+ "pm": [
+ {
+ "cellId": "Cell1",
+ "performance": [
+ {
+ "latency": 50,
+ "throughput": 80
+ },
+ {
+ "latency": 50,
+ "throughput": 80
+ },
+ {
+ "latency": 50,
+ "throughput": 80
+ }
+ ]
+ }
+ ],
+ "itemsLength": 1
+}
+```
+
+Set parameters of environment variables:
+
+A1PolicyManagementService URL can be set using environment variables:
+
+- A1\_HOST
+- A1\_PORT
+
+To customize DataCollector R-APP connectivity you need to set the following:
+
+- DC_HOST
+- DC_PORT
+- DC_VERSION
+
+SleepingCellDetector R-APP configuration fields:
+
+- SCD_PREFIX
+- SCD_SLOT
+- SCD_COUNT
+
+Prefix of high priority user equipment (policy instances will be created only for user equipments with this prefix),
+example:
+`emergency_` - policy instances will be created only for UEs with "emergency\_" prefix Slot of time in seconds,
+number of slots for DataCollector R-APP Aggregated Metrics endpoint call. Slot: aggregation period (in seconds) for
+which an average performance metrics are calculated Count: number of aggregated performance metrics that should be
+returned by the method, one aggregated performance metric per each slot. The first performance metrics is average
+metrics for (startTime, startTime +slot). StartTime for DataCollector R-APP Aggregated Metrics endpoint call is
+generated based on slot and count parameters as "time.now - slot\*count"
+
+Example configuration in environment variables in application.yml:
+
+```
+server:
+ port: 8382
+a1:
+ host: "policy-agent"
+ port: 8081
+dc:
+ host: "localhost"
+ port: 8087
+ version: "v1"
+scd:
+ prefix: "emergency"
+ slot: 10
+ count: 12
+logging:
+ level:
+ org:
+ springframework: DEBUG
+ logging.file.name: logs/rapp-sleepingcelldetector.log
+ pattern:
+ console: "%d %-5level %logger : %msg%n"
+ file: "%d %-5level [%thread] %logger : %msg%n"
+```
+
+During start-up, SleepingCellDetector R-APP registers itself as a service in A1PolicyManagmentService(PMS). After that
+SleepingCellDetector R-APP sends periodic keepalive requests to PMS. PMS exposes the Ric Configuration for SleepingCellDetector R-APP.
+Ric Configuration contains information about Policy Type and Ric name, example:
+
+```json
+[
+ {
+ "ricName": "ric1",
+ "managedElementIds": [
+ ],
+ "policyTypes": [
+ "1000"
+ ],
+ "state": "AVAILABLE"
+ }
+]
+```
+
+SleepingCellDetector R-APP uses this information with created UUID are used for Policy Instances creation request to
+A1PolicyManagementService, example:
+
+`{a1policymanagementservicehost}/policy?id=123e4567-e89b-12d3-a456-426614174000&ric=ric1&service=rapp-sleepingcelldetector&type=1000`
+
+```json
+{
+ "scope": {
+ "ueId": "emergency_samsung_s10_01"
+ },
+ "resources": [
+ {
+ "cellIdList": [
+ "Cell3"
+ ],
+ "preference": "AVOID"
+ }
+ ]
+}
+```
+
+SleepingCellDetector R-APP creates the policy resources, which are used to traffic steering,
+selecting cell for a connection, or scheduling traffic on available cells,
+in a different way than what would be done through default behaviour.
+
+Like was presented on the example above, created policy instances provided information
+which cells (mention in the array "cellIdList") the User Equipment (define in the section "scope", key "ueId"")
+should avoid (section "resources", key "preference").
+
+After start-up SleepingCellDetector R-APP begins to make predictions periodically in intervals defined by CSD_SLOT
+period based on new PM metrics measurement data received in each interval.
+When sleeping cell is detected, creation of A1 Policy instance is enforced by SleepingCellDetector R-APP.
+If cell becomes active again, A1Policy instance deletion request is sent.
+
+# Developer Guide
+
+## Build SleepingCellDetector R-APP
+
+Following mvn command (in the current directory) will build SleepingCellDetector R-APP:
+
+```bash
+mvn clean install
+```
+
+To build docker image add `-P docker:build` flag.
+
+## Run SleepingCellDetector R-APP
+
+Following command will run SleepingCellDetector R-APP:
+
+```bash
+java -jar sleepingcelldetector-0.0.1-SNAPSHOT.jar org.onap.rapp.sleepingcelldetector.SleepingCellDetectorApplication
+```
+
+## Logging
+
+The log file will be created in the /log path. Parameters of logging are in application.yml file.
+After SleepingCellDetector R-APP starts successfully, log/rapp-sleepingcelldetector.log should start to contain the logs:
+
+```
+.
+└──log
+ └── rapp-sleepingcelldetector.log
+```
diff --git a/sleepingcelldetector/pom.xml b/sleepingcelldetector/pom.xml
new file mode 100644
index 0000000..80b790d
--- /dev/null
+++ b/sleepingcelldetector/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 Samsung Electronics
+ ~ 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
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>sleepingcelldetector</artifactId>
+ <groupId>org.onap.rapp.sleepingcelldetector</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <parent>
+ <groupId>org.onap.rapp</groupId>
+ <artifactId>rapp</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <properties>
+ <docker-image.name.prefix>org.onap.rapp.sleepingcelldetector</docker-image.name.prefix>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <version>20190722</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>28.2-android</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/SleepingCellDetectorApplication.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/SleepingCellDetectorApplication.java
new file mode 100644
index 0000000..ebb825c
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/SleepingCellDetectorApplication.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector;
+
+import org.onap.rapp.sleepingcelldetector.configuration.A1Properties;
+import org.onap.rapp.sleepingcelldetector.configuration.DataCollectorProperties;
+import org.onap.rapp.sleepingcelldetector.configuration.SleepingCellDetectorProperties;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@EnableScheduling
+@ComponentScan(basePackages = {"org.onap.rapp.sleepingcelldetector"})
+@EnableConfigurationProperties({A1Properties.class, DataCollectorProperties.class,
+ SleepingCellDetectorProperties.class})
+@EnableAutoConfiguration
+public class SleepingCellDetectorApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(SleepingCellDetectorApplication.class, args);
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/A1Properties.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/A1Properties.java
new file mode 100644
index 0000000..24981e4
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/A1Properties.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.configuration;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "a1")
+public class A1Properties {
+ private String host;
+ private int port;
+
+ public String getA1PolicyUrl() {
+ return String.format("http://%s:%d", host, port);
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/DataCollectorProperties.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/DataCollectorProperties.java
new file mode 100644
index 0000000..6e6b289
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/DataCollectorProperties.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.configuration;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "dc")
+public class DataCollectorProperties {
+ private String host;
+ private int port;
+ private String version;
+
+ public String getDataCollectorUrl() {
+ return String.format("http://%s:%d/%s", host, port, version);
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorConfiguration.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorConfiguration.java
new file mode 100644
index 0000000..e7c1d25
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorConfiguration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.configuration;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class SleepingCellDetectorConfiguration {
+
+ private final A1Properties a1Properties;
+ private final DataCollectorProperties dataCollectorProperties;
+ private final SleepingCellDetectorProperties scdProperties;
+
+ @Autowired
+ public SleepingCellDetectorConfiguration(A1Properties a1Properties, DataCollectorProperties dataCollectorProperties,
+ SleepingCellDetectorProperties scdProperties) {
+ this.a1Properties = a1Properties;
+ this.dataCollectorProperties = dataCollectorProperties;
+ this.scdProperties = scdProperties;
+ }
+
+ public String getA1PolicyBaseUrl() {
+ return a1Properties.getA1PolicyUrl();
+ }
+
+ public String getDataCollectorBaseUrl() {
+ return dataCollectorProperties.getDataCollectorUrl();
+ }
+
+ public String getUeFilteringPrefix(){
+ return scdProperties.getPrefix();
+ }
+
+ public int getPredictionTimeSlot(){
+ return scdProperties.getSlot();
+ }
+
+ public int getPredictionSlotNumber(){
+ return scdProperties.getCount();
+ }
+
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+
+}
+
+
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorProperties.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorProperties.java
new file mode 100644
index 0000000..4e3145f
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorProperties.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.configuration;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "scd")
+public class SleepingCellDetectorProperties {
+ private String prefix;
+ private int slot;
+ private int count;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/MeasurementConfiguration.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/MeasurementConfiguration.java
new file mode 100644
index 0000000..984eb1a
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/MeasurementConfiguration.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import org.onap.rapp.sleepingcelldetector.service.scd.condition.ConditionEnum;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class MeasurementConfiguration {
+ private String name;
+ private ConditionEnum condition;
+ private int averageThresholdValue;
+ private int latestThresholdValue;
+ private int latestSize;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/RicConfiguration.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/RicConfiguration.java
new file mode 100644
index 0000000..db09f8a
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/RicConfiguration.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity;
+
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class RicConfiguration {
+ private String ricName;
+ private List<String> managedElementIds;
+ private List<String> policyTypes;
+ private String state;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/ServiceRegistrationPayload.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/ServiceRegistrationPayload.java
new file mode 100644
index 0000000..3cb2777
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/ServiceRegistrationPayload.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Getter
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ServiceRegistrationPayload {
+ private String callBackUrl;
+ private String keepAliveIntervalSeconds;
+ private String serviceName;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/pm/PMData.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/pm/PMData.java
new file mode 100644
index 0000000..5d26c5f
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/pm/PMData.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity.pm;
+
+import java.util.List;
+import java.util.Map;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class PMData {
+ String cellId;
+ List<Map<String, Integer>> performance;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/pm/PMEntity.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/pm/PMEntity.java
new file mode 100644
index 0000000..805569b
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/pm/PMEntity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity.pm;
+
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class PMEntity {
+ List<PMData> pm;
+ int totalCell;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/A1PolicyEvent.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/A1PolicyEvent.java
new file mode 100644
index 0000000..7b70c0a
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/A1PolicyEvent.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity.policy;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class A1PolicyEvent {
+ private Scope scope;
+ private List<Resources> resources;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/PolicyInstance.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/PolicyInstance.java
new file mode 100644
index 0000000..55d7531
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/PolicyInstance.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity.policy;
+
+import java.util.Date;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class PolicyInstance {
+ private String id;
+ private String type;
+ private String ric;
+ private String service;
+ private Date lastModified;
+ private A1PolicyEvent json;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Preference.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Preference.java
new file mode 100644
index 0000000..72a3569
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Preference.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity.policy;
+
+public enum Preference {
+ SHALL("SHALL"), PREFER("PREFER"), AVOID("AVOID"), FORBID("FORBID");
+ public final String value;
+
+ Preference(String stateName) {
+ this.value = stateName;
+ }
+} \ No newline at end of file
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Resources.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Resources.java
new file mode 100644
index 0000000..6214726
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Resources.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity.policy;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@JsonTypeName("resources")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Resources {
+ private List<String> cellIdList;
+ private Preference preference;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Scope.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Scope.java
new file mode 100644
index 0000000..37e72bd
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/policy/Scope.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity.policy;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@JsonTypeName("scope")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Scope {
+ private String ueId;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/ue/UEInfo.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/ue/UEInfo.java
new file mode 100644
index 0000000..7f5f997
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/entity/ue/UEInfo.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.entity.ue;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class UEInfo {
+ private List<String> ues;
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CallbackController.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CallbackController.java
new file mode 100644
index 0000000..47b6e3e
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CallbackController.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping({"/"})
+public class CallbackController {
+
+ private static final Logger logger = LoggerFactory.getLogger(CallbackController.class);
+
+ @GetMapping()
+ public ResponseEntity<String> checkHealth() {
+ logger.info("Health check performed");
+ return ResponseEntity.ok("Service up and running");
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceHandler.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceHandler.java
new file mode 100644
index 0000000..72bc8d6
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceHandler.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.onap.rapp.sleepingcelldetector.configuration.SleepingCellDetectorConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.service.scd.SleepingCellDetectorService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CellPerformanceHandler {
+
+ private static final Logger logger = LoggerFactory.getLogger(CellPerformanceHandler.class);
+
+ private final SleepingCellDetectorService sleepingCellDetectorService;
+ private final RicConfigurationHolder ricConfigHolder;
+ private final PolicyInstanceManager policyInstancesManager;
+ private final SleepingCellDetectorConfiguration config;
+ private final DataCollectorClient dataCollectorClient;
+
+ public CellPerformanceHandler(SleepingCellDetectorService sleepingCellDetectorService, RicConfigurationHolder ricConfigHolder,
+ PolicyInstanceManager policyInstanceManager, SleepingCellDetectorConfiguration config,
+ DataCollectorClient dataCollectorClient) {
+ this.sleepingCellDetectorService = sleepingCellDetectorService;
+ this.ricConfigHolder = ricConfigHolder;
+ this.policyInstancesManager = policyInstanceManager;
+ this.config = config;
+ this.dataCollectorClient = dataCollectorClient;
+ }
+
+ public void handleCellPerformance(String cell, List<Map<String, Integer>> pmData) {
+ logger.info("Handle cell: {} started", cell);
+ try {
+ if (pmData.isEmpty()) {
+ logger.warn("pm data is empty for cell: {}", cell);
+ return;
+ }
+
+ Boolean isFailing = sleepingCellDetectorService.isFailing(pmData);
+ handleCell(cell, isFailing);
+ } catch (Exception e) {
+ logger.error("Error during sleeping cell detecting: {}", e.getMessage());
+ }
+ }
+
+ private void handleCell(String cell, boolean isFailing) {
+ if (isFailing) {
+ handleFailingCell(cell);
+ } else {
+ handleActiveCell(cell);
+ }
+ }
+
+ private void handleFailingCell(String cell) {
+ logger.info("Cell {} is in failed status, policy instance will be created", cell);
+
+ Optional<RicConfiguration> ricConfig = ricConfigHolder.getRicConfig();
+ if (ricConfig.isEmpty()) {
+ logger.warn("Can't find ric configuration for cell: {}", cell);
+ return;
+ }
+
+ Set<String> userEquipmentsIds = getHighPriorityUEs();
+ if (userEquipmentsIds.isEmpty()) {
+ logger.warn("No high priority user equipment for cell: {}", cell);
+ return;
+ }
+
+ createPolicyInstance(ricConfig.get(), userEquipmentsIds, cell);
+ }
+
+ private Set<String> getHighPriorityUEs() {
+ return dataCollectorClient.getUserEquipment().getUes().stream()
+ .filter(ue -> ue.startsWith(config.getUeFilteringPrefix()))
+ .collect(Collectors.toSet());
+ }
+
+ private void createPolicyInstance(RicConfiguration ricConfig, Set<String> userEquipmentsIds, String cell) {
+ userEquipmentsIds.stream()
+ .filter(ue -> !policyInstancesManager.cellContainsPolicyForUe(cell, ue))
+ .forEach(ue -> policyInstancesManager.createPolicyInstance(cell, ue, ricConfig));
+ }
+
+ private void handleActiveCell(String cell) {
+ if (policyInstancesManager.cellContainsPolicy(cell)) {
+ policyInstancesManager.removePolicyInstancesForCell(cell);
+ }
+ logger.info("Cell {} is not in failed status", cell);
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceVerifierScheduler.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceVerifierScheduler.java
new file mode 100644
index 0000000..bc2aaaf
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceVerifierScheduler.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.onap.rapp.sleepingcelldetector.entity.pm.PMEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CellPerformanceVerifierScheduler {
+
+ private static final Logger logger = LoggerFactory.getLogger(CellPerformanceVerifierScheduler.class);
+
+ private final DataCollectorClient dataCollectorClient;
+ private final CellPerformanceHandler cellPerformanceHandler;
+
+ public CellPerformanceVerifierScheduler(DataCollectorClient dataCollectorClient, CellPerformanceHandler cellPerformanceHandler) {
+ this.dataCollectorClient = dataCollectorClient;
+ this.cellPerformanceHandler = cellPerformanceHandler;
+ }
+
+ @Scheduled(fixedRateString = "${scd.slot}000")
+ public void handleMeasurements() {
+ logger.debug("Perform measurements check");
+ performVesEventsMeasurementVerification();
+ }
+
+ private void performVesEventsMeasurementVerification() {
+ try {
+ PMEntity performanceData = dataCollectorClient.getPMData();
+ Map<String, List<Map<String, Integer>>> eventsByCell = groupByCell(performanceData);
+ eventsByCell.forEach(cellPerformanceHandler::handleCellPerformance);
+ } catch (Exception e) {
+ logger.error("Error occurred during events verification, message: {}", e.getMessage());
+ }
+ }
+
+ private Map<String, List<Map<String, Integer>>> groupByCell(PMEntity pmEntity) {
+ Map<String, List<Map<String, Integer>>> cellPerformanceMap = new HashMap<>();
+ pmEntity.getPm().forEach(pmData -> cellPerformanceMap.put(pmData.getCellId(), pmData.getPerformance()));
+ return cellPerformanceMap;
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/DataCollectorClient.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/DataCollectorClient.java
new file mode 100644
index 0000000..85a5e06
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/DataCollectorClient.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.time.OffsetDateTime;
+import org.onap.rapp.sleepingcelldetector.configuration.SleepingCellDetectorConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.pm.PMEntity;
+import org.onap.rapp.sleepingcelldetector.entity.ue.UEInfo;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class DataCollectorClient {
+
+ public static final String AGGREGATED_METRICS_URL = "/pm/events/aggregatedmetrics";
+ public static final String UES_URL = "/pm/ues";
+ private final SleepingCellDetectorConfiguration config;
+ private final RestTemplate restTemplate;
+
+ public DataCollectorClient(SleepingCellDetectorConfiguration config, RestTemplate restTemplate) {
+ this.config = config;
+ this.restTemplate = restTemplate;
+ }
+
+ public PMEntity getPMData() throws UnsupportedEncodingException {
+ String dataCollectorUrl = config.getDataCollectorBaseUrl() + AGGREGATED_METRICS_URL + getQueryParams();
+ URI uri = URI.create(dataCollectorUrl);
+ ResponseEntity<PMEntity> pmEntityResponse = restTemplate.getForEntity(uri, PMEntity.class);
+ return pmEntityResponse.getBody();
+ }
+
+ private String getQueryParams() throws UnsupportedEncodingException {
+ long slot = config.getPredictionTimeSlot();
+ long count = config.getPredictionSlotNumber();
+ String time = URLEncoder.encode(OffsetDateTime.now().minusSeconds(slot * count).toString(),
+ StandardCharsets.UTF_8.toString());
+ return "?slot=" + slot + "&count=" + count + "&startTime=" + time;
+ }
+
+ public UEInfo getUserEquipment() {
+ String dataCollectorUrl = config.getDataCollectorBaseUrl() + UES_URL;
+ ResponseEntity<UEInfo> userEquipmentResponse = restTemplate.getForEntity(dataCollectorUrl, UEInfo.class);
+ return userEquipmentResponse.getBody();
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/JsonHelper.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/JsonHelper.java
new file mode 100644
index 0000000..cc48ea5
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/JsonHelper.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.stereotype.Service;
+
+@Service
+public class JsonHelper {
+
+ private ObjectMapper mapper;
+
+ public JsonHelper() {
+ this.mapper = new ObjectMapper()
+ .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ }
+
+ public <T> T deserialize(String object, Class<T> clazz) {
+ try {
+ return mapper.readValue(object, clazz);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String objectToJsonString(Object object) {
+ try {
+ return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyAgentClient.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyAgentClient.java
new file mode 100644
index 0000000..e6d3566
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyAgentClient.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import org.onap.rapp.sleepingcelldetector.configuration.SleepingCellDetectorConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.ServiceRegistrationPayload;
+import org.onap.rapp.sleepingcelldetector.entity.policy.PolicyInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class PolicyAgentClient {
+
+ private static final Logger logger = LoggerFactory.getLogger(PolicyAgentClient.class);
+
+ public static final String SERVICE_KEEPALIVE_URL = "/services/keepalive?name=";
+ public static final String SERVICE_URL = "/service";
+ public static final String POLICY_TYPES_URL = "/policy_types";
+ public static final String POLICY_URL = "/policy";
+ public static final String POLICIES_URL = "/policies";
+ public static final String SCD_SERVICE_NAME = "rapp-sleepingcelldetector";
+ public static final String RICS_POLICY_TYPE_URL = "/rics?policyType=";
+ public static final String POLICY_ACTOR_CALLBACK_URL = "http://rapp-sleepingcelldetector:8382/";
+
+ private final SleepingCellDetectorConfiguration config;
+ private final RestTemplate restTemplate;
+ private final JsonHelper jsonHelper;
+
+ public PolicyAgentClient(SleepingCellDetectorConfiguration config, RestTemplate restTemplate, JsonHelper jsonHelper) {
+ this.config = config;
+ this.restTemplate = restTemplate;
+ this.jsonHelper = jsonHelper;
+ }
+
+ public void sendPolicyEvent(PolicyInstance policy, RicConfiguration ricConfig) {
+ ricConfig.getPolicyTypes().forEach(policyType -> {
+ String policyServiceUrl = getUpdatePolicyUrl(ricConfig, policyType, policy.getId());
+ String policyRequest = jsonHelper.objectToJsonString(policy.getJson());
+ sendUpdatePolicyRequest(policyServiceUrl, policyRequest);
+ });
+ }
+
+ private String getUpdatePolicyUrl(RicConfiguration ricConfig, String policyTypeId, String policyId) {
+ String queryParams = POLICY_URL + "?id=" + policyId + "&ric=" + ricConfig.getRicName()
+ + "&service=" + SCD_SERVICE_NAME + "&type=" + policyTypeId;
+ return getA1PolicyBaseUrl() + queryParams;
+ }
+
+ private void sendUpdatePolicyRequest(String policyServiceUrl, String policyRequest) {
+ logger.info("Sending policy event; URL: {},\n Policy: {}", policyServiceUrl, policyRequest);
+ restTemplate.put(policyServiceUrl, createPolicyUpdateRequestEntity(policyRequest));
+ }
+
+ private HttpEntity<String> createPolicyUpdateRequestEntity(String policy) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ return new HttpEntity<>(policy, headers);
+ }
+
+ public void deletePolicyInstance(String id){
+ try {
+ logger.info("Policy instance {} remove request will be send", id);
+ String deletePolicyUrl = getA1PolicyBaseUrl() + POLICY_URL + "?id=" + id;
+ restTemplate.delete(deletePolicyUrl);
+ } catch (Exception e){
+ logger.warn("Exception during policy deletion: {} \nPolicy {} was already removed", e.getMessage(), id);
+ }
+
+ }
+
+ public List<String> getPoliciesIds() {
+ String policyIdsUrl = getA1PolicyBaseUrl() + POLICY_TYPES_URL;
+ ResponseEntity<String[]> policyIds = restTemplate.getForEntity(policyIdsUrl, String[].class);
+ return Arrays.asList(Objects.requireNonNull(policyIds.getBody()));
+ }
+
+ public List<PolicyInstance> getPoliciesInstances(){
+ String policiesUrl = getA1PolicyBaseUrl() + POLICIES_URL;
+ ResponseEntity<PolicyInstance[]> policiesResponse = restTemplate.getForEntity(policiesUrl, PolicyInstance[].class);
+
+ if (policiesResponse.hasBody()){
+ return Arrays.asList(policiesResponse.getBody());
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ public List<RicConfiguration> getRicConfigurationsByPolicyId(String policyId) {
+ String ricConfigUrl = getA1PolicyBaseUrl() + RICS_POLICY_TYPE_URL + policyId;
+ ResponseEntity<RicConfiguration[]> ricConfigResponse = restTemplate.getForEntity(ricConfigUrl, RicConfiguration[].class);
+
+ if (ricConfigResponse.hasBody()){
+ return Arrays.asList(ricConfigResponse.getBody());
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ public boolean createService() {
+ String createServiceUrl = getA1PolicyBaseUrl() + SERVICE_URL;
+ ServiceRegistrationPayload payload = buildPayload();
+ HttpEntity<String> entity = prepareRequest(payload);
+ ResponseEntity<String> response = restTemplate.exchange(createServiceUrl, HttpMethod.PUT, entity, String.class);
+
+ if (response.getStatusCode().is2xxSuccessful()) {
+ logger.info("Service created");
+ return true;
+ } else {
+ logger.warn("Problem with service registration request, response: {}", response.getStatusCode());
+ return false;
+ }
+ }
+
+ private HttpEntity<String> prepareRequest(ServiceRegistrationPayload payload) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ return new HttpEntity<>(jsonHelper.objectToJsonString(payload), headers);
+ }
+
+ private ServiceRegistrationPayload buildPayload() {
+ return ServiceRegistrationPayload.builder()
+ .callBackUrl(POLICY_ACTOR_CALLBACK_URL)
+ .keepAliveIntervalSeconds("20")
+ .serviceName(SCD_SERVICE_NAME)
+ .build();
+ }
+
+ public void sendKeepAliveRequest() {
+ String createServiceUrl = getA1PolicyBaseUrl() + SERVICE_KEEPALIVE_URL + SCD_SERVICE_NAME;
+ restTemplate.put(createServiceUrl, Void.class);
+ logger.info("Keep alive request performed");
+ }
+
+ private String getA1PolicyBaseUrl() {
+ return config.getA1PolicyBaseUrl();
+ }
+
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceBuilder.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceBuilder.java
new file mode 100644
index 0000000..c2dcd5e
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceBuilder.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import com.google.common.collect.Lists;
+import java.util.UUID;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.policy.A1PolicyEvent;
+import org.onap.rapp.sleepingcelldetector.entity.policy.PolicyInstance;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Preference;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Resources;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Scope;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PolicyInstanceBuilder {
+
+ public static final String SCD_SERVICE_NAME = "sleepingcelldetector";
+
+ public PolicyInstance buildPolicyInstance(String cell, String userEquipment, RicConfiguration ric) {
+ Scope scope = new Scope(userEquipment);
+ Resources resources = new Resources(Lists.newArrayList(cell), Preference.AVOID);
+ String id = UUID.randomUUID().toString();
+ return PolicyInstance.builder()
+ .id(id)
+ .ric(ric.getRicName())
+ .service(SCD_SERVICE_NAME)
+ .json(new A1PolicyEvent(scope, Lists.newArrayList(resources)))
+ .build();
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceManager.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceManager.java
new file mode 100644
index 0000000..bce6675
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceManager.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.policy.PolicyInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PolicyInstanceManager {
+
+ private static final Logger logger = LoggerFactory.getLogger(PolicyInstanceManager.class);
+ private Multimap<String, PolicyInstance> cellPolicyInstancesMap = ArrayListMultimap.create();
+
+ private final PolicyAgentClient policyAgentClient;
+ private final PolicyInstanceBuilder payloadBuilder;
+
+ public PolicyInstanceManager(PolicyAgentClient policyAgentClient, PolicyInstanceBuilder payloadBuilder) {
+ this.policyAgentClient = policyAgentClient;
+ this.payloadBuilder = payloadBuilder;
+ }
+
+ public boolean cellContainsPolicy(String cell) {
+ return cellPolicyInstancesMap.containsKey(cell);
+ }
+
+ public boolean cellContainsPolicyForUe(String cell, String ue) {
+ if (cellContainsPolicy(cell)) {
+ List<PolicyInstance> policyInstances = new ArrayList<>(cellPolicyInstancesMap.get(cell));
+ return policyInstances.stream().anyMatch(pi -> pi.getJson().getScope().getUeId().equals(ue));
+ }
+ return false;
+ }
+
+ public void createPolicyInstance(String cell, String ue, RicConfiguration ric) {
+ try {
+ PolicyInstance policy = payloadBuilder.buildPolicyInstance(cell, ue, ric);
+ cellPolicyInstancesMap.put(cell, policy);
+ policyAgentClient.sendPolicyEvent(policy, ric);
+ logger.info("Policy Instance for ue {}, cell {} created with id {}", ue, cell, policy.getId());
+ } catch (Exception e) {
+ logger.error("Error during request to Policy Management Service: {}", e.getMessage());
+ removePolicyInstancesForCell(cell);
+ }
+ }
+
+ public void addPolicyInstance(PolicyInstance policyInstance) {
+ List<String> cells = policyInstance.getJson().getResources()
+ .stream().flatMap(resources -> resources.getCellIdList().stream()).collect(Collectors.toList());
+ cells.forEach(cell -> cellPolicyInstancesMap.put(cell, policyInstance));
+ }
+
+ public void removePolicyInstancesForCell(String cell) {
+ Collection<PolicyInstance> policyInstancesByCell = cellPolicyInstancesMap.get(cell);
+ policyInstancesByCell.forEach(pi -> policyAgentClient.deletePolicyInstance(pi.getId()));
+ cellPolicyInstancesMap.removeAll(cell);
+ logger.info("Policy Instances for cell {} removed", cell);
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/RicConfigurationHolder.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/RicConfigurationHolder.java
new file mode 100644
index 0000000..da89fe8
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/RicConfigurationHolder.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import java.util.Optional;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RicConfigurationHolder {
+
+ private static final Logger logger = LoggerFactory.getLogger(RicConfigurationHolder.class);
+
+ private RicConfiguration ricConfiguration;
+
+ public void addRic(RicConfiguration ricConfig, String policyTypeId) {
+ logger.info("Adding ric configuration for Policy Type {}, config: {}", policyTypeId, ricConfig);
+ ricConfiguration = ricConfig;
+ }
+
+ public Optional<RicConfiguration> getRicConfig() {
+ return Optional.of(ricConfiguration);
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/RicConfigurationManager.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/RicConfigurationManager.java
new file mode 100644
index 0000000..9253865
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/RicConfigurationManager.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.PostConstruct;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.policy.PolicyInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RicConfigurationManager {
+
+ private static final Logger logger = LoggerFactory.getLogger(RicConfigurationManager.class);
+
+ private final RicConfigurationHolder ricConfigurationHolder;
+ private final PolicyInstanceManager policyInstanceManager;
+ private final PolicyAgentClient policyAgentClient;
+
+ public RicConfigurationManager(RicConfigurationHolder ricConfigurationHolder, PolicyAgentClient policyAgentClient,
+ PolicyInstanceManager policyInstanceManager
+ ) {
+ this.ricConfigurationHolder = ricConfigurationHolder;
+ this.policyAgentClient = policyAgentClient;
+ this.policyInstanceManager = policyInstanceManager;
+ }
+
+ @PostConstruct
+ private void getRicConfigurations() throws InterruptedException {
+ logger.info("Policy fetching process started");
+ boolean ricConfigUploadStatus = false;
+ while (!ricConfigUploadStatus) {
+ ricConfigUploadStatus = getRicConfigs();
+ TimeUnit.SECONDS.sleep(10);
+ }
+ }
+
+ private boolean getRicConfigs() {
+ try {
+ List<String> policyIds = policyAgentClient.getPoliciesIds();
+
+ if (policyIds.isEmpty()) {
+ logger.warn("Problems with ric configuration fetching; Next try in 10 sec");
+ return false;
+ }
+
+ saveRicConfiguration(policyIds);
+ policyIds.forEach(this::verifyExistingPolicyInstances);
+ logger.info("Policy fetching process ended successfully");
+ return true;
+ } catch (Exception e) {
+ logger.error("Problems with ric configuration fetching; Next try in 10 sec: " + e.getMessage());
+ return false;
+ }
+ }
+
+ private void saveRicConfiguration(List<String> policyIds) {
+ policyIds.forEach(policyId -> {
+ logger.info("Saving ric configurations for policyId {}", policyId);
+ List<RicConfiguration> ricConfigs = policyAgentClient.getRicConfigurationsByPolicyId(policyId);
+ ricConfigs.forEach(rc -> ricConfigurationHolder.addRic(rc, policyId));
+ });
+ }
+
+ private void verifyExistingPolicyInstances(String policyTypeId) {
+ List<PolicyInstance> policyInstances = policyAgentClient.getPoliciesInstances();
+ if (policyInstances.isEmpty()) {
+ logger.info("No policy instances of type {}", policyTypeId);
+ } else {
+ policyInstances.stream()
+ .filter(pi -> pi.getType().equals(policyTypeId))
+ .forEach(this::addPolicyInstance);
+ }
+ }
+
+ private void addPolicyInstance(PolicyInstance pi) {
+ policyInstanceManager.addPolicyInstance(pi);
+ logger.info("Policy Instance of type {} and id {} added on startup", pi.getType(), pi.getId());
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/ServiceLifeCycleManager.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/ServiceLifeCycleManager.java
new file mode 100644
index 0000000..70407e8
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/ServiceLifeCycleManager.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import java.util.concurrent.TimeUnit;
+import javax.annotation.PostConstruct;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ServiceLifeCycleManager {
+
+ private static final Logger logger = LoggerFactory.getLogger(ServiceLifeCycleManager.class);
+ private final PolicyAgentClient policyAPIClient;
+
+ public ServiceLifeCycleManager(PolicyAgentClient policyAPIClient) {
+ this.policyAPIClient = policyAPIClient;
+ }
+
+ @PostConstruct
+ private void createService() {
+ logger.info("Registering policy actor service");
+
+ boolean serviceCreated = false;
+ while (!serviceCreated) {
+ try {
+ serviceCreated = policyAPIClient.createService();
+ TimeUnit.SECONDS.sleep(10);
+ } catch (Exception e) {
+ logger.error("Error during service registration {}", e.getMessage());
+ }
+ }
+ }
+
+ @Scheduled(fixedRate = 20000)
+ private void keepAlive() {
+ try {
+ logger.info("Send keep alive request");
+ policyAPIClient.sendKeepAliveRequest();
+ } catch (Exception e) {
+ logger.warn("Error during keep alive request {}", e.getMessage());
+ createService();
+ }
+
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/CalculationUtil.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/CalculationUtil.java
new file mode 100644
index 0000000..95aecae
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/CalculationUtil.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.List;
+import java.util.Objects;
+import java.util.OptionalDouble;
+import java.util.stream.Collectors;
+
+public class CalculationUtil {
+
+ private static final Logger logger = LoggerFactory.getLogger(CalculationUtil .class);
+ public static final int MIN_PERCENTAGE_OF_DATA_FILLING = 30;
+
+ private CalculationUtil(){
+ }
+
+ public static Integer calculateAverage(List<Integer> values){
+ OptionalDouble average = values.stream().mapToDouble(l -> l).average();
+
+ if (average.isPresent()) {
+ return (int) average.getAsDouble();
+ } else {
+ throw new ArithmeticException("Can't calculate average");
+ }
+ }
+
+ public static List<Integer> fillGaps(List<Integer> values){
+ verifyDataFilling(values);
+ Integer average = calculateAverage(values.stream().filter(Objects::nonNull).collect(Collectors.toList()));
+
+ for (int i=0; i<values.size(); i++){
+ if(values.get(i) == null){
+ values.set(i, average);
+ }
+ }
+ return values;
+ }
+
+ public static void verifyDataFilling(List<Integer> values) {
+ double measurementsNumber = values.stream().filter(Objects::nonNull).count();
+ double listSize = values.size();
+ double dataFillingPercentage = measurementsNumber/listSize * 100;
+ if (dataFillingPercentage < MIN_PERCENTAGE_OF_DATA_FILLING){
+ logger.warn("Not enough data to make prediction, must be at least 30%; Data filling: {}%", dataFillingPercentage);
+ throw new ArithmeticException("Not enough performance data for prediction, data filling: " + dataFillingPercentage + "%");
+ }
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/SleepingCellDetectorService.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/SleepingCellDetectorService.java
new file mode 100644
index 0000000..f942162
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/SleepingCellDetectorService.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
+import org.onap.rapp.sleepingcelldetector.configuration.SleepingCellDetectorConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.MeasurementConfiguration;
+import org.onap.rapp.sleepingcelldetector.service.JsonHelper;
+import org.onap.rapp.sleepingcelldetector.service.scd.condition.Condition;
+import org.onap.rapp.sleepingcelldetector.service.scd.condition.ConditionFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SleepingCellDetectorService {
+
+ private static final Logger logger = LoggerFactory.getLogger(SleepingCellDetectorService.class);
+
+ private final JsonHelper jsonHelper;
+ private final SleepingCellDetectorConfiguration configuration;
+
+ protected Map<String, MeasurementConfiguration> measurementMap = new HashMap<>();
+
+ @Autowired
+ public SleepingCellDetectorService(JsonHelper jsonHelper, SleepingCellDetectorConfiguration configuration) {
+ this.jsonHelper = jsonHelper;
+ this.configuration = configuration;
+ }
+
+ @PostConstruct
+ public void loadConditionMap() throws Exception {
+ logger.info("TCA config fetching process started");
+ boolean tcaConfigUploadStatus = false;
+ while (!tcaConfigUploadStatus) {
+ tcaConfigUploadStatus = getTCAConfig();
+ TimeUnit.SECONDS.sleep(10);
+ }
+ }
+
+ private boolean getTCAConfig() {
+ try {
+ InputStream in = this.getClass().getResourceAsStream("/tca.json");
+ BufferedReader inr = new BufferedReader(new InputStreamReader(in));
+ String tcaConfig = inr.lines().collect(Collectors.joining(" "));
+
+ MeasurementConfiguration[] measurementConfigurations = jsonHelper.deserialize(tcaConfig, MeasurementConfiguration[].class);
+ Arrays.stream(measurementConfigurations).forEach(mf -> measurementMap.put(mf.getName(), mf));
+ return true;
+ } catch (Exception e) {
+ logger.error("Error during loading Measurement Configuration for TCA: {}", e.getMessage());
+ return false;
+ }
+ }
+
+ public Boolean isFailing(List<Map<String, Integer>> performanceData) {
+ Map<String, List<Integer>> measurementValuesMap = groupMeasurementValues(performanceData);
+
+ measurementValuesMap.forEach((fieldName, values) -> {
+ if (containsEmptyValues(values)) {
+ CalculationUtil.fillGaps(values);
+ }
+ });
+
+ List<Boolean> predictions = new ArrayList<>();
+ measurementValuesMap.forEach((fieldName, values) -> predictions.add(isFailing(values, measurementMap.get(fieldName))));
+
+ return predictions.contains(true);
+ }
+
+ private Map<String, List<Integer>> groupMeasurementValues(List<Map<String, Integer>> performanceData) {
+ Map<String, List<Integer>> measurementValuesMap = prepareMeasurementMap();
+
+ performanceData.forEach(pm -> measurementMap.forEach((fieldName, configuration) -> {
+ Integer measurement = pm.get(fieldName);
+ List<Integer> measurements = measurementValuesMap.get(fieldName);
+ measurements.add(measurement);
+ }));
+
+ return measurementValuesMap;
+ }
+
+ private Map<String, List<Integer>> prepareMeasurementMap() {
+ Map<String, List<Integer>> measurementValuesMap = new HashMap<>();
+ measurementMap.forEach((fieldName, values) -> measurementValuesMap.put(fieldName, new ArrayList<>()));
+ return measurementValuesMap;
+ }
+
+ private boolean containsEmptyValues(List<Integer> performanceData) {
+ for (Integer value : performanceData) {
+ if (value == null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Boolean isFailing(List<Integer> values, MeasurementConfiguration measurementConfiguration) {
+ Condition condition = ConditionFactory.getCondition(measurementConfiguration.getCondition());
+ Integer totalAverage = CalculationUtil.calculateAverage(values);
+ Integer latestAverage = CalculationUtil.calculateAverage(values.stream()
+ .skip(configuration.getPredictionSlotNumber() - measurementConfiguration.getLatestSize())
+ .collect(Collectors.toList()));
+
+ return condition.compare(totalAverage, measurementConfiguration.getAverageThresholdValue())
+ && condition.compare(latestAverage, measurementConfiguration.getLatestThresholdValue());
+ }
+
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Condition.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Condition.java
new file mode 100644
index 0000000..d6b6153
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Condition.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd.condition;
+
+public interface Condition {
+ boolean compare(int value, int toCompare);
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/ConditionEnum.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/ConditionEnum.java
new file mode 100644
index 0000000..e4279ec
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/ConditionEnum.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd.condition;
+
+public enum ConditionEnum {
+ MORE(),
+ MORE_OR_EQUAL(),
+ LESS(),
+ LESS_OR_EQUAL(),
+ EQUAL();
+
+ private ConditionEnum(){
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/ConditionFactory.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/ConditionFactory.java
new file mode 100644
index 0000000..a2f07c1
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/ConditionFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd.condition;
+
+public class ConditionFactory {
+
+ private static final Condition less = new Less();
+ private static final Condition more = new More();
+ private static final Condition equal = new Equal();
+ private static final Condition lessOrEqual = new LessOrEqual();
+ private static final Condition moreOrEqual= new MoreOrEqual();
+
+
+ public static Condition getCondition(ConditionEnum condition) {
+ switch (condition) {
+ case LESS:
+ return less;
+ case MORE:
+ return more;
+ case EQUAL:
+ return equal;
+ case LESS_OR_EQUAL:
+ return lessOrEqual;
+ case MORE_OR_EQUAL:
+ return moreOrEqual;
+ default:
+ throw new RuntimeException("Can't find operation for condition \" " + condition + "\"");
+ }
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Equal.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Equal.java
new file mode 100644
index 0000000..c4d9940
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Equal.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd.condition;
+
+public class Equal implements Condition {
+
+ @Override
+ public boolean compare(int value, int toCompare) {
+ return value == toCompare;
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Less.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Less.java
new file mode 100644
index 0000000..7d6db87
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/Less.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd.condition;
+
+public class Less implements Condition {
+
+ @Override
+ public boolean compare(int value, int toCompare) {
+ return value < toCompare;
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/LessOrEqual.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/LessOrEqual.java
new file mode 100644
index 0000000..2abd5a3
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/LessOrEqual.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd.condition;
+
+public class LessOrEqual implements Condition {
+
+ @Override
+ public boolean compare(int value, int toCompare) {
+ return value <= toCompare;
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/More.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/More.java
new file mode 100644
index 0000000..b257e30
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/More.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd.condition;
+
+public class More implements Condition {
+
+ @Override
+ public boolean compare(int value, int toCompare) {
+ return value > toCompare;
+ }
+}
diff --git a/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/MoreOrEqual.java b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/MoreOrEqual.java
new file mode 100644
index 0000000..37e9496
--- /dev/null
+++ b/sleepingcelldetector/src/main/java/org/onap/rapp/sleepingcelldetector/service/scd/condition/MoreOrEqual.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd.condition;
+
+public class MoreOrEqual implements Condition {
+
+ @Override
+ public boolean compare(int value, int toCompare) {
+ return value >= toCompare;
+ }
+}
diff --git a/sleepingcelldetector/src/main/resources/application.yml b/sleepingcelldetector/src/main/resources/application.yml
new file mode 100644
index 0000000..bfa3982
--- /dev/null
+++ b/sleepingcelldetector/src/main/resources/application.yml
@@ -0,0 +1,21 @@
+server:
+ port: 8382
+a1:
+ host: "policy-agent"
+ port: 8081
+dc:
+ host: "localhost"
+ port: 8087
+ version: "v1"
+scd:
+ prefix: "emergency"
+ slot: 10
+ count: 12
+logging:
+ level:
+ org:
+ springframework: DEBUG
+ logging.file.name: logs/rapp-sleepingcelldetector.log
+ pattern:
+ console: "%d %-5level %logger : %msg%n"
+ file: "%d %-5level [%thread] %logger : %msg%n"
diff --git a/sleepingcelldetector/src/main/resources/tca.json b/sleepingcelldetector/src/main/resources/tca.json
new file mode 100644
index 0000000..3d7baaa
--- /dev/null
+++ b/sleepingcelldetector/src/main/resources/tca.json
@@ -0,0 +1,16 @@
+[
+ {
+ "name": "latency",
+ "condition": "MORE_OR_EQUAL",
+ "averageThresholdValue": 400,
+ "latestThresholdValue": 150,
+ "latestSize": 2
+ },
+ {
+ "name": "throughput",
+ "condition": "LESS_OR_EQUAL",
+ "averageThresholdValue": 10,
+ "latestThresholdValue": 10,
+ "latestSize": 2
+ }
+]
diff --git a/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorConfigurationTest.java b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorConfigurationTest.java
new file mode 100644
index 0000000..dbf59d4
--- /dev/null
+++ b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/configuration/SleepingCellDetectorConfigurationTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.configuration;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@ComponentScan("org.onap.rapp.sleepingcelldetector.configuration")
+@EnableConfigurationProperties({A1Properties.class, DataCollectorProperties.class,
+ SleepingCellDetectorProperties.class})
+@ContextConfiguration(classes = {SleepingCellDetectorConfiguration.class})
+@TestPropertySource(properties = {"a1.host=policy-agent", "a1.port=8081",
+ "dc.host=rapp-datacollector",
+ "dc.port=8087",
+ "dc.version=v1",
+ "scd.prefix=emergency",
+ "scd.slot=10",
+ "scd.count=12"
+})
+public class SleepingCellDetectorConfigurationTest {
+
+ @Autowired()
+ private SleepingCellDetectorConfiguration config;
+
+ @Test
+ public void verifyPolicyAgentUrlConstructionTest() {
+ final String actual = config.getA1PolicyBaseUrl();
+ final String expected = "http://policy-agent:8081";
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void verifyDataCollectorUrlConstructionTest() {
+ final String actual = config.getDataCollectorBaseUrl();
+ final String expected = "http://rapp-datacollector:8087/v1";
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void verifyA1PAPropertiesTest() {
+ Assert.assertEquals(config.getPredictionTimeSlot(), 10);
+ Assert.assertEquals(config.getPredictionSlotNumber(), 12);
+ Assert.assertEquals(config.getUeFilteringPrefix(), "emergency");
+ }
+}
diff --git a/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceHandlerTest.java b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceHandlerTest.java
new file mode 100644
index 0000000..7a72c61
--- /dev/null
+++ b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/CellPerformanceHandlerTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import org.onap.rapp.sleepingcelldetector.configuration.SleepingCellDetectorConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.ue.UEInfo;
+import org.onap.rapp.sleepingcelldetector.service.scd.SleepingCellDetectorService;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CellPerformanceHandlerTest {
+
+ @Mock
+ private SleepingCellDetectorService scdClient;
+
+ @Mock
+ private RicConfigurationHolder ricConfigHolder;
+
+ @Mock
+ private PolicyInstanceManager policyInstancesManager;
+
+ @Mock
+ private SleepingCellDetectorConfiguration config;
+
+ @Mock
+ private DataCollectorClient dcClient;
+
+ private CellPerformanceHandler cellPerformanceHandler;
+
+ @Before
+ public void init() {
+ cellPerformanceHandler = new CellPerformanceHandler(scdClient, ricConfigHolder, policyInstancesManager, config, dcClient);
+ }
+
+ @Test
+ public void handleActiveCellTest() {
+ List<Map<String, Integer>> performanceData = getPMDataList(20, 80);
+ Mockito.when(scdClient.isFailing(performanceData)).thenReturn(false);
+ Mockito.when(policyInstancesManager.cellContainsPolicy("Cell1")).thenReturn(false);
+
+ cellPerformanceHandler.handleCellPerformance("Cell1", performanceData);
+
+ Mockito.verify(scdClient, Mockito.times(1)).isFailing(performanceData);
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).cellContainsPolicy("Cell1");
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).removePolicyInstancesForCell("Cell1");
+ }
+
+ @Test
+ public void handleActiveCellWithPolicyTest() {
+ List<Map<String, Integer>> performanceData = getPMDataList(20, 80);
+ Mockito.when(scdClient.isFailing( performanceData)).thenReturn(false);
+ Mockito.when(policyInstancesManager.cellContainsPolicy("Cell1")).thenReturn(true);
+
+ cellPerformanceHandler.handleCellPerformance("Cell1", performanceData);
+
+ Mockito.verify(scdClient, Mockito.times(1)).isFailing( performanceData);
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).cellContainsPolicy("Cell1");
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).removePolicyInstancesForCell("Cell1");
+ }
+
+ @Test
+ public void handleFailingCellTest() {
+ List<Map<String, Integer>> performanceData = getPMDataList(300, 2);
+ Optional<RicConfiguration> ricConfiguration = getRicConfig();
+ Mockito.when(scdClient.isFailing(performanceData)).thenReturn(true);
+ Mockito.when(policyInstancesManager.cellContainsPolicyForUe("Cell1", "emergency_samsung_s10_01")).thenReturn(false);
+ Mockito.when(policyInstancesManager.cellContainsPolicyForUe("Cell1", "emergency_police_01")).thenReturn(false);
+ Mockito.when(ricConfigHolder.getRicConfig()).thenReturn(ricConfiguration);
+ Mockito.when(dcClient.getUserEquipment()).thenReturn(getUEInfo());
+ Mockito.when(config.getUeFilteringPrefix()).thenReturn("emergency");
+
+ cellPerformanceHandler.handleCellPerformance("Cell1", performanceData);
+
+ Mockito.verify(scdClient, Mockito.times(1)).isFailing( performanceData);
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).cellContainsPolicyForUe("Cell1", "emergency_samsung_s10_01");
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).cellContainsPolicyForUe("Cell1", "emergency_police_01");
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).createPolicyInstance("Cell1", "emergency_samsung_s10_01", ricConfiguration.get());
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).createPolicyInstance("Cell1", "emergency_police_01", ricConfiguration.get());
+ }
+
+ @Test
+ public void handleFailingCellForUeWithPolicyTest() {
+ List<Map<String, Integer>> performanceData = getPMDataList(300, 2);
+ Optional<RicConfiguration> ricConfiguration = getRicConfig();
+ Mockito.when(scdClient.isFailing( performanceData)).thenReturn(true);
+ Mockito.when(policyInstancesManager.cellContainsPolicyForUe("Cell1", "emergency_samsung_s10_01")).thenReturn(false);
+ Mockito.when(policyInstancesManager.cellContainsPolicyForUe("Cell1", "emergency_police_01")).thenReturn(true);
+ Mockito.when(ricConfigHolder.getRicConfig()).thenReturn(ricConfiguration);
+ Mockito.when(dcClient.getUserEquipment()).thenReturn(getUEInfo());
+ Mockito.when(config.getUeFilteringPrefix()).thenReturn("emergency");
+
+ cellPerformanceHandler.handleCellPerformance("Cell1", performanceData);
+
+ Mockito.verify(scdClient, Mockito.times(1)).isFailing(performanceData);
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).cellContainsPolicyForUe("Cell1", "emergency_samsung_s10_01");
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).cellContainsPolicyForUe("Cell1", "emergency_police_01");
+ Mockito.verify(policyInstancesManager, Mockito.times(1)).createPolicyInstance("Cell1", "emergency_samsung_s10_01", ricConfiguration.get());
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).createPolicyInstance("Cell1", "emergency_police_01", ricConfiguration.get());
+ }
+
+ @Test
+ public void handleFailingCellForEmptyRicConfigTest() {
+ List<Map<String, Integer>> performanceData = getPMDataList(300, 2);
+ Optional<RicConfiguration> ricConfiguration = getRicConfig();
+ Mockito.when(scdClient.isFailing( performanceData)).thenReturn(true);
+ Mockito.when(ricConfigHolder.getRicConfig()).thenReturn(Optional.empty());
+
+ cellPerformanceHandler.handleCellPerformance("Cell1", performanceData);
+
+ Mockito.verify(scdClient, Mockito.times(1)).isFailing(performanceData);
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).cellContainsPolicyForUe("Cell1", "emergency_samsung_s10_01");
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).cellContainsPolicyForUe("Cell1", "emergency_police_01");
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).createPolicyInstance("Cell1", "emergency_samsung_s10_01", ricConfiguration.get());
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).createPolicyInstance("Cell1", "emergency_police_01", ricConfiguration.get());
+ }
+
+ @Test
+ public void handleFailingCellForEmptyUeListTest() {
+ List<Map<String, Integer>> performanceData = getPMDataList(300, 2);
+ Optional<RicConfiguration> ricConfiguration = getRicConfig();
+ Mockito.when(scdClient.isFailing( performanceData)).thenReturn(true);
+ Mockito.when(ricConfigHolder.getRicConfig()).thenReturn(ricConfiguration);
+ Mockito.when(dcClient.getUserEquipment()).thenReturn(new UEInfo(Collections.emptyList()));
+
+ cellPerformanceHandler.handleCellPerformance("Cell1", performanceData);
+
+ Mockito.verify(scdClient, Mockito.times(1)).isFailing(performanceData);
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).cellContainsPolicyForUe("Cell1", "emergency_samsung_s10_01");
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).cellContainsPolicyForUe("Cell1", "emergency_police_01");
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).createPolicyInstance("Cell1", "emergency_samsung_s10_01", ricConfiguration.get());
+ Mockito.verify(policyInstancesManager, Mockito.times(0)).createPolicyInstance("Cell1", "emergency_police_01", ricConfiguration.get());
+ }
+
+ public static List<Map<String, Integer>> getPMDataList(int latency, int throughput) {
+ List<Map<String, Integer>> performanceData = new ArrayList<>();
+ for (int i = 0; i < 12; i++) {
+ Map<String, Integer> measurement = new HashMap<>();
+ measurement.put("latency", latency);
+ measurement.put("throughput", throughput);
+ performanceData.add(measurement);
+ }
+ return performanceData;
+ }
+
+ private Optional<RicConfiguration> getRicConfig() {
+ return Optional.of(new RicConfiguration("ric1", Collections.emptyList(), List.of("1000"), "AVAILABLE"));
+ }
+
+ private UEInfo getUEInfo() {
+ return new UEInfo(List.of("emergency_samsung_s10_01", "mobile_samsung_s20_02", "emergency_police_01"));
+ }
+
+}
diff --git a/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/JsonHelperTest.java b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/JsonHelperTest.java
new file mode 100644
index 0000000..e6768e4
--- /dev/null
+++ b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/JsonHelperTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import com.google.common.collect.Lists;
+import org.onap.rapp.sleepingcelldetector.entity.MeasurementConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.policy.A1PolicyEvent;
+import org.onap.rapp.sleepingcelldetector.entity.policy.PolicyInstance;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Preference;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Resources;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Scope;
+import org.onap.rapp.sleepingcelldetector.service.scd.condition.ConditionEnum;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class JsonHelperTest {
+
+ private static final String policy = "{\r\n" +
+ " \"id\" : \"1\",\r\n" +
+ " \"type\" : \"1000\",\r\n" +
+ " \"ric\" : \"ric1\",\r\n" +
+ " \"service\" : \"sleepingcelldetector\",\r\n" +
+ " \"lastModified\" : null,\r\n" +
+ " \"json\" : {\r\n" +
+ " \"scope\" : {\r\n" +
+ " \"ueId\" : \"ue_1\"\r\n" +
+ " },\r\n" +
+ " \"resources\" : [ {\r\n" +
+ " \"cellIdList\" : [ \"Cell1\" ],\r\n" +
+ " \"preference\" : \"AVOID\"\r\n" +
+ " } ]\r\n" +
+ " }\r\n" +
+ "}";
+
+ private static final String tcaConfig = "[\n" +
+ " {\n" +
+ " \"name\": \"latency\",\n" +
+ " \"condition\": \"MORE_OR_EQUAL\",\n" +
+ " \"averageThresholdValue\": 400,\n" +
+ " \"latestThresholdValue\": 150,\n" +
+ " \"latestSize\" : 2\n" +
+ " },\n" +
+ " {\n" +
+ " \"name\": \"throughput\",\n" +
+ " \"condition\": \"LESS_OR_EQUAL\",\n" +
+ " \"averageThresholdValue\": 10,\n" +
+ " \"latestThresholdValue\": 10,\n" +
+ " \"latestSize\" : 2\n" +
+ " }\n" +
+ "]";
+
+ JsonHelper jsonHelper;
+
+ @Before()
+ public void initialSetUp() {
+ jsonHelper = new JsonHelper();
+ }
+
+ @Test
+ public void policyToJsonStringTest() {
+ PolicyInstance instance = getPolicyToCompare();
+ assertThat(policy).isEqualToNormalizingNewlines(jsonHelper.objectToJsonString(instance));
+ }
+
+ @Test
+ public void tcaConfigDeserializeTest() {
+ MeasurementConfiguration[] configurations = jsonHelper.deserialize(tcaConfig, MeasurementConfiguration[].class);
+ assertThat(configurations).isEqualTo(prepareTcaConfig());
+ }
+
+ private PolicyInstance getPolicyToCompare() {
+ Scope scope = new Scope("ue_1");
+ Resources resources = new Resources(Lists.newArrayList("Cell1"), Preference.AVOID);
+ return PolicyInstance.builder()
+ .json(new A1PolicyEvent(scope, Lists.newArrayList(resources)))
+ .service("sleepingcelldetector")
+ .ric("ric1")
+ .id("1")
+ .type("1000")
+ .build();
+ }
+
+ private MeasurementConfiguration[] prepareTcaConfig() {
+ MeasurementConfiguration latencyConfig = new MeasurementConfiguration("latency", ConditionEnum.MORE_OR_EQUAL, 400, 150, 2);
+ MeasurementConfiguration throughputConfig = new MeasurementConfiguration("throughput", ConditionEnum.LESS_OR_EQUAL, 10, 10, 2);
+ return new MeasurementConfiguration[]{latencyConfig, throughputConfig};
+ }
+
+}
diff --git a/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyAgentClientTest.java b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyAgentClientTest.java
new file mode 100644
index 0000000..8eb2a31
--- /dev/null
+++ b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyAgentClientTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import com.google.common.collect.Lists;
+import org.onap.rapp.sleepingcelldetector.configuration.SleepingCellDetectorConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.policy.A1PolicyEvent;
+import org.onap.rapp.sleepingcelldetector.entity.policy.PolicyInstance;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Preference;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Resources;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Scope;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.web.client.RestTemplate;
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(MockitoJUnitRunner.class)
+public class PolicyAgentClientTest {
+
+ @Mock
+ SleepingCellDetectorConfiguration config;
+
+ @Mock
+ RestTemplate restTemplate;
+
+ @Mock
+ JsonHelper jsonHelper;
+
+ private static final String policy = "{\r\n" +
+ " \"scope\" : {\r\n" +
+ " \"ueId\" : \"ue_1\"\r\n" +
+ " },\r\n" +
+ " \"resources\" : [ {\r\n" +
+ " \"cellIdList\" : [ \"Cell1\" ],\r\n" +
+ " \"preference\" : \"AVOID\"\r\n" +
+ " } ]\r\n" +
+ "}";
+
+ PolicyAgentClient policyAgentClient;
+
+ @Before
+ public void init() throws Exception {
+ policyAgentClient = new PolicyAgentClient(config, restTemplate, jsonHelper);
+ }
+
+ @Test
+ public void sendPolicyTest(){
+ PolicyInstance instance = getPolicyInstance();
+ RicConfiguration ricConfiguration = getRicConfig();
+ Mockito.when(config.getA1PolicyBaseUrl()).thenReturn("http://rapp-datacollector:8087");
+ Mockito.when(jsonHelper.objectToJsonString(instance.getJson())).thenReturn(policy);
+
+ policyAgentClient.sendPolicyEvent(instance, ricConfiguration);
+
+ Mockito.verify(config, Mockito.times(1)).getA1PolicyBaseUrl();
+ Mockito.verify(restTemplate, Mockito.times(1)).put("http://rapp-datacollector:8087/policy?id=1&ric=ric1&service=rapp-sleepingcelldetector&type=1000", getHttpEntity(policy));
+ }
+
+ @Test
+ public void removePolicyTest(){
+ Mockito.when(config.getA1PolicyBaseUrl()).thenReturn("http://rapp-datacollector:8087");
+
+ policyAgentClient.deletePolicyInstance("1");
+
+ Mockito.verify(config, Mockito.times(1)).getA1PolicyBaseUrl();
+ Mockito.verify(restTemplate, Mockito.times(1)).delete("http://rapp-datacollector:8087/policy?id=1");
+ }
+
+ private PolicyInstance getPolicyInstance() {
+ Scope scope = new Scope("ue_1");
+ Resources resources = new Resources(Lists.newArrayList("Cell1"), Preference.AVOID);
+ return PolicyInstance.builder()
+ .json(new A1PolicyEvent(scope, Lists.newArrayList(resources)))
+ .service("sleepingcelldetector")
+ .ric("ric1")
+ .id("1")
+ .type("1000")
+ .build();
+ }
+
+ private RicConfiguration getRicConfig() {
+ return new RicConfiguration("ric1", Collections.emptyList(), List.of("1000"), "AVAILABLE");
+ }
+
+ private HttpEntity<String> getHttpEntity(String policy) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ return new HttpEntity<>(policy, headers);
+ }
+}
diff --git a/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceBuilderTest.java b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceBuilderTest.java
new file mode 100644
index 0000000..5c6b459
--- /dev/null
+++ b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceBuilderTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import com.google.common.collect.Lists;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.policy.A1PolicyEvent;
+import org.onap.rapp.sleepingcelldetector.entity.policy.PolicyInstance;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Preference;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Resources;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Scope;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+public class PolicyInstanceBuilderTest {
+
+ private PolicyInstanceBuilder policyInstanceBuilder;
+
+ @Test
+ public void buildPolicyInstanceTest(){
+ policyInstanceBuilder = new PolicyInstanceBuilder();
+ PolicyInstance policyToCompare = getPolicyToCompare();
+ RicConfiguration ricConfiguration = getRicConfig();
+
+ PolicyInstance policy = policyInstanceBuilder.buildPolicyInstance("Cell1", "ue_1", ricConfiguration);
+
+ Assert.assertEquals(policy.getJson(), policyToCompare.getJson());
+ Assert.assertEquals(policy.getLastModified(), policyToCompare.getLastModified());
+ Assert.assertEquals(policy.getService(), policyToCompare.getService());
+ Assert.assertEquals(policy.getRic(), policyToCompare.getRic());
+ }
+
+ private PolicyInstance getPolicyToCompare() {
+ Scope scope = new Scope("ue_1");
+ Resources resources = new Resources(Lists.newArrayList("Cell1"), Preference.AVOID);
+ return PolicyInstance.builder()
+ .json(new A1PolicyEvent(scope, Lists.newArrayList(resources)))
+ .service("sleepingcelldetector")
+ .ric("ric1")
+ .build();
+ }
+
+ private RicConfiguration getRicConfig() {
+ return new RicConfiguration("ric1", Collections.emptyList(), List.of("1000"), "AVAILABLE");
+ }
+
+}
diff --git a/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceManagerTest.java b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceManagerTest.java
new file mode 100644
index 0000000..64277de
--- /dev/null
+++ b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/PolicyInstanceManagerTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service;
+
+import com.google.common.collect.Lists;
+import org.onap.rapp.sleepingcelldetector.entity.RicConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.policy.A1PolicyEvent;
+import org.onap.rapp.sleepingcelldetector.entity.policy.PolicyInstance;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Preference;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Resources;
+import org.onap.rapp.sleepingcelldetector.entity.policy.Scope;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(MockitoJUnitRunner.class)
+public class PolicyInstanceManagerTest {
+
+ @Mock
+ PolicyAgentClient policyAgentClient;
+
+ @Mock
+ PolicyInstanceBuilder policyInstanceBuilder;
+
+ PolicyInstanceManager policyInstanceManager;
+
+ @Test
+ public void createInstanceTest() {
+ initPolicyInstanceManager();
+ RicConfiguration ricConfiguration = getRicConfig();
+ PolicyInstance policyInstance = getPolicy(ricConfiguration);
+ Mockito.when(policyInstanceBuilder.buildPolicyInstance("Cell1", "ue_1", ricConfiguration))
+ .thenReturn(policyInstance);
+
+ Mockito.doNothing().when(policyAgentClient).sendPolicyEvent(policyInstance, ricConfiguration);
+
+ policyInstanceManager.createPolicyInstance("Cell1", "ue_1", ricConfiguration);
+
+ Mockito.verify(policyAgentClient, Mockito.times(1)).sendPolicyEvent(policyInstance, ricConfiguration);
+ containsPolicyTest(policyInstanceManager);
+ }
+
+ @Test
+ public void addInstanceTest(){
+ initPolicyInstanceManager();
+ RicConfiguration ricConfiguration = getRicConfig();
+ PolicyInstance policyInstance = getPolicy(ricConfiguration);
+
+ policyInstanceManager.addPolicyInstance(policyInstance);
+ containsPolicyTest(policyInstanceManager);
+ }
+
+ @Test
+ public void removeInstanceTest(){
+ initPolicyInstanceManager();
+ RicConfiguration ricConfiguration = getRicConfig();
+ PolicyInstance policyInstance = getPolicy(ricConfiguration);
+
+ policyInstanceManager.addPolicyInstance(policyInstance);
+ policyInstanceManager.removePolicyInstancesForCell("Cell1");
+ Assert.assertFalse(policyInstanceManager.cellContainsPolicy("Cell1"));
+ Assert.assertFalse(policyInstanceManager.cellContainsPolicyForUe("Cell1", "ue_1"));
+ }
+
+
+ private void containsPolicyTest(PolicyInstanceManager policyInstanceManager){
+ Assert.assertTrue(policyInstanceManager.cellContainsPolicy("Cell1"));
+ Assert.assertTrue(policyInstanceManager.cellContainsPolicyForUe("Cell1", "ue_1"));
+ Assert.assertFalse(policyInstanceManager.cellContainsPolicy("Cell2"));
+ Assert.assertFalse(policyInstanceManager.cellContainsPolicyForUe("Cell2", "ue_1"));
+ Assert.assertFalse(policyInstanceManager.cellContainsPolicyForUe("Cell1", "ue_2"));
+ Assert.assertFalse(policyInstanceManager.cellContainsPolicyForUe("Cell2", "ue_2"));
+ }
+
+ private void initPolicyInstanceManager(){
+ policyInstanceManager = new PolicyInstanceManager(policyAgentClient, policyInstanceBuilder);
+ }
+
+
+ private RicConfiguration getRicConfig() {
+ return new RicConfiguration("ric1", Collections.emptyList(), List.of("1000"), "AVAILABLE");
+ }
+
+ private PolicyInstance getPolicy(RicConfiguration configuration) {
+ Scope scope = new Scope("ue_1");
+ Resources resources = new Resources(Lists.newArrayList("Cell1"), Preference.AVOID);
+ return PolicyInstance.builder()
+ .json(new A1PolicyEvent(scope, Lists.newArrayList(resources)))
+ .service("sleepingcelldetector")
+ .ric(configuration.getRicName())
+ .build();
+ }
+}
diff --git a/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/scd/CalculationUtilTest.java b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/scd/CalculationUtilTest.java
new file mode 100644
index 0000000..f402fe9
--- /dev/null
+++ b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/scd/CalculationUtilTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd;
+
+import org.assertj.core.util.Lists;
+import org.junit.Assert;
+import org.junit.Test;
+import java.util.List;
+
+public class CalculationUtilTest {
+
+ @Test
+ public void calculateAverageTest(){
+ List<Integer> integers = Lists.list(1,2,3,4,5,6,7,8,9);
+ Assert.assertEquals(CalculationUtil.calculateAverage(integers), Integer.valueOf(5));
+ }
+
+ @Test
+ public void calculateAverageWithSameValuesTest(){
+ List<Integer> integers = Lists.list(1,1,1,1,1,1,1,1,1);
+ Assert.assertEquals(CalculationUtil.calculateAverage(integers), Integer.valueOf(1));
+ }
+
+ @Test
+ public void fillGapsInBeginningTest(){
+ List<Integer> integers = Lists.list(null,null,null,1,2,3,4,5,6,7,8,9);
+ List<Integer> integersToCompare = List.of(5,5,5,1,2,3,4,5,6,7,8,9);
+ Assert.assertEquals(CalculationUtil.fillGaps(integers), integersToCompare);
+ }
+
+ @Test
+ public void fillGapsInMiddleTest(){
+ List<Integer> integers = Lists.list(1,2,3,4,null,null,null,5,6,7,8,9);
+ List<Integer> integersToCompare = List.of(1,2,3,4,5,5,5,5,6,7,8,9);
+ Assert.assertEquals(CalculationUtil.fillGaps(integers), integersToCompare);
+ }
+
+ @Test
+ public void fillGapsInEndTest(){
+ List<Integer> integers = Lists.list(1,2,3,4,5,6,7,8,9,null,null,null);
+ List<Integer> integersToCompare = List.of(1,2,3,4,5,6,7,8,9,5,5,5);
+ Assert.assertEquals(CalculationUtil.fillGaps(integers), integersToCompare);
+ }
+
+ @Test
+ public void fillGapsWithNotEnoughDataTest(){
+ List<Integer> integers = Lists.list(1,2,3,null,null,null,null,null,null,null,null,null);
+ Exception exception = Assert.assertThrows(ArithmeticException.class, () -> CalculationUtil.fillGaps(integers));
+
+ String expectedMessage = "Not enough performance data for prediction, data filling: 25.0%";
+ String actualMessage = exception.getMessage();
+
+ Assert.assertEquals(actualMessage, expectedMessage);
+ }
+
+
+}
diff --git a/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/scd/SleepingCellDetectorServiceTest.java b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/scd/SleepingCellDetectorServiceTest.java
new file mode 100644
index 0000000..4caa5f1
--- /dev/null
+++ b/sleepingcelldetector/src/test/java/org/onap/rapp/sleepingcelldetector/service/scd/SleepingCellDetectorServiceTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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
+ */
+
+package org.onap.rapp.sleepingcelldetector.service.scd;
+
+import org.onap.rapp.sleepingcelldetector.configuration.SleepingCellDetectorConfiguration;
+import org.onap.rapp.sleepingcelldetector.entity.MeasurementConfiguration;
+import org.onap.rapp.sleepingcelldetector.service.CellPerformanceHandlerTest;
+import org.onap.rapp.sleepingcelldetector.service.JsonHelper;
+import org.onap.rapp.sleepingcelldetector.service.scd.condition.ConditionEnum;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SleepingCellDetectorServiceTest {
+
+ private SleepingCellDetectorService sleepingCellDetectorService;
+
+ @Mock
+ SleepingCellDetectorConfiguration configuration;
+
+ @Before
+ public void init() {
+ sleepingCellDetectorService = new SleepingCellDetectorService(new JsonHelper(), configuration);
+ sleepingCellDetectorService.measurementMap = prepareMeasurementConfig();
+ }
+
+ @Test
+ public void predictingActiveCellTestWithFullDataTest() {
+ Mockito.when(configuration.getPredictionSlotNumber()).thenReturn(12);
+ boolean prediction = sleepingCellDetectorService.isFailing(CellPerformanceHandlerTest.getPMDataList(20, 80));
+ Assert.assertFalse(prediction);
+ }
+
+ @Test
+ public void predictingActiveCellTWithEmptyDataOnBeginningTest() {
+ Mockito.when(configuration.getPredictionSlotNumber()).thenReturn(12);
+ boolean prediction = sleepingCellDetectorService.isFailing(preparePerformanceDataWithEmptyDataOnBeginning(20, 80));
+ Assert.assertFalse(prediction);
+ }
+
+ @Test
+ public void predictingActiveCellTWithEmptyDataInMiddleTest() {
+ Mockito.when(configuration.getPredictionSlotNumber()).thenReturn(12);
+ boolean prediction = sleepingCellDetectorService.isFailing(preparePerformanceDataWithEmptyDataInMiddle(20, 80));
+ Assert.assertFalse(prediction);
+ }
+
+ @Test
+ public void predictingActiveCellTWithEmptyDataInEndTest() {
+ Mockito.when(configuration.getPredictionSlotNumber()).thenReturn(12);
+ boolean prediction = sleepingCellDetectorService.isFailing(preparePerformanceDataWithEmptyDataInEnd(20, 80));
+ Assert.assertFalse(prediction);
+ }
+
+ @Test
+ public void predictingFailingCellTestWithFullDataTest() {
+ Mockito.when(configuration.getPredictionSlotNumber()).thenReturn(12);
+ boolean prediction = sleepingCellDetectorService.isFailing(CellPerformanceHandlerTest.getPMDataList(500, 5));
+ Assert.assertTrue(prediction);
+ }
+
+ @Test
+ public void predictingFailingCellTWithEmptyDataOnBeginningTest() {
+ Mockito.when(configuration.getPredictionSlotNumber()).thenReturn(12);
+ boolean prediction = sleepingCellDetectorService.isFailing(preparePerformanceDataWithEmptyDataOnBeginning(500, 5));
+ Assert.assertTrue(prediction);
+ }
+
+ @Test
+ public void predictingFailingCellTWithEmptyDataInMiddleTest() {
+ Mockito.when(configuration.getPredictionSlotNumber()).thenReturn(12);
+ boolean prediction = sleepingCellDetectorService.isFailing(preparePerformanceDataWithEmptyDataInMiddle(500, 5));
+ Assert.assertTrue(prediction);
+ }
+
+ @Test
+ public void predictingFailingCellTWithEmptyDataInEndTest() {
+ Mockito.when(configuration.getPredictionSlotNumber()).thenReturn(12);
+ boolean prediction = sleepingCellDetectorService.isFailing(preparePerformanceDataWithEmptyDataInEnd(500, 5));
+ Assert.assertTrue(prediction);
+ }
+
+ private List<Map<String, Integer>> preparePerformanceDataWithEmptyDataOnBeginning(int latency, int throughput){
+ List<Map<String, Integer>> pmList = CellPerformanceHandlerTest.getPMDataList(latency, throughput);
+ pmList.set(0, getEmptyMeasurementsData());
+ pmList.set(1, getEmptyMeasurementsData());
+ pmList.set(2, getEmptyMeasurementsData());
+ return pmList;
+ }
+
+ private List<Map<String, Integer>> preparePerformanceDataWithEmptyDataInMiddle(int latency, int throughput){
+ List<Map<String, Integer>> pmList = CellPerformanceHandlerTest.getPMDataList(latency, throughput);
+ pmList.set(6, getEmptyMeasurementsData());
+ pmList.set(7, getEmptyMeasurementsData());
+ pmList.set(8, getEmptyMeasurementsData());
+ return pmList;
+ }
+
+ private List<Map<String, Integer>> preparePerformanceDataWithEmptyDataInEnd(int latency, int throughput){
+ List<Map<String, Integer>> pmList = CellPerformanceHandlerTest.getPMDataList(latency, throughput);
+ pmList.set(9, getEmptyMeasurementsData());
+ pmList.set(10, getEmptyMeasurementsData());
+ pmList.set(11, getEmptyMeasurementsData());
+ return pmList;
+ }
+
+ private Map<String, Integer> getEmptyMeasurementsData() {
+ Map<String, Integer> emptyDataMap = new HashMap<>();
+ emptyDataMap.put("latency", null);
+ emptyDataMap.put("throughput", null);
+ return emptyDataMap;
+ }
+
+ private Map<String, MeasurementConfiguration> prepareMeasurementConfig() {
+ MeasurementConfiguration latencyConfig = new MeasurementConfiguration("latency", ConditionEnum.MORE_OR_EQUAL, 400, 150, 2);
+ MeasurementConfiguration throughputConfig = new MeasurementConfiguration("throughput", ConditionEnum.LESS_OR_EQUAL, 10, 10, 2);
+
+ Map<String, MeasurementConfiguration> configMap = new HashMap<>();
+ configMap.put("latency", latencyConfig);
+ configMap.put("throughput", throughputConfig);
+
+ return configMap;
+ }
+}