summaryrefslogtreecommitdiffstats
path: root/components/slice-analysis-ms
diff options
context:
space:
mode:
Diffstat (limited to 'components/slice-analysis-ms')
-rw-r--r--components/slice-analysis-ms/ChangeLog.md4
-rw-r--r--components/slice-analysis-ms/pom.xml6
-rw-r--r--components/slice-analysis-ms/src/main/docker/config/sliceanalysisms/config_all.json47
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/aai/AaiInterface.java (renamed from components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/AaiInterface.java)12
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/aai/AaiService.java350
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/AaiService.java179
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/CpsService.java137
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/controller/SliceConfiguraton.java58
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/cps/CpsInterface.java (renamed from components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/CpsInterface.java)19
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/cps/CpsService.java141
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/exception/CpsClientException.java34
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/exception/DesClientException.java34
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/AggregatedConfig.java39
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/Configuration.java613
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigDetails.java36
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigRequest.java42
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigResponse.java38
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/Relationship.java50
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/RelationshipList.java38
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/ServiceInstance.java55
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/restclients/DesRestClient.java64
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ConsumerThread.java150
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/MLMessageProcessor.java87
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SliceUtilization.java216
-rw-r--r--components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SnssaiSamplesProcessor.java385
-rw-r--r--components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/aai/AaiInterfaceServiceTest.java284
-rw-r--r--components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/configdb/AaiInterfaceServiceTest.java114
-rw-r--r--components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/configdb/CpsInterfaceServiceTest.java109
-rw-r--r--components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/controller/SliceConfiguratonTest.java97
-rw-r--r--components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/cps/CpsInterfaceServiceTest.java110
-rw-r--r--components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/models/ModelsTest.java51
-rw-r--r--components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/MLMessageProcessorTest.java112
-rw-r--r--components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/SliceUtilizationTest.java174
-rw-r--r--components/slice-analysis-ms/src/test/resources/alloted-resource.json115
-rw-r--r--components/slice-analysis-ms/src/test/resources/nsi.json122
-rw-r--r--components/slice-analysis-ms/src/test/resources/nssi.json165
-rw-r--r--components/slice-analysis-ms/src/test/resources/pm_data.json17
-rw-r--r--components/slice-analysis-ms/src/test/resources/sliceConfigRequest.json21
-rw-r--r--components/slice-analysis-ms/src/test/resources/sliceConfigResponse.json20
-rw-r--r--components/slice-analysis-ms/src/test/resources/sliceprofile_an_sa1.json155
-rw-r--r--components/slice-analysis-ms/src/test/resources/sliceprofile_cn_sa1.json80
-rw-r--r--components/slice-analysis-ms/src/test/resources/sliceprofile_tn_sa1.json68
42 files changed, 3432 insertions, 1216 deletions
diff --git a/components/slice-analysis-ms/ChangeLog.md b/components/slice-analysis-ms/ChangeLog.md
index fa59c34d..f2aab16c 100644
--- a/components/slice-analysis-ms/ChangeLog.md
+++ b/components/slice-analysis-ms/ChangeLog.md
@@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [DCAEGEN2-3054](https://jira.onap.org/browse/DCAEGEN2-3054) - Remove security vulnerabilities
+ - [DCAEGEN2-2942](https://jira.onap.org/browse/DCAEGEN2-2942) - Calculate slice utilization data
+
+ - [DCAEGEN2-3034](https://jira.onap.org/browse/DCAEGEN2-3034) - Migrate SliceAnalysis MS to use unauthenticated topic
+
## [1.0.6] - 2021/08/28
- [DCAEGEN2-2885](https://jira.onap.org/browse/DCAEGEN2-2885) - DCAE SliceAnalysis MS - CPS Integration
diff --git a/components/slice-analysis-ms/pom.xml b/components/slice-analysis-ms/pom.xml
index f4fde501..7b909c5a 100644
--- a/components/slice-analysis-ms/pom.xml
+++ b/components/slice-analysis-ms/pom.xml
@@ -282,6 +282,12 @@
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <version>1.18.22</version>
+ <scope>provided</scope>
</dependency>
</dependencies>
<build>
diff --git a/components/slice-analysis-ms/src/main/docker/config/sliceanalysisms/config_all.json b/components/slice-analysis-ms/src/main/docker/config/sliceanalysisms/config_all.json
index 21a82344..26da5523 100644
--- a/components/slice-analysis-ms/src/main/docker/config/sliceanalysisms/config_all.json
+++ b/components/slice-analysis-ms/src/main/docker/config/sliceanalysisms/config_all.json
@@ -5,7 +5,7 @@
"aaf_password": null,
"type": "message-router",
"dmaap_info": {
- "topic_url": "https://message-router.onap.svc.cluster.local:3905/events/unauthenticated.VES_MEASUREMENT_OUTPUT",
+ "topic_url": "http://message-router.onap.svc.cluster.local:3904/events/unauthenticated.PERFORMANCE_MEASUREMENTS",
"client_role": "sliceanalysis-subscriber",
"location": "onap",
"client_id": "sdnr-sliceanalysis-1"
@@ -16,7 +16,18 @@
"aaf_password": null,
"type": "message-router",
"dmaap_info": {
- "topic_url": "https://message-router.onap.svc.cluster.local:3905/events/DCAE_CL_RSP",
+ "topic_url": "http://message-router.onap.svc.cluster.local:3904/events/DCAE_CL_RSP",
+ "client_role": "sliceanalysis-subscriber",
+ "location": "onap",
+ "client_id": "sdnr-sliceanalysis-1"
+ },
+ "aaf_username": null
+ },
+ "intelligent_slicing_topic": {
+ "aaf_password": null,
+ "type": "message-router",
+ "dmaap_info": {
+ "topic_url": "http://message-router.onap.svc.cluster.local:3904/events/unauthenticated.ML_RESPONSE_TOPIC",
"client_role": "sliceanalysis-subscriber",
"location": "onap",
"client_id": "sdnr-sliceanalysis-1"
@@ -29,7 +40,7 @@
"aaf_password": null,
"type": "message-router",
"dmaap_info": {
- "topic_url": "https://message-router.onap.svc.cluster.local:3905/events/unauthenticated.DCAE_CL_OUTPUT",
+ "topic_url": "http://message-router.onap.svc.cluster.local:3904/events/unauthenticated.DCAE_CL_OUTPUT",
"client_role": "sliceanalysis-subscriber",
"location": "onap",
"client_id": "sdnr-sliceanalysis-1"
@@ -47,13 +58,35 @@
"cbsPollingInterval": 60,
"sliceanalysisms.cg": "sliceanalysisms-cg",
"sliceanalysisms.pollingInterval": 20,
+ "sliceanalysisms.samples": 3,
+ "sliceanalysisms.minPercentageChange": 5,
+ "sliceanalysisms.initialDelaySeconds": 300000,
+ "sliceanalysisms.pollingTimeout": 60,
"sliceanalysisms.cid": "sliceanalysisms-cid",
- "sliceanalysisms.configDb.service": "http://sdnc.onap:8181",
+ "sliceanalysisms.configDb.service": "http://configdb_sim:5000",
+ "sliceanalysisms.aai.url": "https://aai-resources:8447/aai/v21",
+ "sliceanalysisms.cps.url": "http://cps-tbdmt:8080/execute/ran-network",
+ "sliceanalysisms.configDbEnabled": "false",
+ "sliceanalysisms.rannfnssiDetailsTemplateId": "get-rannfnssiid-details",
+ "sliceanalysisms.desUrl": "http://dl-des:1681/datalake/v1/exposure/pm_data",
+ "sliceanalysisms.pmDataDurationInWeeks": 4,
"service_calls": {
"policy-req": []
- }
+ },
+ "trust_store_path": "/opt/app/sliceanalysisms/etc/cert/trust.jks",
+ "trust_store_pass_path": "/opt/app/sliceanalysisms/etc/cert/trust.pass"
},
- "policies": {
-
+ "policies": {
+ "event": {
+ "action": "gathered",
+ "timestamp": "2019-09-18T14:57:55.320Z",
+ "update_id": "dbb88da8-8df1-489d-b51d-8d5cbbfbcd99",
+ "policies_count": 1
+ },
+ "items": [
+ {
+ "policyName": "com.Config_PCIMS_CONFIG_POLICY.1.xml"
+ }
+ ]
}
}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/AaiInterface.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/aai/AaiInterface.java
index 68b795b5..87718a5c 100644
--- a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/AaiInterface.java
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/aai/AaiInterface.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* slice-analysis-ms
* ================================================================================
- * Copyright (C) 2021 Wipro Limited.
+ * Copyright (C) 2021-2022 Wipro Limited.
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,18 +19,18 @@
*
*******************************************************************************/
-package org.onap.slice.analysis.ms.configdb;
+package org.onap.slice.analysis.ms.aai;
import java.util.Map;
/**
- *
+ *
* Interface for AAI
*
*/
public interface AaiInterface {
- public Map<String, String> fetchServiceDetails(String snssai);
- public Map<String, Integer> fetchCurrentConfigurationOfSlice(String snssai);
-}
+ public Map<String, String> fetchServiceDetails(String snssai);
+ public Map<String, Integer> fetchCurrentConfigurationOfSlice(String snssai);
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/aai/AaiService.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/aai/AaiService.java
new file mode 100644
index 00000000..6284ddfb
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/aai/AaiService.java
@@ -0,0 +1,350 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2021-2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.aai;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.onap.slice.analysis.ms.models.Configuration;
+import org.onap.slice.analysis.ms.models.aai.ServiceInstance;
+import org.onap.slice.analysis.ms.restclients.AaiRestClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * Service for AAI interfaces
+ *
+ */
+@Service
+public class AaiService implements AaiInterface {
+
+ private static Logger log = LoggerFactory.getLogger(Configuration.class);
+
+ @Autowired
+ AaiRestClient restclient;
+
+ private static ObjectMapper objectMapper = new ObjectMapper();
+ private static String globalSubscriberId;
+ private static String subscriptionServiceType;
+ private static String aaiBaseUrl = Configuration.getInstance().getAaiUrl();
+
+ /**
+ * Fetches the details of a service
+ *
+ * @param snssai SNSSAI ID
+ * @return responseMap contains service details
+ */
+ public Map<String, String> fetchServiceDetails(String snssai) {
+ Map<String, String> responseMap = fetchSubscriberAndSubscriptionServiceType();
+ String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
+ + "/service-subscriptions/service-subscription/" + subscriptionServiceType + "/service-instances";
+ String serviceRole = "AN-NF";
+ try {
+ String serviceInstance =
+ restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONObject serviceInstanceJson = new JSONObject(serviceInstance);
+ JSONArray serviceInstanceList = serviceInstanceJson.getJSONArray("service-instance");
+ for (int i = 0; i < serviceInstanceList.length(); i++) {
+ JSONObject serviceObj = serviceInstanceList.getJSONObject(i);
+ if (serviceObj.getString("environment-context").equalsIgnoreCase(snssai)) {
+ responseMap.put("sliceProfileId", serviceObj.getString("service-instance-id"));
+ }
+ }
+
+ String serviceRoleReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
+ + "/service-subscriptions/service-subscription/" + subscriptionServiceType
+ + "/service-instances/?service-role=nssi&depth=2";
+
+ String serviceInstanceForServiceRole =
+ restclient.sendGetRequest(serviceRoleReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONObject serviceInstanceForServiceRoleJson = new JSONObject(serviceInstanceForServiceRole);
+ JSONArray serviceInstanceListForServiceRole =
+ serviceInstanceForServiceRoleJson.getJSONArray("service-instance");
+ for (int i = 0; i < serviceInstanceListForServiceRole.length(); i++) {
+ JSONObject serviceObj = serviceInstanceListForServiceRole.getJSONObject(i);
+ if (serviceObj.getString("workload-context").trim().equalsIgnoreCase(serviceRole)) {
+ responseMap.put("ranNFNSSIId", serviceObj.getString("service-instance-id"));
+ }
+ }
+ } catch (Exception e) {
+ log.info("Exception while fetching serviceDetails: " + e);
+ }
+ responseMap.put("sNSSAI", snssai);
+ log.info("subscriber details: " + responseMap);
+ return responseMap;
+ }
+
+ /**
+ * Fetches the current configuration of a Slice from AAI
+ *
+ * @param snssai SNSSAI ID
+ * @return responseMap contains slice configuration
+ */
+ public Map<String, Integer> fetchCurrentConfigurationOfSlice(String snssai) {
+ log.info("AAI fetch config Slice: " + aaiBaseUrl);
+ String serviceInstaneId = null;
+ String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
+ + "/service-subscriptions/service-subscription/" + subscriptionServiceType + "/service-instances";
+ Map<String, Integer> responseMap = new HashMap<String, Integer>();
+ try {
+ String serviceInstance =
+ restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONObject serviceInstanceJson = new JSONObject(serviceInstance);
+
+ JSONArray serviceInstanceList = serviceInstanceJson.getJSONArray("service-instance");
+ for (int i = 0; i < serviceInstanceList.length(); i++) {
+ JSONObject serviceObj = serviceInstanceList.getJSONObject(i);
+ if (serviceObj.getString("environment-context").equalsIgnoreCase(snssai)) {
+ serviceInstaneId = serviceObj.getString("service-instance-id");
+ }
+ }
+
+ String sliceProfileReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
+ + "/service-subscriptions/service-subscription/" + subscriptionServiceType
+ + "/service-instances/service-instance/" + serviceInstaneId + "/slice-profiles";
+
+ String sliceProfile = restclient
+ .sendGetRequest(sliceProfileReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONObject sliceProfileJson = new JSONObject(sliceProfile);
+ JSONArray sliceProfileList = sliceProfileJson.getJSONArray("slice-profile");
+ for (int i = 0; i < sliceProfileList.length(); i++) {
+ JSONObject sliceProfileObj = sliceProfileList.getJSONObject(i);
+ responseMap.put("dLThptPerSlice", sliceProfileObj.getInt("exp-data-rate-UL"));
+ responseMap.put("uLThptPerSlice", sliceProfileObj.getInt("exp-data-rate-DL"));
+ break;
+ }
+ log.info("Slice configuration: " + responseMap);
+ } catch (Exception e) {
+ log.info("AAI Slice: " + e);
+ }
+ return responseMap;
+ }
+
+ /**
+ * Fetches the details of a subscriber and subscription Service
+ *
+ * @return responseMap contains details of subscriber and subscription service
+ */
+ public Map<String, String> fetchSubscriberAndSubscriptionServiceType() {
+
+ Map<String, String> responseMap = new HashMap<String, String>();
+
+ log.info("Get GlobalSubscriberId");
+ String subscriberReqUrl = aaiBaseUrl + "/business/customers";
+ try {
+ String subscriberReq =
+ restclient.sendGetRequest(subscriberReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONObject subscriberReqJson = new JSONObject(subscriberReq);
+ JSONArray subscriberReqJsonList = subscriberReqJson.getJSONArray("customer");
+ for (int i = 0; i < subscriberReqJsonList.length(); i++) {
+ JSONObject subscriberReqObj = subscriberReqJsonList.getJSONObject(i);
+ globalSubscriberId = subscriberReqObj.getString("global-customer-id");
+ responseMap.put("globalSubscriberId", globalSubscriberId);
+ break;
+ }
+
+ log.info("Get subscriptionServiceType");
+ String subscriptionServiceReqUrl =
+ aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId + "/service-subscriptions";
+
+ String subscriptionService = restclient
+ .sendGetRequest(subscriptionServiceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONObject subscriptionServiceJson = new JSONObject(subscriptionService);
+ JSONArray subscriptionServiceListJson = subscriptionServiceJson.getJSONArray("service-subscription");
+ for (int i = 0; i < subscriptionServiceListJson.length(); i++) {
+ JSONObject subscriptionServiceObj = subscriptionServiceListJson.getJSONObject(i);
+ subscriptionServiceType = subscriptionServiceObj.getString("service-type");
+ responseMap.put("subscriptionServiceType", subscriptionServiceType);
+ break;
+ }
+ } catch (Exception e) {
+ log.info("Exception while fetching subscriber and subscription: " + e);
+ }
+
+ log.info("responseMap: " + responseMap);
+ return responseMap;
+
+ }
+
+ /**
+ * Fetches the SNSSIs of a serviceInstanceId
+ *
+ * @param serviceInstanceId service instance ID
+ * @return snssaiList contains list of SNSSAIs
+ */
+ public List<String> getSnssaiList(String sliceInstanceId) {
+ fetchSubscriberAndSubscriptionServiceType();
+ List<String> allotedResource = new ArrayList<>();
+ List<String> sliceProfileList = new ArrayList<>();
+ List<String> snssaiList = new ArrayList<>();
+
+ log.info("fetch slice instance details");
+ String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
+ + "/service-subscriptions/service-subscription/" + subscriptionServiceType
+ + "/service-instances/service-instance/" + sliceInstanceId;
+
+ try {
+ String serviceInstanceString =
+ restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ ServiceInstance serviceInstance = objectMapper.readValue(serviceInstanceString, ServiceInstance.class);
+ if (serviceInstance.getServiceRole().equalsIgnoreCase("nsi")) {
+ serviceInstance.getRelationshipList().getRelationship().forEach(relationship -> {
+ if (relationship.getRelatedTo().equalsIgnoreCase("allotted-resource")) {
+ relationship.getRelationshipData().forEach(data -> {
+ if (data.get("relationship-key").equalsIgnoreCase("service-instance.service-instance-id")) {
+ allotedResource.add(data.get("relationship-value"));
+ }
+
+ });
+ }
+ });
+
+ return fetchSnssaiOfSliceProfile(fetchSliceProfilesOfAllotedResourceData(allotedResource));
+
+ }
+ if (serviceInstance.getServiceRole().equalsIgnoreCase("nssi")) {
+ serviceInstance.getRelationshipList().getRelationship().forEach(relationship -> {
+ if (Objects.nonNull(relationship.getRelatedToProperty())) {
+ relationship.getRelatedToProperty().forEach(property -> {
+ if (property.get("property-value").contains("sliceprofile")) {
+ relationship.getRelationshipData().forEach(data -> {
+ if (data.get("relationship-key")
+ .equalsIgnoreCase("service-instance.service-instance-id")) {
+ sliceProfileList.add(data.get("relationship-value"));
+ }
+
+ });
+
+ }
+
+ });
+ }
+ });
+ return fetchSnssaiOfSliceProfile(sliceProfileList);
+ }
+
+ } catch (Exception e) {
+ log.info("Exception while fetching snssaiList: " + e);
+ }
+
+ return snssaiList;
+
+ }
+
+ /**
+ * Fetches the sliceProfileList of a AllotedResource
+ *
+ * @param allotedResourceList contains list of allotedResource IDs
+ * @return sliceProfilesList contains list of SliceProfiles
+ */
+ public List<String> fetchSliceProfilesOfAllotedResourceData(List<String> allotedResourceList) {
+
+ List<String> sliceProfileList = new ArrayList<>();
+
+ log.info("fetch Alloted Resource Data");
+
+ allotedResourceList.forEach(serviceInstanceId -> {
+ try {
+ String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
+ + "/service-subscriptions/service-subscription/" + subscriptionServiceType
+ + "/service-instances/service-instance/" + serviceInstanceId;
+ String serviceInstanceString =
+ restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ ServiceInstance serviceInstance = objectMapper.readValue(serviceInstanceString, ServiceInstance.class);
+
+ serviceInstance.getRelationshipList().getRelationship().forEach(relationship -> {
+ relationship.getRelatedToProperty().forEach(property -> {
+ if (property.get("property-value").contains("sliceprofile")) {
+ relationship.getRelationshipData().forEach(data -> {
+ if (data.get("relationship-key")
+ .equalsIgnoreCase("service-instance.service-instance-id")) {
+ sliceProfileList.add(data.get("relationship-value"));
+ }
+
+ });
+
+ }
+
+ });
+
+ });
+ } catch (Exception e) {
+ log.info("Exception while fetching AllotedResourceData: " + e);
+ }
+
+ });
+
+ log.info("sliceProfileList: " + sliceProfileList);
+
+ return sliceProfileList;
+
+ }
+
+ /**
+ * Fetches the snssaiList of a SliceProfile
+ *
+ * @param sliceProfileList contains list of sliceProfile IDs
+ * @return snssaiList contains list of SNSSAIs
+ */
+ public List<String> fetchSnssaiOfSliceProfile(List<String> sliceProfileList) {
+ List<String> snssaiList = new ArrayList<>();
+
+ log.info("fetch SliceProfile");
+ sliceProfileList.forEach(serviceInstanceId -> {
+ String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
+ + "/service-subscriptions/service-subscription/" + subscriptionServiceType + "/service-instances/"
+ + "service-instance/" + serviceInstanceId;
+
+ try {
+ String serviceInstanceString =
+ restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
+ ServiceInstance serviceInstance = objectMapper.readValue(serviceInstanceString, ServiceInstance.class);
+
+ if (serviceInstance.getServiceRole().equalsIgnoreCase("slice-profile")) {
+ if (!snssaiList.contains(serviceInstance.getEnvironmentContext())) {
+ snssaiList.add(serviceInstance.getEnvironmentContext());
+ }
+ }
+
+ } catch (Exception e) {
+ log.info("Exception while fetching sliceProfile data: " + e);
+ }
+
+ });
+ log.info("snssaiList: " + snssaiList);
+
+ return snssaiList;
+
+ }
+
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/AaiService.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/AaiService.java
deleted file mode 100644
index 16ff71a6..00000000
--- a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/AaiService.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*******************************************************************************
- * ============LICENSE_START=======================================================
- * slice-analysis-ms
- * ================================================================================
- * Copyright (C) 2021 Wipro Limited.
- * ==============================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- *
- *******************************************************************************/
-
-package org.onap.slice.analysis.ms.configdb;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-import org.onap.slice.analysis.ms.models.Configuration;
-import org.onap.slice.analysis.ms.restclients.AaiRestClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.stereotype.Service;
-
-/**
- *
- * Service for AAI interfaces
- *
- */
-@Service
-public class AaiService implements AaiInterface {
-
- private static Logger log = LoggerFactory.getLogger(Configuration.class);
-
- @Autowired
- AaiRestClient restclient;
- private static String globalSubscriberId;
- private static String subscriptionServiceType;
- private static String aaiBaseUrl = Configuration.getInstance().getAaiUrl();
-
- /**
- * Fetches the details of a subscriber
- */
- public Map<String, String> fetchServiceDetails(String snssai) {
- log.info("AAI fetch service: ");
- Map<String, String> responseMap = new HashMap<String, String>();
-
- log.info("AAI getGlobalSubscriberId: ");
- String subscriberReqUrl = aaiBaseUrl + "/business/customers";
- try {
- String subscriberReq = restclient
- .sendGetRequest(subscriberReqUrl, new ParameterizedTypeReference<String>() {
- }).getBody();
- JSONObject subscriberReqJson = new JSONObject(subscriberReq);
- JSONArray subscriberReqJsonList = subscriberReqJson.getJSONArray("customer");
- for (int i = 0; i < subscriberReqJsonList.length(); i++) {
- JSONObject subscriberReqObj = subscriberReqJsonList.getJSONObject(i);
- globalSubscriberId = subscriberReqObj.getString("global-customer-id");
- responseMap.put("globalSubscriberId", globalSubscriberId);
- break;
- }
- } catch (Exception e) {
- log.info("Exception while fetching getGlobalSubscriberId: " + e);
- }
-
- String subscriptionServiceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
- + "/service-subscriptions";
- try {
- String subscriptionService = restclient
- .sendGetRequest(subscriptionServiceReqUrl, new ParameterizedTypeReference<String>() {
- }).getBody();
- JSONObject subscriptionServiceJson = new JSONObject(subscriptionService);
- JSONArray subscriptionServiceListJson = subscriptionServiceJson.getJSONArray("service-subscription");
- for (int i = 0; i < subscriptionServiceListJson.length(); i++) {
- JSONObject subscriptionServiceObj = subscriptionServiceListJson.getJSONObject(i);
- subscriptionServiceType = subscriptionServiceObj.getString("service-type");
- responseMap.put("subscriptionServiceType", subscriptionServiceType);
- break;
- }
- } catch (Exception e) {
- log.info("Exception while fetching subscriptionService: " + e);
- }
-
- String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
- + "/service-subscriptions/service-subscription/" + subscriptionServiceType + "/service-instances";
- String serviceRole = "AN-NF";
- try {
- String serviceInstance = restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {
- }).getBody();
- JSONObject serviceInstanceJson = new JSONObject(serviceInstance);
- JSONArray serviceInstanceList = serviceInstanceJson.getJSONArray("service-instance");
- for (int i = 0; i < serviceInstanceList.length(); i++) {
- JSONObject serviceObj = serviceInstanceList.getJSONObject(i);
- if (serviceObj.getString("environment-context").equalsIgnoreCase(snssai)) {
- responseMap.put("sliceProfileId", serviceObj.getString("service-instance-id"));
- }
- }
-
- String serviceRoleReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
- + "/service-subscriptions/service-subscription/" + subscriptionServiceType
- + "/service-instances/?service-role=nssi&depth=2";
-
- String serviceInstanceForServiceRole = restclient
- .sendGetRequest(serviceRoleReqUrl, new ParameterizedTypeReference<String>() {
- }).getBody();
- JSONObject serviceInstanceForServiceRoleJson = new JSONObject(serviceInstanceForServiceRole);
- JSONArray serviceInstanceListForServiceRole = serviceInstanceForServiceRoleJson
- .getJSONArray("service-instance");
- for (int i = 0; i < serviceInstanceListForServiceRole.length(); i++) {
- JSONObject serviceObj = serviceInstanceListForServiceRole.getJSONObject(i);
- if (serviceObj.getString("workload-context").trim().equalsIgnoreCase(serviceRole)) {
- responseMap.put("ranNFNSSIId", serviceObj.getString("service-instance-id"));
- }
- }
- } catch (Exception e) {
- log.info("Exception while fetching serviceDetails: " + e);
- }
- responseMap.put("sNSSAI", snssai);
- log.info("subscriber details: " + responseMap);
- return responseMap;
- }
-
- /**
- * Fetches the current configuration of an Slice from AAI
- */
- public Map<String, Integer> fetchCurrentConfigurationOfSlice(String snssai) {
- log.info("AAI fetch config Slice: " + aaiBaseUrl);
- String serviceInstaneId = null;
- String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
- + "/service-subscriptions/service-subscription/" + subscriptionServiceType + "/service-instances";
- Map<String, Integer> responseMap = new HashMap<String, Integer>();
- try {
- String serviceInstance = restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {
- }).getBody();
- JSONObject serviceInstanceJson = new JSONObject(serviceInstance);
-
- JSONArray serviceInstanceList = serviceInstanceJson.getJSONArray("service-instance");
- for (int i = 0; i < serviceInstanceList.length(); i++) {
- JSONObject serviceObj = serviceInstanceList.getJSONObject(i);
- if (serviceObj.getString("environment-context").equalsIgnoreCase(snssai)) {
- serviceInstaneId = serviceObj.getString("service-instance-id");
- }
- }
-
- String sliceProfileReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
- + "/service-subscriptions/service-subscription/" + subscriptionServiceType
- + "/service-instances/service-instance/" + serviceInstaneId + "/slice-profiles";
-
- String sliceProfile = restclient
- .sendGetRequest(sliceProfileReqUrl, new ParameterizedTypeReference<String>() {
- }).getBody();
- JSONObject sliceProfileJson = new JSONObject(sliceProfile);
- JSONArray sliceProfileList = sliceProfileJson.getJSONArray("slice-profile");
- for (int i = 0; i < sliceProfileList.length(); i++) {
- JSONObject sliceProfileObj = sliceProfileList.getJSONObject(i);
- responseMap.put("dLThptPerSlice", sliceProfileObj.getInt("exp-data-rate-UL"));
- responseMap.put("uLThptPerSlice", sliceProfileObj.getInt("exp-data-rate-DL"));
- break;
- }
- log.info("Slice configuration: " + responseMap);
- } catch (Exception e) {
- log.info("AAI Slice: " + e);
- }
- return responseMap;
- }
-}
-
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/CpsService.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/CpsService.java
deleted file mode 100644
index 389a75d9..00000000
--- a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/CpsService.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*******************************************************************************
- * ============LICENSE_START=======================================================
- * slice-analysis-ms
- * ================================================================================
- * Copyright (C) 2021 Wipro Limited.
- * ==============================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- *
- *******************************************************************************/
-package org.onap.slice.analysis.ms.configdb;
-
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.ArrayList;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-import org.onap.slice.analysis.ms.models.Configuration;
-import org.onap.slice.analysis.ms.restclients.CpsRestClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.stereotype.Service;
-
-/**
- *
- * Service for CPS interfaces
- *
- */
-@Service
-public class CpsService implements CpsInterface {
-
- private static Logger log = LoggerFactory.getLogger(CpsService.class);
-
- @Autowired
- CpsRestClient restclient;
- private static String cpsBaseUrl = Configuration.getInstance().getCpsUrl();
-
- /**
- * Fetches the current configuration of RIC from CPS
- */
- public Map<String, Map<String, Object>> fetchCurrentConfigurationOfRIC(String snssai) {
- Map<String, Map<String, Object>> responseMap = new HashMap<String, Map<String, Object>>();
- String reqUrl = cpsBaseUrl +"/get-nearrtric-config";
- log.info("fetching current configuration of RIC from Cps: {s-NSSAI: "+snssai+"}");
- String requestBody = "{\"inputParameters\": {\"sNssai\":"+JSONObject.quote(snssai)+"}}";
- try {
- String response = restclient.sendPostRequest(reqUrl,requestBody, new ParameterizedTypeReference<String>() {}).getBody();
- JSONArray sliceArray = new JSONArray(response);
- for (int i=0;i<sliceArray.length();i++) {
- String nearRTTICid = sliceArray.getJSONObject(i).optString("idNearRTRIC");
- JSONArray pLMNInfoList = sliceArray.getJSONObject(i).getJSONObject("attributes").getJSONArray("pLMNInfoList");
- for (int j=0;j<pLMNInfoList.length();j++){
- JSONArray sNSSAIList = pLMNInfoList.getJSONObject(j).getJSONArray("sNSSAIList");
- for(int k=0;k<sNSSAIList.length();k++) {
- Map<String,Object> map = new HashMap<String,Object>();
- JSONArray configDataArray = sNSSAIList.getJSONObject(k).getJSONArray("configData");
- for(int l=0;l<configDataArray.length();l++) {
- JSONObject configData = configDataArray.getJSONObject(l);
- map.put((String) configData.get("configParameter"), configData.get("configValue"));
- }
- responseMap.put(nearRTTICid, map);
- }
- }
- }
- }catch (Exception e) {
- log.info("CPS fetches current configuration of RIC: " + e);
- }
- return responseMap;
- }
-
- /**
- * Fetches all the network functions of an S-NSSAI from CPS
- */
- public List<String> fetchNetworkFunctionsOfSnssai(String snssai) {
- List<String> responseList=new ArrayList<>();
- String reqUrl=cpsBaseUrl+"/get-gnbdufunction-by-snssai";
- log.info("fetching network functions of snssai from Cps: {s-NSSAI: "+snssai+"}");
- String requestBody = "{\"inputParameters\": {\"sNssai\":"+JSONObject.quote(snssai)+"}}";
- try {
- String response=restclient.sendPostRequest(reqUrl,requestBody,new ParameterizedTypeReference<String>() {}).getBody();
- JSONArray networkFunctionJsonArry = new JSONArray(response);
- for (int i=0;i<networkFunctionJsonArry.length();i++) {
- JSONObject networkFunctionJson = networkFunctionJsonArry.getJSONObject(i);
- responseList.add(networkFunctionJson.getJSONObject("attributes").optString("gNBDUId"));
- }
- }
- catch (Exception e) {
- log.info("Fetch network functions of S-NSSAI from CPS" + e);
- }
- return responseList;
- }
-
- /**
- * Fetches the RICS of an S-NSSAI from CPS
- */
- public Map<String, List<String>> fetchRICsOfSnssai(String snssai) {
- Map<String,List<String>> responseMap=new HashMap<>();
- String reqUrl=cpsBaseUrl + "/get-nrcelldu-by-snssai";
- log.info("fetching RIC of s-NSSAI from Cps: {s-NSSAI: "+snssai+"}");
- String requestBody = "{\"inputParameters\": {\"sNssai\":"+JSONObject.quote(snssai)+"}}";
- try {
- String response=restclient.sendPostRequest(reqUrl,requestBody,new ParameterizedTypeReference<String>() {}).getBody();
- JSONArray sliceArray = new JSONArray(response);
- for (int i=0;i<sliceArray.length();i++) {
- String nearRTTICid = sliceArray.getJSONObject(i).optString("idNearRTRIC");
- JSONArray GNBDUFunctionArray = sliceArray.getJSONObject(i).getJSONArray("GNBDUFunction");
- for (int j=0;j<GNBDUFunctionArray.length();j++){
- JSONArray NRCellDUArray = GNBDUFunctionArray.getJSONObject(j).getJSONArray("NRCellDU");
- List<String> cellslist=new ArrayList<>();
- for(int k=0;k<NRCellDUArray.length();k++) {
- cellslist.add(NRCellDUArray.getJSONObject(k).getJSONObject("attributes").optString("cellLocalId"));
- }
- responseMap.put(nearRTTICid,cellslist);
- }
- }
- }catch (Exception e) {
- log.info("Fetch RICS of S-NSSAI from CPS" + e);
- }
- return responseMap;
- }
-}
-
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/controller/SliceConfiguraton.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/controller/SliceConfiguraton.java
new file mode 100644
index 00000000..412d8d2c
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/controller/SliceConfiguraton.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.controller;
+
+import org.onap.slice.analysis.ms.models.SliceConfigRequest;
+import org.onap.slice.analysis.ms.models.SliceConfigResponse;
+import org.onap.slice.analysis.ms.service.SliceUtilization;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * This Controller provides slice configuration details
+ */
+@RestController
+public class SliceConfiguraton {
+
+ @Autowired
+ SliceUtilization sliceUtilization;
+
+ /**
+ * This method provides the slice utilization details for requested slices.
+ *
+ * @param sliceConfigRequest contains sliceInstanceId
+ * @return sliceConfigResponse contains slice configuration details
+ */
+ @GetMapping(value = "/api/v1/slices-config")
+ public ResponseEntity<SliceConfigResponse> sliceConfigRequest(@RequestBody SliceConfigRequest sliceConfigRequest) {
+ try {
+ SliceConfigResponse sliceConfigResponse = sliceUtilization.getSliceUtilizationData(sliceConfigRequest);
+ return new ResponseEntity<SliceConfigResponse>(sliceConfigResponse, HttpStatus.OK);
+ } catch (Exception e) {
+ return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/CpsInterface.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/cps/CpsInterface.java
index ef6211c4..95e7340f 100644
--- a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/configdb/CpsInterface.java
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/cps/CpsInterface.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* slice-analysis-ms
* ================================================================================
- * Copyright (C) 2021 Wipro Limited.
+ * Copyright (C) 2021-2022 Wipro Limited.
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,21 +19,22 @@
*
*******************************************************************************/
-package org.onap.slice.analysis.ms.configdb;
+package org.onap.slice.analysis.ms.cps;
import java.util.List;
import java.util.Map;
/**
- *
- * Interface for CPS
+ *
+ * Interface for CPS
*
*/
public interface CpsInterface {
- public Map<String, List<String>> fetchRICsOfSnssai(String snssai);
- public List<String> fetchNetworkFunctionsOfSnssai(String snssai);
- public Map<String, Map<String,Object>> fetchCurrentConfigurationOfRIC(String snssai);
-
-}
+ public Map<String, List<String>> fetchRICsOfSnssai(String snssai);
+
+ public List<String> fetchNetworkFunctionsOfSnssai(String snssai);
+ public Map<String, Map<String, Object>> fetchCurrentConfigurationOfRIC(String snssai);
+
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/cps/CpsService.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/cps/CpsService.java
new file mode 100644
index 00000000..743ac3cf
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/cps/CpsService.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2021-2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.cps;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.onap.slice.analysis.ms.models.Configuration;
+import org.onap.slice.analysis.ms.restclients.CpsRestClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * Service for CPS interfaces
+ *
+ */
+@Service
+public class CpsService implements CpsInterface {
+
+ private static Logger log = LoggerFactory.getLogger(CpsService.class);
+
+ @Autowired
+ CpsRestClient restclient;
+ private static String cpsBaseUrl = Configuration.getInstance().getCpsUrl();
+
+ /**
+ * Fetches the current configuration of RIC from CPS
+ */
+ public Map<String, Map<String, Object>> fetchCurrentConfigurationOfRIC(String snssai) {
+ Map<String, Map<String, Object>> responseMap = new HashMap<String, Map<String, Object>>();
+ String reqUrl = cpsBaseUrl + "/get-nearrtric-config";
+ log.info("fetching current configuration of RIC from Cps: {s-NSSAI: " + snssai + "}");
+ String requestBody = "{\"inputParameters\": {\"sNssai\":" + JSONObject.quote(snssai) + "}}";
+ try {
+ String response = restclient
+ .sendPostRequest(reqUrl, requestBody, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONArray sliceArray = new JSONArray(response);
+ for (int i = 0; i < sliceArray.length(); i++) {
+ String nearRTTICid = sliceArray.getJSONObject(i).optString("idNearRTRIC");
+ JSONArray pLMNInfoList =
+ sliceArray.getJSONObject(i).getJSONObject("attributes").getJSONArray("pLMNInfoList");
+ for (int j = 0; j < pLMNInfoList.length(); j++) {
+ JSONArray sNSSAIList = pLMNInfoList.getJSONObject(j).getJSONArray("sNSSAIList");
+ for (int k = 0; k < sNSSAIList.length(); k++) {
+ Map<String, Object> map = new HashMap<String, Object>();
+ JSONArray configDataArray = sNSSAIList.getJSONObject(k).getJSONArray("configData");
+ for (int l = 0; l < configDataArray.length(); l++) {
+ JSONObject configData = configDataArray.getJSONObject(l);
+ map.put((String) configData.get("configParameter"), configData.get("configValue"));
+ }
+ responseMap.put(nearRTTICid, map);
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.info("CPS fetches current configuration of RIC: " + e);
+ }
+ return responseMap;
+ }
+
+ /**
+ * Fetches all the network functions of an S-NSSAI from CPS
+ */
+ public List<String> fetchNetworkFunctionsOfSnssai(String snssai) {
+ List<String> responseList = new ArrayList<>();
+ String reqUrl = cpsBaseUrl + "/get-gnbdufunction-by-snssai";
+ log.info("fetching network functions of snssai from Cps: {s-NSSAI: " + snssai + "}");
+ String requestBody = "{\"inputParameters\": {\"sNssai\":" + JSONObject.quote(snssai) + "}}";
+ try {
+ String response = restclient
+ .sendPostRequest(reqUrl, requestBody, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONArray networkFunctionJsonArry = new JSONArray(response);
+ for (int i = 0; i < networkFunctionJsonArry.length(); i++) {
+ JSONObject networkFunctionJson = networkFunctionJsonArry.getJSONObject(i);
+ responseList.add(networkFunctionJson.getJSONObject("attributes").optString("gNBDUId"));
+ }
+ } catch (Exception e) {
+ log.info("Fetch network functions of S-NSSAI from CPS" + e);
+ }
+ return responseList;
+ }
+
+ /**
+ * Fetches the RICS of an S-NSSAI from CPS
+ */
+ public Map<String, List<String>> fetchRICsOfSnssai(String snssai) {
+ Map<String, List<String>> responseMap = new HashMap<>();
+ String reqUrl = cpsBaseUrl + "/get-nrcelldu-by-snssai";
+ log.info("fetching RIC of s-NSSAI from Cps: {s-NSSAI: " + snssai + "}");
+ String requestBody = "{\"inputParameters\": {\"sNssai\":" + JSONObject.quote(snssai) + "}}";
+ try {
+ String response = restclient
+ .sendPostRequest(reqUrl, requestBody, new ParameterizedTypeReference<String>() {}).getBody();
+ JSONArray sliceArray = new JSONArray(response);
+ for (int i = 0; i < sliceArray.length(); i++) {
+ String nearRTTICid = sliceArray.getJSONObject(i).optString("idNearRTRIC");
+ JSONArray GNBDUFunctionArray = sliceArray.getJSONObject(i).getJSONArray("GNBDUFunction");
+ for (int j = 0; j < GNBDUFunctionArray.length(); j++) {
+ JSONArray NRCellDUArray = GNBDUFunctionArray.getJSONObject(j).getJSONArray("NRCellDU");
+ List<String> cellslist = new ArrayList<>();
+ for (int k = 0; k < NRCellDUArray.length(); k++) {
+ cellslist.add(
+ NRCellDUArray.getJSONObject(k).getJSONObject("attributes").optString("cellLocalId"));
+ }
+ responseMap.put(nearRTTICid, cellslist);
+ }
+ }
+ } catch (Exception e) {
+ log.info("Fetch RICS of S-NSSAI from CPS" + e);
+ }
+ return responseMap;
+ }
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/exception/CpsClientException.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/exception/CpsClientException.java
new file mode 100644
index 00000000..9a993d12
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/exception/CpsClientException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.exception;
+
+/**
+ * CpsClientException is thown when expected response is not received from CPS
+ */
+public class CpsClientException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public CpsClientException(final String exception) {
+ super(exception);
+ }
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/exception/DesClientException.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/exception/DesClientException.java
new file mode 100644
index 00000000..7356b0b2
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/exception/DesClientException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.exception;
+
+/**
+ * DesClientException is thown when expected response is not received from DES
+ */
+public class DesClientException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public DesClientException(final String exception) {
+ super(exception);
+ }
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/AggregatedConfig.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/AggregatedConfig.java
new file mode 100644
index 00000000..b754f641
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/AggregatedConfig.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.models;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * AggregatedConfig contains slice utilization data
+ */
+@Data
+@NoArgsConstructor
+public class AggregatedConfig {
+
+ Integer dLThptPerSlice;
+
+ Integer uLThptPerSlice;
+
+ Integer maxNumberOfConns;
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/Configuration.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/Configuration.java
index 60f52f0f..2f3f6c2a 100644
--- a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/Configuration.java
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/Configuration.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* slice-analysis-ms
* ================================================================================
- * Copyright (C) 2020-2021 Wipro Limited.
+ * Copyright (C) 2020-2022 Wipro Limited.
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,11 @@
package org.onap.slice.analysis.ms.models;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
+
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
@@ -29,290 +34,332 @@ import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-import com.google.gson.reflect.TypeToken;
-
/**
* Model class for the application Configuration
*/
public class Configuration {
- private static Logger log = LoggerFactory.getLogger(Configuration.class);
-
- private static Configuration instance = null;
- private String pgHost;
- private int pgPort;
- private String pgUsername;
- private String pgPassword;
- private List<String> dmaapServers;
- private String configDbService;
- private String cpsUrl;
- private String aaiUrl;
- private Boolean configDbEnabled;
- private String cg;
- private String cid;
- private int pollingInterval;
- private int pollingTimeout;
- private String aafUsername;
- private String aafPassword;
- private Map<String, Object> streamsSubscribes;
- private Map<String, Object> streamsPublishes;
- private int samples;
- private int minPercentageChange;
- private long initialDelaySeconds;
-
- /**
- * Check if topic is secure.
- */
- public boolean isSecured() {
- return (aafUsername != null);
-
- }
-
- public String getAafUsername() {
- return aafUsername;
- }
-
- public void setAafUsername(String aafUsername) {
- this.aafUsername = aafUsername;
- }
-
- public String getAafPassword() {
- return aafPassword;
- }
-
- public void setAafPassword(String aafPassword) {
- this.aafPassword = aafPassword;
- }
-
- public Map<String, Object> getStreamsSubscribes() {
- return streamsSubscribes;
- }
-
- public void setStreamsSubscribes(Map<String, Object> streamsSubscribes) {
- this.streamsSubscribes = streamsSubscribes;
- }
-
- public Map<String, Object> getStreamsPublishes() {
- return streamsPublishes;
- }
-
- public void setStreamsPublishes(Map<String, Object> streamsPublishes) {
- this.streamsPublishes = streamsPublishes;
- }
-
- protected Configuration() {
-
- }
-
- /**
- * Get instance of class.
- */
- public static Configuration getInstance() {
- if (instance == null) {
- instance = new Configuration();
- }
- return instance;
- }
-
- public String getCg() {
- return cg;
- }
-
- public void setCg(String cg) {
- this.cg = cg;
- }
-
- public String getCid() {
- return cid;
- }
-
- public void setCid(String cid) {
- this.cid = cid;
- }
-
- public int getPollingInterval() {
- return pollingInterval;
- }
-
- public void setPollingInterval(int pollingInterval) {
- this.pollingInterval = pollingInterval;
- }
-
- public int getPollingTimeout() {
- return pollingTimeout;
- }
-
- public void setPollingTimeout(int pollingTimeout) {
- this.pollingTimeout = pollingTimeout;
- }
-
- public String getPgHost() {
- return pgHost;
- }
-
- public void setPgHost(String pgHost) {
- this.pgHost = pgHost;
- }
-
- public int getPgPort() {
- return pgPort;
- }
-
- public void setPgPort(int pgPort) {
- this.pgPort = pgPort;
- }
-
- public String getPgUsername() {
- return pgUsername;
- }
-
- public void setPgUsername(String pgUsername) {
- this.pgUsername = pgUsername;
- }
-
- public String getPgPassword() {
- return pgPassword;
- }
-
- public void setPgPassword(String pgPassword) {
- this.pgPassword = pgPassword;
- }
-
- public List<String> getDmaapServers() {
- return dmaapServers;
- }
-
- public void setDmaapServers(List<String> dmaapServers) {
- this.dmaapServers = dmaapServers;
- }
-
- public String getConfigDbService() {
- return configDbService;
- }
-
- public void setConfigDbService(String configDbService) {
- this.configDbService = configDbService;
- }
-
- public String getCpsUrl() {
- return cpsUrl;
- }
-
- public void setCpsUrl(String cpsUrl) {
- this.cpsUrl = cpsUrl;
- }
-
- public String getAaiUrl() {
- return aaiUrl;
- }
-
- public void setAaiUrl(String aaiUrl) {
- this.aaiUrl = aaiUrl;
- }
-
- public Boolean getConfigDbEnabled() {
- return configDbEnabled;
- }
-
- public void setConfigDbEnabled(Boolean configDbEnabled) {
- this.configDbEnabled = configDbEnabled;
- }
-
- public int getSamples() {
- return samples;
- }
-
- public void setSamples(int samples) {
- this.samples = samples;
- }
-
- public int getMinPercentageChange() {
- return minPercentageChange;
- }
-
- public void setMinPercentageChange(int minPercentageChange) {
- this.minPercentageChange = minPercentageChange;
- }
-
- public long getInitialDelaySeconds() {
- return initialDelaySeconds;
- }
-
- public void setInitialDelaySeconds(long initialDelaySeconds) {
- this.initialDelaySeconds = initialDelaySeconds;
- }
-
- @Override
- public String toString() {
- return "Configuration [pgHost=" + pgHost + ", pgPort=" + pgPort + ", pgUsername=" + pgUsername + ", pgPassword="
- + pgPassword + ", dmaapServers=" + dmaapServers + ", configDbService=" + configDbService + ", cpsUrl="
- + cpsUrl + ", aaiUrl=" + aaiUrl + ", configDbEnabled=" + configDbEnabled + ", cg=" + cg + ", cid=" + cid + ", pollingInterval=" + pollingInterval + ", pollingTimeout="
- + pollingTimeout + ", aafUsername=" + aafUsername + ", aafPassword=" + aafPassword
- + ", streamsSubscribes=" + streamsSubscribes + ", streamsPublishes=" + streamsPublishes + ", samples="
- + samples + ", minPercentageChange=" + minPercentageChange + ", initialDelaySeconds="
- + initialDelaySeconds + "]";
- }
-
- /**
- * updates application configuration.
- */
- public void updateConfigurationFromJsonObject(JsonObject jsonObject) {
-
- log.info("Updating configuration from CBS");
-
- Type mapType = new TypeToken<Map<String, Object>>() {
- }.getType();
-
- JsonObject subscribes = jsonObject.getAsJsonObject("streams_subscribes");
- streamsSubscribes = new Gson().fromJson(subscribes, mapType);
-
- JsonObject publishes = jsonObject.getAsJsonObject("streams_publishes");
- streamsPublishes = new Gson().fromJson(publishes, mapType);
-
- pgPort = jsonObject.get("postgres.port").getAsInt();
- pollingInterval = jsonObject.get("sliceanalysisms.pollingInterval").getAsInt();
- pgPassword = jsonObject.get("postgres.password").getAsString();
- pgUsername = jsonObject.get("postgres.username").getAsString();
- pgHost = jsonObject.get("postgres.host").getAsString();
-
- JsonArray servers = jsonObject.getAsJsonArray("sliceanalysisms.dmaap.server");
- Type listType = new TypeToken<List<String>>() {
- }.getType();
- dmaapServers = new Gson().fromJson(servers, listType);
-
- cg = jsonObject.get("sliceanalysisms.cg").getAsString();
- cid = jsonObject.get("sliceanalysisms.cid").getAsString();
- configDbService = jsonObject.get("sliceanalysisms.configDb.service").getAsString();
- configDbEnabled = jsonObject.get("sliceanalysisms.configDbEnabled").getAsBoolean();
-
- pollingTimeout = jsonObject.get("sliceanalysisms.pollingTimeout").getAsInt();
- samples = jsonObject.get("sliceanalysisms.samples").getAsInt();
- minPercentageChange = jsonObject.get("sliceanalysisms.minPercentageChange").getAsInt();
- initialDelaySeconds = jsonObject.get("sliceanalysisms.initialDelaySeconds").getAsLong();
-
- if (Objects.isNull(jsonObject.get("aafUsername"))) {
- aafUsername = null;
- } else {
- aafUsername = jsonObject.get("aafUsername").getAsString();
- }
- if (Objects.isNull(jsonObject.get("aafPassword"))) {
- aafPassword = null;
- } else {
- aafPassword = jsonObject.get("aafPassword").getAsString();
- }
- if (Objects.isNull(jsonObject.get("sliceanalysisms.aai.url"))) {
- aaiUrl = null;
- } else {
- aaiUrl = jsonObject.get("sliceanalysisms.aai.url").getAsString();
- }
- if (Objects.isNull(jsonObject.get("sliceanalysisms.cps.url"))) {
- cpsUrl = null;
- } else {
- cpsUrl = jsonObject.get("sliceanalysisms.cps.url").getAsString();
- }
- log.info("configuration from CBS {}", this);
- }
+ private static Logger log = LoggerFactory.getLogger(Configuration.class);
+
+ private static Configuration instance = null;
+ private String pgHost;
+ private int pgPort;
+ private String pgUsername;
+ private String pgPassword;
+ private List<String> dmaapServers;
+ private String configDbService;
+ private String cpsUrl;
+ private String aaiUrl;
+ private Boolean configDbEnabled;
+ private String cg;
+ private String cid;
+ private int pollingInterval;
+ private int pollingTimeout;
+ private String aafUsername;
+ private String aafPassword;
+ private Map<String, Object> streamsSubscribes;
+ private Map<String, Object> streamsPublishes;
+ private int samples;
+ private int minPercentageChange;
+ private long initialDelaySeconds;
+ private String rannfnssiDetailsTemplateId;
+ private String desUrl;
+ private int pmDataDurationInWeeks;
+
+ /**
+ * Check if topic is secure.
+ */
+ public boolean isSecured() {
+ return (aafUsername != null);
+
+ }
+
+ public String getAafUsername() {
+ return aafUsername;
+ }
+
+ public void setAafUsername(String aafUsername) {
+ this.aafUsername = aafUsername;
+ }
+
+ public String getAafPassword() {
+ return aafPassword;
+ }
+
+ public void setAafPassword(String aafPassword) {
+ this.aafPassword = aafPassword;
+ }
+
+ public Map<String, Object> getStreamsSubscribes() {
+ return streamsSubscribes;
+ }
+
+ public void setStreamsSubscribes(Map<String, Object> streamsSubscribes) {
+ this.streamsSubscribes = streamsSubscribes;
+ }
+
+ public Map<String, Object> getStreamsPublishes() {
+ return streamsPublishes;
+ }
+
+ public void setStreamsPublishes(Map<String, Object> streamsPublishes) {
+ this.streamsPublishes = streamsPublishes;
+ }
+
+ protected Configuration() {
+
+ }
+
+ /**
+ * Get instance of class.
+ */
+ public static Configuration getInstance() {
+ if (instance == null) {
+ instance = new Configuration();
+ }
+ return instance;
+ }
+
+ public String getCg() {
+ return cg;
+ }
+
+ public void setCg(String cg) {
+ this.cg = cg;
+ }
+
+ public String getCid() {
+ return cid;
+ }
+
+ public void setCid(String cid) {
+ this.cid = cid;
+ }
+
+ public int getPollingInterval() {
+ return pollingInterval;
+ }
+
+ public void setPollingInterval(int pollingInterval) {
+ this.pollingInterval = pollingInterval;
+ }
+
+ public int getPollingTimeout() {
+ return pollingTimeout;
+ }
+
+ public void setPollingTimeout(int pollingTimeout) {
+ this.pollingTimeout = pollingTimeout;
+ }
+
+ public String getPgHost() {
+ return pgHost;
+ }
+
+ public void setPgHost(String pgHost) {
+ this.pgHost = pgHost;
+ }
+
+ public int getPgPort() {
+ return pgPort;
+ }
+
+ public void setPgPort(int pgPort) {
+ this.pgPort = pgPort;
+ }
+
+ public String getPgUsername() {
+ return pgUsername;
+ }
+
+ public void setPgUsername(String pgUsername) {
+ this.pgUsername = pgUsername;
+ }
+
+ public String getPgPassword() {
+ return pgPassword;
+ }
+
+ public void setPgPassword(String pgPassword) {
+ this.pgPassword = pgPassword;
+ }
+
+ public List<String> getDmaapServers() {
+ return dmaapServers;
+ }
+
+ public void setDmaapServers(List<String> dmaapServers) {
+ this.dmaapServers = dmaapServers;
+ }
+
+ public String getConfigDbService() {
+ return configDbService;
+ }
+
+ public void setConfigDbService(String configDbService) {
+ this.configDbService = configDbService;
+ }
+
+ public String getCpsUrl() {
+ return cpsUrl;
+ }
+
+ public void setCpsUrl(String cpsUrl) {
+ this.cpsUrl = cpsUrl;
+ }
+
+ public String getAaiUrl() {
+ return aaiUrl;
+ }
+
+ public void setAaiUrl(String aaiUrl) {
+ this.aaiUrl = aaiUrl;
+ }
+
+ public Boolean getConfigDbEnabled() {
+ return configDbEnabled;
+ }
+
+ public void setConfigDbEnabled(Boolean configDbEnabled) {
+ this.configDbEnabled = configDbEnabled;
+ }
+
+ public int getSamples() {
+ return samples;
+ }
+
+ public void setSamples(int samples) {
+ this.samples = samples;
+ }
+
+ public int getMinPercentageChange() {
+ return minPercentageChange;
+ }
+
+ public void setMinPercentageChange(int minPercentageChange) {
+ this.minPercentageChange = minPercentageChange;
+ }
+
+ public long getInitialDelaySeconds() {
+ return initialDelaySeconds;
+ }
+
+ public void setInitialDelaySeconds(long initialDelaySeconds) {
+ this.initialDelaySeconds = initialDelaySeconds;
+ }
+
+ /**
+ * Get RannfnssiDetails TemplateId from Configuration
+ */
+ public String getRannfnssiDetailsTemplateId() {
+ return rannfnssiDetailsTemplateId;
+ }
+
+ /**
+ * Set RannfnssiDetails TemplateId
+ */
+ public void setRannfnssiDetailsTemplateId(String rannfnssiDetailsTemplateId) {
+ this.rannfnssiDetailsTemplateId = rannfnssiDetailsTemplateId;
+ }
+
+ /**
+ * Get Data Extraction Service Url
+ */
+ public String getDesUrl() {
+ return desUrl;
+ }
+
+ /**
+ * Set Data Extraction Service Url
+ */
+ public void setDesUrl(String desUrl) {
+ this.desUrl = desUrl;
+ }
+
+ /**
+ * Get duration for which PM data is to be fetched from DES
+ */
+ public int getPmDataDurationInWeeks() {
+ return pmDataDurationInWeeks;
+ }
+
+ /**
+ * Set duration for which PM data is to be fetched from DES
+ */
+ public void setPmDataDurationInWeeks(int pmDataDurationInWeeks) {
+ this.pmDataDurationInWeeks = pmDataDurationInWeeks;
+ }
+
+ @Override
+ public String toString() {
+ return "Configuration [pgHost=" + pgHost + ", pgPort=" + pgPort + ", pgUsername=" + pgUsername + ", pgPassword="
+ + pgPassword + ", dmaapServers=" + dmaapServers + ", configDbService=" + configDbService + ", cpsUrl="
+ + cpsUrl + ", aaiUrl=" + aaiUrl + ", configDbEnabled=" + configDbEnabled + ", cg=" + cg + ", cid=" + cid
+ + ", pollingInterval=" + pollingInterval + ", pollingTimeout=" + pollingTimeout + ", aafUsername="
+ + aafUsername + ", aafPassword=" + aafPassword + ", streamsSubscribes=" + streamsSubscribes
+ + ", streamsPublishes=" + streamsPublishes + ", samples=" + samples + ", minPercentageChange="
+ + minPercentageChange + ", initialDelaySeconds=" + initialDelaySeconds + ", rannfnssiDetailsTemplateId="
+ + rannfnssiDetailsTemplateId + ", desUrl=" + desUrl + ", pmDataDurationInWeeks=" + pmDataDurationInWeeks
+ + "]";
+ }
+
+ /**
+ * updates application configuration.
+ */
+ public void updateConfigurationFromJsonObject(JsonObject jsonObject) {
+
+ log.info("Updating configuration from CBS");
+
+ Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
+
+ JsonObject subscribes = jsonObject.getAsJsonObject("streams_subscribes");
+ streamsSubscribes = new Gson().fromJson(subscribes, mapType);
+
+ JsonObject publishes = jsonObject.getAsJsonObject("streams_publishes");
+ streamsPublishes = new Gson().fromJson(publishes, mapType);
+
+ pgPort = jsonObject.get("postgres.port").getAsInt();
+ pollingInterval = jsonObject.get("sliceanalysisms.pollingInterval").getAsInt();
+ pgPassword = jsonObject.get("postgres.password").getAsString();
+ pgUsername = jsonObject.get("postgres.username").getAsString();
+ pgHost = jsonObject.get("postgres.host").getAsString();
+
+ JsonArray servers = jsonObject.getAsJsonArray("sliceanalysisms.dmaap.server");
+ Type listType = new TypeToken<List<String>>() {}.getType();
+ dmaapServers = new Gson().fromJson(servers, listType);
+
+ cg = jsonObject.get("sliceanalysisms.cg").getAsString();
+ cid = jsonObject.get("sliceanalysisms.cid").getAsString();
+ configDbService = jsonObject.get("sliceanalysisms.configDb.service").getAsString();
+ configDbEnabled = jsonObject.get("sliceanalysisms.configDbEnabled").getAsBoolean();
+
+ pollingTimeout = jsonObject.get("sliceanalysisms.pollingTimeout").getAsInt();
+ samples = jsonObject.get("sliceanalysisms.samples").getAsInt();
+ minPercentageChange = jsonObject.get("sliceanalysisms.minPercentageChange").getAsInt();
+ initialDelaySeconds = jsonObject.get("sliceanalysisms.initialDelaySeconds").getAsLong();
+ rannfnssiDetailsTemplateId = jsonObject.get("sliceanalysisms.rannfnssiDetailsTemplateId").getAsString();
+ desUrl = jsonObject.get("sliceanalysisms.desUrl").getAsString();
+ pmDataDurationInWeeks = jsonObject.get("sliceanalysisms.pmDataDurationInWeeks").getAsInt();
+
+ if (Objects.isNull(jsonObject.get("aafUsername"))) {
+ aafUsername = null;
+ } else {
+ aafUsername = jsonObject.get("aafUsername").getAsString();
+ }
+ if (Objects.isNull(jsonObject.get("aafPassword"))) {
+ aafPassword = null;
+ } else {
+ aafPassword = jsonObject.get("aafPassword").getAsString();
+ }
+ if (Objects.isNull(jsonObject.get("sliceanalysisms.aai.url"))) {
+ aaiUrl = null;
+ } else {
+ aaiUrl = jsonObject.get("sliceanalysisms.aai.url").getAsString();
+ }
+ if (Objects.isNull(jsonObject.get("sliceanalysisms.cps.url"))) {
+ cpsUrl = null;
+ } else {
+ cpsUrl = jsonObject.get("sliceanalysisms.cps.url").getAsString();
+ }
+ log.info("configuration from CBS {}", this);
+ }
}
-
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigDetails.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigDetails.java
new file mode 100644
index 00000000..5f8b7434
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigDetails.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.models;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * SliceConfigDetails contains slice utilization data for requested slice
+ */
+@Data
+@NoArgsConstructor
+public class SliceConfigDetails {
+
+ String sliceIdentifiers;
+ AggregatedConfig aggregatedConfig;
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigRequest.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigRequest.java
new file mode 100644
index 00000000..aefbdd38
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigRequest.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.models;
+
+import java.util.List;
+
+import javax.validation.constraints.NotEmpty;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Request body to get slice utilization data
+ */
+@Data
+@NoArgsConstructor
+public class SliceConfigRequest {
+
+ @NotEmpty(message = "Slice Identifier missing")
+ List<String> sliceIdentifiers;
+ @NotEmpty(message = "Config Param missing")
+ List<String> configParams;
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigResponse.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigResponse.java
new file mode 100644
index 00000000..18d28ca2
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/SliceConfigResponse.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.models;
+
+import java.util.List;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * SliceConfigResponse contains slice utilization data for requested slices
+ */
+@Data
+@NoArgsConstructor
+public class SliceConfigResponse {
+
+ List<SliceConfigDetails> sliceConfigDetails;
+
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/Relationship.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/Relationship.java
new file mode 100644
index 00000000..f4acc08b
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/Relationship.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.models.aai;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+import java.util.Map;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Model for receiving Relationship data of a service from AAI
+ */
+@Data
+@NoArgsConstructor
+public class Relationship {
+
+ @JsonProperty("related-to")
+ private String relatedTo;
+ @JsonProperty("relationship-label")
+ private String relationshipLabel;
+ @JsonProperty("related-link")
+ private String relatedLink;
+ @JsonProperty("relationship-data")
+ private List<Map<String, String>> relationshipData;
+ @JsonProperty("related-to-property")
+ private List<Map<String, String>> relatedToProperty;
+
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/RelationshipList.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/RelationshipList.java
new file mode 100644
index 00000000..1cda2ae5
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/RelationshipList.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.models.aai;
+
+import java.util.List;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Model for receiving RelationshipList data of a service from AAI
+ */
+@Data
+@NoArgsConstructor
+public class RelationshipList {
+
+ List<Relationship> relationship;
+
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/ServiceInstance.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/ServiceInstance.java
new file mode 100644
index 00000000..ecb2c4cd
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/models/aai/ServiceInstance.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.models.aai;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Model for receiving ServiceInstance data from AAI
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@Data
+@NoArgsConstructor
+public class ServiceInstance {
+
+ @JsonProperty("service-instance-id")
+ private String serviceInstanceId;
+ @JsonProperty("service-instance-name")
+ private String serviceInstanceName;
+ @JsonProperty("service-type;")
+ private String serviceType;
+ @JsonProperty("service-role")
+ private String serviceRole;
+ @JsonProperty("environment-context")
+ private String environmentContext;
+ @JsonProperty("workload-context")
+ private String workloadContext;
+ @JsonProperty("orchestration-status")
+ private String orchestrationStatus;
+ @JsonProperty("relationship-list")
+ private RelationshipList relationshipList;
+
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/restclients/DesRestClient.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/restclients/DesRestClient.java
new file mode 100644
index 00000000..5d29af3a
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/restclients/DesRestClient.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.restclients;
+
+import java.util.Collections;
+
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class represents rest client for DES interfaces
+ */
+@Component
+public class DesRestClient extends RestClient {
+
+ public DesRestClient() {
+ super();
+ }
+
+ /**
+ * Send Post Request to DES
+ */
+
+ public <T> ResponseEntity<T> sendPostRequest(String requestUrl, String requestBody,
+ ParameterizedTypeReference<T> responseType) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ return super.sendPostRequest(headers, requestUrl, requestBody, responseType);
+ }
+
+ /**
+ * Send Get Request to DES
+ */
+
+ public <T> ResponseEntity<T> sendGetRequest(String requestUrl, ParameterizedTypeReference<T> responseType) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ return super.sendGetRequest(headers, requestUrl, responseType);
+ }
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ConsumerThread.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ConsumerThread.java
index 6098142e..5dcd9189 100644
--- a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ConsumerThread.java
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ConsumerThread.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* slice-analysis-ms
* ================================================================================
- * Copyright (C) 2020-2021 Wipro Limited.
+ * Copyright (C) 2020-2022 Wipro Limited.
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,95 +24,93 @@ package org.onap.slice.analysis.ms.service;
import java.util.List;
import java.util.Objects;
-import org.onap.slice.analysis.ms.configdb.CpsInterface;
import org.onap.slice.analysis.ms.configdb.IConfigDbService;
+import org.onap.slice.analysis.ms.cps.CpsInterface;
import org.onap.slice.analysis.ms.models.Configuration;
import org.onap.slice.analysis.ms.models.SubCounter;
import org.onap.slice.analysis.ms.utils.BeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/**
+/**
* This Thread class consumes message from pm data queue and sends onset message to policy
*/
public class ConsumerThread extends Thread {
- private static Logger log = LoggerFactory.getLogger(ConsumerThread.class);
- private PmDataQueue pmDataQueue;
- private IConfigDbService configDbService;
- private SnssaiSamplesProcessor snssaiSamplesProcessor;
- private CpsInterface cpsInterface;
- private long initialDelaySec;
- private int samples;
+ private static Logger log = LoggerFactory.getLogger(ConsumerThread.class);
+ private PmDataQueue pmDataQueue;
+ private IConfigDbService configDbService;
+ private SnssaiSamplesProcessor snssaiSamplesProcessor;
+ private CpsInterface cpsInterface;
+ private long initialDelaySec;
+ private int samples;
- /**
- * Default constructor.
- */
- public ConsumerThread() {
- super();
- this.pmDataQueue = BeanUtil.getBean(PmDataQueue.class);
- this.configDbService = BeanUtil.getBean(IConfigDbService.class);
- this.initialDelaySec = Configuration.getInstance().getInitialDelaySeconds();
- this.samples = Configuration.getInstance().getSamples();
- this.cpsInterface = BeanUtil.getBean(CpsInterface.class);
- }
+ /**
+ * Default constructor.
+ */
+ public ConsumerThread() {
+ super();
+ this.pmDataQueue = BeanUtil.getBean(PmDataQueue.class);
+ this.configDbService = BeanUtil.getBean(IConfigDbService.class);
+ this.initialDelaySec = Configuration.getInstance().getInitialDelaySeconds();
+ this.samples = Configuration.getInstance().getSamples();
+ this.cpsInterface = BeanUtil.getBean(CpsInterface.class);
+ }
- /**
- * Consumes data from PM data queue, process the data and sends onset message to policy if needed
- */
- @Override
- public void run() {
- Boolean isConfigDbEnabled = (Objects.isNull(Configuration.getInstance().getConfigDbEnabled())) ? true
- : Configuration.getInstance().getConfigDbEnabled();
- boolean done = false;
- boolean result = false;
- String snssai = "";
- List<String> nfs = null;
- while (!done) {
- try {
- Thread.sleep(initialDelaySec);
- log.info("Starting Consumer Thread");
- snssai = pmDataQueue.getSnnsaiFromQueue();
- if (!snssai.equals("")) {
- log.info("Consumer thread processing data for s-nssai {}",snssai);
- try {
- if (isConfigDbEnabled) {
- nfs = configDbService.fetchNetworkFunctionsOfSnssai(snssai);
- }
- else {
- nfs = cpsInterface.fetchNetworkFunctionsOfSnssai(snssai);
- }
- }
- catch(Exception e) {
- pmDataQueue.putSnssaiToQueue(snssai);
- log.error("Exception caught while fetching nfs of snssai {}, {}", snssai, e.getMessage());
- }
- if(nfs != null && checkForEnoughSamples(nfs, snssai)) {
- this.snssaiSamplesProcessor = BeanUtil.getBean(SnssaiSamplesProcessor.class);
- result = snssaiSamplesProcessor.processSamplesOfSnnsai(snssai, nfs);
- if(!result) {
- log.info("Not enough samples to process for {}",snssai);
- pmDataQueue.putSnssaiToQueue(snssai);
- }
- }
- }
- } catch (Exception e) {
- log.error("Exception in Consumer Thread, {}", e.getMessage());
- done = true;
- }
- }
- }
+ /**
+ * Consumes data from PM data queue, process the data and sends onset message to policy if needed
+ */
+ @Override
+ public void run() {
+ Boolean isConfigDbEnabled = (Objects.isNull(Configuration.getInstance().getConfigDbEnabled())) ? true
+ : Configuration.getInstance().getConfigDbEnabled();
+ boolean done = false;
+ boolean result = false;
+ String snssai = "";
+ List<String> nfs = null;
+ while (!done) {
+ try {
+ Thread.sleep(initialDelaySec);
+ log.info("Starting Consumer Thread");
+ snssai = pmDataQueue.getSnnsaiFromQueue();
+ if (!snssai.equals("")) {
+ log.info("Consumer thread processing data for s-nssai {}", snssai);
+ try {
+ if (isConfigDbEnabled) {
+ nfs = configDbService.fetchNetworkFunctionsOfSnssai(snssai);
+ } else {
+ nfs = cpsInterface.fetchNetworkFunctionsOfSnssai(snssai);
+ }
+ } catch (Exception e) {
+ pmDataQueue.putSnssaiToQueue(snssai);
+ log.error("Exception caught while fetching nfs of snssai {}, {}", snssai, e.getMessage());
+ }
+ if (nfs != null && checkForEnoughSamples(nfs, snssai)) {
+ this.snssaiSamplesProcessor = BeanUtil.getBean(SnssaiSamplesProcessor.class);
+ result = snssaiSamplesProcessor.processSamplesOfSnnsai(snssai, nfs);
+ if (!result) {
+ log.info("Not enough samples to process for {}", snssai);
+ pmDataQueue.putSnssaiToQueue(snssai);
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("Exception in Consumer Thread, {}", e.getMessage());
+ done = true;
+ }
+ }
+ }
/**
* Checks whether enough samples are available for the network functions
*/
- public boolean checkForEnoughSamples(List<String> nfs, String snssai) {
- for(String nf : nfs) {
- if(! pmDataQueue.checkSamplesInQueue(new SubCounter(nf, snssai), samples)) {
- log.info("Not enough samples to process for network function {} of snssai {}", nf, snssai);
- pmDataQueue.putSnssaiToQueue(snssai);
- return false;
- }
- }
- return true;
- }
+ public boolean checkForEnoughSamples(List<String> nfs, String snssai) {
+ for (String nf : nfs) {
+ if (!pmDataQueue.checkSamplesInQueue(new SubCounter(nf, snssai), samples)) {
+ log.info("Not enough samples to process for network function {} of snssai {}", nf, snssai);
+ pmDataQueue.putSnssaiToQueue(snssai);
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/MLMessageProcessor.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/MLMessageProcessor.java
index 8bc7b0d5..f692efcc 100644
--- a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/MLMessageProcessor.java
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/MLMessageProcessor.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* slice-analysis-ms
* ================================================================================
- * Copyright (C) 2020-2021 Wipro Limited.
+ * Copyright (C) 2020-2022 Wipro Limited.
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,9 +25,9 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
-import org.onap.slice.analysis.ms.configdb.AaiInterface;
-import org.onap.slice.analysis.ms.configdb.CpsInterface;
+import org.onap.slice.analysis.ms.aai.AaiInterface;
import org.onap.slice.analysis.ms.configdb.IConfigDbService;
+import org.onap.slice.analysis.ms.cps.CpsInterface;
import org.onap.slice.analysis.ms.models.CUModel;
import org.onap.slice.analysis.ms.models.Configuration;
import org.onap.slice.analysis.ms.models.MLOutputModel;
@@ -44,51 +44,54 @@ import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class MLMessageProcessor {
- private static Logger log = LoggerFactory.getLogger(MLMessageProcessor.class);
+ private static Logger log = LoggerFactory.getLogger(MLMessageProcessor.class);
- @Autowired
- private IConfigDbService configDbService;
+ @Autowired
+ private IConfigDbService configDbService;
- @Autowired
- private PolicyService policyService;
+ @Autowired
+ private PolicyService policyService;
- @Autowired
- private AaiInterface aaiInterface;
+ @Autowired
+ private AaiInterface aaiInterface;
- @Autowired
- private CpsInterface cpsInterface;
+ @Autowired
+ private CpsInterface cpsInterface;
- public void processMLMsg(MLOutputModel mlOutputMsg) {
- Boolean isConfigDbEnabled = (Objects.isNull(Configuration.getInstance().getConfigDbEnabled())) ? true
- : Configuration.getInstance().getConfigDbEnabled();
- Map<String, List<String>> ricToCellMapping = null;
- Map<String, String> serviceDetails = null;
- String snssai = mlOutputMsg.getSnssai();
- List<CUModel> cuData = mlOutputMsg.getData();
- if (isConfigDbEnabled) {
- ricToCellMapping = configDbService.fetchRICsOfSnssai(snssai);
- } else {
- ricToCellMapping = cpsInterface.fetchRICsOfSnssai(snssai);
- }
- log.debug("RIC to cell mapping of S-NSSAI {} is {}", snssai, ricToCellMapping);
- for (CUModel cuModel : cuData) {
- String cellId = String.valueOf(cuModel.getCellCUList().get(0).getCellLocalId());
- ricToCellMapping.forEach((ricId, cells) -> {
- if (cells.contains(cellId)) {
- cuModel.setNearRTRICId(ricId);
- }
- });
- }
- AdditionalProperties<MLOutputModel> addProps = new AdditionalProperties<>();
- addProps.setResourceConfig(mlOutputMsg);
+ /**
+ * Process the message sent by ML service and sends notification to policy
+ */
+ public void processMLMsg(MLOutputModel mlOutputMsg) {
+ Boolean isConfigDbEnabled = (Objects.isNull(Configuration.getInstance().getConfigDbEnabled())) ? true
+ : Configuration.getInstance().getConfigDbEnabled();
+ Map<String, List<String>> ricToCellMapping = null;
+ Map<String, String> serviceDetails = null;
+ String snssai = mlOutputMsg.getSnssai();
+ List<CUModel> cuData = mlOutputMsg.getData();
+ if (isConfigDbEnabled) {
+ ricToCellMapping = configDbService.fetchRICsOfSnssai(snssai);
+ } else {
+ ricToCellMapping = cpsInterface.fetchRICsOfSnssai(snssai);
+ }
+ log.debug("RIC to cell mapping of S-NSSAI {} is {}", snssai, ricToCellMapping);
+ for (CUModel cuModel : cuData) {
+ String cellId = String.valueOf(cuModel.getCellCUList().get(0).getCellLocalId());
+ ricToCellMapping.forEach((ricId, cells) -> {
+ if (cells.contains(cellId)) {
+ cuModel.setNearRTRICId(ricId);
+ }
+ });
+ }
+ AdditionalProperties<MLOutputModel> addProps = new AdditionalProperties<>();
+ addProps.setResourceConfig(mlOutputMsg);
- if (isConfigDbEnabled) {
- serviceDetails = configDbService.fetchServiceDetails(snssai);
- } else {
- serviceDetails = aaiInterface.fetchServiceDetails(snssai);
+ if (isConfigDbEnabled) {
+ serviceDetails = configDbService.fetchServiceDetails(snssai);
+ } else {
+ serviceDetails = aaiInterface.fetchServiceDetails(snssai);
- }
- policyService.sendOnsetMessageToPolicy(snssai, addProps, serviceDetails);
- }
+ }
+ policyService.sendOnsetMessageToPolicy(snssai, addProps, serviceDetails);
+ }
}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SliceUtilization.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SliceUtilization.java
new file mode 100644
index 00000000..94696343
--- /dev/null
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SliceUtilization.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.onap.slice.analysis.ms.aai.AaiService;
+import org.onap.slice.analysis.ms.exception.DesClientException;
+import org.onap.slice.analysis.ms.models.AggregatedConfig;
+import org.onap.slice.analysis.ms.models.Configuration;
+import org.onap.slice.analysis.ms.models.SliceConfigDetails;
+import org.onap.slice.analysis.ms.models.SliceConfigRequest;
+import org.onap.slice.analysis.ms.models.SliceConfigResponse;
+import org.onap.slice.analysis.ms.restclients.DesRestClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+/**
+ * This Service calculates the slice utilization details
+ */
+@Service
+public class SliceUtilization {
+
+ private static Logger log = LoggerFactory.getLogger(SliceUtilization.class);
+
+ @Autowired
+ private AaiService aaiService;
+
+ @Autowired
+ DesRestClient desRestClient;
+
+ /**
+ * Default values set for uplink and downlink throughput calculation (in
+ * accordance with 3GPP specifications)
+ *
+ */
+ private static final Integer numOfAggregatedComponentCarries = 8;
+ private static final Integer maxNumOfLayers = 4;
+ private static final Integer maxModulationOrder = 2;
+ private static final Integer scalingFactor = 1;
+ private static final Double maxBitRate = 948.0 / 1024;
+ private static final Integer nrNumerology = 2;
+ private static final Double averageSymbolDuration = Math.pow(10, -3) / (14 * 2 * nrNumerology);
+ private static final Double overHeadForDl = 0.18;
+ private static final Double overHeadForUl = 0.10;
+ private static final Integer TOTAL_PRB = 132;
+
+ /**
+ * Calculates the slice utilization details for requested slices.
+ *
+ * @param sliceConfigRequest contains sliceInstanceId
+ * @return SliceConfigResponse contains slice utilization details
+ */
+ public SliceConfigResponse getSliceUtilizationData(SliceConfigRequest sliceConfigRequest) {
+
+ log.info("getSliceUtilizationData");
+ SliceConfigResponse sliceConfigResponse = new SliceConfigResponse();
+ ArrayList<SliceConfigDetails> sliceConfigDetailsList = new ArrayList<>();
+
+ try {
+ sliceConfigRequest.getSliceIdentifiers().forEach(sliceInstanceId -> {
+ List<String> snssaiList = null;
+ snssaiList = aaiService.getSnssaiList(sliceInstanceId);
+ List<JSONObject> pmDataList = new ArrayList<>();
+ snssaiList.forEach(snssai -> {
+ JSONObject pmData = getPMData(snssai);
+ pmDataList.add(pmData);
+ });
+ AggregatedConfig aggregatedConfig = calculateSliceUtilization(pmDataList);
+ SliceConfigDetails sliceConfigDetails = new SliceConfigDetails();
+ sliceConfigDetails.setSliceIdentifiers(sliceInstanceId);
+ sliceConfigDetails.setAggregatedConfig(aggregatedConfig);
+ sliceConfigDetailsList.add(sliceConfigDetails);
+
+ });
+ } catch (Exception e) {
+ log.error("Exception caught while fetching data");
+ }
+ sliceConfigResponse.setSliceConfigDetails(sliceConfigDetailsList);
+ log.info("SliceConfigResponse: " + sliceConfigResponse.toString());
+ return sliceConfigResponse;
+
+ }
+
+ /**
+ * Fetches the PM data for requested SNSSAI from DES.
+ *
+ * @param snssai snssai ID
+ * @return PM Data for requested SNSSAI
+ */
+ protected JSONObject getPMData(String snssai) {
+ String desUrl = Configuration.getInstance().getDesUrl();
+ Map<String, String> inputParameter = new HashMap<>();
+ int duration = Configuration.getInstance().getPmDataDurationInWeeks();
+ Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ calendar.add(Calendar.WEEK_OF_MONTH, -duration);
+ inputParameter.put("snssai", "SM.PrbUsedDl." + snssai);
+ inputParameter.put("time", String.valueOf(calendar.getTimeInMillis()));
+ ResponseEntity<String> response = null;
+ JSONObject pmData = null;
+ try {
+
+ String jsonRequestBody = new ObjectMapper().writeValueAsString(inputParameter);
+ log.info("fetching PM Data for : {}", snssai);
+ response =
+ desRestClient.sendPostRequest(desUrl, jsonRequestBody, new ParameterizedTypeReference<String>() {});
+ pmData = new JSONObject(response.getBody());
+ if (response.getStatusCode().value() != 200) {
+ throw new DesClientException(String.format("Response code from DES other than 200: %d\", statusCode",
+ response.getStatusCode().value()));
+ }
+
+ } catch (Exception e) {
+ log.error("Error while fetching PM data from DES {} ", e);
+ }
+
+ return pmData;
+ }
+
+ /**
+ * Calculates average DL and UL PRB used from the PM data and returns the
+ * remaining resources(utilization details) in terms of throughput
+ *
+ * @param pmDataList PM data for all SNSSAIs
+ * @return aggregatedConfig containing slice utilization details
+ */
+ protected AggregatedConfig calculateSliceUtilization(List<JSONObject> pmDataList) {
+
+ Integer numOfPRBData = 0;
+ Integer dlPRBUsed = 0;
+ Integer ulPRBUsed = 0;
+ Integer dlThptIndex = 0;
+ Integer ulThptIndex = 1;
+ try {
+ for (JSONObject pmData : pmDataList) {
+ JSONArray result = pmData.getJSONArray("result");
+ for (int i = 0; i < result.length(); i++) {
+ JSONObject measValuesObject = result.getJSONObject(i);
+ String measValuesListStr = measValuesObject.getString("measValuesList");
+ String sMeasTypesListtStr = measValuesObject.getString("sMeasTypesList");
+ JSONArray measValuesArray = new JSONArray(measValuesListStr);
+ JSONArray sMeasTypesArray = new JSONArray(sMeasTypesListtStr);
+ if (sMeasTypesArray.getString(0).contains("PrbUsedUl")) {
+ ulThptIndex = 0;
+ dlThptIndex = 1;
+ }
+ numOfPRBData += measValuesArray.length();
+ for (int j = 0; j < measValuesArray.length(); j++) {
+ dlPRBUsed +=
+ measValuesArray.getJSONArray(j).getJSONArray(2).getJSONArray(dlThptIndex).getInt(1);
+ ulPRBUsed +=
+ measValuesArray.getJSONArray(j).getJSONArray(2).getJSONArray(ulThptIndex).getInt(1);
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("Exception caught while calculating slice utilization: {}", e);
+ }
+
+ Integer averageDLPrb = dlPRBUsed / numOfPRBData;
+ Integer averageULPrb = ulPRBUsed / numOfPRBData;
+ Double tempdl = 0.0;
+ Double tempul = 0.0;
+ int j = 1;
+
+ while (j <= numOfAggregatedComponentCarries) {
+ tempdl += ((Math.pow(maxNumOfLayers, j) * Math.pow(maxModulationOrder, j) * Math.pow(scalingFactor, j)
+ * maxBitRate * (TOTAL_PRB - averageDLPrb) * 12 * (1 - Math.pow(overHeadForDl, j)))
+ / averageSymbolDuration) * Math.pow(10, -6);
+ tempul += ((Math.pow(maxNumOfLayers, j) * Math.pow(maxModulationOrder, j) * Math.pow(scalingFactor, j)
+ * maxBitRate * (TOTAL_PRB - averageULPrb) * 12 * (1 - Math.pow(overHeadForUl, j)))
+ / averageSymbolDuration) * Math.pow(10, -6);
+ j++;
+
+ }
+
+ Integer dLThptPerSliceInMbps = (int) Math.round(tempdl);
+ Integer uLThptPerSliceInMbps = (int) Math.round(tempul);
+ AggregatedConfig aggregatedConfig = new AggregatedConfig();
+ aggregatedConfig.setDLThptPerSlice(dLThptPerSliceInMbps);
+ aggregatedConfig.setULThptPerSlice(uLThptPerSliceInMbps);
+ return aggregatedConfig;
+ }
+}
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SnssaiSamplesProcessor.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SnssaiSamplesProcessor.java
index d802f81d..b4e06896 100644
--- a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SnssaiSamplesProcessor.java
+++ b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/SnssaiSamplesProcessor.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* slice-analysis-ms
* ================================================================================
- * Copyright (C) 2020-2021 Wipro Limited.
+ * Copyright (C) 2020-2022 Wipro Limited.
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
* ============LICENSE_END=========================================================
*
*******************************************************************************/
+
package org.onap.slice.analysis.ms.service;
import java.util.ArrayList;
@@ -29,9 +30,9 @@ import java.util.Objects;
import javax.annotation.PostConstruct;
-import org.onap.slice.analysis.ms.configdb.AaiInterface;
-import org.onap.slice.analysis.ms.configdb.CpsInterface;
+import org.onap.slice.analysis.ms.aai.AaiInterface;
import org.onap.slice.analysis.ms.configdb.IConfigDbService;
+import org.onap.slice.analysis.ms.cps.CpsInterface;
import org.onap.slice.analysis.ms.models.Configuration;
import org.onap.slice.analysis.ms.models.MeasurementObject;
import org.onap.slice.analysis.ms.models.SubCounter;
@@ -48,201 +49,201 @@ import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class SnssaiSamplesProcessor {
- private static Logger log = LoggerFactory.getLogger(SnssaiSamplesProcessor.class);
-
- @Autowired
- private PolicyService policyService;
-
- @Autowired
- private IConfigDbService configDbService;
-
- @Autowired
- private PmDataQueue pmDataQueue;
-
- @Autowired
- private AverageCalculator averageCalculator;
-
- @Autowired
- private AaiInterface aaiInterface;
-
- @Autowired
- private CpsInterface cpsInterface;
-
- private List<MeasurementObject> snssaiMeasurementList = new ArrayList<>();
- private Map<String, List<String>> ricToCellMapping = new HashMap<>();
- private Map<String, Map<String, Integer>> ricToPrbsMapping = new HashMap<>();
- private Map<String, Map<String, Integer>> ricToThroughputMapping = new HashMap<>();
- private int noOfSamples;
- private List<String> pmsToCompute;
- private Map<String, String> prbThroughputMapping = new HashMap<>();
- private int minPercentageChange;
-
- @PostConstruct
- public void init() {
- Configuration configuration = Configuration.getInstance();
- noOfSamples = configuration.getSamples();
- pmsToCompute = new ArrayList<>();
- pmsToCompute.add("PrbUsedDl");
- pmsToCompute.add("PrbUsedUl");
- prbThroughputMapping = new HashMap<>();
- prbThroughputMapping.put("PrbUsedDl", "dLThptPerSlice");
- prbThroughputMapping.put("PrbUsedUl", "uLThptPerSlice");
- minPercentageChange = configuration.getMinPercentageChange();
+ private static Logger log = LoggerFactory.getLogger(SnssaiSamplesProcessor.class);
+
+ @Autowired
+ private PolicyService policyService;
+
+ @Autowired
+ private IConfigDbService configDbService;
+
+ @Autowired
+ private PmDataQueue pmDataQueue;
+
+ @Autowired
+ private AverageCalculator averageCalculator;
+
+ @Autowired
+ private AaiInterface aaiInterface;
+
+ @Autowired
+ private CpsInterface cpsInterface;
+
+ private List<MeasurementObject> snssaiMeasurementList = new ArrayList<>();
+ private Map<String, List<String>> ricToCellMapping = new HashMap<>();
+ private Map<String, Map<String, Integer>> ricToPrbsMapping = new HashMap<>();
+ private Map<String, Map<String, Integer>> ricToThroughputMapping = new HashMap<>();
+ private int noOfSamples;
+ private List<String> pmsToCompute;
+ private Map<String, String> prbThroughputMapping = new HashMap<>();
+ private int minPercentageChange;
+
+ @PostConstruct
+ public void init() {
+ Configuration configuration = Configuration.getInstance();
+ noOfSamples = configuration.getSamples();
+ pmsToCompute = new ArrayList<>();
+ pmsToCompute.add("PrbUsedDl");
+ pmsToCompute.add("PrbUsedUl");
+ prbThroughputMapping = new HashMap<>();
+ prbThroughputMapping.put("PrbUsedDl", "dLThptPerSlice");
+ prbThroughputMapping.put("PrbUsedUl", "uLThptPerSlice");
+ minPercentageChange = configuration.getMinPercentageChange();
+ }
+
+ /**
+ * process the measurement data of an S-NSSAI
+ */
+ public boolean processSamplesOfSnnsai(String snssai, List<String> networkFunctions) {
+ Boolean isConfigDbEnabled = (Objects.isNull(Configuration.getInstance().getConfigDbEnabled())) ? true
+ : Configuration.getInstance().getConfigDbEnabled();
+ List<MeasurementObject> sample = null;
+ List<List<MeasurementObject>> samples = null;
+ Map<String, String> serviceDetails = null;
+ log.info("Network Functions {} of snssai {}", networkFunctions, snssai);
+ for (String nf : networkFunctions) {
+ log.debug("Average of samples for {}:", snssai);
+ samples = pmDataQueue.getSamplesFromQueue(new SubCounter(nf, snssai), noOfSamples);
+ if (samples != null) {
+ sample = averageCalculator.findAverageOfSamples(samples);
+ addToMeasurementList(sample);
+ } else {
+ log.info("Not enough samples present for nf {}", nf);
+ return false;
+ }
}
-
- /**
- * process the measurement data of an S-NSSAI
- */
- public boolean processSamplesOfSnnsai(String snssai, List<String> networkFunctions) {
- Boolean isConfigDbEnabled = (Objects.isNull(Configuration.getInstance().getConfigDbEnabled())) ? true
- : Configuration.getInstance().getConfigDbEnabled();
- List<MeasurementObject> sample = null;
- List<List<MeasurementObject>> samples = null;
- Map<String, String> serviceDetails =null;
- log.info("Network Functions {} of snssai {}", networkFunctions, snssai);
- for (String nf : networkFunctions) {
- log.debug("Average of samples for {}:", snssai);
- samples = pmDataQueue.getSamplesFromQueue(new SubCounter(nf, snssai), noOfSamples);
- if (samples != null) {
- sample = averageCalculator.findAverageOfSamples(samples);
- addToMeasurementList(sample);
- } else {
- log.info("Not enough samples present for nf {}", nf);
- return false;
- }
- }
- log.info("snssai measurement list {}", snssaiMeasurementList);
- Map<String, Map<String, Object>> ricConfiguration;
- Map<String, Integer> sliceConfiguration;
- if (isConfigDbEnabled) {
- ricToCellMapping = configDbService.fetchRICsOfSnssai(snssai);
- ricConfiguration = configDbService.fetchCurrentConfigurationOfRIC(snssai);
- sliceConfiguration = configDbService.fetchCurrentConfigurationOfSlice(snssai);
- serviceDetails = configDbService.fetchServiceDetails(snssai);
- } else {
- ricToCellMapping = cpsInterface.fetchRICsOfSnssai(snssai);
- ricConfiguration = cpsInterface.fetchCurrentConfigurationOfRIC(snssai);
- serviceDetails = aaiInterface.fetchServiceDetails(snssai);
- sliceConfiguration = aaiInterface.fetchCurrentConfigurationOfSlice(snssai);
- }
- log.info("RIC to Cell Mapping for {} S-NSSAI: {}", snssai, ricToCellMapping);
- log.info("RIC Configuration {} and Slice Configuration {}", ricConfiguration, sliceConfiguration);
- pmsToCompute.forEach(pm -> {
- log.debug("processing for pm {}", pm);
- sumOfPrbsAcrossCells(pm);
- int sum = computeSum(pm);
- computeThroughput(sliceConfiguration, sum, pm);
- calculatePercentageChange(ricConfiguration, prbThroughputMapping.get(pm));
- });
- updateConfiguration();
- if (ricToThroughputMapping.size() > 0) {
- AdditionalProperties<Map<String, List<Map<String, Integer>>>> addProps = new AdditionalProperties<>();
- addProps.setResourceConfig(getChangedRIConfigFormat(ricToThroughputMapping));
- policyService.sendOnsetMessageToPolicy(snssai, addProps, serviceDetails);
- }
- return true;
+ log.info("snssai measurement list {}", snssaiMeasurementList);
+ Map<String, Map<String, Object>> ricConfiguration;
+ Map<String, Integer> sliceConfiguration;
+ if (isConfigDbEnabled) {
+ ricToCellMapping = configDbService.fetchRICsOfSnssai(snssai);
+ ricConfiguration = configDbService.fetchCurrentConfigurationOfRIC(snssai);
+ sliceConfiguration = configDbService.fetchCurrentConfigurationOfSlice(snssai);
+ serviceDetails = configDbService.fetchServiceDetails(snssai);
+ } else {
+ ricToCellMapping = cpsInterface.fetchRICsOfSnssai(snssai);
+ ricConfiguration = cpsInterface.fetchCurrentConfigurationOfRIC(snssai);
+ serviceDetails = aaiInterface.fetchServiceDetails(snssai);
+ sliceConfiguration = aaiInterface.fetchCurrentConfigurationOfSlice(snssai);
}
-
- /**
- * change the RICConfig data format to be compatible with SDN-R
- */
- protected Map<String, List<Map<String, Integer>>> getChangedRIConfigFormat(
- Map<String, Map<String, Integer>> ricToThroughputMapping) {
- Iterator<Map.Entry<String, Map<String, Integer>>> it = ricToThroughputMapping.entrySet().iterator();
- Map.Entry<String, Map<String, Integer>> entry = null;
- List<Map<String, Integer>> ricConfigList = new ArrayList<>();
- Map<String, List<Map<String, Integer>>> ricConfigData = new HashMap<>();
- while (it.hasNext()) {
- Map<String, Integer> newConfigMap = new HashMap<>();
- entry = it.next();
- newConfigMap = entry.getValue();
- newConfigMap.put("nearRTRICId", Integer.parseInt(entry.getKey()));
- ricConfigList.add(newConfigMap);
- }
- ricConfigData.put("data", ricConfigList);
- return ricConfigData;
+ log.info("RIC to Cell Mapping for {} S-NSSAI: {}", snssai, ricToCellMapping);
+ log.info("RIC Configuration {} and Slice Configuration {}", ricConfiguration, sliceConfiguration);
+ pmsToCompute.forEach(pm -> {
+ log.debug("processing for pm {}", pm);
+ sumOfPrbsAcrossCells(pm);
+ int sum = computeSum(pm);
+ computeThroughput(sliceConfiguration, sum, pm);
+ calculatePercentageChange(ricConfiguration, prbThroughputMapping.get(pm));
+ });
+ updateConfiguration();
+ if (ricToThroughputMapping.size() > 0) {
+ AdditionalProperties<Map<String, List<Map<String, Integer>>>> addProps = new AdditionalProperties<>();
+ addProps.setResourceConfig(getChangedRIConfigFormat(ricToThroughputMapping));
+ policyService.sendOnsetMessageToPolicy(snssai, addProps, serviceDetails);
}
-
- /**
- * process the measurement data of an S-NSSAI
- */
- protected void updateConfiguration() {
- Iterator<Map.Entry<String, Map<String, Integer>>> it = ricToThroughputMapping.entrySet().iterator();
- Map.Entry<String, Map<String, Integer>> entry = null;
- while (it.hasNext()) {
- entry = it.next();
- if (entry.getValue().size() == 0) {
- it.remove();
- }
- }
+ return true;
+ }
+
+ /**
+ * change the RICConfig data format to be compatible with SDN-R
+ */
+ protected Map<String, List<Map<String, Integer>>> getChangedRIConfigFormat(
+ Map<String, Map<String, Integer>> ricToThroughputMapping) {
+ Iterator<Map.Entry<String, Map<String, Integer>>> it = ricToThroughputMapping.entrySet().iterator();
+ Map.Entry<String, Map<String, Integer>> entry = null;
+ List<Map<String, Integer>> ricConfigList = new ArrayList<>();
+ Map<String, List<Map<String, Integer>>> ricConfigData = new HashMap<>();
+ while (it.hasNext()) {
+ Map<String, Integer> newConfigMap = new HashMap<>();
+ entry = it.next();
+ newConfigMap = entry.getValue();
+ newConfigMap.put("nearRTRICId", Integer.parseInt(entry.getKey()));
+ ricConfigList.add(newConfigMap);
}
-
- private void addToMeasurementList(List<MeasurementObject> sample) {
- snssaiMeasurementList.addAll(sample);
+ ricConfigData.put("data", ricConfigList);
+ return ricConfigData;
+ }
+
+ /**
+ * process the measurement data of an S-NSSAI
+ */
+ protected void updateConfiguration() {
+ Iterator<Map.Entry<String, Map<String, Integer>>> it = ricToThroughputMapping.entrySet().iterator();
+ Map.Entry<String, Map<String, Integer>> entry = null;
+ while (it.hasNext()) {
+ entry = it.next();
+ if (entry.getValue().size() == 0) {
+ it.remove();
+ }
}
-
- /**
- * Calculate the change in the configuration value and keep the configuration
- * only if it is greater than a specific limit
- */
- protected void calculatePercentageChange(Map<String, Map<String, Object>> ricConfiguration, String pm) {
- Iterator<Map.Entry<String, Map<String, Integer>>> it = ricToThroughputMapping.entrySet().iterator();
- Map.Entry<String, Map<String, Integer>> entry = null;
- float existing = 0;
- float change = 0;
- while (it.hasNext()) {
- entry = it.next();
- existing = (float) ((int) ricConfiguration.get(entry.getKey()).get(pm));
- change = ((Math.abs(entry.getValue().get(pm) - existing)) / existing) * 100;
- if (change <= minPercentageChange) {
- ricToThroughputMapping.get(entry.getKey()).remove(pm);
- log.info("Removing pm data {} for RIC {}", pm, entry.getKey());
- }
- }
+ }
+
+ private void addToMeasurementList(List<MeasurementObject> sample) {
+ snssaiMeasurementList.addAll(sample);
+ }
+
+ /**
+ * Calculate the change in the configuration value and keep the configuration
+ * only if it is greater than a specific limit
+ */
+ protected void calculatePercentageChange(Map<String, Map<String, Object>> ricConfiguration, String pm) {
+ Iterator<Map.Entry<String, Map<String, Integer>>> it = ricToThroughputMapping.entrySet().iterator();
+ Map.Entry<String, Map<String, Integer>> entry = null;
+ float existing = 0;
+ float change = 0;
+ while (it.hasNext()) {
+ entry = it.next();
+ existing = (float) ((int) ricConfiguration.get(entry.getKey()).get(pm));
+ change = ((Math.abs(entry.getValue().get(pm) - existing)) / existing) * 100;
+ if (change <= minPercentageChange) {
+ ricToThroughputMapping.get(entry.getKey()).remove(pm);
+ log.info("Removing pm data {} for RIC {}", pm, entry.getKey());
+ }
}
-
- protected void sumOfPrbsAcrossCells(String pmName) {
- ricToCellMapping.forEach((ric, cells) -> {
- int sumOfPrbs = 0;
- for (String cell : cells) {
- int index = MeasurementObject.findIndex(cell, snssaiMeasurementList);
- sumOfPrbs += snssaiMeasurementList.get(index).getPmData().get(pmName);
- }
- if (ricToPrbsMapping.containsKey(ric)) {
- ricToPrbsMapping.get(ric).put(pmName, sumOfPrbs);
- } else {
- Map<String, Integer> pmToPrbMapping = new HashMap<>();
- pmToPrbMapping.put(pmName, sumOfPrbs);
- ricToPrbsMapping.put(ric, pmToPrbMapping);
- }
- });
- log.info("PRBs sum computed for RIC {}", ricToPrbsMapping);
- }
-
- protected Integer computeSum(String pm) {
- return ricToPrbsMapping.entrySet().stream().map(x -> x.getValue().get(pm)).reduce(0, Integer::sum);
- }
-
- protected void computeThroughput(Map<String, Integer> sliceConfiguration, int sum, String pm) {
- Iterator<Map.Entry<String, Map<String, Integer>>> it = ricToPrbsMapping.entrySet().iterator();
- Map.Entry<String, Map<String, Integer>> entry = null;
- Map<String, Integer> throughtputMap = null;
- String ric = "";
- int value = 0;
- while (it.hasNext()) {
- entry = it.next();
- ric = entry.getKey();
- value = Math.round(((float) entry.getValue().get(pm) / sum)
- * (float) sliceConfiguration.get(prbThroughputMapping.get(pm)));
- if (ricToThroughputMapping.containsKey(ric)) {
- ricToThroughputMapping.get(ric).put(prbThroughputMapping.get(pm), value);
- } else {
- throughtputMap = new HashMap<>();
- throughtputMap.put(prbThroughputMapping.get(pm), value);
- ricToThroughputMapping.put(ric, throughtputMap);
- }
- }
- log.info("Throughput computed for RIC {}", ricToThroughputMapping);
+ }
+
+ protected void sumOfPrbsAcrossCells(String pmName) {
+ ricToCellMapping.forEach((ric, cells) -> {
+ int sumOfPrbs = 0;
+ for (String cell : cells) {
+ int index = MeasurementObject.findIndex(cell, snssaiMeasurementList);
+ sumOfPrbs += snssaiMeasurementList.get(index).getPmData().get(pmName);
+ }
+ if (ricToPrbsMapping.containsKey(ric)) {
+ ricToPrbsMapping.get(ric).put(pmName, sumOfPrbs);
+ } else {
+ Map<String, Integer> pmToPrbMapping = new HashMap<>();
+ pmToPrbMapping.put(pmName, sumOfPrbs);
+ ricToPrbsMapping.put(ric, pmToPrbMapping);
+ }
+ });
+ log.info("PRBs sum computed for RIC {}", ricToPrbsMapping);
+ }
+
+ protected Integer computeSum(String pm) {
+ return ricToPrbsMapping.entrySet().stream().map(x -> x.getValue().get(pm)).reduce(0, Integer::sum);
+ }
+
+ protected void computeThroughput(Map<String, Integer> sliceConfiguration, int sum, String pm) {
+ Iterator<Map.Entry<String, Map<String, Integer>>> it = ricToPrbsMapping.entrySet().iterator();
+ Map.Entry<String, Map<String, Integer>> entry = null;
+ Map<String, Integer> throughtputMap = null;
+ String ric = "";
+ int value = 0;
+ while (it.hasNext()) {
+ entry = it.next();
+ ric = entry.getKey();
+ value = Math.round(((float) entry.getValue().get(pm) / sum)
+ * (float) sliceConfiguration.get(prbThroughputMapping.get(pm)));
+ if (ricToThroughputMapping.containsKey(ric)) {
+ ricToThroughputMapping.get(ric).put(prbThroughputMapping.get(pm), value);
+ } else {
+ throughtputMap = new HashMap<>();
+ throughtputMap.put(prbThroughputMapping.get(pm), value);
+ ricToThroughputMapping.put(ric, throughtputMap);
+ }
}
+ log.info("Throughput computed for RIC {}", ricToThroughputMapping);
+ }
}
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/aai/AaiInterfaceServiceTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/aai/AaiInterfaceServiceTest.java
new file mode 100644
index 00000000..31264e8c
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/aai/AaiInterfaceServiceTest.java
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2021-2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.aai;
+
+import static org.junit.Assert.assertEquals;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.onap.slice.analysis.ms.models.Configuration;
+import org.onap.slice.analysis.ms.restclients.AaiRestClient;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(SpringRunner.class)
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "javax.management.*"})
+@PrepareForTest({AaiService.class, Configuration.class})
+@SpringBootTest(classes = AaiInterfaceServiceTest.class)
+public class AaiInterfaceServiceTest {
+
+ Configuration configuration = Configuration.getInstance();
+
+ @InjectMocks
+ AaiService aaiService;
+
+ @Mock
+ AaiRestClient restClient;
+
+ @Test
+ public void fetchCurrentConfigurationOfSlice() {
+ configuration.setAaiUrl("http://aai:30233/aai/v21/business/customers/customer/");
+ PowerMockito.mockStatic(AaiService.class);
+ PowerMockito.mockStatic(Configuration.class);
+ PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
+ Map<String, Integer> responsemap = new HashMap<>();
+ responsemap.put("dLThptPerSlice", 60);
+ responsemap.put("uLThptPerSlice", 54);
+ try {
+ String serviceInstance =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/aaiDetailsList.json")));
+ Mockito.when(restClient.sendGetRequest(Mockito.anyString(), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstance, HttpStatus.OK));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ assertEquals(responsemap, aaiService.fetchCurrentConfigurationOfSlice("001-010000"));
+ }
+
+ @Test
+ public void fetchServiceProfile() {
+ Map<String, String> responseMap = new HashMap<String, String>();
+ responseMap.put("sNSSAI", "001-00110");
+ responseMap.put("ranNFNSSIId", "4b889f2b-8ee4-4ec7-881f-5b1af8a74039");
+ responseMap.put("sliceProfileId", "ab9af40f13f7219099333");
+ responseMap.put("globalSubscriberId", "5GCustomer");
+ responseMap.put("subscriptionServiceType", "5G");
+
+ try {
+ String serviceInstance =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/aaiDetailsList.json")));
+ Mockito.when(restClient.sendGetRequest(Mockito.anyString(), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstance, HttpStatus.OK));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+
+ assertEquals(responseMap, aaiService.fetchServiceDetails("001-00110"));
+ }
+
+ @Test
+ public void fetchSubscriberAndSubscriptionServiceTypeTest() throws Exception {
+
+ configuration.setAaiUrl("http://aai:30233/aai/v21");
+ Map<String, String> expectedResponse = new HashMap<String, String>();
+ expectedResponse.put("globalSubscriberId", "5GCustomer");
+ expectedResponse.put("subscriptionServiceType", "5G");
+ PowerMockito.mockStatic(AaiService.class);
+ PowerMockito.mockStatic(Configuration.class);
+ PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
+
+ try {
+
+ String serviceInstance =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/aaiDetailsList.json")));
+ Mockito.when(restClient.sendGetRequest(Mockito.anyString(), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstance, HttpStatus.OK));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Map<String, String> actualResponse = aaiService.fetchSubscriberAndSubscriptionServiceType();
+ assertEquals(expectedResponse, actualResponse);
+ }
+
+ @Test
+ public void fetchSliceProfilesOfAllotedResourceDataTest() throws Exception {
+ configuration.setAaiUrl("http://aai:30233/aai/v21");
+ List<String> allotedResourceList = new ArrayList<>();
+ allotedResourceList.add("530d188d-9087-49af-a44a-90c40e0c2d47");
+ List<String> expectedResponse = new ArrayList<>();
+ expectedResponse.add("b2ae730f-1d5f-495a-8112-dac017a7348c");
+ expectedResponse.add("cad8fa36-2d55-4c12-a92e-1bd551517a0c");
+ expectedResponse.add("8d0d698e-77f4-4453-8c09-ae2cbe6a9a04");
+ PowerMockito.mockStatic(AaiService.class);
+ PowerMockito.mockStatic(Configuration.class);
+ PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
+
+ try {
+
+ String serviceInstance =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/alloted-resource.json")));
+ Mockito.when(restClient.sendGetRequest(Mockito.anyString(), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstance, HttpStatus.OK));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ List<String> actualResponse = aaiService.fetchSliceProfilesOfAllotedResourceData(allotedResourceList);
+ assertEquals(expectedResponse, actualResponse);
+ }
+
+ @Test
+ public void fetchSnssaiOfSliceProfileTest() throws Exception {
+ configuration.setAaiUrl("http://aai:30233/aai/v21");
+ List<String> sliceProfileList = new ArrayList<>();
+ sliceProfileList.add("b2ae730f-1d5f-495a-8112-dac017a7348c");
+ sliceProfileList.add("cad8fa36-2d55-4c12-a92e-1bd551517a0c");
+ sliceProfileList.add("8d0d698e-77f4-4453-8c09-ae2cbe6a9a04");
+ List<String> expectedResponse = new ArrayList<>();
+ expectedResponse.add("01-06E442");
+ expectedResponse.add("01-B989BD");
+
+ PowerMockito.mockStatic(AaiService.class);
+ PowerMockito.mockStatic(Configuration.class);
+ PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
+ String serviceInstanceUrlAn = "b2ae730f-1d5f-495a-8112-dac017a7348c";
+ String serviceInstanceUrlCn = "cad8fa36-2d55-4c12-a92e-1bd551517a0c";
+ String serviceInstanceUrlTn = "8d0d698e-77f4-4453-8c09-ae2cbe6a9a04";
+
+ try {
+
+ String serviceInstanceAn =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/sliceprofile_an_sa1.json")));
+ Mockito.when(restClient.sendGetRequest(Mockito.contains(serviceInstanceUrlAn), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstanceAn, HttpStatus.OK));
+
+ String serviceInstanceCn =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/sliceprofile_cn_sa1.json")));
+ Mockito.when(restClient.sendGetRequest(Mockito.contains(serviceInstanceUrlCn), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstanceCn, HttpStatus.OK));
+
+ String serviceInstanceTn =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/sliceprofile_tn_sa1.json")));
+ Mockito.when(restClient.sendGetRequest(Mockito.contains(serviceInstanceUrlTn), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstanceTn, HttpStatus.OK));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ List<String> actualResponse = aaiService.fetchSnssaiOfSliceProfile(sliceProfileList);
+ assertEquals(expectedResponse, actualResponse);
+ }
+
+ @Test
+ public void getSnssaiListForNsiTest() throws Exception {
+ configuration.setAaiUrl("http://aai:30233/aai/v21");
+ List<String> expectedResponse = new ArrayList<>();
+ expectedResponse.add("01-06E442");
+ expectedResponse.add("01-B989BD");
+ PowerMockito.mockStatic(AaiService.class);
+ PowerMockito.mockStatic(Configuration.class);
+ PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
+
+ try {
+
+ String allotedResource =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/alloted-resource.json")));
+ Mockito.when(
+ restClient.sendGetRequest(Mockito.contains("0835fd19-6726-4081-befb-cc8932c47767"), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(allotedResource, HttpStatus.OK));
+
+ String serviceInstance = new String(Files.readAllBytes(Paths.get("src/test/resources/nsi.json")));
+ Mockito.when(
+ restClient.sendGetRequest(Mockito.contains("09cad94e-fbb8-4c70-9c4d-74ec75e97683"), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstance, HttpStatus.OK));
+
+ String serviceInstanceAn =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/sliceprofile_an_sa1.json")));
+ Mockito.when(
+ restClient.sendGetRequest(Mockito.contains("b2ae730f-1d5f-495a-8112-dac017a7348c"), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstanceAn, HttpStatus.OK));
+
+ String serviceInstanceCn =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/sliceprofile_cn_sa1.json")));
+ Mockito.when(
+ restClient.sendGetRequest(Mockito.contains("cad8fa36-2d55-4c12-a92e-1bd551517a0c"), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstanceCn, HttpStatus.OK));
+
+ String serviceInstanceTn =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/sliceprofile_tn_sa1.json")));
+ Mockito.when(
+ restClient.sendGetRequest(Mockito.contains("8d0d698e-77f4-4453-8c09-ae2cbe6a9a04"), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstanceTn, HttpStatus.OK));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ List<String> actualResponse = aaiService.getSnssaiList("09cad94e-fbb8-4c70-9c4d-74ec75e97683");
+ assertEquals(expectedResponse, actualResponse);
+ }
+
+ @Test
+ public void getSnssaiListForNssiTest() throws Exception {
+ configuration.setAaiUrl("http://aai:30233/aai/v21");
+ List<String> expectedResponse = new ArrayList<>();
+ expectedResponse.add("01-06E442");
+ PowerMockito.mockStatic(AaiService.class);
+ PowerMockito.mockStatic(Configuration.class);
+ PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
+ try {
+
+ String nssi = new String(Files.readAllBytes(Paths.get("src/test/resources/nssi.json")));
+ Mockito.when(
+ restClient.sendGetRequest(Mockito.contains("50f418a6-804f-4453-bf70-21f0efaf6fcd"), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(nssi, HttpStatus.OK));
+
+ String serviceInstanceAn =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/sliceprofile_an_sa1.json")));
+ Mockito.when(
+ restClient.sendGetRequest(Mockito.contains("b2ae730f-1d5f-495a-8112-dac017a7348c"), Mockito.any()))
+ .thenReturn(new ResponseEntity<Object>(serviceInstanceAn, HttpStatus.OK));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ List<String> actualResponse = aaiService.getSnssaiList("50f418a6-804f-4453-bf70-21f0efaf6fcd");
+ assertEquals(expectedResponse, actualResponse);
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/configdb/AaiInterfaceServiceTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/configdb/AaiInterfaceServiceTest.java
deleted file mode 100644
index 78607788..00000000
--- a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/configdb/AaiInterfaceServiceTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*******************************************************************************
- * ============LICENSE_START=======================================================
- * slice-analysis-ms
- * ================================================================================
- * Copyright (C) 2021 Wipro Limited.
- * ==============================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- *
- *******************************************************************************/
-package org.onap.slice.analysis.ms.configdb;
-
-import static org.junit.Assert.assertEquals;
-
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-import org.onap.slice.analysis.ms.models.Configuration;
-import org.onap.slice.analysis.ms.models.configdb.CellsModel;
-import org.onap.slice.analysis.ms.models.configdb.NetworkFunctionModel;
-import org.onap.slice.analysis.ms.restclients.AaiRestClient;
-import org.onap.slice.analysis.ms.restclients.ConfigDbRestClient;
-import org.onap.slice.analysis.ms.utils.BeanUtil;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.test.context.junit4.SpringRunner;
-
-@RunWith(PowerMockRunner.class)
-@PowerMockRunnerDelegate(SpringRunner.class)
-@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "javax.management.*"})
-@PrepareForTest({ AaiService.class,Configuration.class })
-@SpringBootTest(classes = AaiInterfaceServiceTest.class)
-public class AaiInterfaceServiceTest {
-
- Configuration configuration = Configuration.getInstance();
-
- @InjectMocks
- AaiService aaiService;
-
- @Mock
- AaiRestClient restClient;
-
- @Test
- public void fetchCurrentConfigurationOfSlice() {
- configuration.setAaiUrl("http://aai:30233/aai/v21/business/customers/customer/");
- PowerMockito.mockStatic(AaiService.class);
- PowerMockito.mockStatic(Configuration.class);
- PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
- Map<String, Integer> responsemap = new HashMap<>();
- responsemap.put("dLThptPerSlice", 60);
- responsemap.put("uLThptPerSlice", 54);
- try {
- String serviceInstance = new String(
- Files.readAllBytes(Paths.get("src/test/resources/aaiDetailsList.json")));
- Mockito.when(restClient.sendGetRequest(Mockito.anyString(), Mockito.any()))
- .thenReturn(new ResponseEntity<Object>(serviceInstance, HttpStatus.OK));
-
-
- } catch (Exception e) {
- e.printStackTrace();
-
- }
- assertEquals(responsemap, aaiService.fetchCurrentConfigurationOfSlice("001-010000"));
- }
-
- @Test
- public void fetchServiceProfile() {
- Map<String, String> responseMap = new HashMap<String, String>();
- responseMap.put("sNSSAI", "001-00110");
- responseMap.put("ranNFNSSIId", "4b889f2b-8ee4-4ec7-881f-5b1af8a74039");
- responseMap.put("sliceProfileId", "ab9af40f13f7219099333");
- responseMap.put("globalSubscriberId", "5GCustomer");
- responseMap.put("subscriptionServiceType", "5G");
-
- try {
- String serviceInstance = new String(
- Files.readAllBytes(Paths.get("src/test/resources/aaiDetailsList.json")));
- Mockito.when(restClient.sendGetRequest(Mockito.anyString(), Mockito.any()))
- .thenReturn(new ResponseEntity<Object>(serviceInstance, HttpStatus.OK));
-
- } catch (Exception e) {
- e.printStackTrace();
-
- }
-
- assertEquals(responseMap, aaiService.fetchServiceDetails("001-00110"));
- }
-}
-
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/configdb/CpsInterfaceServiceTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/configdb/CpsInterfaceServiceTest.java
deleted file mode 100644
index 008736d3..00000000
--- a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/configdb/CpsInterfaceServiceTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*******************************************************************************
- * ============LICENSE_START=======================================================
- * slice-analysis-ms
- * ================================================================================
- * Copyright (C) 2021 Wipro Limited.
- * ==============================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- *
- *******************************************************************************/
-package org.onap.slice.analysis.ms.configdb;
-
-import static org.junit.Assert.assertEquals;
-
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.onap.slice.analysis.ms.models.Configuration;
-import org.onap.slice.analysis.ms.restclients.CpsRestClient;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.test.context.junit4.SpringRunner;
-
-@RunWith(PowerMockRunner.class)
-@PowerMockRunnerDelegate(SpringRunner.class)
-@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "javax.management.*"})
-@PrepareForTest({ CpsService.class,Configuration.class })
-@SpringBootTest(classes = CpsInterfaceServiceTest.class)
-public class CpsInterfaceServiceTest {
- @InjectMocks
- CpsService cpsService;
-
- @Mock
- CpsRestClient restClient;
-
- @Test
- public void fetchCurrentConfigurationOfRICTest() {
- Map<String, Object> map = new HashMap<>();
- map.put("dLThptPerSlice", 10);
- map.put("uLThptPerSlice", 10);
- map.put("maxNumberOfConns", 10);
- Map<String, Map<String, Object>> responseMap = new HashMap<>();
- responseMap.put("11", map);
- try {
- String serviceInstance = new String(
- Files.readAllBytes(Paths.get("src/test/resources/sliceConfig.json")));
- Mockito.when(restClient.sendPostRequest(Mockito.anyString(), Mockito.anyString(), Mockito.any())).thenReturn(new ResponseEntity<>(serviceInstance, HttpStatus.OK));
- } catch (Exception e) {
- e.printStackTrace();
- }
- assertEquals(responseMap, cpsService.fetchCurrentConfigurationOfRIC("111-1111"));
- }
-
- @Test
- public void fetchNetworkFunctionsOfSnssaiTest() {
- List<String> responseList=new ArrayList<>();
- responseList.add("22");
- responseList.add("23");
- try {
- String serviceInstance = new String(
- Files.readAllBytes(Paths.get("src/test/resources/DUList.json")));
- Mockito.when(restClient.sendPostRequest(Mockito.anyString(), Mockito.anyString(), Mockito.any())).thenReturn(new ResponseEntity<>(serviceInstance, HttpStatus.OK));
- } catch (Exception e) {
- e.printStackTrace();
- }
- assertEquals(responseList, cpsService.fetchNetworkFunctionsOfSnssai("111-1111"));
- }
-
- @Test
- public void fetchRICsOfSnssaiTest() {
- Map<String,List<String>> responseMap=new HashMap<>();
- List<String> cellslist=new ArrayList<>();
- cellslist.add("1599");
- cellslist.add("1598");
- responseMap.put("11",cellslist);
- try {
- String serviceInstance = new String(
- Files.readAllBytes(Paths.get("src/test/resources/DUCellsList.json")));
- Mockito.when(restClient.sendPostRequest(Mockito.anyString(), Mockito.anyString(), Mockito.any())).thenReturn(new ResponseEntity<>(serviceInstance, HttpStatus.OK));
- } catch (Exception e) {
- e.printStackTrace();
- }
- assertEquals(responseMap, cpsService.fetchRICsOfSnssai("111-1111"));
- }
-}
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/controller/SliceConfiguratonTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/controller/SliceConfiguratonTest.java
new file mode 100644
index 00000000..b35ecdea
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/controller/SliceConfiguratonTest.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.controller;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.slice.analysis.ms.models.SliceConfigRequest;
+import org.onap.slice.analysis.ms.models.SliceConfigResponse;
+import org.onap.slice.analysis.ms.service.SliceUtilization;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+
+@RunWith(SpringRunner.class)
+@WebMvcTest(SliceConfiguraton.class)
+public class SliceConfiguratonTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @MockBean
+ private SliceUtilization sliceUtilization;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ private static final String UTF8 = StandardCharsets.UTF_8.name();
+
+ @Test
+ public void getSnssaiListTest() throws Exception {
+ SliceConfigRequest sliceConfigRequest = new SliceConfigRequest();
+ List<String> sliceIdentifiersList = new ArrayList<>();
+ sliceIdentifiersList.add("14559ead-f4fe-4c1c-a94c-8015fad3ea35");
+ sliceIdentifiersList.add("14559ead-f4fe-4c1c-a94c-8015fad3ea36");
+ sliceConfigRequest.setSliceIdentifiers(sliceIdentifiersList);
+ List<String> configParamsList = new ArrayList<>();
+ configParamsList.add("dLThptPerSlice");
+ configParamsList.add("uLThptPerSlice");
+ sliceConfigRequest.setConfigParams(configParamsList);
+
+ String executePath = "/api/v1/slices-config";
+ String sliceConfigResquestString =
+ new String(Files.readAllBytes(Paths.get("src/test/resources/sliceConfigRequest.json")));
+ ObjectMapper objectMapper = new ObjectMapper();
+ SliceConfigResponse sliceConfigResponse = objectMapper
+ .readValue(new File("src/test/resources/sliceConfigResponse.json"), SliceConfigResponse.class);
+ Mockito.when(sliceUtilization.getSliceUtilizationData(ArgumentMatchers.any())).thenReturn(sliceConfigResponse);
+
+ mockMvc.perform(get(executePath).contentType(MediaType.APPLICATION_JSON).characterEncoding(UTF8)
+ .content(objectMapper.writeValueAsString(sliceConfigRequest)).accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(objectMapper.writeValueAsString(sliceConfigResponse)));
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/cps/CpsInterfaceServiceTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/cps/CpsInterfaceServiceTest.java
new file mode 100644
index 00000000..0ae7d4f3
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/cps/CpsInterfaceServiceTest.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2021-2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.cps;
+
+import static org.junit.Assert.assertEquals;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.onap.slice.analysis.ms.models.Configuration;
+import org.onap.slice.analysis.ms.restclients.CpsRestClient;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(SpringRunner.class)
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "javax.management.*"})
+@PrepareForTest({CpsService.class, Configuration.class})
+@SpringBootTest(classes = CpsInterfaceServiceTest.class)
+public class CpsInterfaceServiceTest {
+ @InjectMocks
+ CpsService cpsService;
+
+ @Mock
+ CpsRestClient restClient;
+
+ @Test
+ public void fetchCurrentConfigurationOfRICTest() {
+ Map<String, Object> map = new HashMap<>();
+ map.put("dLThptPerSlice", 10);
+ map.put("uLThptPerSlice", 10);
+ map.put("maxNumberOfConns", 10);
+ Map<String, Map<String, Object>> responseMap = new HashMap<>();
+ responseMap.put("11", map);
+ try {
+ String serviceInstance = new String(Files.readAllBytes(Paths.get("src/test/resources/sliceConfig.json")));
+ Mockito.when(restClient.sendPostRequest(Mockito.anyString(), Mockito.anyString(), Mockito.any()))
+ .thenReturn(new ResponseEntity<>(serviceInstance, HttpStatus.OK));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ assertEquals(responseMap, cpsService.fetchCurrentConfigurationOfRIC("111-1111"));
+ }
+
+ @Test
+ public void fetchNetworkFunctionsOfSnssaiTest() {
+ List<String> responseList = new ArrayList<>();
+ responseList.add("22");
+ responseList.add("23");
+ try {
+ String serviceInstance = new String(Files.readAllBytes(Paths.get("src/test/resources/DUList.json")));
+ Mockito.when(restClient.sendPostRequest(Mockito.anyString(), Mockito.anyString(), Mockito.any()))
+ .thenReturn(new ResponseEntity<>(serviceInstance, HttpStatus.OK));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ assertEquals(responseList, cpsService.fetchNetworkFunctionsOfSnssai("111-1111"));
+ }
+
+ @Test
+ public void fetchRICsOfSnssaiTest() {
+ Map<String, List<String>> responseMap = new HashMap<>();
+ List<String> cellslist = new ArrayList<>();
+ cellslist.add("1599");
+ cellslist.add("1598");
+ responseMap.put("11", cellslist);
+ try {
+ String serviceInstance = new String(Files.readAllBytes(Paths.get("src/test/resources/DUCellsList.json")));
+ Mockito.when(restClient.sendPostRequest(Mockito.anyString(), Mockito.anyString(), Mockito.any()))
+ .thenReturn(new ResponseEntity<>(serviceInstance, HttpStatus.OK));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ assertEquals(responseMap, cpsService.fetchRICsOfSnssai("111-1111"));
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/models/ModelsTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/models/ModelsTest.java
index 3150fb5c..682bef43 100644
--- a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/models/ModelsTest.java
+++ b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/models/ModelsTest.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* slice-analysis-ms
* ================================================================================
- * Copyright (C) 2020-2021 Wipro Limited.
+ * Copyright (C) 2020-2022 Wipro Limited.
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,9 @@
* ============LICENSE_END=========================================================
*
*******************************************************************************/
+
package org.onap.slice.analysis.ms.models;
-import org.junit.Test;
+
import com.openpojo.reflection.PojoClass;
import com.openpojo.reflection.impl.PojoClassFactory;
import com.openpojo.validation.Validator;
@@ -29,28 +30,37 @@ import com.openpojo.validation.rule.impl.GetterMustExistRule;
import com.openpojo.validation.rule.impl.SetterMustExistRule;
import com.openpojo.validation.test.impl.GetterTester;
import com.openpojo.validation.test.impl.SetterTester;
+
import nl.jqno.equalsverifier.EqualsVerifier;
+
+import org.junit.Test;
+
public class ModelsTest {
@Test
public void configDataEqualHashcodeTest() {
- EqualsVerifier.simple().forClass(ConfigData.class).verify();
+ EqualsVerifier.simple().forClass(ConfigData.class).verify();
}
+
@Test
public void cellCUListEqualHashcodeTest() {
- EqualsVerifier.simple().forClass(CellCUList.class).verify();
+ EqualsVerifier.simple().forClass(CellCUList.class).verify();
}
+
@Test
public void cuModelEqualHashcodeTest() {
- EqualsVerifier.simple().forClass(CUModel.class).verify();
+ EqualsVerifier.simple().forClass(CUModel.class).verify();
}
+
@Test
public void subCounterEqualHashcodeTest() {
EqualsVerifier.simple().forClass(SubCounter.class).verify();
}
+
@Test
public void measurementObjectEqualHashcodeTest() {
- EqualsVerifier.simple().forClass(MeasurementObject.class).verify();
+ EqualsVerifier.simple().forClass(MeasurementObject.class).verify();
}
+
@Test
public void testGetterSetterSubCounter() {
PojoClass pojoclass = PojoClassFactory.getPojoClass(SubCounter.class);
@@ -64,34 +74,55 @@ public class ModelsTest {
.build();
validator.validate(pojoclass);
}
+
@Test
public void testGetterSetterMeasurementObject() {
PojoClass pojoclass = PojoClassFactory.getPojoClass(MeasurementObject.class);
validateMd(pojoclass);
}
+
@Test
public void testGetterSetterCellCUList() {
PojoClass pojoclass = PojoClassFactory.getPojoClass(CellCUList.class);
validateMd(pojoclass);
}
+
@Test
public void testGetterSetterCUModel() {
PojoClass pojoclass = PojoClassFactory.getPojoClass(CUModel.class);
validateMd(pojoclass);
}
+
@Test
public void testGetterSetterConfigData() {
PojoClass pojoclass = PojoClassFactory.getPojoClass(ConfigData.class);
validateMd(pojoclass);
}
+
+ @Test
+ public void testGetterSetterSliceConfigDetailsModel() {
+ PojoClass pojoclass = PojoClassFactory.getPojoClass(SliceConfigDetails.class);
+ validateMd(pojoclass);
+ }
+
+ @Test
+ public void testGetterSetterSliceConfigRequestModel() {
+ PojoClass pojoclass = PojoClassFactory.getPojoClass(SliceConfigRequest.class);
+ validateMd(pojoclass);
+ }
+
+ @Test
+ public void testGetterSetterSliceConfigResponseModel() {
+ PojoClass pojoclass = PojoClassFactory.getPojoClass(SliceConfigResponse.class);
+ validateMd(pojoclass);
+ }
+
public void validateMd(PojoClass pojoclass) {
- Validator validator = ValidatorBuilder
+ Validator validator = ValidatorBuilder
.create()
.with(new SetterMustExistRule())
.with(new GetterMustExistRule())
- .with(new SetterTester())
- .with(new GetterTester())
- .build();
+ .with(new SetterTester()).with(new GetterTester()).build();
validator.validate(pojoclass);
}
}
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/MLMessageProcessorTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/MLMessageProcessorTest.java
index 6e0d1243..387b5fd0 100644
--- a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/MLMessageProcessorTest.java
+++ b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/MLMessageProcessorTest.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* slice-analysis-ms
* ================================================================================
- * Copyright (C) 2020 Wipro Limited.
+ * Copyright (C) 2020-2022 Wipro Limited.
* ==============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,16 @@
package org.onap.slice.analysis.ms.service;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.anyMap;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -29,73 +39,71 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
-
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
+import org.onap.slice.analysis.ms.aai.AaiService;
import org.onap.slice.analysis.ms.configdb.IConfigDbService;
-import org.onap.slice.analysis.ms.configdb.AaiService;
-import org.onap.slice.analysis.ms.configdb.CpsService;
+import org.onap.slice.analysis.ms.cps.CpsService;
import org.onap.slice.analysis.ms.models.MLOutputModel;
import org.onap.slice.analysis.ms.models.policy.AdditionalProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MLMessageProcessorTest.class)
public class MLMessageProcessorTest {
- ObjectMapper obj = new ObjectMapper();
-
- @InjectMocks
- private MLMessageProcessor mlMessageProcessor;
-
- @Mock
- private IConfigDbService configDbService;
+ ObjectMapper obj = new ObjectMapper();
+
+ @InjectMocks
+ private MLMessageProcessor mlMessageProcessor;
+
+ @Mock
+ private IConfigDbService configDbService;
+
+ @Mock
+ AaiService aaiService;
+
+ @Mock
+ CpsService cpsService;
- @Mock
- AaiService aaiService;
+ @Mock
+ private PolicyService policyService;
- @Mock
- CpsService cpsService;
+ @SuppressWarnings({"unchecked"})
+ @Test
+ public void processMLMsgTest() {
+ MLOutputModel mloutput = null;
+ MLOutputModel mloutputExp = null;
- @Mock
- private PolicyService policyService;
-
- @SuppressWarnings({"unchecked" })
- @Test
- public void processMLMsgTest() {
- MLOutputModel mloutput = null;
- MLOutputModel mloutputExp = null;
+ Map<String, List<String>> ricToCellMapping = new HashMap<>();
+ List<String> myList = new ArrayList<String>();
+ myList.add("111");
+ myList.add("112");
+ ricToCellMapping.put("12", myList);
+ myList = new ArrayList<String>();
+ myList.add("113");
+ myList.add("114");
+ ricToCellMapping.put("13", myList);
- Map<String, List<String>> ricToCellMapping = new HashMap<>();
- List<String> myList = new ArrayList<String>();
- myList.add("111");
- myList.add("112");
- ricToCellMapping.put("12", myList);
- myList = new ArrayList<String>();
- myList.add("113");
- myList.add("114");
- ricToCellMapping.put("13", myList);
+ try {
+ mloutput =
+ obj.readValue(new String(Files.readAllBytes(Paths.get("src/test/resources/MLOutputModel1.json"))),
+ new TypeReference<MLOutputModel>() {});
+ mloutputExp =
+ obj.readValue(new String(Files.readAllBytes(Paths.get("src/test/resources/MLOutputModel.json"))),
+ new TypeReference<MLOutputModel>() {});
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ when(configDbService.fetchRICsOfSnssai("0001-0111")).thenReturn(ricToCellMapping);
+ AdditionalProperties<MLOutputModel> addProps = new AdditionalProperties<>();
+ addProps.setResourceConfig(mloutputExp);
+ doNothing().when(policyService).sendOnsetMessageToPolicy(anyString(), any(AdditionalProperties.class),
+ anyMap());
+ mlMessageProcessor.processMLMsg(mloutput);
+ assertEquals(mloutputExp, mloutput);
+ }
- try {
- mloutput = obj.readValue(new String(Files.readAllBytes(Paths.get("src/test/resources/MLOutputModel1.json"))), new TypeReference<MLOutputModel>(){});
- mloutputExp = obj.readValue(new String(Files.readAllBytes(Paths.get("src/test/resources/MLOutputModel.json"))), new TypeReference<MLOutputModel>(){});
- }
- catch (IOException e) {
- e.printStackTrace();
- }
- when(configDbService.fetchRICsOfSnssai("0001-0111")).thenReturn(ricToCellMapping);
- AdditionalProperties<MLOutputModel> addProps = new AdditionalProperties<>();
- addProps.setResourceConfig(mloutputExp);
- doNothing().when(policyService).sendOnsetMessageToPolicy(anyString(), any(AdditionalProperties.class), anyMap());
- mlMessageProcessor.processMLMsg(mloutput);
- assertEquals(mloutputExp, mloutput);
- }
-
}
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/SliceUtilizationTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/SliceUtilizationTest.java
new file mode 100644
index 00000000..90202366
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/SliceUtilizationTest.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * slice-analysis-ms
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ==============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.slice.analysis.ms.aai.AaiService;
+import org.onap.slice.analysis.ms.models.AggregatedConfig;
+import org.onap.slice.analysis.ms.models.Configuration;
+import org.onap.slice.analysis.ms.models.SliceConfigRequest;
+import org.onap.slice.analysis.ms.models.SliceConfigResponse;
+import org.onap.slice.analysis.ms.restclients.DesRestClient;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(SpringRunner.class)
+@PrepareForTest({SliceUtilization.class, Configuration.class})
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "javax.management.*"})
+@SpringBootTest(classes = SliceUtilizationTest.class)
+public class SliceUtilizationTest {
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ Configuration configuration = Configuration.getInstance();
+
+ @InjectMocks
+ SliceUtilization sliceUtilization;
+
+ @Mock
+ AaiService aaiService;
+
+ @Mock
+ DesRestClient desRestClient;
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void getPmDataTest() throws Exception {
+ configuration.setDesUrl("http://des:1681/datalake/v1/exposure/pm_data");
+ configuration.setPmDataDurationInWeeks(4);
+ PowerMockito.mockStatic(SliceUtilization.class);
+ PowerMockito.mockStatic(Configuration.class);
+ PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
+ String pmData = null;
+ try {
+ pmData = new String(Files.readAllBytes(Paths.get("src/test/resources/pm_data.json")));
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ Mockito.when(desRestClient.sendPostRequest(Mockito.any(), Mockito.any(), Mockito.any()))
+ .thenReturn(new ResponseEntity<>(pmData, HttpStatus.OK));
+ JSONObject actualResponse = sliceUtilization.getPMData("001-1100");
+ assertTrue(actualResponse.has("result"));
+
+ }
+
+ @Test
+ public void calculateSliceUtilizationTest() throws Exception {
+
+ PowerMockito.mockStatic(SliceUtilization.class);
+ List<JSONObject> pmDataList = new ArrayList<>();
+ String pmData;
+ try {
+ pmData = new String(Files.readAllBytes(Paths.get("src/test/resources/pm_data.json")));
+ JSONObject pmDataObj = new JSONObject(pmData);
+ pmDataList.add(pmDataObj);
+ pmDataList.add(pmDataObj);
+ pmDataList.add(pmDataObj);
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ AggregatedConfig actualResponse = sliceUtilization.calculateSliceUtilization(pmDataList);
+ assertEquals(190857028, (int) actualResponse.getDLThptPerSlice());
+ assertEquals(119285978, (int) actualResponse.getULThptPerSlice());
+ }
+
+ @Test
+ public void getSliceUtilizationDataTest() throws Exception {
+
+ PowerMockito.mockStatic(SliceUtilization.class);
+ SliceConfigRequest sliceConfigRequest = new SliceConfigRequest();
+ List<String> sliceIdentifiersList = new ArrayList<>();
+ sliceIdentifiersList.add("14559ead-f4fe-4c1c-a94c-8015fad3ea35");
+ sliceIdentifiersList.add("14559ead-f4fe-4c1c-a94c-8015fad3ea36");
+ sliceConfigRequest.setSliceIdentifiers(sliceIdentifiersList);
+ List<String> configParamsList = new ArrayList<>();
+ configParamsList.add("dLThptPerSlice");
+ configParamsList.add("uLThptPerSlice");
+ sliceConfigRequest.setConfigParams(configParamsList);
+ List<String> snssaiList = new ArrayList<>();
+ snssaiList.add("01-06E442");
+ snssaiList.add("01-B989BD");
+ configuration.setDesUrl("http://des:1681/datalake/v1/exposure/pm_data");
+ configuration.setPmDataDurationInWeeks(4);
+
+ PowerMockito.mockStatic(SliceUtilization.class);
+ PowerMockito.mockStatic(Configuration.class);
+ PowerMockito.when(Configuration.getInstance()).thenReturn(configuration);
+
+ try {
+
+ Mockito.when(aaiService.getSnssaiList(Mockito.any())).thenReturn(snssaiList);
+
+ String pmData = new String(Files.readAllBytes(Paths.get("src/test/resources/pm_data.json")));
+ Mockito.when(desRestClient.sendPostRequest(Mockito.any(), Mockito.any(), Mockito.any()))
+ .thenReturn(new ResponseEntity<>(pmData, HttpStatus.OK));
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ SliceConfigResponse actualResponse = sliceUtilization.getSliceUtilizationData(sliceConfigRequest);
+ String actualResponseString = objectMapper.writeValueAsString(actualResponse);
+ SliceConfigResponse sliceConfigResponse = objectMapper
+ .readValue(new File("src/test/resources/sliceConfigResponse.json"), SliceConfigResponse.class);
+ assertEquals(objectMapper.writeValueAsString(sliceConfigResponse), actualResponseString);
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/resources/alloted-resource.json b/components/slice-analysis-ms/src/test/resources/alloted-resource.json
new file mode 100644
index 00000000..56cfc9f3
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/alloted-resource.json
@@ -0,0 +1,115 @@
+{
+ "service-instance-id":"0835fd19-6726-4081-befb-cc8932c47767",
+ "service-instance-name":"sa1",
+ "service-type":"embb",
+ "service-role":"service-profile",
+ "environment-context":"01-06E442",
+ "model-invariant-id":"8b94b147-2233-4e9f-b939-55c1b0e618ac",
+ "model-version-id":"961ec436-7b16-4d71-9d62-9c4ca5dd94bf",
+ "resource-version":"1645003055191",
+ "orchestration-status":"deactivated",
+ "relationship-list":{
+ "relationship":[
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/8a6115ef-bbca-48ea-98e2-831a2b0226d2",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"8a6115ef-bbca-48ea-98e2-831a2b0226d2"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sa1"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/b2ae730f-1d5f-495a-8112-dac017a7348c",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"b2ae730f-1d5f-495a-8112-dac017a7348c"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sliceprofile_an_sa1"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/cad8fa36-2d55-4c12-a92e-1bd551517a0c",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"cad8fa36-2d55-4c12-a92e-1bd551517a0c"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sliceprofile_cn_sa1"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/8d0d698e-77f4-4453-8c09-ae2cbe6a9a04",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"8d0d698e-77f4-4453-8c09-ae2cbe6a9a04"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sliceprofile_tn_sa1"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/resources/nsi.json b/components/slice-analysis-ms/src/test/resources/nsi.json
new file mode 100644
index 00000000..0ca3e529
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/nsi.json
@@ -0,0 +1,122 @@
+{
+ "service-instance-id":"09cad94e-fbb8-4c70-9c4d-74ec75e97683",
+ "service-instance-name":"nsi_sa1",
+ "service-type":"embb",
+ "service-role":"nsi",
+ "model-invariant-id":"8a8e6666-6e1e-4f0d-88ee-71b9f12f6399",
+ "model-version-id":"1938db5a-213e-4ba8-b3a8-b39c66a79562",
+ "resource-version":"1645003054775",
+ "orchestration-status":"deactivated",
+ "service-function":"non-shared",
+ "relationship-list":{
+ "relationship":[
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/50f418a6-804f-4453-bf70-21f0efaf6fcd",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"50f418a6-804f-4453-bf70-21f0efaf6fcd"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_ansa1"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/99f24e52-5117-430e-a42d-5f77df3dddef",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"99f24e52-5117-430e-a42d-5f77df3dddef"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_cnsa1"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/23ed8231-016c-4420-be91-c042b68f9ea0",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"23ed8231-016c-4420-be91-c042b68f9ea0"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_tnsa1"
+ }
+ ]
+ },
+ {
+ "related-to":"allotted-resource",
+ "relationship-label":"org.onap.relationships.inventory.Uses",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/0835fd19-6726-4081-befb-cc8932c47767/allotted-resources/allotted-resource/530d188d-9087-49af-a44a-90c40e0c2d47",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"0835fd19-6726-4081-befb-cc8932c47767"
+ },
+ {
+ "relationship-key":"allotted-resource.id",
+ "relationship-value":"530d188d-9087-49af-a44a-90c40e0c2d47"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"allotted-resource.description"
+ },
+ {
+ "property-key":"allotted-resource.allotted-resource-name",
+ "property-value":"Allotted_sa1"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/resources/nssi.json b/components/slice-analysis-ms/src/test/resources/nssi.json
new file mode 100644
index 00000000..42916a70
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/nssi.json
@@ -0,0 +1,165 @@
+{
+ "service-instance-id":"50f418a6-804f-4453-bf70-21f0efaf6fcd",
+ "service-instance-name":"nssi_ansa1",
+ "service-type":"embb",
+ "service-role":"nssi",
+ "environment-context":"an",
+ "workload-context":"AN",
+ "model-invariant-id":"68c76946-95a8-4a15-8100-ea482f31341f",
+ "model-version-id":"c8c1ba78-b7a2-4d72-a82a-75eb79d95347",
+ "service-instance-location-id":"39-00",
+ "resource-version":"1645002869853",
+ "orchestration-status":"deactivated",
+ "service-function":"non-shared",
+ "relationship-list":{
+ "relationship":[
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/b2ae730f-1d5f-495a-8112-dac017a7348c",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"b2ae730f-1d5f-495a-8112-dac017a7348c"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sliceprofile_an_sa1"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/09cad94e-fbb8-4c70-9c4d-74ec75e97683",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"09cad94e-fbb8-4c70-9c4d-74ec75e97683"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nsi_sa1"
+ }
+ ]
+ },
+ {
+ "related-to":"network-route",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/network/network-routes/network-route/450b4494-8f24-4c6b-b0a2-2c8a904bf032",
+ "relationship-data":[
+ {
+ "relationship-key":"network-route.route-id",
+ "relationship-value":"450b4494-8f24-4c6b-b0a2-2c8a904bf032"
+ }
+ ]
+ },
+ {
+ "related-to":"network-route",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/network/network-routes/network-route/361b6d8b-ad80-4f55-a8fb-be05cde37d5e",
+ "relationship-data":[
+ {
+ "relationship-key":"network-route.route-id",
+ "relationship-value":"361b6d8b-ad80-4f55-a8fb-be05cde37d5e"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/01dfe2e6-eb8b-4907-bf26-2790a7211a07",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"01dfe2e6-eb8b-4907-bf26-2790a7211a07"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_tn_mh_9c6fed98-4ce2-4390-8824-ba7cf921851c"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/ec4a9f30-f025-4abb-bacd-33bb61bf2aec",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"ec4a9f30-f025-4abb-bacd-33bb61bf2aec"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_tn_fh_54aa886f-bb46-474f-96ff-b6f04962a37d"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/b6085a7b-2b34-48db-8150-70cfdd6f41fc",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"b6085a7b-2b34-48db-8150-70cfdd6f41fc"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_an_nf_ff726432-7c66-4afb-a1eb-096b493db635"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/resources/pm_data.json b/components/slice-analysis-ms/src/test/resources/pm_data.json
new file mode 100644
index 00000000..4642e813
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/pm_data.json
@@ -0,0 +1,17 @@
+{
+ "result":[
+ {
+ "measValuesList":"[[\"11220\",\"false\",[[1.0,\"75\"],[2.0,\"84\"]]],[\"11221\",\"false\",[[1.0,\"76\"],[2.0,\"85\"]]],[\"11222\",\"false\",[[1.0,\"90\"],[2.0,\"95\"]]]]",
+ "sMeasTypesList":"[\"SM.PrbUsedDl.01-06E442\",\"SM.PrbUsedUl.01-06E442\"]"
+ },
+ {
+ "measValuesList":"[[\"11225\",\"false\",[[1.0,\"175\"],[2.0,\"184\"]]],[\"11224\",\"false\",[[1.0,\"176\"],[2.0,\"185\"]]],[\"11222\",\"false\",[[1.0,\"105\"],[2.0,\"100\"]]]]",
+ "sMeasTypesList":"[\"SM.PrbUsedDl.01-06E442\",\"SM.PrbUsedUl.01-06E442\"]"
+ }
+ ],
+ "request":{
+ "snssai":"SM.PrbUsedDl.001-1100",
+ "time":"1538478000000"
+ },
+ "result_count":2
+}
diff --git a/components/slice-analysis-ms/src/test/resources/sliceConfigRequest.json b/components/slice-analysis-ms/src/test/resources/sliceConfigRequest.json
new file mode 100644
index 00000000..133c4a1c
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/sliceConfigRequest.json
@@ -0,0 +1,21 @@
+{
+
+ "sliceIdentifiers": [
+
+ "14559ead-f4fe-4c1c-a94c-8015fad3ea35",
+
+ "14559ead-f4fe-4c1c-a94c-8015fad3ea36"
+
+ ],
+
+ "configParams": [
+
+ "dLThptPerSlice",
+
+ "uLThptPerSlice",
+
+ "maxNumberOfConns"
+
+ ]
+
+}
diff --git a/components/slice-analysis-ms/src/test/resources/sliceConfigResponse.json b/components/slice-analysis-ms/src/test/resources/sliceConfigResponse.json
new file mode 100644
index 00000000..c99a92cd
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/sliceConfigResponse.json
@@ -0,0 +1,20 @@
+{
+ "sliceConfigDetails":[
+ {
+ "sliceIdentifiers":"14559ead-f4fe-4c1c-a94c-8015fad3ea35",
+ "aggregatedConfig":{
+ "maxNumberOfConns":null,
+ "dlthptPerSlice":190857028,
+ "ulthptPerSlice":119285978
+ }
+ },
+ {
+ "sliceIdentifiers":"14559ead-f4fe-4c1c-a94c-8015fad3ea36",
+ "aggregatedConfig":{
+ "maxNumberOfConns":null,
+ "dlthptPerSlice":190857028,
+ "ulthptPerSlice":119285978
+ }
+ }
+ ]
+}
diff --git a/components/slice-analysis-ms/src/test/resources/sliceprofile_an_sa1.json b/components/slice-analysis-ms/src/test/resources/sliceprofile_an_sa1.json
new file mode 100644
index 00000000..aab0d531
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/sliceprofile_an_sa1.json
@@ -0,0 +1,155 @@
+{
+ "service-instance-id":"b2ae730f-1d5f-495a-8112-dac017a7348c",
+ "service-instance-name":"sliceprofile_an_sa1",
+ "service-type":"embb",
+ "service-role":"slice-profile",
+ "environment-context":"01-06E442",
+ "workload-context":"AN",
+ "created-at":"2022-02-16 09:12:27",
+ "model-invariant-id":"68c76946-95a8-4a15-8100-ea482f31341f",
+ "model-version-id":"c8c1ba78-b7a2-4d72-a82a-75eb79d95347",
+ "service-instance-location-id":"39-00",
+ "resource-version":"1645002869957",
+ "orchestration-status":"deactivated",
+ "service-function":"non-shared",
+ "relationship-list":{
+ "relationship":[
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/0835fd19-6726-4081-befb-cc8932c47767",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"0835fd19-6726-4081-befb-cc8932c47767"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sa1"
+ }
+ ]
+ },
+ {
+ "related-to":"network-route",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/network/network-routes/network-route/361b6d8b-ad80-4f55-a8fb-be05cde37d5e",
+ "relationship-data":[
+ {
+ "relationship-key":"network-route.route-id",
+ "relationship-value":"361b6d8b-ad80-4f55-a8fb-be05cde37d5e"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/29b15561-0d2d-491d-8022-66d19e2175ca",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"29b15561-0d2d-491d-8022-66d19e2175ca"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sliceprofile_7bda9caa-4726-4460-bf70-38c598d165e4"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/50f418a6-804f-4453-bf70-21f0efaf6fcd",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"50f418a6-804f-4453-bf70-21f0efaf6fcd"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_ansa1"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/f08ce80d-0dec-4cbe-934e-197c516cbecc",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"f08ce80d-0dec-4cbe-934e-197c516cbecc"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sliceprofile_2b3147bc-4d89-459b-81d4-73c971fb4767"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/4f2cdc4d-bd1d-466a-bf7a-9d3d3f299dd5",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"4f2cdc4d-bd1d-466a-bf7a-9d3d3f299dd5"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sliceprofile_7eed6ea4-d2ae-4319-9613-847cc89cc3ab"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/resources/sliceprofile_cn_sa1.json b/components/slice-analysis-ms/src/test/resources/sliceprofile_cn_sa1.json
new file mode 100644
index 00000000..90c594d7
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/sliceprofile_cn_sa1.json
@@ -0,0 +1,80 @@
+{
+ "service-instance-id":"cad8fa36-2d55-4c12-a92e-1bd551517a0c",
+ "service-instance-name":"sliceprofile_cn_sa1",
+ "service-type":"embb",
+ "service-role":"slice-profile",
+ "environment-context":"01-06E442",
+ "workload-context":"CN",
+ "created-at":"2022-02-16 09:14:30",
+ "model-invariant-id":"32438b92-1450-4d32-9bb1-9642d08d260e",
+ "model-version-id":"3cb7b6ad-54a7-4a0f-8e80-d5dcc18f2184",
+ "service-instance-location-id":"39-00",
+ "resource-version":"1645002992778",
+ "orchestration-status":"deactivated",
+ "service-function":"non-shared",
+ "relationship-list":{
+ "relationship":[
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/0835fd19-6726-4081-befb-cc8932c47767",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"0835fd19-6726-4081-befb-cc8932c47767"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sa1"
+ }
+ ]
+ },
+ {
+ "related-to":"network-route",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/network/network-routes/network-route/03c281af-f59c-4b3e-a42b-bbc28477e11d",
+ "relationship-data":[
+ {
+ "relationship-key":"network-route.route-id",
+ "relationship-value":"03c281af-f59c-4b3e-a42b-bbc28477e11d"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/99f24e52-5117-430e-a42d-5f77df3dddef",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"99f24e52-5117-430e-a42d-5f77df3dddef"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_cnsa1"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/components/slice-analysis-ms/src/test/resources/sliceprofile_tn_sa1.json b/components/slice-analysis-ms/src/test/resources/sliceprofile_tn_sa1.json
new file mode 100644
index 00000000..005df5b3
--- /dev/null
+++ b/components/slice-analysis-ms/src/test/resources/sliceprofile_tn_sa1.json
@@ -0,0 +1,68 @@
+{
+ "service-instance-id":"8d0d698e-77f4-4453-8c09-ae2cbe6a9a04",
+ "service-instance-name":"sliceprofile_tn_sa1",
+ "service-type":"embb",
+ "service-role":"slice-profile",
+ "environment-context":"01-B989BD",
+ "workload-context":"TN_BH",
+ "created-at":"2022-02-16 09:16:32",
+ "model-invariant-id":"60424cf8-591a-4804-b189-9e2251d9d36b",
+ "model-version-id":"ed5bcf6a-6c0a-4286-96b1-877c5344f91a",
+ "resource-version":"1645003055020",
+ "orchestration-status":"deactivated",
+ "service-function":"non-shared",
+ "relationship-list":{
+ "relationship":[
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/0835fd19-6726-4081-befb-cc8932c47767",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"0835fd19-6726-4081-befb-cc8932c47767"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"sa1"
+ }
+ ]
+ },
+ {
+ "related-to":"service-instance",
+ "relationship-label":"org.onap.relationships.inventory.ComposedOf",
+ "related-link":"/aai/v21/business/customers/customer/5GCustomer/service-subscriptions/service-subscription/5G/service-instances/service-instance/23ed8231-016c-4420-be91-c042b68f9ea0",
+ "relationship-data":[
+ {
+ "relationship-key":"customer.global-customer-id",
+ "relationship-value":"5GCustomer"
+ },
+ {
+ "relationship-key":"service-subscription.service-type",
+ "relationship-value":"5G"
+ },
+ {
+ "relationship-key":"service-instance.service-instance-id",
+ "relationship-value":"23ed8231-016c-4420-be91-c042b68f9ea0"
+ }
+ ],
+ "related-to-property":[
+ {
+ "property-key":"service-instance.service-instance-name",
+ "property-value":"nssi_tnsa1"
+ }
+ ]
+ }
+ ]
+ }
+}