diff --git a/src/policy/src/main/java/org/etsi/tfs/policy/policy/AddPolicyDeviceImpl.java b/src/policy/src/main/java/org/etsi/tfs/policy/policy/AddPolicyDeviceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..1d6302a28f5a0e869769c2ce0fcb80404b838ea5 --- /dev/null +++ b/src/policy/src/main/java/org/etsi/tfs/policy/policy/AddPolicyDeviceImpl.java @@ -0,0 +1,80 @@ +package org.etsi.tfs.policy.policy; + +import static org.etsi.tfs.policy.common.ApplicationProperties.INVALID_MESSAGE; +import static org.etsi.tfs.policy.common.ApplicationProperties.VALIDATED_POLICYRULE_STATE; + +import io.smallrye.mutiny.Uni; +import io.smallrye.mutiny.groups.UniJoin; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.util.List; +import org.etsi.tfs.policy.context.ContextService; +import org.etsi.tfs.policy.exception.ExternalServiceFailureException; +import org.etsi.tfs.policy.policy.model.PolicyRule; +import org.etsi.tfs.policy.policy.model.PolicyRuleBasic; +import org.etsi.tfs.policy.policy.model.PolicyRuleDevice; +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.service.PolicyRuleConditionValidator; + +@ApplicationScoped +public class AddPolicyDeviceImpl { + + @Inject private PolicyRuleConditionValidator policyRuleConditionValidator; + + @Inject private CommonPolicyServiceImpl commonPolicyServiceImpl; + @Inject private CommonAlarmService commonAlarmService; + + @Inject private ContextService contextService; + + public 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(); + } + + public 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 = commonPolicyServiceImpl.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 -> { + commonAlarmService.startMonitoringBasedOnAlarmDescriptors( + policyId, policyRuleDevice, alarmDescriptorList); + return VALIDATED_POLICYRULE_STATE; + }); + } +} diff --git a/src/policy/src/main/java/org/etsi/tfs/policy/policy/AddPolicyServiceImpl.java b/src/policy/src/main/java/org/etsi/tfs/policy/policy/AddPolicyServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..9784841305bbc82395e5262fcebbb100330157a3 --- /dev/null +++ b/src/policy/src/main/java/org/etsi/tfs/policy/policy/AddPolicyServiceImpl.java @@ -0,0 +1,78 @@ +package org.etsi.tfs.policy.policy; + +import static org.etsi.tfs.policy.common.ApplicationProperties.INVALID_MESSAGE; +import static org.etsi.tfs.policy.common.ApplicationProperties.VALIDATED_POLICYRULE_STATE; + +import io.smallrye.mutiny.Uni; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.util.List; +import org.etsi.tfs.policy.context.ContextService; +import org.etsi.tfs.policy.context.model.ServiceId; +import org.etsi.tfs.policy.exception.NewException; +import org.etsi.tfs.policy.monitoring.model.AlarmDescriptor; +import org.etsi.tfs.policy.policy.model.PolicyRule; +import org.etsi.tfs.policy.policy.model.PolicyRuleBasic; +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.PolicyRuleTypeService; +import org.jboss.logging.Logger; + +@ApplicationScoped +public class AddPolicyServiceImpl { + private static final Logger LOGGER = Logger.getLogger(AddPolicyServiceImpl.class); + + @Inject private CommonPolicyServiceImpl commonPolicyService; + @Inject private CommonAlarmService commonAlarmService; + @Inject private ContextService contextService; + + public 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 = commonPolicyService.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 NewException(failure.getMessage())) + .onItem() + .transform( + policyId -> { + commonAlarmService.startMonitoringBasedOnAlarmDescriptors( + policyId, policyRuleService, alarmDescriptorList); + + return VALIDATED_POLICYRULE_STATE; + }); + } +} diff --git a/src/policy/src/main/java/org/etsi/tfs/policy/policy/CommonAlarmService.java b/src/policy/src/main/java/org/etsi/tfs/policy/policy/CommonAlarmService.java new file mode 100644 index 0000000000000000000000000000000000000000..a5bb7df216bdd5b005972341b84b0d3bb34a6cd5 --- /dev/null +++ b/src/policy/src/main/java/org/etsi/tfs/policy/policy/CommonAlarmService.java @@ -0,0 +1,173 @@ +package org.etsi.tfs.policy.policy; + +import static org.etsi.tfs.policy.common.ApplicationProperties.PROVISIONED_POLICYRULE_STATE; +import static org.etsi.tfs.policy.common.ApplicationProperties.VALIDATED_POLICYRULE_STATE; + +import io.smallrye.mutiny.Multi; +import io.smallrye.mutiny.Uni; +import io.smallrye.mutiny.subscription.Cancellable; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.util.ArrayList; +import java.util.List; +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.policy.model.PolicyRuleDevice; +import org.etsi.tfs.policy.policy.model.PolicyRuleService; +import org.jboss.logging.Logger; + +@ApplicationScoped +public class CommonAlarmService { + private static final Logger LOGGER = Logger.getLogger(CommonAlarmService.class); + + @Inject private CommonPolicyServiceImpl commonPolicyServiceImpl; + @Inject private MonitoringService monitoringService; + + public void startMonitoringBasedOnAlarmDescriptors( + String policyId, + PolicyRuleDevice policyRuleDevice, + List<AlarmDescriptor> alarmDescriptorList) { + commonPolicyServiceImpl.setPolicyRuleDeviceToContext( + policyRuleDevice, VALIDATED_POLICYRULE_STATE); + commonPolicyServiceImpl.noAlarms = 0; + + List<Uni<String>> alarmIds = createAlarmList(alarmDescriptorList); + + List<Multi<AlarmResponse>> alarmResponseStreamList = + transformAlarmIds(alarmIds, policyRuleDevice); + + // Merge the promised alarms into one stream (Multi Object) + final var multi = Multi.createBy().merging().streams(alarmResponseStreamList); + commonPolicyServiceImpl.setPolicyRuleDeviceToContext( + policyRuleDevice, PROVISIONED_POLICYRULE_STATE); + + commonPolicyServiceImpl + .getSubscriptionList() + .put(policyId, monitorAlarmResponseForDevice(multi)); + + // TODO: Resubscribe to the stream, if it has ended + + // TODO: Redesign evaluation of action + // evaluateAction(policyRule, alarmDescriptorList, multi); + } + + public void startMonitoringBasedOnAlarmDescriptors( + String policyId, + PolicyRuleService policyRuleService, + List<AlarmDescriptor> alarmDescriptorList) { + commonPolicyServiceImpl.setPolicyRuleServiceToContext( + policyRuleService, VALIDATED_POLICYRULE_STATE); + commonPolicyServiceImpl.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); + commonPolicyServiceImpl.setPolicyRuleServiceToContext( + policyRuleService, PROVISIONED_POLICYRULE_STATE); + + commonPolicyServiceImpl + .getSubscriptionList() + .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 List<Multi<AlarmResponse>> transformAlarmIds( + 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 -> setPolicyMonitor(policyRuleDevice, id))); + } + return alarmResponseStreamList; + } + + private Multi<AlarmResponse> setPolicyMonitor(PolicyRuleService policyRuleService, String id) { + commonPolicyServiceImpl.getAlarmPolicyRuleServiceMap().put(id, policyRuleService); + + // TODO: Create infinite subscription + var alarmSubscription = new AlarmSubscription(id, 259200, 5000); + return monitoringService.getAlarmResponseStream(alarmSubscription); + } + + private Multi<AlarmResponse> setPolicyMonitor(PolicyRuleDevice policyRuleDevice, String id) { + commonPolicyServiceImpl.getAlarmPolicyRuleDeviceMap().put(id, policyRuleDevice); + + // 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; + } + + 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()); + commonPolicyServiceImpl.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()); + commonPolicyServiceImpl.applyActionDevice(alarmResponse.getAlarmId()); + }); + } +} diff --git a/src/policy/src/main/java/org/etsi/tfs/policy/policy/CommonPolicyServiceImpl.java b/src/policy/src/main/java/org/etsi/tfs/policy/policy/CommonPolicyServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..263619f812b8a57c4761d42c6eac4a1edaf820f0 --- /dev/null +++ b/src/policy/src/main/java/org/etsi/tfs/policy/policy/CommonPolicyServiceImpl.java @@ -0,0 +1,525 @@ +package org.etsi.tfs.policy.policy; + +import static org.etsi.tfs.policy.common.ApplicationProperties.ACTIVE_POLICYRULE_STATE; +import static org.etsi.tfs.policy.common.ApplicationProperties.ENFORCED_POLICYRULE_STATE; +import static org.etsi.tfs.policy.common.ApplicationProperties.INVALID_MESSAGE; + +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 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.device.DeviceService; +import org.etsi.tfs.policy.monitoring.MonitoringService; +import org.etsi.tfs.policy.monitoring.model.AlarmDescriptor; +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.service.ServiceService; +import org.jboss.logging.Logger; + +@ApplicationScoped +public class CommonPolicyServiceImpl { + + private static final Logger LOGGER = Logger.getLogger(CommonPolicyServiceImpl.class); + + @Inject private MonitoringService monitoringService; + @Inject private ContextService contextService; + @Inject private ServiceService serviceService; + @Inject private DeviceService deviceService; + + 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 + public static int noAlarms = 0; + + private ConcurrentHashMap<String, PolicyRuleService> alarmPolicyRuleServiceMap = + new ConcurrentHashMap<>(); + private ConcurrentHashMap<String, PolicyRuleDevice> alarmPolicyRuleDeviceMap = + new ConcurrentHashMap<>(); + private ConcurrentHashMap<String, Cancellable> subscriptionList = new ConcurrentHashMap<>(); + private HashMap<String, PolicyRuleAction> policyRuleActionMap = new HashMap<>(); + + public ConcurrentHashMap<String, Cancellable> getSubscriptionList() { + return subscriptionList; + } + + public ConcurrentHashMap<String, PolicyRuleService> getAlarmPolicyRuleServiceMap() { + return alarmPolicyRuleServiceMap; + } + + public ConcurrentHashMap<String, PolicyRuleDevice> getAlarmPolicyRuleDeviceMap() { + return alarmPolicyRuleDeviceMap; + } + + public HashMap<String, PolicyRuleAction> getPolicyRuleActionMap() { + return policyRuleActionMap; + } + + 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(); + } + + public 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++; + } + } + + public 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 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 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 AlarmDescriptor createAlarmDescriptorWithoutRange( + PolicyRuleCondition policyRuleCondition) { + + final var kpiId = policyRuleCondition.getKpiId(); + final var kpiValueRange = convertPolicyRuleConditionToKpiValueRange(policyRuleCondition); + + return new AlarmDescriptor( + "", "alarmDescription", "alarmName-" + gen(), kpiId, kpiValueRange, getTimeStamp()); + } + + // 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); + // } + // } + + public 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 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); + } + } + + public 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 -> {}); + } + + public 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 -> {}); + } +} diff --git a/src/policy/src/main/java/org/etsi/tfs/policy/policy/DeletePolicyImpl.java b/src/policy/src/main/java/org/etsi/tfs/policy/policy/DeletePolicyImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..d78d00b8340fdaf09076aa06a86428af33109c5d --- /dev/null +++ b/src/policy/src/main/java/org/etsi/tfs/policy/policy/DeletePolicyImpl.java @@ -0,0 +1,3 @@ +package org.etsi.tfs.policy.policy; + +public class DeletePolicyImpl {} diff --git a/src/policy/src/main/java/org/etsi/tfs/policy/policy/PolicyServiceImpl.java b/src/policy/src/main/java/org/etsi/tfs/policy/policy/PolicyServiceImpl.java index 984276f59100d59a538f920d709fb3a0120c2afb..8a3a86508612be54c860f88159af512e7564c33f 100644 --- a/src/policy/src/main/java/org/etsi/tfs/policy/policy/PolicyServiceImpl.java +++ b/src/policy/src/main/java/org/etsi/tfs/policy/policy/PolicyServiceImpl.java @@ -18,54 +18,18 @@ 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.exception.NewException; -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 @@ -73,52 +37,24 @@ 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<>(); + private final CommonPolicyServiceImpl commonPolicyServiceImpl; + private final AddPolicyServiceImpl addPolicyServiceImpl; + private final AddPolicyDeviceImpl addPolicyDeviceImpl; @Inject public PolicyServiceImpl( ContextService contextService, - MonitoringService monitoringService, - ServiceService serviceService, - DeviceService deviceService, PolicyRuleConditionValidator policyRuleConditionValidator, - PolicyRuleConditionFieldsGetter policyRuleConditionFieldsGetter) { + CommonPolicyServiceImpl commonPolicyServiceImpl, + AddPolicyServiceImpl addPolicyServiceImpl, + AddPolicyDeviceImpl addPolicyDeviceImpl) { 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(); + this.commonPolicyServiceImpl = commonPolicyServiceImpl; + this.addPolicyServiceImpl = addPolicyServiceImpl; + this.addPolicyDeviceImpl = addPolicyDeviceImpl; } @Override @@ -153,128 +89,11 @@ public class PolicyServiceImpl implements PolicyService { .onItem() .transform( isService -> - constructPolicyStateBasedOnCriteria( + addPolicyServiceImpl.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 NewException(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); @@ -298,110 +117,17 @@ public class PolicyServiceImpl implements PolicyService { } final var deviceIds = policyRuleDevice.getDeviceIds(); - final var areDevicesValid = returnInvalidDeviceIds(deviceIds); + final var areDevicesValid = addPolicyDeviceImpl.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; + areDevices -> + addPolicyDeviceImpl.areDeviceOnContext( + areDevices, policyRuleDevice, policyRuleBasic)) + .flatMap(Function.identity()); } @Override @@ -472,6 +198,8 @@ public class PolicyServiceImpl implements PolicyService { policyRuleConditionValidator.isUpdatedPolicyRuleIdValid(policyRuleId); return isPolicyRuleValid + .onFailure() + .transform(failure -> new ExternalServiceFailureException(failure.getMessage())) .onItem() .transform( isPolicyRuleService -> { @@ -505,6 +233,8 @@ public class PolicyServiceImpl implements PolicyService { contextService .setPolicyRule(policyRule) + .onFailure() + .transform(failure -> new ExternalServiceFailureException(failure.getMessage())) .subscribe() .with( tmp -> @@ -514,471 +244,9 @@ public class PolicyServiceImpl implements PolicyService { 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(); + if (commonPolicyServiceImpl.getSubscriptionList().contains(policyId)) + commonPolicyServiceImpl.getSubscriptionList().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 -> {}); - } }