diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java index df92c5c1af8a5bf47df980dcea4db1d2309351b4..e835a818846a1cb87e1accc66a90ff2fa4c51b30 100644 --- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java +++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.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.monitoring.model.KpiValue; public class PolicyRuleCondition { @@ -26,8 +29,18 @@ public class PolicyRuleCondition { public PolicyRuleCondition( String kpiId, NumericalOperator numericalOperator, KpiValue<?> kpiValue) { + checkNotNull(kpiId, "Kpi ID must not be null."); + checkArgument(!kpiId.isBlank(), "Kpi ID must not be empty."); this.kpiId = kpiId; + checkArgument( + numericalOperator != NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_UNDEFINED, + "Numerical operator cannot be undefined"); this.numericalOperator = numericalOperator; + checkNotNull(kpiValue, "Kpi value must not be null."); + checkArgument( + isKpiValueValid(kpiValue), + "Kpi value must be: String, Float, Boolean or Integer but it was [%s].", + kpiValue.getValue().getClass().getName()); this.kpiValue = kpiValue; } @@ -43,6 +56,24 @@ public class PolicyRuleCondition { return kpiValue; } + private boolean isKpiValueValid(KpiValue<?> kpiValue) { + final var kpiValueType = kpiValue.getValue(); + + if (kpiValueType instanceof String) { + return true; + } + + if (kpiValueType instanceof Boolean) { + return true; + } + + if (kpiValueType instanceof Integer) { + return true; + } + + return kpiValueType instanceof Float; + } + @Override public String toString() { return String.format( diff --git a/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleConditionValidationTest.java b/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleConditionValidationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..635876dcba59eef27273ff2bc24a7921991e2975 --- /dev/null +++ b/src/policy/src/test/java/eu/teraflow/policy/PolicyRuleConditionValidationTest.java @@ -0,0 +1,139 @@ +/* +* 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.NumericalOperator; +import eu.teraflow.policy.model.PolicyRuleCondition; +import eu.teraflow.policy.monitoring.model.BooleanKpiValue; +import eu.teraflow.policy.monitoring.model.FloatKpiValue; +import eu.teraflow.policy.monitoring.model.IntegerKpiValue; +import eu.teraflow.policy.monitoring.model.KpiValue; +import eu.teraflow.policy.monitoring.model.StringKpiValue; +import io.quarkus.test.junit.QuarkusTest; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mockito; + +@QuarkusTest +class PolicyRuleConditionValidationTest { + + private PolicyRuleCondition createPolicyRuleCondition( + String kpiId, NumericalOperator numericalOperator, KpiValue<?> kpiValue) { + + return new PolicyRuleCondition(kpiId, numericalOperator, kpiValue); + } + + private static Stream<Arguments> provideKpiValues() { + return Stream.of( + Arguments.of(new StringKpiValue("stringKpiValue")), + Arguments.of(new BooleanKpiValue(true)), + Arguments.of(new IntegerKpiValue(44)), + Arguments.of(new FloatKpiValue(12.3f))); + } + + @ParameterizedTest + @MethodSource("provideKpiValues") + void shouldThrowNullPointerExceptionGivenNullKpiId(KpiValue<?> kpiValue) { + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy( + () -> + createPolicyRuleCondition( + null, + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN, + kpiValue)); + } + + @ParameterizedTest + @MethodSource("provideKpiValues") + void shouldThrowIllegalArgumentExceptionGivenEmptyKpiId(KpiValue<?> kpiValue) { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + createPolicyRuleCondition( + "", NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL, kpiValue)); + } + + @ParameterizedTest + @MethodSource("provideKpiValues") + void shouldThrowIllegalArgumentExceptionGivenWhiteSpacedKpiId(KpiValue<?> kpiValue) { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + createPolicyRuleCondition( + " ", NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL, kpiValue)); + } + + @ParameterizedTest + @MethodSource("provideKpiValues") + void shouldThrowIllegalArgumentExceptionGivenUndefinedNumericalOperator(KpiValue<?> kpiValue) { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + createPolicyRuleCondition( + "kpiId", + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_UNDEFINED, + kpiValue)); + } + + @Test + void shouldThrowNullPointerExceptionGivenNullKpiValue() { + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy( + () -> + createPolicyRuleCondition( + "kpiId", NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN, null)); + } + + @Test + void shouldThrowIllegalArgumentExceptionIfIsKpiValueIsOfInvalidType() { + final var kpiValue = Mockito.mock(KpiValue.class); + Mockito.when(kpiValue.getValue()).thenReturn(1_2L); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + createPolicyRuleCondition( + "kpiId", + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN, + kpiValue)); + } + + @ParameterizedTest + @MethodSource("provideKpiValues") + void shouldCreatePolicyRuleConditionObject(KpiValue<?> kpiValue) { + final var expectedKpiId = "expectedKpiId"; + final var expectedNumericalOperator = + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN; + + final var expectedPolicyRuleCondition = + new PolicyRuleCondition(expectedKpiId, expectedNumericalOperator, kpiValue); + + final var policyRuleCondition = + createPolicyRuleCondition( + "expectedKpiId", NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN, kpiValue); + + assertThat(policyRuleCondition) + .usingRecursiveComparison() + .isEqualTo(expectedPolicyRuleCondition); + } +} diff --git a/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java b/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java index 755dc08d8ad93319a96022809af3ca780adf22f7..05f835d58f6552f3bd21f467b02026c9c509a67c 100644 --- a/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java +++ b/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java @@ -2367,8 +2367,30 @@ class SerializerTest { assertThat(subscriptionId).isEqualTo(expectedSubscriptionId); } + private static Stream<Arguments> provideNumericalOperators() { + return Stream.of( + Arguments.of( + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_EQUAL, + PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_EQUAL), + Arguments.of( + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL, + PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL), + Arguments.of( + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN, + PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_LESS_THAN), + Arguments.of( + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL, + PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL), + Arguments.of( + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN, + PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN), + Arguments.of( + NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL, + PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL)); + } + @ParameterizedTest - @MethodSource("provideNumericalOperator") + @MethodSource("provideNumericalOperators") void shouldSerializePolicyRuleConditionGivenMultipleNumericalOperators( NumericalOperator expectedNumericalOperator) { final var expectedPolicyRuleConditionKpiId = "expectedPolicyRuleConditionKpiId"; diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml index fa8f8df32cdd910f2be7801387325c502d401303..3472446aa9c83c8f742462850cab79a37e0a14f1 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: 164149a37bb250bca49a933b823f7c82877b277a - app.quarkus.io/build-timestamp: 2022-08-02 - 11:19:07 +0000 + app.quarkus.io/commit-id: 8d012ef481feb17b0f599b8cd2367799150706d9 + app.quarkus.io/build-timestamp: 2022-08-04 - 13:19:34 +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: 164149a37bb250bca49a933b823f7c82877b277a - app.quarkus.io/build-timestamp: 2022-08-02 - 11:19:07 +0000 + app.quarkus.io/commit-id: 8d012ef481feb17b0f599b8cd2367799150706d9 + app.quarkus.io/build-timestamp: 2022-08-04 - 13:19:34 +0000 labels: app: policyservice app.kubernetes.io/name: policyservice @@ -39,8 +39,8 @@ spec: template: metadata: annotations: - app.quarkus.io/commit-id: 164149a37bb250bca49a933b823f7c82877b277a - app.quarkus.io/build-timestamp: 2022-08-02 - 11:19:07 +0000 + app.quarkus.io/commit-id: 8d012ef481feb17b0f599b8cd2367799150706d9 + app.quarkus.io/build-timestamp: 2022-08-04 - 13:19:34 +0000 labels: app: policyservice app.kubernetes.io/name: policyservice @@ -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: