From 1e48f7806eeaecfbae1d2438c9c7d22d7078fdcb Mon Sep 17 00:00:00 2001 From: Fotis Soldatos <fsoldatos@ubitech.eu> Date: Fri, 5 Aug 2022 00:52:11 +0300 Subject: [PATCH] refactor(policy): add validation at PolicyRuleDevice --- .../policy/model/PolicyRuleDevice.java | 6 + .../policy/PolicyRuleBasicValidationTest.java | 2 +- .../PolicyRuleDeviceValidationTest.java | 178 ++++++++++++++++++ .../eu/teraflow/policy/PolicyServiceTest.java | 17 +- src/policy/target/kubernetes/kubernetes.yml | 28 +-- 5 files changed, 215 insertions(+), 16 deletions(-) create mode 100644 src/policy/src/test/java/eu/teraflow/policy/PolicyRuleDeviceValidationTest.java diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleDevice.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleDevice.java index 46151ea5c..6dbbe2e00 100644 --- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleDevice.java +++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleDevice.java @@ -16,6 +16,9 @@ package eu.teraflow.policy.model; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + import eu.teraflow.policy.common.Util; import java.util.List; @@ -25,7 +28,10 @@ public class PolicyRuleDevice { private final List<String> deviceIds; public PolicyRuleDevice(PolicyRuleBasic policyRuleBasic, List<String> deviceIds) { + checkNotNull(policyRuleBasic, "PolicyRuleBasic must not be null."); this.policyRuleBasic = policyRuleBasic; + checkNotNull(deviceIds, "Device Ids must not be null."); + checkArgument(!deviceIds.isEmpty(), "Device Ids must not be empty."); this.deviceIds = deviceIds; } diff --git a/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleBasicValidationTest.java b/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleBasicValidationTest.java index 907473f80..53cddf6be 100644 --- a/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleBasicValidationTest.java +++ b/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleBasicValidationTest.java @@ -56,7 +56,7 @@ class PolicyRuleBasicValidationTest { } private List<PolicyRuleCondition> createPolicyRuleConditions( - String kpiId, NumericalOperator numericalOperator, KpiValue kpiValue) { + String kpiId, NumericalOperator numericalOperator, KpiValue<?> kpiValue) { final var policyRuleCondition = new PolicyRuleCondition(kpiId, numericalOperator, kpiValue); return List.of(policyRuleCondition); diff --git a/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleDeviceValidationTest.java b/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleDeviceValidationTest.java new file mode 100644 index 000000000..064cd7ee0 --- /dev/null +++ b/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleDeviceValidationTest.java @@ -0,0 +1,178 @@ +/* +* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +* +* 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 eu.teraflow.policy; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import eu.teraflow.policy.model.BooleanOperator; +import eu.teraflow.policy.model.NumericalOperator; +import eu.teraflow.policy.model.PolicyRuleAction; +import eu.teraflow.policy.model.PolicyRuleActionEnum; +import eu.teraflow.policy.model.PolicyRuleBasic; +import eu.teraflow.policy.model.PolicyRuleCondition; +import eu.teraflow.policy.model.PolicyRuleDevice; +import eu.teraflow.policy.model.PolicyRuleState; +import eu.teraflow.policy.model.RuleState; +import eu.teraflow.policy.monitoring.model.IntegerKpiValue; +import eu.teraflow.policy.monitoring.model.KpiValue; +import io.quarkus.test.junit.QuarkusTest; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.Test; + +@QuarkusTest +class PolicyRuleDeviceValidationTest { + + private PolicyRuleBasic createPolicyRuleBasic( + String policyRuleId, + int priority, + PolicyRuleState policyRuleState, + BooleanOperator booleanOperator, + List<PolicyRuleCondition> policyRuleConditions, + List<PolicyRuleAction> policyRuleActions) { + + return new PolicyRuleBasic( + policyRuleId, + policyRuleState, + priority, + policyRuleConditions, + booleanOperator, + policyRuleActions); + } + + private List<PolicyRuleCondition> createPolicyRuleConditions( + String kpiId, NumericalOperator numericalOperator, KpiValue<?> kpiValue) { + final var policyRuleCondition = new PolicyRuleCondition(kpiId, numericalOperator, kpiValue); + + return List.of(policyRuleCondition); + } + + private List<PolicyRuleAction> createPolicyRuleActions( + PolicyRuleActionEnum policyRuleActionEnum, List<String> parameters) { + final var policyRuleAction = new PolicyRuleAction(policyRuleActionEnum, parameters); + + return List.of(policyRuleAction); + } + + private PolicyRuleDevice createPolicyRuleDevice( + PolicyRuleBasic policyRuleBasic, List<String> deviceIds) { + + return new PolicyRuleDevice(policyRuleBasic, deviceIds); + } + + private List<String> createDeviceIds() { + return List.of("deviceId1", "deviceId2"); + } + + @Test + void shouldThrowNullPointerExceptionGivenNullPolicyRuleBasic() { + final var deviceIds = createDeviceIds(); + + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(() -> createPolicyRuleDevice(null, deviceIds)); + } + + @Test + void shouldThrowNullPointerExceptionGivenNullDeviceIds() { + final var policyRuleConditions = + createPolicyRuleConditions( + UUID.randomUUID().toString(), + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN, + new IntegerKpiValue(3)); + final var policyRuleActions = + createPolicyRuleActions( + PolicyRuleActionEnum.POLICY_RULE_ACTION_ADD_SERVICE_CONSTRAINT, + List.of(UUID.randomUUID().toString(), UUID.randomUUID().toString())); + + final var policyRuleState = new PolicyRuleState(RuleState.POLICY_EFFECTIVE); + + final var policyRuleBasic = + createPolicyRuleBasic( + "policyRuleId", + 3, + policyRuleState, + BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_OR, + policyRuleConditions, + policyRuleActions); + + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(() -> createPolicyRuleDevice(policyRuleBasic, null)); + } + + @Test + void shouldThrowIllegalArgumentExceptionGivenEmptyDeviceIds() { + final var policyRuleConditions = + createPolicyRuleConditions( + UUID.randomUUID().toString(), + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL, + new IntegerKpiValue(3)); + final var policyRuleActions = + createPolicyRuleActions( + PolicyRuleActionEnum.POLICY_RULE_ACTION_ADD_SERVICE_CONFIGRULE, + List.of(UUID.randomUUID().toString(), UUID.randomUUID().toString())); + + final var policyRuleState = new PolicyRuleState(RuleState.POLICY_EFFECTIVE); + + final var policyRuleBasic = + createPolicyRuleBasic( + "policyRuleId1", + 213, + policyRuleState, + BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_AND, + policyRuleConditions, + policyRuleActions); + + final var deviceIds = Collections.<String>emptyList(); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> createPolicyRuleDevice(policyRuleBasic, deviceIds)); + } + + @Test + void shouldCreatePolicyRuleDeviceObject() { + final var policyRuleConditions = + createPolicyRuleConditions( + UUID.randomUUID().toString(), + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL, + new IntegerKpiValue(3)); + final var policyRuleActions = + createPolicyRuleActions( + PolicyRuleActionEnum.POLICY_RULE_ACTION_SET_DEVICE_STATUS, + List.of(UUID.randomUUID().toString(), UUID.randomUUID().toString())); + + final var policyRuleState = new PolicyRuleState(RuleState.POLICY_EFFECTIVE); + + final var policyRuleBasic = + createPolicyRuleBasic( + "policyRuleId", + 3, + policyRuleState, + BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_OR, + policyRuleConditions, + policyRuleActions); + + final var deviceIds = createDeviceIds(); + + final var expectedPolicyRuleDevice = new PolicyRuleDevice(policyRuleBasic, deviceIds); + + final var policyRuleDevice = createPolicyRuleDevice(policyRuleBasic, deviceIds); + + assertThat(policyRuleDevice).usingRecursiveComparison().isEqualTo(expectedPolicyRuleDevice); + } +} diff --git a/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java b/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java index 7e3044c1d..3f1232432 100644 --- a/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java +++ b/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java @@ -144,11 +144,26 @@ class PolicyServiceTest { void shouldAddPolicyDevice() throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture<String> message = new CompletableFuture<>(); + final var expectedDeviceIdUuid1 = + serializer.serializeUuid("20db867c-772d-4872-9179-244ecafb3257"); + final var expectedDeviceIdUuid2 = + serializer.serializeUuid("095974ac-d757-412d-b317-bcf355220aa9"); + + final var expectedDeviceId1 = + ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(expectedDeviceIdUuid1).build(); + final var expectedDeviceId2 = + ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(expectedDeviceIdUuid2).build(); + final var policyRuleBasic = createPolicyRuleBasic(); + final var deviceIds = List.of(expectedDeviceId1, expectedDeviceId2); + final var expectedPolicyRuleState = policyRuleBasic.getPolicyRuleState(); final var policyRuleDevice = - Policy.PolicyRuleDevice.newBuilder().setPolicyRuleBasic(policyRuleBasic).build(); + Policy.PolicyRuleDevice.newBuilder() + .setPolicyRuleBasic(policyRuleBasic) + .addAllDeviceList(deviceIds) + .build(); client .policyAddDevice(policyRuleDevice) diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml index 360485dcc..680929bc0 100644 --- a/src/policy/target/kubernetes/kubernetes.yml +++ b/src/policy/target/kubernetes/kubernetes.yml @@ -3,20 +3,20 @@ apiVersion: v1 kind: Service metadata: annotations: - app.quarkus.io/commit-id: a5550cfa37e56aef1054126dd063b112df66b531 - app.quarkus.io/build-timestamp: 2022-08-04 - 21:21:19 +0000 + app.quarkus.io/commit-id: 7d24cfdf286fcca1ff04620ee026933bedd8960e + app.quarkus.io/build-timestamp: 2022-08-04 - 22:13:18 +0000 labels: app.kubernetes.io/name: policyservice app: policyservice name: policyservice spec: ports: - - name: grpc - port: 6060 - targetPort: 6060 - name: http port: 8080 targetPort: 8080 + - name: grpc + port: 6060 + targetPort: 6060 selector: app.kubernetes.io/name: policyservice type: ClusterIP @@ -25,8 +25,8 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: - app.quarkus.io/commit-id: a5550cfa37e56aef1054126dd063b112df66b531 - app.quarkus.io/build-timestamp: 2022-08-04 - 21:21:19 +0000 + app.quarkus.io/commit-id: 7d24cfdf286fcca1ff04620ee026933bedd8960e + app.quarkus.io/build-timestamp: 2022-08-04 - 22:13:18 +0000 labels: app: policyservice app.kubernetes.io/name: policyservice @@ -39,8 +39,8 @@ spec: template: metadata: annotations: - app.quarkus.io/commit-id: a5550cfa37e56aef1054126dd063b112df66b531 - app.quarkus.io/build-timestamp: 2022-08-04 - 21:21:19 +0000 + app.quarkus.io/commit-id: 7d24cfdf286fcca1ff04620ee026933bedd8960e + app.quarkus.io/build-timestamp: 2022-08-04 - 22:13:18 +0000 labels: app: policyservice app.kubernetes.io/name: policyservice @@ -51,10 +51,10 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - - name: SERVICE_SERVICE_HOST - value: serviceservice - name: CONTEXT_SERVICE_HOST value: contextservice + - name: SERVICE_SERVICE_HOST + value: serviceservice - name: MONITORING_SERVICE_HOST value: monitoringservice image: registry.gitlab.com/teraflow-h2020/controller/policy:0.1.0 @@ -71,12 +71,12 @@ spec: timeoutSeconds: 10 name: policyservice ports: - - containerPort: 6060 - name: grpc - protocol: TCP - containerPort: 8080 name: http protocol: TCP + - containerPort: 6060 + name: grpc + protocol: TCP readinessProbe: failureThreshold: 3 httpGet: -- GitLab