Skip to content
...@@ -21,7 +21,7 @@ import org.etsi.tfs.policy.context.model.Device; ...@@ -21,7 +21,7 @@ import org.etsi.tfs.policy.context.model.Device;
import org.etsi.tfs.policy.context.model.Empty; import org.etsi.tfs.policy.context.model.Empty;
import org.etsi.tfs.policy.context.model.Service; import org.etsi.tfs.policy.context.model.Service;
import org.etsi.tfs.policy.context.model.ServiceId; import org.etsi.tfs.policy.context.model.ServiceId;
import org.etsi.tfs.policy.model.PolicyRule; import org.etsi.tfs.policy.policy.model.PolicyRule;
public interface ContextGateway { public interface ContextGateway {
......
...@@ -20,14 +20,14 @@ import context.MutinyContextServiceGrpc.MutinyContextServiceStub; ...@@ -20,14 +20,14 @@ import context.MutinyContextServiceGrpc.MutinyContextServiceStub;
import context_policy.MutinyContextPolicyServiceGrpc.MutinyContextPolicyServiceStub; import context_policy.MutinyContextPolicyServiceGrpc.MutinyContextPolicyServiceStub;
import io.quarkus.grpc.GrpcClient; import io.quarkus.grpc.GrpcClient;
import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.Uni;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import org.etsi.tfs.policy.Serializer; import org.etsi.tfs.policy.Serializer;
import org.etsi.tfs.policy.context.model.Device; import org.etsi.tfs.policy.context.model.Device;
import org.etsi.tfs.policy.context.model.Empty; import org.etsi.tfs.policy.context.model.Empty;
import org.etsi.tfs.policy.context.model.Service; import org.etsi.tfs.policy.context.model.Service;
import org.etsi.tfs.policy.context.model.ServiceId; import org.etsi.tfs.policy.context.model.ServiceId;
import org.etsi.tfs.policy.model.PolicyRule; import org.etsi.tfs.policy.policy.model.PolicyRule;
@ApplicationScoped @ApplicationScoped
public class ContextGatewayImpl implements ContextGateway { public class ContextGatewayImpl implements ContextGateway {
......
...@@ -21,7 +21,7 @@ import org.etsi.tfs.policy.context.model.Device; ...@@ -21,7 +21,7 @@ import org.etsi.tfs.policy.context.model.Device;
import org.etsi.tfs.policy.context.model.Empty; import org.etsi.tfs.policy.context.model.Empty;
import org.etsi.tfs.policy.context.model.Service; import org.etsi.tfs.policy.context.model.Service;
import org.etsi.tfs.policy.context.model.ServiceId; import org.etsi.tfs.policy.context.model.ServiceId;
import org.etsi.tfs.policy.model.PolicyRule; import org.etsi.tfs.policy.policy.model.PolicyRule;
public interface ContextService { public interface ContextService {
......
...@@ -17,13 +17,13 @@ ...@@ -17,13 +17,13 @@
package org.etsi.tfs.policy.context; package org.etsi.tfs.policy.context;
import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.Uni;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import org.etsi.tfs.policy.context.model.Device; import org.etsi.tfs.policy.context.model.Device;
import org.etsi.tfs.policy.context.model.Empty; import org.etsi.tfs.policy.context.model.Empty;
import org.etsi.tfs.policy.context.model.Service; import org.etsi.tfs.policy.context.model.Service;
import org.etsi.tfs.policy.context.model.ServiceId; import org.etsi.tfs.policy.context.model.ServiceId;
import org.etsi.tfs.policy.model.PolicyRule; import org.etsi.tfs.policy.policy.model.PolicyRule;
@ApplicationScoped @ApplicationScoped
public class ContextServiceImpl implements ContextService { public class ContextServiceImpl implements ContextService {
......
...@@ -19,8 +19,8 @@ package org.etsi.tfs.policy.device; ...@@ -19,8 +19,8 @@ package org.etsi.tfs.policy.device;
import device.DeviceService; import device.DeviceService;
import io.quarkus.grpc.GrpcClient; import io.quarkus.grpc.GrpcClient;
import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.Uni;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import org.etsi.tfs.policy.Serializer; import org.etsi.tfs.policy.Serializer;
import org.etsi.tfs.policy.context.model.Device; import org.etsi.tfs.policy.context.model.Device;
import org.etsi.tfs.policy.context.model.DeviceConfig; import org.etsi.tfs.policy.context.model.DeviceConfig;
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
package org.etsi.tfs.policy.device; package org.etsi.tfs.policy.device;
import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.Uni;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import org.etsi.tfs.policy.context.model.Device; import org.etsi.tfs.policy.context.model.Device;
import org.etsi.tfs.policy.context.model.DeviceConfig; import org.etsi.tfs.policy.context.model.DeviceConfig;
import org.etsi.tfs.policy.context.model.Empty; import org.etsi.tfs.policy.context.model.Empty;
......
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.exception;
public class ExternalServiceFailureException extends RuntimeException {
public ExternalServiceFailureException(String message, Exception e) {
super(message, e);
}
public ExternalServiceFailureException(String message) {
super(message);
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.exception;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.quarkus.grpc.ExceptionHandler;
import io.quarkus.grpc.ExceptionHandlerProvider;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GeneralExceptionHandler implements ExceptionHandlerProvider {
@Override
public <ReqT, RespT> ExceptionHandler<ReqT, RespT> createHandler(
ServerCall.Listener<ReqT> listener, ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
return new HelloExceptionHandler<>(listener, serverCall, metadata);
}
@Override
public Throwable transform(Throwable t) {
if (t instanceof ExternalServiceFailureException) {
return new StatusRuntimeException(Status.INTERNAL.withDescription(t.getMessage()));
} else {
return ExceptionHandlerProvider.toStatusException(t, true);
}
}
private static class HelloExceptionHandler<A, B> extends ExceptionHandler<A, B> {
public HelloExceptionHandler(
ServerCall.Listener<A> listener, ServerCall<A, B> call, Metadata metadata) {
super(listener, call, metadata);
}
@Override
protected void handleException(Throwable t, ServerCall<A, B> call, Metadata metadata) {
StatusRuntimeException sre =
(StatusRuntimeException) ExceptionHandlerProvider.toStatusException(t, true);
Metadata trailers = sre.getTrailers() != null ? sre.getTrailers() : metadata;
call.close(sre.getStatus(), trailers);
}
}
}
...@@ -19,8 +19,8 @@ package org.etsi.tfs.policy.monitoring; ...@@ -19,8 +19,8 @@ package org.etsi.tfs.policy.monitoring;
import io.quarkus.grpc.GrpcClient; import io.quarkus.grpc.GrpcClient;
import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.Uni;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import monitoring.MutinyMonitoringServiceGrpc.MutinyMonitoringServiceStub; import monitoring.MutinyMonitoringServiceGrpc.MutinyMonitoringServiceStub;
import org.etsi.tfs.policy.Serializer; import org.etsi.tfs.policy.Serializer;
import org.etsi.tfs.policy.context.model.Empty; import org.etsi.tfs.policy.context.model.Empty;
......
...@@ -18,8 +18,8 @@ package org.etsi.tfs.policy.monitoring; ...@@ -18,8 +18,8 @@ package org.etsi.tfs.policy.monitoring;
import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.Uni;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import org.etsi.tfs.policy.context.model.Empty; import org.etsi.tfs.policy.context.model.Empty;
import org.etsi.tfs.policy.monitoring.model.AlarmDescriptor; import org.etsi.tfs.policy.monitoring.model.AlarmDescriptor;
import org.etsi.tfs.policy.monitoring.model.AlarmResponse; import org.etsi.tfs.policy.monitoring.model.AlarmResponse;
......
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy;
import policy.PolicyService;
public interface PolicyGateway extends PolicyService {}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy;
import context.ContextOuterClass.ServiceId;
import io.quarkus.grpc.GrpcService;
import io.smallrye.mutiny.Uni;
import jakarta.inject.Inject;
import org.eclipse.microprofile.metrics.MetricUnits;
import org.eclipse.microprofile.metrics.annotation.Counted;
import org.eclipse.microprofile.metrics.annotation.Timed;
import org.etsi.tfs.policy.Serializer;
import policy.Policy;
import policy.Policy.PolicyRuleBasic;
import policy.Policy.PolicyRuleDevice;
import policy.Policy.PolicyRuleId;
import policy.Policy.PolicyRuleService;
import policy.Policy.PolicyRuleServiceList;
import policy.Policy.PolicyRuleState;
@GrpcService
public class PolicyGatewayImpl implements PolicyGateway {
private final PolicyService policyService;
private final Serializer serializer;
@Inject
public PolicyGatewayImpl(PolicyService policyService, Serializer serializer) {
this.policyService = policyService;
this.serializer = serializer;
}
@Override
@Counted(name = "policy_policyAddService_counter")
@Timed(name = "policy_policyAddService_histogram", unit = MetricUnits.MILLISECONDS)
public Uni<PolicyRuleState> policyAddService(PolicyRuleService request) {
final var policyRuleService = serializer.deserialize(request);
return policyService
.addPolicyService(policyRuleService)
.onItem()
.transform(serializer::serialize);
}
@Override
@Counted(name = "policy_policyUpdateService_counter")
@Timed(name = "policy_policyUpdateService_histogram", unit = MetricUnits.MILLISECONDS)
public Uni<PolicyRuleState> policyUpdateService(PolicyRuleService request) {
final var policyRuleService = serializer.deserialize(request);
return policyService
.updatePolicyService(policyRuleService)
.onItem()
.transform(serializer::serialize);
}
@Override
@Counted(name = "policy_policyAddDevice_counter")
@Timed(name = "policy_policyAddDevice_histogram", unit = MetricUnits.MILLISECONDS)
public Uni<PolicyRuleState> policyAddDevice(PolicyRuleDevice request) {
final var policyRuleDevice = serializer.deserialize(request);
return policyService
.addPolicyDevice(policyRuleDevice)
.onItem()
.transform(serializer::serialize);
}
@Override
@Counted(name = "policy_policyUpdateDevice_counter")
@Timed(name = "policy_policyUpdateDevice_histogram", unit = MetricUnits.MILLISECONDS)
public Uni<PolicyRuleState> policyUpdateDevice(PolicyRuleDevice request) {
final var policyRuleDevice = serializer.deserialize(request);
return policyService
.updatePolicyDevice(policyRuleDevice)
.onItem()
.transform(serializer::serialize);
}
@Override
@Counted(name = "policy_policyDelete_counter")
@Timed(name = "policy_policyDelete_histogram", unit = MetricUnits.MILLISECONDS)
public Uni<PolicyRuleState> policyDelete(PolicyRuleId request) {
final var policyRuleId = serializer.deserialize(request);
return policyService.deletePolicy(policyRuleId).onItem().transform(serializer::serialize);
}
@Override
@Counted(name = "policy_getPolicyService_counter")
@Timed(name = "policy_getPolicyService_histogram", unit = MetricUnits.MILLISECONDS)
public Uni<PolicyRuleService> getPolicyService(PolicyRuleId request) {
final var policyRuleBasic = PolicyRuleBasic.newBuilder().setPolicyRuleId(request).build();
return Uni.createFrom()
.item(() -> PolicyRuleService.newBuilder().setPolicyRuleBasic(policyRuleBasic).build());
}
@Override
@Counted(name = "policy_getPolicyDevice_counter")
@Timed(name = "policy_getPolicyDevice_histogram", unit = MetricUnits.MILLISECONDS)
public Uni<PolicyRuleDevice> getPolicyDevice(PolicyRuleId request) {
final var policyRuleBasic = PolicyRuleBasic.newBuilder().setPolicyRuleId(request).build();
return Uni.createFrom()
.item(() -> PolicyRuleDevice.newBuilder().setPolicyRuleBasic(policyRuleBasic).build());
}
@Override
@Counted(name = "policy_getPolicyByServiceId_counter")
@Timed(name = "policy_getPolicyByServiceId_histogram", unit = MetricUnits.MILLISECONDS)
public Uni<PolicyRuleServiceList> getPolicyByServiceId(ServiceId request) {
return Uni.createFrom().item(() -> Policy.PolicyRuleServiceList.newBuilder().build());
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy;
import io.smallrye.mutiny.Uni;
import org.etsi.tfs.policy.policy.model.PolicyRuleDevice;
import org.etsi.tfs.policy.policy.model.PolicyRuleService;
import org.etsi.tfs.policy.policy.model.PolicyRuleState;
public interface PolicyService {
Uni<PolicyRuleState> addPolicyService(PolicyRuleService policyRuleService);
Uni<PolicyRuleState> updatePolicyService(PolicyRuleService policyRuleService);
Uni<PolicyRuleState> addPolicyDevice(PolicyRuleDevice policyRuleDevice);
Uni<PolicyRuleState> updatePolicyDevice(PolicyRuleDevice policyRuleDevice);
Uni<PolicyRuleState> deletePolicy(String policyRuleId);
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy;
import static org.etsi.tfs.policy.common.ApplicationProperties.*;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.groups.UniJoin;
import io.smallrye.mutiny.subscription.Cancellable;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import org.etsi.tfs.policy.context.ContextService;
import org.etsi.tfs.policy.context.model.ConfigActionEnum;
import org.etsi.tfs.policy.context.model.ConfigRule;
import org.etsi.tfs.policy.context.model.ConfigRuleCustom;
import org.etsi.tfs.policy.context.model.ConfigRuleTypeCustom;
import org.etsi.tfs.policy.context.model.Constraint;
import org.etsi.tfs.policy.context.model.ConstraintCustom;
import org.etsi.tfs.policy.context.model.ConstraintTypeCustom;
import org.etsi.tfs.policy.context.model.ServiceConfig;
import org.etsi.tfs.policy.context.model.ServiceId;
import org.etsi.tfs.policy.device.DeviceService;
import org.etsi.tfs.policy.exception.ExternalServiceFailureException;
import org.etsi.tfs.policy.monitoring.MonitoringService;
import org.etsi.tfs.policy.monitoring.model.AlarmDescriptor;
import org.etsi.tfs.policy.monitoring.model.AlarmResponse;
import org.etsi.tfs.policy.monitoring.model.AlarmSubscription;
import org.etsi.tfs.policy.monitoring.model.KpiValueRange;
import org.etsi.tfs.policy.policy.model.BooleanOperator;
import org.etsi.tfs.policy.policy.model.PolicyRule;
import org.etsi.tfs.policy.policy.model.PolicyRuleAction;
import org.etsi.tfs.policy.policy.model.PolicyRuleActionConfig;
import org.etsi.tfs.policy.policy.model.PolicyRuleActionEnum;
import org.etsi.tfs.policy.policy.model.PolicyRuleBasic;
import org.etsi.tfs.policy.policy.model.PolicyRuleCondition;
import org.etsi.tfs.policy.policy.model.PolicyRuleDevice;
import org.etsi.tfs.policy.policy.model.PolicyRuleService;
import org.etsi.tfs.policy.policy.model.PolicyRuleState;
import org.etsi.tfs.policy.policy.model.PolicyRuleStateEnum;
import org.etsi.tfs.policy.policy.model.PolicyRuleTypeDevice;
import org.etsi.tfs.policy.policy.model.PolicyRuleTypeService;
import org.etsi.tfs.policy.policy.service.PolicyRuleConditionFieldsGetter;
import org.etsi.tfs.policy.policy.service.PolicyRuleConditionValidator;
import org.etsi.tfs.policy.service.ServiceService;
import org.jboss.logging.Logger;
@ApplicationScoped
public class PolicyServiceImpl implements PolicyService {
private static final Logger LOGGER = Logger.getLogger(PolicyServiceImpl.class);
private static final int POLICY_EVALUATION_TIMEOUT = 5;
private static final int ACCEPTABLE_NUMBER_OF_ALARMS = 3;
private static final int MONITORING_WINDOW_IN_SECONDS = 5;
private static final int SAMPLING_RATE_PER_SECOND = 1;
// TODO: Find a better way to disregard alarms while reconfiguring path
// Temporary solution for not calling the same rpc more than it's needed
private static int noAlarms = 0;
private final ContextService contextService;
private final MonitoringService monitoringService;
private final ServiceService serviceService;
private final DeviceService deviceService;
private final PolicyRuleConditionValidator policyRuleConditionValidator;
private final PolicyRuleConditionFieldsGetter policyRuleConditionFieldsGetter;
private HashMap<String, PolicyRuleAction> policyRuleActionMap = new HashMap<>();
private ConcurrentHashMap<String, PolicyRuleService> alarmPolicyRuleServiceMap =
new ConcurrentHashMap<>();
private ConcurrentHashMap<String, PolicyRuleDevice> alarmPolicyRuleDeviceMap =
new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Cancellable> subscriptionList = new ConcurrentHashMap<>();
@Inject
public PolicyServiceImpl(
ContextService contextService,
MonitoringService monitoringService,
ServiceService serviceService,
DeviceService deviceService,
PolicyRuleConditionValidator policyRuleConditionValidator,
PolicyRuleConditionFieldsGetter policyRuleConditionFieldsGetter) {
this.contextService = contextService;
this.monitoringService = monitoringService;
this.serviceService = serviceService;
this.deviceService = deviceService;
this.policyRuleConditionValidator = policyRuleConditionValidator;
this.policyRuleConditionFieldsGetter = policyRuleConditionFieldsGetter;
}
private static String gen() {
Random r = new Random(System.currentTimeMillis());
return String.valueOf((1 + r.nextInt(2)) * 10000 + r.nextInt(10000));
}
private static double getTimeStamp() {
long now = Instant.now().getEpochSecond();
return Long.valueOf(now).doubleValue();
}
@Override
public Uni<PolicyRuleState> addPolicyService(PolicyRuleService policyRuleService) {
LOGGER.infof("Received %s", policyRuleService);
if (!policyRuleService.areArgumentsValid()) {
LOGGER.error(policyRuleService.getExceptionMessage());
final var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, policyRuleService.getExceptionMessage());
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleBasic = policyRuleService.getPolicyRuleBasic();
if (!policyRuleBasic.areArgumentsValid()) {
LOGGER.error(policyRuleService.getExceptionMessage());
final var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, policyRuleBasic.getExceptionMessage());
return Uni.createFrom().item(policyRuleState);
}
final var serviceId = policyRuleService.getServiceId();
final var deviceIds = policyRuleService.getDeviceIds();
final var isServiceValid = policyRuleConditionValidator.isServiceIdValid(serviceId, deviceIds);
return isServiceValid
.onFailure()
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transform(
isService ->
constructPolicyStateBasedOnCriteria(
isService, serviceId, policyRuleService, policyRuleBasic))
.flatMap(Function.identity());
}
private Uni<PolicyRuleState> constructPolicyStateBasedOnCriteria(
Boolean isService,
ServiceId serviceId,
PolicyRuleService policyRuleService,
PolicyRuleBasic policyRuleBasic) {
if (!isService) {
var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, String.format(INVALID_MESSAGE, serviceId));
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleTypeService = new PolicyRuleTypeService(policyRuleService);
final var policyRule = new PolicyRule(policyRuleTypeService);
final var alarmDescriptorList = createAlarmDescriptorList(policyRule);
if (alarmDescriptorList.isEmpty()) {
var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED,
String.format(
"Invalid PolicyRuleConditions in PolicyRule with ID: %s",
policyRuleBasic.getPolicyRuleId()));
return Uni.createFrom().item(policyRuleState);
}
return setPolicyRuleOnContextAndReturnState(policyRule, policyRuleService, alarmDescriptorList);
}
private Uni<PolicyRuleState> setPolicyRuleOnContextAndReturnState(
PolicyRule policyRule,
PolicyRuleService policyRuleService,
List<AlarmDescriptor> alarmDescriptorList) {
return contextService
.setPolicyRule(policyRule)
.onFailure()
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transform(
policyId -> {
startMonitoringBasedOnAlarmDescriptors(
policyId, policyRuleService, alarmDescriptorList);
return VALIDATED_POLICYRULE_STATE;
});
}
private void startMonitoringBasedOnAlarmDescriptors(
String policyId,
PolicyRuleService policyRuleService,
List<AlarmDescriptor> alarmDescriptorList) {
setPolicyRuleServiceToContext(policyRuleService, VALIDATED_POLICYRULE_STATE);
noAlarms = 0;
List<Uni<String>> alarmIds =
createAlarmList(alarmDescriptorList); // setAllarmtomonitoring get back alarmid
List<Multi<AlarmResponse>> alarmResponseStreamList =
transformAlarmIds(alarmIds, policyRuleService);
// Merge the promised alarms into one stream (Multi Object)
final var multi = Multi.createBy().merging().streams(alarmResponseStreamList);
setPolicyRuleServiceToContext(policyRuleService, PROVISIONED_POLICYRULE_STATE);
subscriptionList.put(policyId, monitorAlarmResponseForService(multi));
// TODO: Resubscribe to the stream, if it has ended
// TODO: Redesign evaluation of action
// evaluateAction(policyRule, alarmDescriptorList, multi);
}
/**
* Transform the alarmIds into promised alarms returned from the getAlarmResponseStream
*
* @param alarmIds the list of alarm ids
* @param policyRuleService the policy rule service
* @return
*/
private List<Multi<AlarmResponse>> transformAlarmIds(
List<Uni<String>> alarmIds, PolicyRuleService policyRuleService) {
List<Multi<AlarmResponse>> alarmResponseStreamList = new ArrayList<>();
for (Uni<String> alarmId : alarmIds) {
Multi<AlarmResponse> alarmResponseStream =
alarmId.onItem().transformToMulti(id -> setPolicyMonitor(policyRuleService, id));
alarmResponseStreamList.add(alarmResponseStream);
}
return alarmResponseStreamList;
}
private Multi<AlarmResponse> setPolicyMonitor(PolicyRuleService policyRuleService, String id) {
alarmPolicyRuleServiceMap.put(id, policyRuleService);
// TODO: Create infinite subscription
var alarmSubscription = new AlarmSubscription(id, 259200, 5000);
return monitoringService.getAlarmResponseStream(alarmSubscription);
}
/**
* Create an alarmIds list that contains the promised ids returned from setKpiAlarm
*
* @param alarmDescriptorList the list of alarm descriptors
* @return the list of alarm descriptors
*/
public List<Uni<String>> createAlarmList(List<AlarmDescriptor> alarmDescriptorList) {
List<Uni<String>> alarmIds = new ArrayList<Uni<String>>();
for (AlarmDescriptor alarmDescriptor : alarmDescriptorList) {
LOGGER.infof("alarmDescriptor:");
LOGGER.infof(alarmDescriptor.toString());
alarmIds.add(monitoringService.setKpiAlarm(alarmDescriptor));
}
return alarmIds;
}
@Override
public Uni<PolicyRuleState> addPolicyDevice(PolicyRuleDevice policyRuleDevice) {
LOGGER.infof("Received %s", policyRuleDevice);
if (!policyRuleDevice.areArgumentsValid()) {
LOGGER.error(policyRuleDevice.getExceptionMessage());
final var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, policyRuleDevice.getExceptionMessage());
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleBasic = policyRuleDevice.getPolicyRuleBasic();
if (!policyRuleBasic.areArgumentsValid()) {
LOGGER.error(policyRuleDevice.getExceptionMessage());
final var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, policyRuleBasic.getExceptionMessage());
return Uni.createFrom().item(policyRuleState);
}
final var deviceIds = policyRuleDevice.getDeviceIds();
final var areDevicesValid = returnInvalidDeviceIds(deviceIds);
return areDevicesValid
.onFailure()
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transform(areDevices -> areDeviceOnContext(areDevices, policyRuleDevice, policyRuleBasic))
.flatMap(Function.identity());
}
private Uni<PolicyRuleState> areDeviceOnContext(
List<Boolean> areDevices,
PolicyRuleDevice policyRuleDevice,
PolicyRuleBasic policyRuleBasic) {
if (areDevices.contains(false)) {
var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED,
String.format(
INVALID_MESSAGE, policyRuleDevice.getPolicyRuleBasic().getPolicyRuleId()));
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleTypeDevice = new PolicyRuleTypeDevice(policyRuleDevice);
final var policyRule = new PolicyRule(policyRuleTypeDevice);
final var alarmDescriptorList = createAlarmDescriptorList(policyRule);
if (alarmDescriptorList.isEmpty()) {
var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED,
String.format(
"Invalid PolicyRuleConditions in PolicyRule with ID: %s",
policyRuleBasic.getPolicyRuleId()));
return Uni.createFrom().item(policyRuleState);
}
return contextService
.setPolicyRule(policyRule)
.onFailure()
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transform(
policyId -> {
startMonitoringBasedOnAlarmDescriptors(
policyId, policyRuleDevice, alarmDescriptorList);
return VALIDATED_POLICYRULE_STATE;
});
}
private void startMonitoringBasedOnAlarmDescriptors(
String policyId,
PolicyRuleDevice policyRuleDevice,
List<AlarmDescriptor> alarmDescriptorList) {
setPolicyRuleDeviceToContext(policyRuleDevice, VALIDATED_POLICYRULE_STATE);
noAlarms = 0;
List<Uni<String>> alarmIds = getAlarmIds(alarmDescriptorList);
List<Multi<AlarmResponse>> alarmResponseStreamList =
getAlarmResponse(alarmIds, policyRuleDevice);
// Merge the promised alarms into one stream (Multi Object)
final var multi = Multi.createBy().merging().streams(alarmResponseStreamList);
setPolicyRuleDeviceToContext(policyRuleDevice, PROVISIONED_POLICYRULE_STATE);
subscriptionList.put(policyId, monitorAlarmResponseForDevice(multi));
// TODO: Resubscribe to the stream, if it has ended
// TODO: Redesign evaluation of action
// evaluateAction(policyRule, alarmDescriptorList, multi);
}
private List<Multi<AlarmResponse>> getAlarmResponse(
List<Uni<String>> alarmIds, PolicyRuleDevice policyRuleDevice) {
// Transform the alarmIds into promised alarms returned from the
// getAlarmResponseStream
List<Multi<AlarmResponse>> alarmResponseStreamList = new ArrayList<>();
for (Uni<String> alarmId : alarmIds) {
alarmResponseStreamList.add(
alarmId.onItem().transformToMulti(id -> setPolicyMonitoringDevice(policyRuleDevice, id)));
}
return alarmResponseStreamList;
}
private Multi<AlarmResponse> setPolicyMonitoringDevice(
PolicyRuleDevice policyRuleDevice, String id) {
alarmPolicyRuleDeviceMap.put(id, policyRuleDevice);
// TODO: Create infinite subscription
var alarmSubscription = new AlarmSubscription(id, 259200, 5000);
return monitoringService.getAlarmResponseStream(alarmSubscription);
}
private List<Uni<String>> getAlarmIds(List<AlarmDescriptor> alarmDescriptorList) {
List<Uni<String>> alarmIds = new ArrayList<Uni<String>>();
for (AlarmDescriptor alarmDescriptor : alarmDescriptorList) {
LOGGER.infof("alarmDescriptor:");
LOGGER.infof(alarmDescriptor.toString());
alarmIds.add(monitoringService.setKpiAlarm(alarmDescriptor));
}
return alarmIds;
}
@Override
public Uni<PolicyRuleState> updatePolicyService(PolicyRuleService policyRuleService) {
LOGGER.infof("Received %s", policyRuleService);
if (!policyRuleService.areArgumentsValid()) {
LOGGER.error(policyRuleService.getExceptionMessage());
final var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, policyRuleService.getExceptionMessage());
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleBasic = policyRuleService.getPolicyRuleBasic();
if (!policyRuleBasic.areArgumentsValid()) {
LOGGER.error(policyRuleService.getExceptionMessage());
final var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, policyRuleBasic.getExceptionMessage());
return Uni.createFrom().item(policyRuleState);
}
final var serviceId = policyRuleService.getServiceId();
final var policyRuleId = policyRuleBasic.getPolicyRuleId();
final var isPolicyRuleServiceValid =
policyRuleConditionValidator.isPolicyRuleServiceValid(policyRuleId, serviceId);
return isPolicyRuleServiceValid
.onFailure()
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transform(
isPolicyRuleService -> {
if (!isPolicyRuleService) {
return new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, String.format(INVALID_MESSAGE, serviceId));
}
return VALIDATED_POLICYRULE_STATE;
});
}
@Override
public Uni<PolicyRuleState> updatePolicyDevice(PolicyRuleDevice policyRuleDevice) {
LOGGER.infof("Received %s", policyRuleDevice);
if (!policyRuleDevice.areArgumentsValid()) {
LOGGER.error(policyRuleDevice.getExceptionMessage());
final var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, policyRuleDevice.getExceptionMessage());
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleBasic = policyRuleDevice.getPolicyRuleBasic();
if (!policyRuleBasic.areArgumentsValid()) {
final var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, policyRuleBasic.getExceptionMessage());
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleId = policyRuleBasic.getPolicyRuleId();
final var isPolicyRuleValid =
policyRuleConditionValidator.isUpdatedPolicyRuleIdValid(policyRuleId);
return isPolicyRuleValid
.onItem()
.transform(
isPolicyRuleService -> {
if (!isPolicyRuleService) {
return new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED,
String.format(INVALID_MESSAGE, policyRuleId));
}
return VALIDATED_POLICYRULE_STATE;
});
}
@Override
public Uni<PolicyRuleState> deletePolicy(String policyRuleId) {
LOGGER.infof("Received %s", policyRuleId);
final var getPolicyRule = contextService.getPolicyRule(policyRuleId);
return getPolicyRule.onItem().transform(policyRule -> removePolicyFromContext(policyRule));
}
private PolicyRuleState removePolicyFromContext(PolicyRule policyRule) {
var policyRuleBasic = policyRule.getPolicyRuleType().getPolicyRuleBasic();
String policyId = policyRuleBasic.getPolicyRuleId();
policyRule
.getPolicyRuleType()
.getPolicyRuleBasic()
.setPolicyRuleState(REMOVED_POLICYRULE_STATE);
contextService
.setPolicyRule(policyRule)
.subscribe()
.with(
tmp ->
LOGGER.infof(
"DeletePolicy with id: " + VALID_MESSAGE, policyRuleBasic.getPolicyRuleId()));
contextService.removePolicyRule(policyId).subscribe().with(x -> {});
// TODO: When the Map doesn't contains the policyId we should throw an exception?
if (subscriptionList.contains(policyId)) subscriptionList.get(policyId).cancel();
return policyRuleBasic.getPolicyRuleState();
}
private Uni<List<Boolean>> returnInvalidDeviceIds(List<String> deviceIds) {
UniJoin.Builder<Boolean> builder = Uni.join().builder();
for (String deviceId : deviceIds) {
final var validatedDeviceId = policyRuleConditionValidator.isDeviceIdValid(deviceId);
builder.add(validatedDeviceId);
}
return builder.joinAll().andFailFast();
}
private List<AlarmDescriptor> createAlarmDescriptorList(PolicyRule policyRule) {
final var policyRuleType = policyRule.getPolicyRuleType();
final var policyRuleTypeSpecificType = policyRuleType.getPolicyRuleType();
List<AlarmDescriptor> alarmDescriptorList = new ArrayList<>();
if (policyRuleTypeSpecificType instanceof PolicyRuleService) {
final var policyRuleService = (PolicyRuleService) policyRuleTypeSpecificType;
final var policyRuleBasic = policyRuleService.getPolicyRuleBasic();
alarmDescriptorList = parsePolicyRuleCondition(policyRuleBasic);
if (alarmDescriptorList.isEmpty()) {
return List.of();
}
} else {
final var policyRuleDevice = (PolicyRuleDevice) policyRuleTypeSpecificType;
final var policyRuleBasic = policyRuleDevice.getPolicyRuleBasic();
alarmDescriptorList = parsePolicyRuleCondition(policyRuleBasic);
if (alarmDescriptorList.isEmpty()) {
return List.of();
}
for (AlarmDescriptor alarmDescriptor : alarmDescriptorList) {
alarmPolicyRuleDeviceMap.put(alarmDescriptor.getAlarmId(), policyRuleDevice);
}
}
return alarmDescriptorList;
}
private Cancellable monitorAlarmResponseForService(Multi<AlarmResponse> multi) {
return multi
.subscribe()
.with(
alarmResponse -> {
LOGGER.infof("**************************Received Alarm!**************************");
LOGGER.infof("alarmResponse:");
LOGGER.info(alarmResponse);
LOGGER.info(alarmResponse.getAlarmId());
applyActionService(alarmResponse.getAlarmId());
});
}
private Cancellable monitorAlarmResponseForDevice(Multi<AlarmResponse> multi) {
return multi
.subscribe()
.with(
alarmResponse -> {
LOGGER.infof("**************************Received Alarm!**************************");
LOGGER.infof("alarmResponse:");
LOGGER.info(alarmResponse);
LOGGER.info(alarmResponse.getAlarmId());
applyActionDevice(alarmResponse.getAlarmId());
});
}
// TODO: To be refactored or deprecated
// private void evaluateAction(
// PolicyRule policyRule,
// List<AlarmDescriptor> alarmDescriptorList,
// Multi<AlarmResponse> multi) {
//
// Long count =
// multi
// .collect()
// .with(Collectors.counting())
// .await()
// .atMost(Duration.ofMinutes(POLICY_EVALUATION_TIMEOUT));
//
// if (count > ACCEPTABLE_NUMBER_OF_ALARMS) {
// for (AlarmDescriptor alarmDescriptor : alarmDescriptorList) {
// monitoringService
// .deleteAlarm(alarmDescriptor.getAlarmId())
// .subscribe()
// .with(
// emptyMessage ->
// LOGGER.infof(
// "Alarm [%s] has been deleted as ineffective.\n",
// alarmDescriptor.getAlarmId()));
// }
// setPolicyRuleToContext(policyRule, INEFFECTIVE_POLICYRULE_STATE);
// } else {
// setPolicyRuleToContext(policyRule, EFFECTIVE_POLICYRULE_STATE);
// }
// }
private void applyActionDevice(String alarmId) {
PolicyRuleDevice policyRuleDevice = alarmPolicyRuleDeviceMap.get(alarmId);
if (policyRuleActionMap.get(alarmId).getPolicyRuleActionEnum()
== PolicyRuleActionEnum.POLICY_RULE_ACTION_SET_DEVICE_STATUS) {
// In case additional PolicyRuleAction for Devices will be added
}
setPolicyRuleDeviceToContext(policyRuleDevice, ACTIVE_POLICYRULE_STATE);
List<String> deviceIds = policyRuleDevice.getDeviceIds();
List<PolicyRuleActionConfig> actionConfigs =
policyRuleActionMap.get(alarmId).getPolicyRuleActionConfigs();
if (deviceIds.size() != actionConfigs.size()) {
String message =
String.format(
"The number of action parameters in PolicyRuleDevice with ID: %s, is not aligned with the number of devices.",
policyRuleDevice.getPolicyRuleBasic().getPolicyRuleId());
setPolicyRuleDeviceToContext(
policyRuleDevice, new PolicyRuleState(PolicyRuleStateEnum.POLICY_FAILED, message));
return;
}
for (var i = 0; i < deviceIds.size(); i++) {
activateDevice(deviceIds.get(i), actionConfigs.get(i));
}
setPolicyRuleDeviceToContext(policyRuleDevice, ENFORCED_POLICYRULE_STATE);
}
private void activateDevice(String deviceId, PolicyRuleActionConfig actionConfig) {
Boolean toBeEnabled;
if (actionConfig.getActionKey() == "ENABLED") {
toBeEnabled = true;
} else if (actionConfig.getActionKey() == "DISABLED") {
toBeEnabled = false;
} else {
LOGGER.errorf(INVALID_MESSAGE, actionConfig.getActionKey());
return;
}
final var deserializedDeviceUni = contextService.getDevice(deviceId);
deserializedDeviceUni
.subscribe()
.with(
device -> {
if (toBeEnabled && device.isDisabled()) {
device.enableDevice();
} else if (!toBeEnabled && device.isEnabled()) {
device.disableDevice();
} else {
LOGGER.errorf(INVALID_MESSAGE, "Device is already in the desired state");
return;
}
deviceService.configureDevice(device);
});
}
private void addServiceConfigRule(
PolicyRuleService policyRuleService, PolicyRuleAction policyRuleAction) {
ConfigActionEnum configActionEnum = ConfigActionEnum.SET;
List<PolicyRuleActionConfig> actionConfigs = policyRuleAction.getPolicyRuleActionConfigs();
List<ConfigRule> newConfigRules = new ArrayList<>();
for (PolicyRuleActionConfig actionConfig : actionConfigs) {
ConfigRuleCustom configRuleCustom =
new ConfigRuleCustom(actionConfig.getActionKey(), actionConfig.getActionValue());
ConfigRuleTypeCustom configRuleType = new ConfigRuleTypeCustom(configRuleCustom);
ConfigRule configRule = new ConfigRule(configActionEnum, configRuleType);
newConfigRules.add(configRule);
}
var deserializedServiceUni = contextService.getService(policyRuleService.getServiceId());
deserializedServiceUni
.subscribe()
.with(
deserializedService -> {
List<ConfigRule> configRules =
deserializedService.getServiceConfig().getConfigRules();
configRules.addAll(newConfigRules);
deserializedService.setServiceConfig(new ServiceConfig(configRules));
});
}
private void addServiceConstraint(
PolicyRuleService policyRuleService, PolicyRuleAction policyRuleAction) {
List<PolicyRuleActionConfig> actionConfigs = policyRuleAction.getPolicyRuleActionConfigs();
List<Constraint> constraintList = new ArrayList<>();
for (PolicyRuleActionConfig actionConfig : actionConfigs) {
var constraintCustom =
new ConstraintCustom(actionConfig.getActionKey(), actionConfig.getActionValue());
var constraintTypeCustom = new ConstraintTypeCustom(constraintCustom);
constraintList.add(new Constraint(constraintTypeCustom));
}
final var deserializedServiceUni = contextService.getService(policyRuleService.getServiceId());
deserializedServiceUni
.subscribe()
.with(
deserializedService -> {
deserializedService.appendServiceConstraints(constraintList);
serviceService.updateService(deserializedService);
setPolicyRuleServiceToContext(policyRuleService, ENFORCED_POLICYRULE_STATE);
});
}
private void callRecalculatePathRPC(
PolicyRuleService policyRuleService, PolicyRuleAction policyRuleAction) {
final var deserializedServiceUni = contextService.getService(policyRuleService.getServiceId());
deserializedServiceUni
.subscribe()
.with(
deserializedService -> {
serviceService
.recomputeConnections(deserializedService)
.subscribe()
.with(
x -> {
LOGGER.info("called recomputeConnections with:");
LOGGER.info(deserializedService);
setPolicyRuleServiceToContext(policyRuleService, ENFORCED_POLICYRULE_STATE);
});
});
}
private void applyActionService(String alarmId) {
PolicyRuleService policyRuleService = alarmPolicyRuleServiceMap.get(alarmId);
PolicyRuleAction policyRuleAction =
policyRuleService.getPolicyRuleBasic().getPolicyRuleActions().get(0);
if (noAlarms == 0) {
noAlarms++;
setPolicyRuleServiceToContext(policyRuleService, ACTIVE_POLICYRULE_STATE);
switch (policyRuleAction.getPolicyRuleActionEnum()) {
case POLICY_RULE_ACTION_ADD_SERVICE_CONSTRAINT:
addServiceConstraint(policyRuleService, policyRuleAction);
case POLICY_RULE_ACTION_ADD_SERVICE_CONFIGRULE:
addServiceConfigRule(policyRuleService, policyRuleAction);
case POLICY_RULE_ACTION_RECALCULATE_PATH:
callRecalculatePathRPC(policyRuleService, policyRuleAction);
default:
LOGGER.errorf(INVALID_MESSAGE, policyRuleAction.getPolicyRuleActionEnum());
return;
}
} else if (noAlarms == 2) {
noAlarms = 0;
} else {
noAlarms++;
}
}
private List<AlarmDescriptor> parsePolicyRuleCondition(PolicyRuleBasic policyRuleBasic) {
BooleanOperator booleanOperator = policyRuleBasic.getBooleanOperator();
if (booleanOperator == BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_OR) {
return parsePolicyRuleConditionOr(policyRuleBasic);
}
if (booleanOperator == BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_AND) {
return Arrays.asList(parsePolicyRuleConditionAnd(policyRuleBasic));
}
return List.of();
}
private List<AlarmDescriptor> parsePolicyRuleConditionOr(PolicyRuleBasic policyRuleBasic) {
List<PolicyRuleCondition> policyRuleConditions = policyRuleBasic.getPolicyRuleConditions();
List<AlarmDescriptor> alarmDescriptorList = new ArrayList<>();
for (PolicyRuleCondition policyRuleCondition : policyRuleConditions) {
var kpiValueRange = convertPolicyRuleConditionToKpiValueRange(policyRuleCondition);
// TODO: Temp fix for AlarmDescriptor object
AlarmDescriptor alarmDescriptor =
new AlarmDescriptor(
"",
"alarmDescription",
"alarmName-" + gen(),
policyRuleCondition.getKpiId(),
kpiValueRange,
getTimeStamp());
alarmDescriptorList.add(alarmDescriptor);
}
HashMap<String, PolicyRuleAction> policyRuleActionMap = new HashMap<>();
List<PolicyRuleAction> policyRuleActions = policyRuleBasic.getPolicyRuleActions();
for (int i = 0; i < policyRuleActions.size(); i++) {
policyRuleActionMap.put(alarmDescriptorList.get(i).getAlarmId(), policyRuleActions.get(i));
}
return alarmDescriptorList;
}
private AlarmDescriptor parsePolicyRuleConditionAnd(PolicyRuleBasic policyRuleBasic) {
// TODO: KpiIds should be the same. Add check.
List<PolicyRuleCondition> policyRuleConditionList = policyRuleBasic.getPolicyRuleConditions();
List<String> kpisList = new ArrayList<String>();
for (PolicyRuleCondition policyRuleCondition : policyRuleConditionList) {
kpisList.add(policyRuleCondition.getKpiId());
}
if (policyRuleConditionList.size() > 1) {
return createAlarmDescriptorWithRange(policyRuleConditionList);
}
return createAlarmDescriptorWithoutRange(policyRuleConditionList.get(0));
}
private AlarmDescriptor createAlarmDescriptorWithoutRange(
PolicyRuleCondition policyRuleCondition) {
final var kpiId = policyRuleCondition.getKpiId();
final var kpiValueRange = convertPolicyRuleConditionToKpiValueRange(policyRuleCondition);
return new AlarmDescriptor(
"", "alarmDescription", "alarmName-" + gen(), kpiId, kpiValueRange, getTimeStamp());
}
private AlarmDescriptor createAlarmDescriptorWithRange(
List<PolicyRuleCondition> policyRuleConditionList) {
final var kpiId = policyRuleConditionList.get(0).getKpiId();
HashMap<String, KpiValueRange> KpiValueRangeMap = new HashMap<>();
for (PolicyRuleCondition policyRuleCondition : policyRuleConditionList) {
if (!KpiValueRangeMap.containsKey(kpiId)) {
var kpiValueRange = convertPolicyRuleConditionToKpiValueRange(policyRuleCondition);
KpiValueRangeMap.put(kpiId, kpiValueRange);
continue;
}
var kpiValueRange = convertPolicyRuleConditionToKpiValueRange(policyRuleCondition);
// TODO: Handle combineKpiValueRanges exceptions
var combinedKpiValueRange =
combineKpiValueRanges(kpiId, KpiValueRangeMap.get(kpiId), kpiValueRange);
KpiValueRangeMap.put(kpiId, combinedKpiValueRange);
}
return new AlarmDescriptor(
"",
"alarmDescription",
"alarmName-" + gen(),
kpiId,
KpiValueRangeMap.get(kpiId),
getTimeStamp());
}
private KpiValueRange convertPolicyRuleConditionToKpiValueRange(
PolicyRuleCondition policyRuleCondition) {
switch (policyRuleCondition.getNumericalOperator()) {
case POLICY_RULE_CONDITION_NUMERICAL_EQUAL:
return new KpiValueRange(
policyRuleCondition.getKpiValue(), policyRuleCondition.getKpiValue(), true, true, true);
case POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL:
return new KpiValueRange(
policyRuleCondition.getKpiValue(),
policyRuleCondition.getKpiValue(),
true,
false,
false);
case POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN:
return new KpiValueRange(null, policyRuleCondition.getKpiValue(), true, false, false);
case POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL:
return new KpiValueRange(null, policyRuleCondition.getKpiValue(), true, true, false);
case POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN:
return new KpiValueRange(policyRuleCondition.getKpiValue(), null, true, false, false);
case POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL:
return new KpiValueRange(policyRuleCondition.getKpiValue(), null, true, false, true);
default:
return null;
}
}
private KpiValueRange combineKpiValueRanges(
String kpiId, KpiValueRange firstKpiValueRange, KpiValueRange secondKpiValueRange) {
if (secondKpiValueRange.getInRange() == true) {
LOGGER.errorf("KpiId: %s, has already range values", kpiId);
return null;
}
if ((firstKpiValueRange.getKpiMinValue() != null)
&& (secondKpiValueRange.getKpiMinValue() != null)) {
LOGGER.errorf("KpiId: %s, has already min value", kpiId);
return null;
}
if ((firstKpiValueRange.getKpiMaxValue() != null)
&& (secondKpiValueRange.getKpiMinValue() != null)) {
LOGGER.errorf("KpiId: %s, has already max value", kpiId);
return null;
}
// Objects.nonNull(secondKpiValueRange);
var kpiMinValue =
firstKpiValueRange.getKpiMinValue() != null
? firstKpiValueRange.getKpiMinValue()
: secondKpiValueRange.getKpiMinValue();
var kpiMaxValue =
firstKpiValueRange.getKpiMaxValue() != null
? firstKpiValueRange.getKpiMaxValue()
: secondKpiValueRange.getKpiMaxValue();
boolean includeMinValue =
firstKpiValueRange.getIncludeMinValue() || secondKpiValueRange.getIncludeMinValue();
boolean includeMaxValue =
firstKpiValueRange.getIncludeMaxValue() || secondKpiValueRange.getIncludeMaxValue();
return new KpiValueRange(kpiMinValue, kpiMaxValue, true, includeMinValue, includeMaxValue);
}
private void setPolicyRuleToContext(PolicyRule policyRule, PolicyRuleState policyRuleState) {
final var policyRuleType = policyRule.getPolicyRuleType();
final var policyRuleTypeSpecificType = policyRuleType.getPolicyRuleType();
if (policyRuleTypeSpecificType instanceof PolicyRuleService) {
setPolicyRuleServiceToContext(
(PolicyRuleService) policyRuleTypeSpecificType, policyRuleState);
}
if (policyRuleTypeSpecificType instanceof PolicyRuleDevice) {
setPolicyRuleDeviceToContext((PolicyRuleDevice) policyRuleTypeSpecificType, policyRuleState);
}
}
private void setPolicyRuleServiceToContext(
PolicyRuleService policyRuleService, PolicyRuleState policyRuleState) {
LOGGER.infof("Setting Policy Rule state to [%s]", policyRuleState.toString());
final var policyRuleBasic = policyRuleService.getPolicyRuleBasic();
policyRuleBasic.setPolicyRuleState(policyRuleState);
policyRuleService.setPolicyRuleBasic(policyRuleBasic);
final var policyRuleTypeService = new PolicyRuleTypeService(policyRuleService);
final var policyRule = new PolicyRule(policyRuleTypeService);
contextService.setPolicyRule(policyRule).subscribe().with(x -> {});
}
private void setPolicyRuleDeviceToContext(
PolicyRuleDevice policyRuleDevice, PolicyRuleState policyRuleState) {
LOGGER.infof("Setting Policy Rule state to [%s]", policyRuleState.toString());
final var policyRuleBasic = policyRuleDevice.getPolicyRuleBasic();
policyRuleBasic.setPolicyRuleState(policyRuleState);
policyRuleDevice.setPolicyRuleBasic(policyRuleBasic);
final var policyRuleTypeService = new PolicyRuleTypeDevice(policyRuleDevice);
final var policyRule = new PolicyRule(policyRuleTypeService);
contextService.setPolicyRule(policyRule).subscribe().with(x -> {});
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy.model;
public enum BooleanOperator {
POLICYRULE_CONDITION_BOOLEAN_UNDEFINED,
POLICYRULE_CONDITION_BOOLEAN_AND,
POLICYRULE_CONDITION_BOOLEAN_OR
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy.model;
public enum NumericalOperator {
POLICY_RULE_CONDITION_NUMERICAL_UNDEFINED,
POLICY_RULE_CONDITION_NUMERICAL_EQUAL,
POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL,
POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN,
POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL,
POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN,
POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy.model;
public class PolicyRule {
private final PolicyRuleType<?> policyRuleType;
public PolicyRule(PolicyRuleType<?> policyRuleType) {
this.policyRuleType = policyRuleType;
}
public PolicyRuleType getPolicyRuleType() {
return policyRuleType;
}
@Override
public String toString() {
return String.format(
"%s:{configActionEnum:\"%s\", %s}", getClass().getSimpleName(), policyRuleType);
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy.model;
import java.util.List;
import java.util.stream.Collectors;
public class PolicyRuleAction {
private final PolicyRuleActionEnum policyRuleActionEnum;
private final List<PolicyRuleActionConfig> policyRuleActionConfigs;
public PolicyRuleAction(
PolicyRuleActionEnum policyRuleActionEnum,
List<PolicyRuleActionConfig> policyRuleActionConfigs) {
this.policyRuleActionEnum = policyRuleActionEnum;
this.policyRuleActionConfigs = policyRuleActionConfigs;
}
public PolicyRuleActionEnum getPolicyRuleActionEnum() {
return policyRuleActionEnum;
}
public List<PolicyRuleActionConfig> getPolicyRuleActionConfigs() {
return policyRuleActionConfigs;
}
@Override
public String toString() {
return String.format(
"%s:{policyRuleActionEnum:\"%s\", [%s]}",
getClass().getSimpleName(),
policyRuleActionEnum.toString(),
toString(policyRuleActionConfigs));
}
private <T> String toString(List<T> list) {
return list.stream().map(T::toString).collect(Collectors.joining(", "));
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy.model;
public class PolicyRuleActionConfig {
private final String actionKey;
private final String actionValue;
public PolicyRuleActionConfig(String actionKey, String actionValue) {
this.actionKey = actionKey;
this.actionValue = actionValue;
}
public String getActionKey() {
return actionKey;
}
public String getActionValue() {
return actionValue;
}
@Override
public String toString() {
return String.format(
"%s:{resourceKey:\"%s\", resourceValue:\"%s\"}",
getClass().getSimpleName(), actionKey, actionValue);
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* 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.etsi.tfs.policy.policy.model;
public enum PolicyRuleActionEnum {
POLICY_RULE_ACTION_NO_ACTION,
POLICY_RULE_ACTION_SET_DEVICE_STATUS,
POLICY_RULE_ACTION_ADD_SERVICE_CONFIGRULE,
POLICY_RULE_ACTION_ADD_SERVICE_CONSTRAINT,
POLICY_RULE_ACTION_CALL_SERVICE_RPC,
// This is temporary
POLICY_RULE_ACTION_RECALCULATE_PATH
}