aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/org/onap/a1pesimulator/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/onap/a1pesimulator/util')
-rw-r--r--src/main/java/org/onap/a1pesimulator/util/Constants.java23
-rw-r--r--src/main/java/org/onap/a1pesimulator/util/DistanceCalculator.java46
-rw-r--r--src/main/java/org/onap/a1pesimulator/util/ItemsRefresher.java44
-rw-r--r--src/main/java/org/onap/a1pesimulator/util/JsonUtils.java99
-rw-r--r--src/main/java/org/onap/a1pesimulator/util/RanVesUtils.java167
-rw-r--r--src/main/java/org/onap/a1pesimulator/util/TopologyReader.java71
-rw-r--r--src/main/java/org/onap/a1pesimulator/util/VnfConfigReader.java67
7 files changed, 517 insertions, 0 deletions
diff --git a/src/main/java/org/onap/a1pesimulator/util/Constants.java b/src/main/java/org/onap/a1pesimulator/util/Constants.java
new file mode 100644
index 0000000..1964efd
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/util/Constants.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package org.onap.a1pesimulator.util;
+
+public class Constants {
+
+ private Constants() {
+ }
+
+ public static final String MEASUREMENT_FIELD_IDENTIFIER = "identifier";
+ public static final String MEASUREMENT_FIELD_VALUE = "value";
+}
diff --git a/src/main/java/org/onap/a1pesimulator/util/DistanceCalculator.java b/src/main/java/org/onap/a1pesimulator/util/DistanceCalculator.java
new file mode 100644
index 0000000..e487ed3
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/util/DistanceCalculator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package org.onap.a1pesimulator.util;
+
+public class DistanceCalculator {
+
+ private static final int EARTH_RADIUS = 6371; // Earth radius in KM
+
+ private DistanceCalculator() {
+ }
+
+ /**
+ * Calculate distance in KM using Haversine formula
+ */
+ public static double calculate(double startLat, double startLong, double endLat, double endLong) {
+ return haversine(startLat, startLong, endLat, endLong);
+ }
+
+ public static boolean isInRange(double startLat, double startLong, double endLat, double endLong, double range) {
+ double distance = calculate(startLat, startLong, endLat, endLong);
+ return distance < range;
+ }
+
+ private static double haversine(double startLat, double startLong, double endLat, double endLong) {
+ double dLat = Math.toRadians(endLat - startLat);
+ double dLon = Math.toRadians(endLong - startLong);
+ double startLatInRadians = Math.toRadians(startLat);
+ double endLatInRadians = Math.toRadians(endLat);
+
+ double a = Math.pow(Math.sin(dLat / 2), 2) + Math.pow(Math.sin(dLon / 2), 2) * Math.cos(startLatInRadians)
+ * Math.cos(endLatInRadians);
+ double c = 2 * Math.asin(Math.sqrt(a));
+ return EARTH_RADIUS * c;
+ }
+}
diff --git a/src/main/java/org/onap/a1pesimulator/util/ItemsRefresher.java b/src/main/java/org/onap/a1pesimulator/util/ItemsRefresher.java
new file mode 100644
index 0000000..6991da0
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/util/ItemsRefresher.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package org.onap.a1pesimulator.util;
+
+import org.onap.a1pesimulator.service.cell.RanCellsHolder;
+import org.onap.a1pesimulator.service.ue.RanUeHolder;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+@Service
+@EnableScheduling
+public class ItemsRefresher {
+
+ private final RanCellsHolder cellsHolder;
+ private final RanUeHolder ueHolder;
+
+ public ItemsRefresher(final RanCellsHolder cellsHolder, final RanUeHolder ueHolder) {
+ this.cellsHolder = cellsHolder;
+ this.ueHolder = ueHolder;
+ }
+
+ @Scheduled(fixedRateString = "${refresher.fixed.rate.ms}")
+ public void refresh() {
+ if (cellsHolder.hasChanged()) {
+ cellsHolder.refresh();
+ }
+
+ if (ueHolder.hasChanged()) {
+ ueHolder.refresh();
+ }
+ }
+}
diff --git a/src/main/java/org/onap/a1pesimulator/util/JsonUtils.java b/src/main/java/org/onap/a1pesimulator/util/JsonUtils.java
new file mode 100644
index 0000000..9263bc1
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/util/JsonUtils.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package org.onap.a1pesimulator.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.URL;
+import java.text.MessageFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public enum JsonUtils {
+
+ INSTANCE;
+
+ private static final Logger log = LoggerFactory.getLogger(JsonUtils.class);
+
+ private ObjectMapper mapper;
+
+ private JsonUtils() {
+ this.mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ }
+
+ public String objectToPrettyString(Object object) {
+ try {
+ return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
+ } catch (JsonProcessingException e) {
+ throw new JsonUtilsException("Cannot serialize object", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T clone(T object) {
+ String stringValue;
+ try {
+ stringValue = mapper.writeValueAsString(object);
+ return (T) mapper.readValue(stringValue, object.getClass());
+ } catch (JsonProcessingException e) {
+ throw new JsonUtilsException("Cannot clone object", e);
+ }
+ }
+
+ public <T> T deserializeFromFile(String fileName, Class<T> clazz) {
+ try {
+ return mapper.readValue(new FileReader(fileName), clazz);
+ } catch (IOException e) {
+ String errorMsg = MessageFormat.format("Could not deserialize from file: {0} into {1}", fileName,
+ clazz.getSimpleName());
+ log.error(errorMsg, e);
+ throw new JsonUtilsException(errorMsg, e);
+ }
+ }
+
+ public <T> T deserializeFromFileUrl(URL url, Class<T> clazz) {
+ try {
+ return mapper.readValue(url, clazz);
+ } catch (IOException e) {
+ String errorMsg = MessageFormat.format("Could not deserialize from file URL: {0} into {1}", url,
+ clazz.getSimpleName());
+ log.error(errorMsg, e);
+ throw new JsonUtilsException(errorMsg, e);
+ }
+ }
+
+ public <T> T deserialize(String string, Class<T> clazz) throws JsonUtilsException {
+ try {
+ return mapper.readValue(string, clazz);
+ } catch (IOException e) {
+ String errorMsg = MessageFormat
+ .format("Could not deserialize into {0} from object: {1}", clazz.getSimpleName(),
+ string);
+ log.error(errorMsg, e);
+ throw new JsonUtilsException(errorMsg, e);
+ }
+ }
+
+ public static class JsonUtilsException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public JsonUtilsException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+ }
+}
diff --git a/src/main/java/org/onap/a1pesimulator/util/RanVesUtils.java b/src/main/java/org/onap/a1pesimulator/util/RanVesUtils.java
new file mode 100644
index 0000000..d5f3e67
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/util/RanVesUtils.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package org.onap.a1pesimulator.util;
+
+import java.text.MessageFormat;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.function.UnaryOperator;
+import java.util.stream.Collectors;
+import org.onap.a1pesimulator.data.ue.UserEquipment;
+import org.onap.a1pesimulator.data.ves.CommonEventHeader;
+import org.onap.a1pesimulator.data.ves.Event;
+import org.onap.a1pesimulator.data.ves.MeasurementFields.AdditionalMeasurement;
+import org.onap.a1pesimulator.service.ue.RanUeHolder;
+
+public class RanVesUtils {
+
+ private static final String PATTERN_DIGIT = "\\d+";
+ private static final String PATTERN_SPLIT_RANDOM = "-";
+ private static final String PATTERN_SPLIT_TRENDING = "->";
+ private static final String MARKER_START = "[[";
+ private static final String MARKER_END = "]]";
+ private static final String PATTERN_MARKER_START = "\\[\\[";
+ private static final String PATTERN_MARKER_END = "\\]\\]";
+
+ private static final String UE_PARAM_TRAFFIC_MODEL = "trafficModel";
+ private static final int TEN_MINUTES_MICROSECONDS = 10 * 60 * 1000_000;
+
+ private static final Random random = new Random();
+
+ private RanVesUtils() {
+ }
+
+ public static void updateHeader(Event event) {
+ CommonEventHeader commonEventHeader = event.getCommonEventHeader();
+ commonEventHeader.setLastEpochMicrosec(ChronoUnit.MICROS.between(Instant.EPOCH, Instant.now()));
+ commonEventHeader.setStartEpochMicrosec(getStartEpochMicroseconds());
+ }
+
+ public static AdditionalMeasurement buildTrafficModelMeasurement(AdditionalMeasurement identityMeasurement,
+ RanUeHolder ranUeHolder, String valuePattern) {
+ String cellId = identityMeasurement.getHashMap().get(Constants.MEASUREMENT_FIELD_VALUE);
+ AdditionalMeasurement trafficModel = new AdditionalMeasurement();
+ Map<String, String> hashMap = new HashMap<>();
+ trafficModel.setName(UE_PARAM_TRAFFIC_MODEL);
+ trafficModel.setHashMap(hashMap);
+ Collection<UserEquipment> cellUes = ranUeHolder.getUserEquipmentsConnectedToCell(cellId);
+ cellUes.stream().map(UserEquipment::getId).forEach(ueId -> hashMap.put(ueId, valuePattern));
+
+ return trafficModel;
+ }
+
+ public static List<AdditionalMeasurement> randomizeAdditionalMeasurements(
+ Collection<AdditionalMeasurement> toRandomize) {
+ return toRandomize.stream().map(measurement -> transformAdditionalMeasurementValues(measurement,
+ RanVesUtils::randomizeValue)).collect(Collectors.toList());
+ }
+
+ public static List<AdditionalMeasurement> setLowRangeValues(List<AdditionalMeasurement> toUpdateMeasurements) {
+ return toUpdateMeasurements.stream().map(measurement -> transformAdditionalMeasurementValues(measurement,
+ RanVesUtils::getLowRangeValue)).collect(Collectors.toList());
+ }
+
+ private static AdditionalMeasurement transformAdditionalMeasurementValues(AdditionalMeasurement measurement,
+ UnaryOperator<String> transformAction) {
+ AdditionalMeasurement randomizedMeasurement = new AdditionalMeasurement();
+ randomizedMeasurement.setName(measurement.getName());
+ randomizedMeasurement.setHashMap(transformValues(measurement.getHashMap(), transformAction));
+ return randomizedMeasurement;
+ }
+
+ private static Map<String, String> transformValues(Map<String, String> values,
+ UnaryOperator<String> transformAction) {
+ Map<String, String> randomizedMap = new HashMap<>(values.size());
+ values.forEach((key, value) -> randomizedMap.put(key, transformAction.apply(value)));
+ return randomizedMap;
+ }
+
+ private static String randomizeValue(String value) {
+ if (!isRange(value)) {
+ return value;
+ }
+ String toRandomize = value.substring(MARKER_START.length(), value.length() - MARKER_END.length());
+ String[] ranges = toRandomize.split(PATTERN_SPLIT_RANDOM);
+ int randomNumber = getRandomNumber(parseInt(ranges[0]), parseInt(ranges[1]));
+ return String.valueOf(randomNumber);
+ }
+
+ private static String getLowRangeValue(String value) {
+ if (!isRange(value)) {
+ return value;
+ }
+ String toRandomize = value.substring(MARKER_START.length(), value.length() - MARKER_END.length());
+ String[] ranges = toRandomize.split(PATTERN_SPLIT_RANDOM);
+ return String.valueOf(ranges[0]);
+ }
+
+ private static Long getStartEpochMicroseconds() {
+ long epochMicrosecondsNow = ChronoUnit.MICROS.between(Instant.EPOCH, Instant.now());
+ long lowest10minInterval = epochMicrosecondsNow - epochMicrosecondsNow % TEN_MINUTES_MICROSECONDS;
+ long highest10minInterval = lowest10minInterval + TEN_MINUTES_MICROSECONDS;
+
+ if ((epochMicrosecondsNow - lowest10minInterval) < (highest10minInterval - epochMicrosecondsNow)) {
+ return lowest10minInterval;
+ } else {
+ return highest10minInterval;
+ }
+ }
+
+ public static int getRandomNumber(int min, int max) {
+ return random.nextInt(max - min) + min;
+ }
+
+ private static int parseInt(String strNum) {
+ try {
+ return Integer.parseInt(strNum);
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException(MessageFormat.format("Cannot parse int for value: {0}", strNum), nfe);
+ }
+ }
+
+ public static boolean isRange(String value) {
+ return value.startsWith(MARKER_START) && value.endsWith(MARKER_END);
+ }
+
+ private static boolean isRange(String value, String splitPattern) {
+ String pattern = PATTERN_MARKER_START + PATTERN_DIGIT + splitPattern + PATTERN_DIGIT + PATTERN_MARKER_END;
+ return value.matches(pattern);
+ }
+
+ public static boolean isRandomRange(String value) {
+ return isRange(value, PATTERN_SPLIT_RANDOM);
+ }
+
+ public static boolean isTrandingRange(String value) {
+ return isRange(value, PATTERN_SPLIT_TRENDING);
+ }
+
+ public static String[] splitRandomRange(String value) {
+ return splitRange(value, PATTERN_SPLIT_RANDOM);
+ }
+
+ public static String[] splitTrendingRange(String value) {
+ return splitRange(value, PATTERN_SPLIT_TRENDING);
+ }
+
+ private static String[] splitRange(String value, String splitPattern) {
+ String truncated = value.substring(MARKER_START.length(), value.length() - MARKER_END.length());
+ return truncated.split(splitPattern);
+ }
+}
diff --git a/src/main/java/org/onap/a1pesimulator/util/TopologyReader.java b/src/main/java/org/onap/a1pesimulator/util/TopologyReader.java
new file mode 100644
index 0000000..55e47cf
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/util/TopologyReader.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package org.onap.a1pesimulator.util;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import org.onap.a1pesimulator.data.cell.CellList;
+import org.onap.a1pesimulator.data.ue.UserEquipment;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TopologyReader {
+
+ private final String topologyCellConfigFile;
+ private final String topologyUeConfigFile;
+
+ private long topologyCellLastModified = 0L;
+ private long topologyUeLastModified = 0L;
+
+ private TopologyReader(@Value("${topology.cell.config.file}") final String topologyCellConfigFile,
+ @Value("${topology.ue.config.file}") final String topologyUeConfigFile) {
+ this.topologyCellConfigFile = topologyCellConfigFile;
+ this.topologyUeConfigFile = topologyUeConfigFile;
+ }
+
+ public CellList loadCellTopology() {
+ final File file = new File(topologyCellConfigFile);
+ topologyCellLastModified = file.lastModified();
+
+ if (!file.exists()) {
+ return new CellList();
+ }
+
+ return JsonUtils.INSTANCE.deserializeFromFile(topologyCellConfigFile, CellList.class);
+ }
+
+ public Collection<UserEquipment> loadUeTopology() {
+ final File file = new File(topologyUeConfigFile);
+ topologyUeLastModified = file.lastModified();
+
+ if (!file.exists()) {
+ return Collections.emptyList();
+ }
+
+ final UserEquipment[] userEquipments =
+ JsonUtils.INSTANCE.deserializeFromFile(topologyUeConfigFile, UserEquipment[].class);
+ return Arrays.asList(userEquipments);
+ }
+
+ public boolean topologyCellHasChanged() {
+ return topologyCellLastModified != new File(topologyCellConfigFile).lastModified();
+ }
+
+ public boolean topologyUeHasChanged() {
+ return topologyUeLastModified != new File(topologyUeConfigFile).lastModified();
+ }
+}
diff --git a/src/main/java/org/onap/a1pesimulator/util/VnfConfigReader.java b/src/main/java/org/onap/a1pesimulator/util/VnfConfigReader.java
new file mode 100644
index 0000000..318b3d6
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/util/VnfConfigReader.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package org.onap.a1pesimulator.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.util.Properties;
+import org.onap.a1pesimulator.data.VnfConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+@Service
+public class VnfConfigReader {
+
+ private static final Logger log = LoggerFactory.getLogger(VnfConfigReader.class);
+
+ private String vnfConfigFile;
+
+ private VnfConfigReader(@Value("${vnf.config.file}") String vnfConfigFile) {
+ this.vnfConfigFile = vnfConfigFile;
+ }
+
+ public VnfConfig getVnfConfig() {
+
+ Properties props = new Properties();
+ VnfConfig vnfConfig;
+
+ try {
+ props.load(new FileReader(vnfConfigFile));
+ ObjectMapper mapper = new ObjectMapper();
+ vnfConfig = mapper.convertValue(props, VnfConfig.class);
+ } catch (FileNotFoundException e) {
+ String errorMsg = "Could not find vnfConfigFile under: " + vnfConfigFile;
+ log.error(errorMsg);
+ throw new VnfConfigReaderException(errorMsg, e);
+ } catch (Exception e) {
+ String errorMsg = "Failed to get VnfConfig: " + e.getMessage();
+ log.error(errorMsg);
+ throw new VnfConfigReaderException(errorMsg, e);
+ }
+
+ return vnfConfig;
+ }
+
+ private static class VnfConfigReaderException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public VnfConfigReaderException(String message, Throwable t) {
+ super(message, t);
+ }
+ }
+}