aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/org/onap/a1pesimulator/service/a1
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/onap/a1pesimulator/service/a1')
-rw-r--r--src/main/java/org/onap/a1pesimulator/service/a1/A1Service.java44
-rw-r--r--src/main/java/org/onap/a1pesimulator/service/a1/OnPolicyAction.java21
-rw-r--r--src/main/java/org/onap/a1pesimulator/service/a1/PolicyInstancesHolder.java47
-rw-r--r--src/main/java/org/onap/a1pesimulator/service/a1/RanA1ServiceLocalStoreImpl.java116
-rw-r--r--src/main/java/org/onap/a1pesimulator/service/a1/RanUeHandoverOnPolicyAction.java130
-rw-r--r--src/main/java/org/onap/a1pesimulator/service/a1/SetLowRangeValuesOnPolicyAction.java53
6 files changed, 411 insertions, 0 deletions
diff --git a/src/main/java/org/onap/a1pesimulator/service/a1/A1Service.java b/src/main/java/org/onap/a1pesimulator/service/a1/A1Service.java
new file mode 100644
index 0000000..aa2c407
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/service/a1/A1Service.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.service.a1;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestClientException;
+
+public interface A1Service {
+
+ ResponseEntity<String> healthCheck() throws URISyntaxException;
+
+ ResponseEntity<String> putPolicy(Integer policyTypeId, String policyId, String body) throws URISyntaxException;
+
+ ResponseEntity<String> putPolicySchema(Integer policyTypeId, String body) throws URISyntaxException;
+
+ ResponseEntity<String> deletePolicy(Integer policyTypeId, String policyId) throws URISyntaxException;
+
+ ResponseEntity<String> getPolicyTypeIds() throws RestClientException, URISyntaxException;
+
+ ResponseEntity<String> getPolicyType(Integer policyTypeId) throws RestClientException, URISyntaxException;
+
+ ResponseEntity<String> getPolicyIdsOfType(Integer policyTypeId)
+ throws RestClientException, URISyntaxException, IOException;
+
+ ResponseEntity<String> getPolicy(Integer policyTypeId, String policyInstanceId)
+ throws RestClientException, URISyntaxException;
+
+ ResponseEntity<String> getAllPoliciesForType(Integer policyTypeId)
+ throws IOException, RestClientException, URISyntaxException;
+
+}
diff --git a/src/main/java/org/onap/a1pesimulator/service/a1/OnPolicyAction.java b/src/main/java/org/onap/a1pesimulator/service/a1/OnPolicyAction.java
new file mode 100644
index 0000000..821e395
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/service/a1/OnPolicyAction.java
@@ -0,0 +1,21 @@
+/*
+ * 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.service.a1;
+
+public interface OnPolicyAction {
+
+ boolean isForMe(Integer policyTypeId, String policyId, String body);
+
+ void onPolicy(Integer policyTypeId, String policyId, String body);
+}
diff --git a/src/main/java/org/onap/a1pesimulator/service/a1/PolicyInstancesHolder.java b/src/main/java/org/onap/a1pesimulator/service/a1/PolicyInstancesHolder.java
new file mode 100644
index 0000000..a5e5a07
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/service/a1/PolicyInstancesHolder.java
@@ -0,0 +1,47 @@
+/*
+ * 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.service.a1;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.onap.a1pesimulator.util.JsonUtils;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PolicyInstancesHolder {
+
+ Map<String, String> cellPolicyMap = new HashMap<>();
+
+ public void addPolicy(String policyId, String body) {
+ cellPolicyMap.put(policyId, body);
+ }
+
+ public void removePolicy(String policyId) {
+ cellPolicyMap.remove(policyId);
+ }
+
+ public boolean containsPoliciesForCell(String cell) {
+ return cellPolicyMap.values().stream().map(this::getCellListFromPolicyInstance).flatMap(List::stream)
+ .anyMatch(c -> c.equals(cell));
+ }
+
+ private List<String> getCellListFromPolicyInstance(String policyInstance) {
+ RanUeHandoverOnPolicyAction.UeHandoverPolicy policy =
+ JsonUtils.INSTANCE.deserialize(policyInstance, RanUeHandoverOnPolicyAction.UeHandoverPolicy.class);
+ return policy.getResources().stream().flatMap(resources -> resources.getCellIdList().stream())
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/org/onap/a1pesimulator/service/a1/RanA1ServiceLocalStoreImpl.java b/src/main/java/org/onap/a1pesimulator/service/a1/RanA1ServiceLocalStoreImpl.java
new file mode 100644
index 0000000..feb481d
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/service/a1/RanA1ServiceLocalStoreImpl.java
@@ -0,0 +1,116 @@
+package org.onap.a1pesimulator.service.a1;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestClientException;
+
+/**
+ * A1 Service implementation which uses in-memory policy data store.
+ */
+@Service
+public class RanA1ServiceLocalStoreImpl implements A1Service {
+
+ private static final Logger log = LoggerFactory.getLogger(RanA1ServiceLocalStoreImpl.class);
+
+ private Map<Integer, Map<String, String>> policyTypesMap = new HashMap<>();
+ private Map<Integer, String> policySchemaMap = new HashMap<>();
+ private ObjectMapper mapper;
+
+ public RanA1ServiceLocalStoreImpl(ObjectMapper mapper) {
+ this.mapper = mapper;
+ }
+
+ @Override
+ public ResponseEntity<String> healthCheck() throws RestClientException {
+ return ResponseEntity.ok().build();
+ }
+
+ @Override
+ public ResponseEntity<String> putPolicySchema(Integer policyTypeId, String body) {
+ policySchemaMap.put(policyTypeId, body);
+ return new ResponseEntity<>(HttpStatus.CREATED);
+ }
+
+ @Override
+ public ResponseEntity<String> putPolicy(final Integer policyTypeId, final String policyId, final String body) {
+ log.debug("Create or update policy id {} of policy type id {} with following content {} ", policyId,
+ policyTypeId, body);
+ if (policyTypesMap.containsKey(policyTypeId)) {
+ policyTypesMap.get(policyTypeId).put(policyId, body);
+ } else {
+ Map<String, String> policies = new HashMap<>();
+ policies.put(policyId, body);
+ policyTypesMap.put(policyTypeId, policies);
+ }
+ return ResponseEntity.accepted().build();
+ }
+
+ @Override
+ public ResponseEntity<String> deletePolicy(final Integer policyTypeId, final String policyId) {
+ log.debug("Delete policy id {} of policy type id {}", policyId, policyTypeId);
+ if (policyTypesMap.containsKey(policyTypeId)) {
+ policyTypesMap.get(policyTypeId).remove(policyId);
+ return ResponseEntity.accepted().build();
+ } else {
+ return ResponseEntity.notFound().build();
+ }
+ }
+
+ @Override
+ public ResponseEntity<String> getPolicyTypeIds() throws RestClientException {
+ return getRestAsString(policySchemaMap.keySet());
+ }
+
+ @Override
+ public ResponseEntity<String> getPolicyType(final Integer policyTypeId) throws RestClientException {
+ if (policySchemaMap.isEmpty() || !policySchemaMap.containsKey(policyTypeId)) {
+ return ResponseEntity.notFound().build();
+ } else {
+ return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(policySchemaMap.get(policyTypeId));
+ }
+ }
+
+ @Override
+ public ResponseEntity<String> getPolicyIdsOfType(final Integer policyTypeId) throws RestClientException {
+ Set<String> result = new HashSet<>();
+ if (policyTypesMap.containsKey(policyTypeId)) {
+ result = policyTypesMap.get(policyTypeId).keySet();
+ }
+ return getRestAsString(result);
+ }
+
+ @Override
+ public ResponseEntity<String> getPolicy(final Integer policyTypeId, final String policyId)
+ throws RestClientException {
+ if (policyTypesMap.containsKey(policyTypeId) && policyTypesMap.get(policyTypeId).containsKey(policyId)) {
+ return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON)
+ .body(policyTypesMap.get(policyTypeId).get(policyId));
+ } else {
+ return ResponseEntity.notFound().build();
+ }
+ }
+
+ @Override
+ public ResponseEntity<String> getAllPoliciesForType(final Integer policyTypeId) throws RestClientException {
+ return getRestAsString(policyTypesMap.get(policyTypeId));
+ }
+
+ private ResponseEntity<String> getRestAsString(Object obj) throws RestClientException {
+ try {
+ return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(mapper.writeValueAsString(obj));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException("Cannot serialize object", e);
+ }
+ }
+
+}
diff --git a/src/main/java/org/onap/a1pesimulator/service/a1/RanUeHandoverOnPolicyAction.java b/src/main/java/org/onap/a1pesimulator/service/a1/RanUeHandoverOnPolicyAction.java
new file mode 100644
index 0000000..fdbbd97
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/service/a1/RanUeHandoverOnPolicyAction.java
@@ -0,0 +1,130 @@
+/*
+ * 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.service.a1;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import lombok.Getter;
+import org.onap.a1pesimulator.data.ue.UserEquipment;
+import org.onap.a1pesimulator.data.ue.UserEquipmentNotification;
+import org.onap.a1pesimulator.service.cell.RanCellService;
+import org.onap.a1pesimulator.service.ue.RanUeService;
+import org.onap.a1pesimulator.util.JsonUtils;
+import org.onap.a1pesimulator.util.JsonUtils.JsonUtilsException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RanUeHandoverOnPolicyAction implements OnPolicyAction {
+
+ private static final String TOPIC_UE = "/topic/userEquipment";
+ private static final String POLICY_EXAMPLE =
+ "{ \"scope\": { \"ueId\": \"emergency_samsung_s10_01\" }, \"resources\": [ { \"cellIdList\": [ \"Cell1\" ], \"preference\": \"AVOID\" } ] }";
+ private static final Logger log = LoggerFactory.getLogger(RanUeHandoverOnPolicyAction.class);
+
+ private final RanUeService ranUeService;
+ private final SimpMessagingTemplate messagingTemplate;
+ private final RanCellService ranCellService;
+ private final PolicyInstancesHolder policyHolder;
+
+ public RanUeHandoverOnPolicyAction(SimpMessagingTemplate messagingTemplate, RanUeService ranUeService,
+ RanCellService ranCellService, PolicyInstancesHolder policyHolder) {
+ this.messagingTemplate = messagingTemplate;
+ this.ranUeService = ranUeService;
+ this.ranCellService = ranCellService;
+ this.policyHolder = policyHolder;
+ }
+
+ @Override
+ public boolean isForMe(Integer policyTypeId, String policyId, String body) {
+ try {
+ JsonUtils.INSTANCE.deserialize(body, UeHandoverPolicy.class);
+ return true;
+ } catch (JsonUtilsException ex) {
+ log.info(
+ "Policy {} is not for me because policy body doesn't comply with Ue Handover policy. Follow example: {}",
+ policyId, POLICY_EXAMPLE);
+ return false;
+ }
+ }
+
+ @Override
+ public void onPolicy(Integer policyTypeId, String policyId, String body) {
+ UeHandoverPolicy policy = JsonUtils.INSTANCE.deserialize(body, UeHandoverPolicy.class);
+ String ueId = policy.getScope().getUeId();
+ List<String> cellId = policy.getResources().stream().flatMap(resources -> resources.getCellIdList().stream())
+ .collect(Collectors.toList());
+
+ if (ueId == null || cellId.isEmpty()) {
+ log.warn("Cannot handover because {} is not provided in preload! Follow example: {}",
+ ueId == null ? "ueId" : "cellId", POLICY_EXAMPLE);
+ return;
+ }
+
+ Optional<String> activeCellId = getActiveCellForUE(ueId);
+
+ if (!activeCellId.isPresent()) {
+ log.warn("Cannot handover ue {} because there is no active cell in range", ueId);
+ return;
+ }
+
+ ranUeService.handover(ueId, activeCellId.get());
+ messagingTemplate.convertAndSend(TOPIC_UE, new UserEquipmentNotification(ueId, activeCellId.get()));
+ }
+
+ private Optional<String> getActiveCellForUE(String ue) {
+ Optional<UserEquipment> equipment = ranUeService.getUserEquipment(ue);
+ if (!equipment.isPresent()) {
+ log.warn("Cannot handover because is not ue with id: {}", ue);
+ return Optional.empty();
+ }
+
+ return ranCellService.getAllCellsWithStatus().stream().filter(c -> !c.isFailureMode())
+ .map(cellWithStatus -> cellWithStatus.getCell().getIdentifier())
+ .filter(cell -> ranUeService.canHandover(ue, cell))
+ .filter(cell -> !policyHolder.containsPoliciesForCell(cell)).findFirst();
+ }
+
+ @Getter
+ public static class UeHandoverPolicy {
+
+ private Scope scope;
+ private List<Resources> resources;
+ }
+
+ @Getter
+ public static class Scope {
+
+ private String ueId;
+ }
+
+ @Getter
+ public static class Resources {
+
+ private List<String> cellIdList;
+ private Preference preference;
+ }
+
+ public enum Preference {
+ SHALL("SHALL"), PREFER("PREFER"), AVOID("AVOID"), FORBID("FORBID");
+ public final String value;
+
+ Preference(String stateName) {
+ this.value = stateName;
+ }
+ }
+}
diff --git a/src/main/java/org/onap/a1pesimulator/service/a1/SetLowRangeValuesOnPolicyAction.java b/src/main/java/org/onap/a1pesimulator/service/a1/SetLowRangeValuesOnPolicyAction.java
new file mode 100644
index 0000000..e608aa5
--- /dev/null
+++ b/src/main/java/org/onap/a1pesimulator/service/a1/SetLowRangeValuesOnPolicyAction.java
@@ -0,0 +1,53 @@
+/*
+ * 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.service.a1;
+
+import java.util.List;
+import org.onap.a1pesimulator.data.ves.Event;
+import org.onap.a1pesimulator.data.ves.MeasurementFields.AdditionalMeasurement;
+import org.onap.a1pesimulator.data.ves.RanPeriodicVesEvent;
+import org.onap.a1pesimulator.service.ves.RanVesBrokerService;
+import org.onap.a1pesimulator.util.JsonUtils;
+import org.onap.a1pesimulator.util.RanVesUtils;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SetLowRangeValuesOnPolicyAction implements OnPolicyAction {
+
+ private final RanVesBrokerService vesBrokerService;
+
+ public SetLowRangeValuesOnPolicyAction(RanVesBrokerService vesBrokerService) {
+ this.vesBrokerService = vesBrokerService;
+ }
+
+ @Override
+ public boolean isForMe(Integer policyTypeId, String policyId, String body) {
+ // disabling for now
+ return false;
+ }
+
+ @Override
+ public void onPolicy(Integer policyTypeId, String policyId, String body) {
+ vesBrokerService.getPeriodicEventsCache().values().forEach(this::updateEvent);
+ }
+
+ private void updateEvent(RanPeriodicVesEvent periodicEvent) {
+ List<AdditionalMeasurement> lowRangeValues = RanVesUtils.setLowRangeValues(
+ periodicEvent.getEvent().getMeasurementFields().getAdditionalMeasurements());
+ Event clonedEvent = JsonUtils.INSTANCE.clone(periodicEvent.getEvent());
+ clonedEvent.getMeasurementFields().setAdditionalMeasurements(lowRangeValues);
+ periodicEvent.getSendVesRunnable().updateEvent(clonedEvent);
+ }
+
+}