diff --git a/src/policy/src/main/java/eu/teraflow/policy/Serializer.java b/src/policy/src/main/java/eu/teraflow/policy/Serializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..687a507fcdec304129d84862ae1f386975d48c52
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/Serializer.java
@@ -0,0 +1,1956 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy;
+
+import acl.Acl;
+import context.ContextOuterClass;
+import context.ContextOuterClass.ConfigRule_ACL;
+import context.ContextOuterClass.ConfigRule_Custom;
+import context.ContextOuterClass.ContextId;
+import context.ContextOuterClass.DeviceId;
+import context.ContextOuterClass.Uuid;
+import eu.teraflow.policy.acl.AclAction;
+import eu.teraflow.policy.acl.AclEntry;
+import eu.teraflow.policy.acl.AclForwardActionEnum;
+import eu.teraflow.policy.acl.AclLogActionEnum;
+import eu.teraflow.policy.acl.AclMatch;
+import eu.teraflow.policy.acl.AclRuleSet;
+import eu.teraflow.policy.acl.AclRuleTypeEnum;
+import eu.teraflow.policy.context.model.ConfigActionEnum;
+import eu.teraflow.policy.context.model.ConfigRule;
+import eu.teraflow.policy.context.model.ConfigRuleAcl;
+import eu.teraflow.policy.context.model.ConfigRuleCustom;
+import eu.teraflow.policy.context.model.ConfigRuleTypeAcl;
+import eu.teraflow.policy.context.model.ConfigRuleTypeCustom;
+import eu.teraflow.policy.context.model.Constraint;
+import eu.teraflow.policy.context.model.ConstraintCustom;
+import eu.teraflow.policy.context.model.ConstraintEndPointLocation;
+import eu.teraflow.policy.context.model.ConstraintSchedule;
+import eu.teraflow.policy.context.model.ConstraintSlaAvailability;
+import eu.teraflow.policy.context.model.ConstraintSlaCapacity;
+import eu.teraflow.policy.context.model.ConstraintSlaIsolationLevel;
+import eu.teraflow.policy.context.model.ConstraintSlaLatency;
+import eu.teraflow.policy.context.model.ConstraintTypeCustom;
+import eu.teraflow.policy.context.model.ConstraintTypeEndPointLocation;
+import eu.teraflow.policy.context.model.ConstraintTypeSchedule;
+import eu.teraflow.policy.context.model.ConstraintTypeSlaAvailability;
+import eu.teraflow.policy.context.model.ConstraintTypeSlaCapacity;
+import eu.teraflow.policy.context.model.ConstraintTypeSlaIsolationLevel;
+import eu.teraflow.policy.context.model.ConstraintTypeSlaLatency;
+import eu.teraflow.policy.context.model.EndPointId;
+import eu.teraflow.policy.context.model.Event;
+import eu.teraflow.policy.context.model.EventTypeEnum;
+import eu.teraflow.policy.context.model.GpsPosition;
+import eu.teraflow.policy.context.model.IsolationLevelEnum;
+import eu.teraflow.policy.context.model.Location;
+import eu.teraflow.policy.context.model.LocationTypeGpsPosition;
+import eu.teraflow.policy.context.model.LocationTypeRegion;
+import eu.teraflow.policy.context.model.Service;
+import eu.teraflow.policy.context.model.ServiceConfig;
+import eu.teraflow.policy.context.model.ServiceId;
+import eu.teraflow.policy.context.model.ServiceStatus;
+import eu.teraflow.policy.context.model.ServiceStatusEnum;
+import eu.teraflow.policy.context.model.ServiceTypeEnum;
+import eu.teraflow.policy.context.model.SliceId;
+import eu.teraflow.policy.context.model.TopologyId;
+import eu.teraflow.policy.kpi_sample_types.model.KpiSampleType;
+import eu.teraflow.policy.model.BooleanOperator;
+import eu.teraflow.policy.model.NumericalOperator;
+import eu.teraflow.policy.model.PolicyRuleAction;
+import eu.teraflow.policy.model.PolicyRuleActionEnum;
+import eu.teraflow.policy.model.PolicyRuleBasic;
+import eu.teraflow.policy.model.PolicyRuleCondition;
+import eu.teraflow.policy.model.PolicyRuleDevice;
+import eu.teraflow.policy.model.PolicyRuleService;
+import eu.teraflow.policy.model.PolicyRuleState;
+import eu.teraflow.policy.model.RuleState;
+import eu.teraflow.policy.monitoring.model.AlarmDescriptor;
+import eu.teraflow.policy.monitoring.model.AlarmResponse;
+import eu.teraflow.policy.monitoring.model.BooleanKpiValue;
+import eu.teraflow.policy.monitoring.model.FloatKpiValue;
+import eu.teraflow.policy.monitoring.model.IntegerKpiValue;
+import eu.teraflow.policy.monitoring.model.Kpi;
+import eu.teraflow.policy.monitoring.model.KpiDescriptor;
+import eu.teraflow.policy.monitoring.model.KpiValue;
+import eu.teraflow.policy.monitoring.model.KpiValueRange;
+import eu.teraflow.policy.monitoring.model.StringKpiValue;
+import eu.teraflow.policy.monitoring.model.SubsDescriptor;
+import java.util.stream.Collectors;
+import javax.inject.Singleton;
+import kpi_sample_types.KpiSampleTypes;
+import monitoring.Monitoring;
+import monitoring.Monitoring.KpiId;
+import policy.Policy;
+import policy.Policy.PolicyRuleId;
+import policy.PolicyAction;
+import policy.PolicyCondition;
+
+@Singleton
+public class Serializer {
+
+    public DeviceId serializeDeviceId(String expectedDeviceId) {
+        final var builder = DeviceId.newBuilder();
+        final var uuid = serializeUuid(expectedDeviceId);
+
+        builder.setDeviceUuid(uuid);
+
+        return builder.build();
+    }
+
+    public String deserialize(DeviceId deviceId) {
+        return deviceId.getDeviceUuid().getUuid();
+    }
+
+    public ContextId serializeContextId(String expectedContextId) {
+        final var builder = ContextId.newBuilder();
+        final var uuid = serializeUuid(expectedContextId);
+
+        builder.setContextUuid(uuid);
+
+        return builder.build();
+    }
+
+    public String deserialize(ContextId contextId) {
+        return contextId.getContextUuid().getUuid();
+    }
+
+    public PolicyRuleId serializePolicyRuleId(String expectedPolicyRuleId) {
+        final var builder = PolicyRuleId.newBuilder();
+        final var uuid = serializeUuid(expectedPolicyRuleId);
+
+        builder.setUuid(uuid);
+
+        return builder.build();
+    }
+
+    public String deserialize(PolicyRuleId policyRuleId) {
+        return policyRuleId.getUuid().getUuid();
+    }
+
+    public ContextOuterClass.TopologyId serialize(TopologyId topologyId) {
+        final var builder = ContextOuterClass.TopologyId.newBuilder();
+
+        final var topologyIdContextId = topologyId.getContextId();
+        final var topologyIdId = topologyId.getId();
+
+        final var contextId = serializeContextId(topologyIdContextId);
+        final var topologyIdIdUuid = serializeUuid(topologyIdId);
+
+        builder.setContextId(contextId);
+        builder.setTopologyUuid(topologyIdIdUuid);
+
+        return builder.build();
+    }
+
+    public TopologyId deserialize(ContextOuterClass.TopologyId topologyId) {
+        final var topologyIdContextId = deserialize(topologyId.getContextId());
+        final var topologyIdId = deserialize(topologyId.getTopologyUuid());
+
+        return new TopologyId(topologyIdContextId, topologyIdId);
+    }
+
+    public ContextOuterClass.ConfigActionEnum serialize(ConfigActionEnum configActionEnum) {
+        switch (configActionEnum) {
+            case SET:
+                return ContextOuterClass.ConfigActionEnum.CONFIGACTION_SET;
+            case DELETE:
+                return ContextOuterClass.ConfigActionEnum.CONFIGACTION_DELETE;
+            case UNDEFINED:
+                return ContextOuterClass.ConfigActionEnum.CONFIGACTION_UNDEFINED;
+            default:
+                return ContextOuterClass.ConfigActionEnum.UNRECOGNIZED;
+        }
+    }
+
+    public ConfigActionEnum deserialize(
+            ContextOuterClass.ConfigActionEnum serializedConfigActionEnum) {
+        switch (serializedConfigActionEnum) {
+            case CONFIGACTION_SET:
+                return ConfigActionEnum.SET;
+            case CONFIGACTION_DELETE:
+                return ConfigActionEnum.DELETE;
+            case CONFIGACTION_UNDEFINED:
+            case UNRECOGNIZED:
+            default:
+                return ConfigActionEnum.UNDEFINED;
+        }
+    }
+
+    public Acl.AclRuleTypeEnum serialize(AclRuleTypeEnum aclRuleTypeEnum) {
+        switch (aclRuleTypeEnum) {
+            case IPV4:
+                return Acl.AclRuleTypeEnum.ACLRULETYPE_IPV4;
+            case IPV6:
+                return Acl.AclRuleTypeEnum.ACLRULETYPE_IPV6;
+            case L2:
+                return Acl.AclRuleTypeEnum.ACLRULETYPE_L2;
+            case MPLS:
+                return Acl.AclRuleTypeEnum.ACLRULETYPE_MPLS;
+            case MIXED:
+                return Acl.AclRuleTypeEnum.ACLRULETYPE_MIXED;
+            case UNDEFINED:
+                return Acl.AclRuleTypeEnum.ACLRULETYPE_UNDEFINED;
+            default:
+                return Acl.AclRuleTypeEnum.UNRECOGNIZED;
+        }
+    }
+
+    public AclRuleTypeEnum deserialize(Acl.AclRuleTypeEnum serializedAclRuleTypeEnum) {
+        switch (serializedAclRuleTypeEnum) {
+            case ACLRULETYPE_IPV4:
+                return AclRuleTypeEnum.IPV4;
+            case ACLRULETYPE_IPV6:
+                return AclRuleTypeEnum.IPV6;
+            case ACLRULETYPE_L2:
+                return AclRuleTypeEnum.L2;
+            case ACLRULETYPE_MPLS:
+                return AclRuleTypeEnum.MPLS;
+            case ACLRULETYPE_MIXED:
+                return AclRuleTypeEnum.MIXED;
+            case UNRECOGNIZED:
+            default:
+                return AclRuleTypeEnum.UNDEFINED;
+        }
+    }
+
+    public Acl.AclMatch serialize(AclMatch aclMatch) {
+        final var builder = Acl.AclMatch.newBuilder();
+
+        final var dscp = aclMatch.getDscp();
+        final var protocol = aclMatch.getProtocol();
+        final var srcAddress = aclMatch.getSrcAddress();
+        final var dstAddress = aclMatch.getDstAddress();
+        final var srcPort = aclMatch.getSrcPort();
+        final var dstPort = aclMatch.getDstPort();
+        final var startMplsLabel = aclMatch.getStartMplsLabel();
+        final var endMplsLabel = aclMatch.getEndMplsLabel();
+
+        builder.setDscp(dscp);
+        builder.setProtocol(protocol);
+        builder.setSrcAddress(srcAddress);
+        builder.setDstAddress(dstAddress);
+        builder.setSrcPort(srcPort);
+        builder.setDstPort(dstPort);
+        builder.setStartMplsLabel(startMplsLabel);
+        builder.setEndMplsLabel(endMplsLabel);
+
+        return builder.build();
+    }
+
+    public AclMatch deserialize(Acl.AclMatch serializedAclMatch) {
+        final var dscp = serializedAclMatch.getDscp();
+        final var protocol = serializedAclMatch.getProtocol();
+        final var srcAddress = serializedAclMatch.getSrcAddress();
+        final var dstAddress = serializedAclMatch.getDstAddress();
+        final var srcPort = serializedAclMatch.getSrcPort();
+        final var dstPort = serializedAclMatch.getDstPort();
+        final var startMplsLabel = serializedAclMatch.getStartMplsLabel();
+        final var endMplsLabel = serializedAclMatch.getEndMplsLabel();
+
+        return new AclMatch(
+                dscp, protocol, srcAddress, dstAddress, srcPort, dstPort, startMplsLabel, endMplsLabel);
+    }
+
+    public Acl.AclForwardActionEnum serialize(AclForwardActionEnum aclForwardActionEnum) {
+        switch (aclForwardActionEnum) {
+            case DROP:
+                return Acl.AclForwardActionEnum.ACLFORWARDINGACTION_DROP;
+            case ACCEPT:
+                return Acl.AclForwardActionEnum.ACLFORWARDINGACTION_ACCEPT;
+            case REJECT:
+                return Acl.AclForwardActionEnum.ACLFORWARDINGACTION_REJECT;
+            case UNDEFINED:
+                return Acl.AclForwardActionEnum.ACLFORWARDINGACTION_UNDEFINED;
+            default:
+                return Acl.AclForwardActionEnum.UNRECOGNIZED;
+        }
+    }
+
+    public AclForwardActionEnum deserialize(Acl.AclForwardActionEnum serializedAclForwardActionEnum) {
+        switch (serializedAclForwardActionEnum) {
+            case ACLFORWARDINGACTION_DROP:
+                return AclForwardActionEnum.DROP;
+            case ACLFORWARDINGACTION_ACCEPT:
+                return AclForwardActionEnum.ACCEPT;
+            case ACLFORWARDINGACTION_REJECT:
+                return AclForwardActionEnum.REJECT;
+            case UNRECOGNIZED:
+            default:
+                return AclForwardActionEnum.UNDEFINED;
+        }
+    }
+
+    public Acl.AclLogActionEnum serialize(AclLogActionEnum aclLogActionEnum) {
+        switch (aclLogActionEnum) {
+            case NO_LOG:
+                return Acl.AclLogActionEnum.ACLLOGACTION_NOLOG;
+            case SYSLOG:
+                return Acl.AclLogActionEnum.ACLLOGACTION_SYSLOG;
+            case UNDEFINED:
+                return Acl.AclLogActionEnum.ACLLOGACTION_UNDEFINED;
+            default:
+                return Acl.AclLogActionEnum.UNRECOGNIZED;
+        }
+    }
+
+    public AclLogActionEnum deserialize(Acl.AclLogActionEnum serializedAclLogActionEnum) {
+        switch (serializedAclLogActionEnum) {
+            case ACLLOGACTION_NOLOG:
+                return AclLogActionEnum.NO_LOG;
+            case ACLLOGACTION_SYSLOG:
+                return AclLogActionEnum.SYSLOG;
+            case UNRECOGNIZED:
+            default:
+                return AclLogActionEnum.UNDEFINED;
+        }
+    }
+
+    public Acl.AclAction serialize(AclAction aclAction) {
+        final var builder = Acl.AclAction.newBuilder();
+
+        final var aclForwardActionEnum = aclAction.getAclForwardActionEnum();
+        final var aclLogActionEnum = aclAction.getAclLogActionEnum();
+
+        final var serializedAclForwardActionEnum = serialize(aclForwardActionEnum);
+        final var serializedAclLogActionEnum = serialize(aclLogActionEnum);
+
+        builder.setForwardAction(serializedAclForwardActionEnum);
+        builder.setLogAction(serializedAclLogActionEnum);
+
+        return builder.build();
+    }
+
+    public AclAction deserialize(Acl.AclAction serializedAclAction) {
+        final var serializedAclForwardActionEnum = serializedAclAction.getForwardAction();
+        final var serializedAclLogActionEnum = serializedAclAction.getLogAction();
+
+        final var aclForwardActionEnum = deserialize(serializedAclForwardActionEnum);
+        final var aclLogActionEnum = deserialize(serializedAclLogActionEnum);
+
+        return new AclAction(aclForwardActionEnum, aclLogActionEnum);
+    }
+
+    public Acl.AclEntry serialize(AclEntry aclEntry) {
+        final var builder = Acl.AclEntry.newBuilder();
+
+        final var sequenceId = aclEntry.getSequenceId();
+        final var description = aclEntry.getDescription();
+        final var aclMatch = aclEntry.getMatch();
+        final var aclAction = aclEntry.getAction();
+
+        final var serializedAclMatch = serialize(aclMatch);
+        final var serializedAclAction = serialize(aclAction);
+
+        builder.setSequenceId(sequenceId);
+        builder.setDescription(description);
+        builder.setMatch(serializedAclMatch);
+        builder.setAction(serializedAclAction);
+
+        return builder.build();
+    }
+
+    public AclEntry deserialize(Acl.AclEntry serializedAclEntry) {
+        final var sequenceId = serializedAclEntry.getSequenceId();
+        final var description = serializedAclEntry.getDescription();
+        final var serializedAclMatch = serializedAclEntry.getMatch();
+        final var serializedAclAction = serializedAclEntry.getAction();
+
+        final var aclMatch = deserialize(serializedAclMatch);
+        final var aclAction = deserialize(serializedAclAction);
+
+        return new AclEntry(sequenceId, description, aclMatch, aclAction);
+    }
+
+    public Acl.AclRuleSet serialize(AclRuleSet aclRuleSet) {
+        final var builder = Acl.AclRuleSet.newBuilder();
+
+        final var name = aclRuleSet.getName();
+        final var type = aclRuleSet.getType();
+        final var description = aclRuleSet.getDescription();
+        final var userId = aclRuleSet.getUserId();
+        final var entries = aclRuleSet.getEntries();
+
+        final var serializedType = serialize(type);
+        final var serializedEntries =
+                entries.stream().map(this::serialize).collect(Collectors.toList());
+
+        builder.setName(name);
+        builder.setType(serializedType);
+        builder.setDescription(description);
+        builder.setUserId(userId);
+        builder.addAllEntries(serializedEntries);
+
+        return builder.build();
+    }
+
+    public AclRuleSet deserialize(Acl.AclRuleSet serializedAclRuleSet) {
+        final var serializedName = serializedAclRuleSet.getName();
+        final var serializedType = serializedAclRuleSet.getType();
+        final var serializedDescription = serializedAclRuleSet.getDescription();
+        final var serializedUserId = serializedAclRuleSet.getUserId();
+        final var serializedEntries = serializedAclRuleSet.getEntriesList();
+
+        final var type = deserialize(serializedType);
+        final var entries =
+                serializedEntries.stream().map(this::deserialize).collect(Collectors.toList());
+
+        return new AclRuleSet(serializedName, type, serializedDescription, serializedUserId, entries);
+    }
+
+    public ConfigRule_ACL serialize(ConfigRuleAcl configRuleAcl) {
+        final var builder = ContextOuterClass.ConfigRule_ACL.newBuilder();
+
+        final var endPointId = configRuleAcl.getEndPointId();
+        final var aclRuleSet = configRuleAcl.getRuleSet();
+
+        final var serializedEndPointId = serialize(endPointId);
+        final var serializedAclRuleSet = serialize(aclRuleSet);
+
+        builder.setEndpointId(serializedEndPointId);
+        builder.setRuleSet(serializedAclRuleSet);
+
+        return builder.build();
+    }
+
+    public ConfigRuleAcl deserialize(ConfigRule_ACL serializedConfigRuleAcl) {
+        final var serializedEndPointId = serializedConfigRuleAcl.getEndpointId();
+        final var serializedAclRuleSet = serializedConfigRuleAcl.getRuleSet();
+
+        final var endPointId = deserialize(serializedEndPointId);
+        final var aclRuleSet = deserialize(serializedAclRuleSet);
+
+        return new ConfigRuleAcl(endPointId, aclRuleSet);
+    }
+
+    public ConfigRule_Custom serialize(ConfigRuleCustom configRuleCustom) {
+        final var builder = ConfigRule_Custom.newBuilder();
+
+        final var resourceKey = configRuleCustom.getResourceKey();
+        final var resourceValue = configRuleCustom.getResourceValue();
+
+        builder.setResourceKey(resourceKey);
+        builder.setResourceValue(resourceValue);
+
+        return builder.build();
+    }
+
+    public ConfigRuleCustom deserialize(ConfigRule_Custom serializedConfigRuleCustom) {
+        final var serializedResourceKey = serializedConfigRuleCustom.getResourceKey();
+        final var serializedResourceValue = serializedConfigRuleCustom.getResourceValue();
+
+        return new ConfigRuleCustom(serializedResourceKey, serializedResourceValue);
+    }
+
+    public ContextOuterClass.ConfigRule serialize(ConfigRule configRule) {
+        final var builder = ContextOuterClass.ConfigRule.newBuilder();
+
+        final var configActionEnum = configRule.getConfigActionEnum();
+        final var configRuleType = configRule.getConfigRuleType();
+        final var configRuleTypeSpecificType = configRuleType.getConfigRuleType();
+
+        if (configRuleTypeSpecificType instanceof ConfigRuleAcl) {
+            final var endPointId = ((ConfigRuleAcl) configRuleTypeSpecificType).getEndPointId();
+            final var aclRuleSet = ((ConfigRuleAcl) configRuleTypeSpecificType).getRuleSet();
+
+            final var serializedEndPointId = serialize(endPointId);
+            final var serializedAclRuleSet = serialize(aclRuleSet);
+
+            final var serializedConfigRuleAcl =
+                    ConfigRule_ACL.newBuilder()
+                            .setEndpointId(serializedEndPointId)
+                            .setRuleSet(serializedAclRuleSet)
+                            .build();
+
+            builder.setAcl(serializedConfigRuleAcl);
+        }
+
+        if (configRuleTypeSpecificType instanceof ConfigRuleCustom) {
+            final var configRuleCustomResourceKey =
+                    ((ConfigRuleCustom) configRuleTypeSpecificType).getResourceKey();
+            final var configRuleCustomResourceValue =
+                    ((ConfigRuleCustom) configRuleTypeSpecificType).getResourceValue();
+
+            final var serializedConfigRuleCustom =
+                    ConfigRule_Custom.newBuilder()
+                            .setResourceKey(configRuleCustomResourceKey)
+                            .setResourceValue(configRuleCustomResourceValue)
+                            .build();
+
+            builder.setCustom(serializedConfigRuleCustom);
+        }
+
+        final var serializedConfigActionEnum = serialize(configActionEnum);
+
+        builder.setAction(serializedConfigActionEnum);
+
+        return builder.build();
+    }
+
+    public ConfigRule deserialize(ContextOuterClass.ConfigRule serializedConfigRule) {
+        final var serializedConfigActionEnum = serializedConfigRule.getAction();
+        final var typeOfConfigRule = serializedConfigRule.getConfigRuleCase();
+
+        final var configActionEnum = deserialize(serializedConfigActionEnum);
+
+        switch (typeOfConfigRule) {
+            case ACL:
+                final var serializedConfigRuleAcl = serializedConfigRule.getAcl();
+
+                final var configRuleAcl = deserialize(serializedConfigRuleAcl);
+                final var configRuleTypeAcl = new ConfigRuleTypeAcl(configRuleAcl);
+
+                return new ConfigRule(configActionEnum, configRuleTypeAcl);
+            case CUSTOM:
+                final var serializedConfigRuleCustom = serializedConfigRule.getCustom();
+
+                final var configRuleCustom = deserialize(serializedConfigRuleCustom);
+                final var configRuleTypeCustom = new ConfigRuleTypeCustom(configRuleCustom);
+
+                return new ConfigRule(configActionEnum, configRuleTypeCustom);
+            default:
+            case CONFIGRULE_NOT_SET:
+                throw new IllegalStateException("Config Rule not set");
+        }
+    }
+
+    public ContextOuterClass.Location serialize(Location location) {
+        final var builder = ContextOuterClass.Location.newBuilder();
+
+        final var locationType = location.getLocationType();
+        final var locationTypeSpecificType = locationType.getLocationType();
+
+        if (locationTypeSpecificType instanceof GpsPosition) {
+            final var latitude = ((GpsPosition) locationTypeSpecificType).getLatitude();
+            final var longitude = ((GpsPosition) locationTypeSpecificType).getLongitude();
+
+            final var serializedGpsPosition =
+                    ContextOuterClass.GPS_Position.newBuilder()
+                            .setLatitude(latitude)
+                            .setLongitude(longitude)
+                            .build();
+
+            builder.setGpsPosition(serializedGpsPosition);
+        }
+
+        if (locationTypeSpecificType instanceof String) {
+            final var region = ((String) locationTypeSpecificType);
+
+            builder.setRegion(region);
+        }
+
+        return builder.build();
+    }
+
+    public Location deserialize(ContextOuterClass.Location serializedLocation) {
+        final var typeOfLocation = serializedLocation.getLocationCase();
+
+        switch (typeOfLocation) {
+            case REGION:
+                final var region = serializedLocation.getRegion();
+                final var locationTypeRegion = new LocationTypeRegion(region);
+
+                return new Location(locationTypeRegion);
+            case GPS_POSITION:
+                final var serializedGpsPosition = serializedLocation.getGpsPosition();
+                final var latitude = serializedGpsPosition.getLatitude();
+                final var longitude = serializedGpsPosition.getLongitude();
+
+                final var gpsPosition = new GpsPosition(latitude, longitude);
+                final var locationTypeGpsPosition = new LocationTypeGpsPosition(gpsPosition);
+
+                return new Location(locationTypeGpsPosition);
+            default:
+            case LOCATION_NOT_SET:
+                throw new IllegalStateException("Location value not set");
+        }
+    }
+
+    public ContextOuterClass.IsolationLevelEnum serialize(IsolationLevelEnum isolationLevelEnum) {
+        switch (isolationLevelEnum) {
+            case NO_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.NO_ISOLATION;
+            case PHYSICAL_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.PHYSICAL_ISOLATION;
+            case LOGICAL_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.LOGICAL_ISOLATION;
+            case PROCESS_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.PROCESS_ISOLATION;
+            case PHYSICAL_MEMORY_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.PHYSICAL_MEMORY_ISOLATION;
+            case PHYSICAL_NETWORK_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.PHYSICAL_NETWORK_ISOLATION;
+            case VIRTUAL_RESOURCE_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.VIRTUAL_RESOURCE_ISOLATION;
+            case NETWORK_FUNCTIONS_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.NETWORK_FUNCTIONS_ISOLATION;
+            case SERVICE_ISOLATION:
+                return ContextOuterClass.IsolationLevelEnum.SERVICE_ISOLATION;
+            default:
+                return ContextOuterClass.IsolationLevelEnum.UNRECOGNIZED;
+        }
+    }
+
+    public IsolationLevelEnum deserialize(
+            ContextOuterClass.IsolationLevelEnum serializedIsolationLevelEnum) {
+        switch (serializedIsolationLevelEnum) {
+            case PHYSICAL_ISOLATION:
+                return IsolationLevelEnum.PHYSICAL_ISOLATION;
+            case LOGICAL_ISOLATION:
+                return IsolationLevelEnum.LOGICAL_ISOLATION;
+            case PROCESS_ISOLATION:
+                return IsolationLevelEnum.PROCESS_ISOLATION;
+            case PHYSICAL_MEMORY_ISOLATION:
+                return IsolationLevelEnum.PHYSICAL_MEMORY_ISOLATION;
+            case PHYSICAL_NETWORK_ISOLATION:
+                return IsolationLevelEnum.PHYSICAL_NETWORK_ISOLATION;
+            case VIRTUAL_RESOURCE_ISOLATION:
+                return IsolationLevelEnum.VIRTUAL_RESOURCE_ISOLATION;
+            case NETWORK_FUNCTIONS_ISOLATION:
+                return IsolationLevelEnum.NETWORK_FUNCTIONS_ISOLATION;
+            case SERVICE_ISOLATION:
+                return IsolationLevelEnum.SERVICE_ISOLATION;
+            case UNRECOGNIZED:
+            default:
+                return IsolationLevelEnum.NO_ISOLATION;
+        }
+    }
+
+    public ContextOuterClass.Constraint_Custom serialize(ConstraintCustom constraintCustom) {
+        final var builder = ContextOuterClass.Constraint_Custom.newBuilder();
+
+        final var constraintType = constraintCustom.getConstraintType();
+        final var constraintValue = constraintCustom.getConstraintValue();
+
+        builder.setConstraintType(constraintType);
+        builder.setConstraintValue(constraintValue);
+
+        return builder.build();
+    }
+
+    public ConstraintCustom deserialize(
+            ContextOuterClass.Constraint_Custom serializedConstraintCustom) {
+        final var constraintType = serializedConstraintCustom.getConstraintType();
+        final var constraintValue = serializedConstraintCustom.getConstraintValue();
+
+        return new ConstraintCustom(constraintType, constraintValue);
+    }
+
+    public ContextOuterClass.Constraint_Schedule serialize(ConstraintSchedule constraintSchedule) {
+        final var builder = ContextOuterClass.Constraint_Schedule.newBuilder();
+
+        final var startTimestamp = constraintSchedule.getStartTimestamp();
+        final var durationDays = constraintSchedule.getDurationDays();
+
+        builder.setStartTimestamp(startTimestamp);
+        builder.setDurationDays(durationDays);
+
+        return builder.build();
+    }
+
+    public ConstraintSchedule deserialize(
+            ContextOuterClass.Constraint_Schedule serializedConstraintSchedule) {
+        final var startTimestamp = serializedConstraintSchedule.getStartTimestamp();
+        final var durationDays = serializedConstraintSchedule.getDurationDays();
+
+        return new ConstraintSchedule(startTimestamp, durationDays);
+    }
+
+    public ContextOuterClass.Constraint_EndPointLocation serialize(
+            ConstraintEndPointLocation constraintEndPointLocation) {
+        final var builder = ContextOuterClass.Constraint_EndPointLocation.newBuilder();
+
+        final var endPointId = constraintEndPointLocation.getEndPointId();
+        final var location = constraintEndPointLocation.getLocation();
+
+        final var serializedEndPointId = serialize(endPointId);
+        final var serializedLocation = serialize(location);
+
+        builder.setEndpointId(serializedEndPointId);
+        builder.setLocation(serializedLocation);
+
+        return builder.build();
+    }
+
+    public ConstraintEndPointLocation deserialize(
+            ContextOuterClass.Constraint_EndPointLocation serializedConstraintEndPointLocation) {
+        final var serializedEndPointId = serializedConstraintEndPointLocation.getEndpointId();
+        final var serializedLocation = serializedConstraintEndPointLocation.getLocation();
+
+        final var endPointId = deserialize(serializedEndPointId);
+        final var location = deserialize(serializedLocation);
+
+        return new ConstraintEndPointLocation(endPointId, location);
+    }
+
+    public ContextOuterClass.Constraint_SLA_Availability serialize(
+            ConstraintSlaAvailability constraintSlaAvailability) {
+        final var builder = ContextOuterClass.Constraint_SLA_Availability.newBuilder();
+
+        final var numDisjointPaths = constraintSlaAvailability.getNumDisjointPaths();
+        final var isAllActive = constraintSlaAvailability.isAllActive();
+
+        builder.setNumDisjointPaths(numDisjointPaths);
+        builder.setAllActive(isAllActive);
+
+        return builder.build();
+    }
+
+    public ConstraintSlaAvailability deserialize(
+            ContextOuterClass.Constraint_SLA_Availability serializedConstraintSlaAvailability) {
+        final var numDisjointPaths = serializedConstraintSlaAvailability.getNumDisjointPaths();
+        final var isAllActive = serializedConstraintSlaAvailability.getAllActive();
+
+        return new ConstraintSlaAvailability(numDisjointPaths, isAllActive);
+    }
+
+    public ContextOuterClass.Constraint_SLA_Capacity serialize(
+            ConstraintSlaCapacity constraintSlaCapacity) {
+        final var builder = ContextOuterClass.Constraint_SLA_Capacity.newBuilder();
+
+        final var capacityGbps = constraintSlaCapacity.getCapacityGbps();
+
+        builder.setCapacityGbps(capacityGbps);
+
+        return builder.build();
+    }
+
+    public ConstraintSlaCapacity deserialize(
+            ContextOuterClass.Constraint_SLA_Capacity serializedConstraintSlaCapacity) {
+        final var capacityGbps = serializedConstraintSlaCapacity.getCapacityGbps();
+
+        return new ConstraintSlaCapacity(capacityGbps);
+    }
+
+    public ContextOuterClass.Constraint_SLA_Isolation_level serialize(
+            ConstraintSlaIsolationLevel constraintSlaIsolationLevel) {
+        final var builder = ContextOuterClass.Constraint_SLA_Isolation_level.newBuilder();
+
+        final var isolationLevelEnum = constraintSlaIsolationLevel.getIsolationLevelEnum();
+
+        final var serializedIsolationLevelEnum = serialize(isolationLevelEnum);
+
+        builder.setIsolationLevel(serializedIsolationLevelEnum);
+
+        return builder.build();
+    }
+
+    public ConstraintSlaIsolationLevel deserialize(
+            ContextOuterClass.Constraint_SLA_Isolation_level serializedConstraintIsolationLevel) {
+        final var serializedIsolationLevelEnum = serializedConstraintIsolationLevel.getIsolationLevel();
+
+        final var isolationLevelEnum = deserialize(serializedIsolationLevelEnum);
+
+        return new ConstraintSlaIsolationLevel(isolationLevelEnum);
+    }
+
+    public ContextOuterClass.Constraint_SLA_Latency serialize(
+            ConstraintSlaLatency constraintSlaLatency) {
+        final var builder = ContextOuterClass.Constraint_SLA_Latency.newBuilder();
+
+        final var e2eLatencyMs = constraintSlaLatency.getE2eLatencyMs();
+
+        builder.setE2ELatencyMs(e2eLatencyMs);
+
+        return builder.build();
+    }
+
+    public ConstraintSlaLatency deserialize(
+            ContextOuterClass.Constraint_SLA_Latency serializedConstraintSlaLatency) {
+        final var e2ELatencyMs = serializedConstraintSlaLatency.getE2ELatencyMs();
+
+        return new ConstraintSlaLatency(e2ELatencyMs);
+    }
+
+    public ContextOuterClass.Constraint serialize(Constraint constraint) {
+        final var builder = ContextOuterClass.Constraint.newBuilder();
+
+        final var constraintType = constraint.getConstraintType();
+        final var constraintTypeSpecificType = constraintType.getConstraintType();
+
+        if (constraintTypeSpecificType instanceof ConstraintCustom) {
+            final var constraintCustomType =
+                    ((ConstraintCustom) constraintTypeSpecificType).getConstraintType();
+            final var constraintCustomValue =
+                    ((ConstraintCustom) constraintTypeSpecificType).getConstraintValue();
+
+            final var serializedConstraintCustom =
+                    ContextOuterClass.Constraint_Custom.newBuilder()
+                            .setConstraintType(constraintCustomType)
+                            .setConstraintValue(constraintCustomValue)
+                            .build();
+
+            builder.setCustom(serializedConstraintCustom);
+        }
+
+        if (constraintTypeSpecificType instanceof ConstraintSchedule) {
+            final var startTimestamp =
+                    ((ConstraintSchedule) constraintTypeSpecificType).getStartTimestamp();
+            final var durationDays = ((ConstraintSchedule) constraintTypeSpecificType).getDurationDays();
+
+            final var serializedConstraintSchedule =
+                    ContextOuterClass.Constraint_Schedule.newBuilder()
+                            .setStartTimestamp(startTimestamp)
+                            .setDurationDays(durationDays)
+                            .build();
+
+            builder.setSchedule(serializedConstraintSchedule);
+        }
+
+        if (constraintTypeSpecificType instanceof ConstraintEndPointLocation) {
+            final var endPointId =
+                    ((ConstraintEndPointLocation) constraintTypeSpecificType).getEndPointId();
+            final var location = ((ConstraintEndPointLocation) constraintTypeSpecificType).getLocation();
+
+            final var serializedEndPointId = serialize(endPointId);
+            final var serializedLocation = serialize(location);
+
+            final var serializedConstraintEndPointLocation =
+                    ContextOuterClass.Constraint_EndPointLocation.newBuilder()
+                            .setEndpointId(serializedEndPointId)
+                            .setLocation(serializedLocation)
+                            .build();
+
+            builder.setEndpointLocation(serializedConstraintEndPointLocation);
+        }
+
+        if (constraintTypeSpecificType instanceof ConstraintSlaAvailability) {
+            final var numDisJointPaths =
+                    ((ConstraintSlaAvailability) constraintTypeSpecificType).getNumDisjointPaths();
+            final var isAllActive =
+                    ((ConstraintSlaAvailability) constraintTypeSpecificType).isAllActive();
+
+            final var serializedConstraintSlaAvailability =
+                    ContextOuterClass.Constraint_SLA_Availability.newBuilder()
+                            .setNumDisjointPaths(numDisJointPaths)
+                            .setAllActive(isAllActive)
+                            .build();
+
+            builder.setSlaAvailability(serializedConstraintSlaAvailability);
+        }
+
+        if (constraintTypeSpecificType instanceof ConstraintSlaCapacity) {
+            final var capacityGbps =
+                    ((ConstraintSlaCapacity) constraintTypeSpecificType).getCapacityGbps();
+
+            final var serializedConstraintSlaCapacity =
+                    ContextOuterClass.Constraint_SLA_Capacity.newBuilder()
+                            .setCapacityGbps(capacityGbps)
+                            .build();
+
+            builder.setSlaCapacity(serializedConstraintSlaCapacity);
+        }
+
+        if (constraintTypeSpecificType instanceof ConstraintSlaIsolationLevel) {
+            final var isolationLevelEnum =
+                    ((ConstraintSlaIsolationLevel) constraintTypeSpecificType).getIsolationLevelEnum();
+
+            final var serializedIsolationLevelEnum = serialize(isolationLevelEnum);
+            final var serializedConstraintSlaIsolationLevel =
+                    ContextOuterClass.Constraint_SLA_Isolation_level.newBuilder()
+                            .setIsolationLevel(serializedIsolationLevelEnum)
+                            .build();
+
+            builder.setSlaIsolation(serializedConstraintSlaIsolationLevel);
+        }
+
+        if (constraintTypeSpecificType instanceof ConstraintSlaLatency) {
+            final var e2eLatencyMs =
+                    ((ConstraintSlaLatency) constraintTypeSpecificType).getE2eLatencyMs();
+
+            final var serializedConstraintSlaLatency =
+                    ContextOuterClass.Constraint_SLA_Latency.newBuilder()
+                            .setE2ELatencyMs(e2eLatencyMs)
+                            .build();
+
+            builder.setSlaLatency(serializedConstraintSlaLatency);
+        }
+
+        return builder.build();
+    }
+
+    public Constraint deserialize(ContextOuterClass.Constraint serializedConstraint) {
+        final var typeOfConstraint = serializedConstraint.getConstraintCase();
+
+        switch (typeOfConstraint) {
+            case CUSTOM:
+                final var serializedConstraintCustom = serializedConstraint.getCustom();
+                final var constraintType = serializedConstraintCustom.getConstraintType();
+                final var constraintValue = serializedConstraintCustom.getConstraintValue();
+
+                final var constraintCustom = new ConstraintCustom(constraintType, constraintValue);
+                final var constraintTypeCustom = new ConstraintTypeCustom(constraintCustom);
+
+                return new Constraint(constraintTypeCustom);
+            case SCHEDULE:
+                final var serializedConstraintSchedule = serializedConstraint.getSchedule();
+                final var startTimestamp = serializedConstraintSchedule.getStartTimestamp();
+                final var durationDays = serializedConstraintSchedule.getDurationDays();
+
+                final var constraintSchedule = new ConstraintSchedule(startTimestamp, durationDays);
+                final var constraintTypeSchedule = new ConstraintTypeSchedule(constraintSchedule);
+
+                return new Constraint(constraintTypeSchedule);
+            case ENDPOINT_LOCATION:
+                final var serializedConstrainEndPointLocation = serializedConstraint.getEndpointLocation();
+                final var serializedEndPointId = serializedConstrainEndPointLocation.getEndpointId();
+                final var serializedLocation = serializedConstrainEndPointLocation.getLocation();
+
+                final var endPointId = deserialize(serializedEndPointId);
+                final var location = deserialize(serializedLocation);
+                final var constraintEndPointLocation = new ConstraintEndPointLocation(endPointId, location);
+                final var constraintTypeEndPointLocation =
+                        new ConstraintTypeEndPointLocation(constraintEndPointLocation);
+
+                return new Constraint(constraintTypeEndPointLocation);
+            case SLA_CAPACITY:
+                final var serializedConstrainSlaCapacity = serializedConstraint.getSlaCapacity();
+                final var capacityGbps = serializedConstrainSlaCapacity.getCapacityGbps();
+
+                final var constraintSlaCapacity = new ConstraintSlaCapacity(capacityGbps);
+                final var constraintTypeSlaCapacity = new ConstraintTypeSlaCapacity(constraintSlaCapacity);
+
+                return new Constraint(constraintTypeSlaCapacity);
+            case SLA_LATENCY:
+                final var serializedConstrainSlaLatency = serializedConstraint.getSlaLatency();
+                final var e2ELatencyMs = serializedConstrainSlaLatency.getE2ELatencyMs();
+
+                final var constraintSlaLatency = new ConstraintSlaLatency(e2ELatencyMs);
+                final var constraintTypeSlaLatency = new ConstraintTypeSlaLatency(constraintSlaLatency);
+
+                return new Constraint(constraintTypeSlaLatency);
+            case SLA_AVAILABILITY:
+                final var serializedConstrainSlaAvailability = serializedConstraint.getSlaAvailability();
+                final var numDisjointPaths = serializedConstrainSlaAvailability.getNumDisjointPaths();
+                final var isAllActive = serializedConstrainSlaAvailability.getAllActive();
+
+                final var constraintSlaAvailability =
+                        new ConstraintSlaAvailability(numDisjointPaths, isAllActive);
+                final var constraintTypeSlaAvailability =
+                        new ConstraintTypeSlaAvailability(constraintSlaAvailability);
+
+                return new Constraint(constraintTypeSlaAvailability);
+            case SLA_ISOLATION:
+                final var serializedConstrainSlaIsolation = serializedConstraint.getSlaIsolation();
+                final var serializedIsolationLevelEnum =
+                        serializedConstrainSlaIsolation.getIsolationLevel();
+
+                final var isolationLevelEnum = deserialize(serializedIsolationLevelEnum);
+                final var constraintSlaIsolation = new ConstraintSlaIsolationLevel(isolationLevelEnum);
+                final var constraintTypeSlaIsolation =
+                        new ConstraintTypeSlaIsolationLevel(constraintSlaIsolation);
+
+                return new Constraint(constraintTypeSlaIsolation);
+
+            default:
+            case CONSTRAINT_NOT_SET:
+                throw new IllegalStateException("Constraint value not set");
+        }
+    }
+
+    public ContextOuterClass.EndPointId serialize(EndPointId endPointId) {
+        final var builder = ContextOuterClass.EndPointId.newBuilder();
+
+        final var endPointIdTopologyId = endPointId.getTopologyId();
+        final var endPointIdDeviceId = endPointId.getDeviceId();
+        final var endPointIdId = endPointId.getId();
+
+        final var serializedTopologyId = serialize(endPointIdTopologyId);
+        final var serializedDeviceId = serializeDeviceId(endPointIdDeviceId);
+        final var serializedEndPointIdId = serializeUuid(endPointIdId);
+
+        builder.setTopologyId(serializedTopologyId);
+        builder.setDeviceId(serializedDeviceId);
+        builder.setEndpointUuid(serializedEndPointIdId);
+
+        return builder.build();
+    }
+
+    public EndPointId deserialize(ContextOuterClass.EndPointId serializedEndPointId) {
+        final var serializedTopologyId = serializedEndPointId.getTopologyId();
+        final var serializedDeviceId = serializedEndPointId.getDeviceId();
+        final var serializedId = serializedEndPointId.getEndpointUuid();
+
+        final var topologyId = deserialize(serializedTopologyId);
+        final var deviceId = deserialize(serializedDeviceId);
+        final var id = deserialize(serializedId);
+
+        return new EndPointId(topologyId, deviceId, id);
+    }
+
+    public ContextOuterClass.EventTypeEnum serialize(EventTypeEnum eventTypeEnum) {
+        switch (eventTypeEnum) {
+            case CREATE:
+                return ContextOuterClass.EventTypeEnum.EVENTTYPE_CREATE;
+            case REMOVE:
+                return ContextOuterClass.EventTypeEnum.EVENTTYPE_REMOVE;
+            case UPDATE:
+                return ContextOuterClass.EventTypeEnum.EVENTTYPE_UPDATE;
+            case UNDEFINED:
+                return ContextOuterClass.EventTypeEnum.EVENTTYPE_UNDEFINED;
+            default:
+                return ContextOuterClass.EventTypeEnum.UNRECOGNIZED;
+        }
+    }
+
+    public EventTypeEnum deserialize(ContextOuterClass.EventTypeEnum serializedEventType) {
+        switch (serializedEventType) {
+            case EVENTTYPE_CREATE:
+                return EventTypeEnum.CREATE;
+            case EVENTTYPE_REMOVE:
+                return EventTypeEnum.REMOVE;
+            case EVENTTYPE_UPDATE:
+                return EventTypeEnum.UPDATE;
+            case EVENTTYPE_UNDEFINED:
+            case UNRECOGNIZED:
+            default:
+                return EventTypeEnum.UNDEFINED;
+        }
+    }
+
+    public ContextOuterClass.Timestamp serialize(double timestamp) {
+        final var builder = ContextOuterClass.Timestamp.newBuilder();
+
+        builder.setTimestamp(timestamp);
+
+        return builder.build();
+    }
+
+    public double deserialize(ContextOuterClass.Timestamp serializedTimeStamp) {
+
+        return serializedTimeStamp.getTimestamp();
+    }
+
+    public ContextOuterClass.Event serialize(Event event) {
+        final var builder = ContextOuterClass.Event.newBuilder();
+
+        final var eventType = serialize(event.getEventTypeEnum());
+        final var timestamp = serialize(event.getTimestamp());
+        builder.setEventType(eventType);
+        builder.setTimestamp(timestamp);
+
+        return builder.build();
+    }
+
+    public Event deserialize(ContextOuterClass.Event serializedEvent) {
+        final var timestamp = deserialize(serializedEvent.getTimestamp());
+        final var eventType = deserialize(serializedEvent.getEventType());
+
+        return new Event(timestamp, eventType);
+    }
+
+    public ContextOuterClass.ServiceId serialize(ServiceId serviceId) {
+        final var builder = ContextOuterClass.ServiceId.newBuilder();
+
+        final var contextId = serviceId.getContextId();
+        final var id = serviceId.getId();
+
+        final var serializedContextId = serializeContextId(contextId);
+        final var serializedId = serializeUuid(id);
+
+        builder.setContextId(serializedContextId);
+        builder.setServiceUuid(serializedId);
+
+        return builder.build();
+    }
+
+    public ServiceId deserialize(ContextOuterClass.ServiceId serializedServiceId) {
+        final var serializedContextId = serializedServiceId.getContextId();
+        final var serializedId = serializedServiceId.getServiceUuid();
+
+        final var contextId = deserialize(serializedContextId);
+        final var id = deserialize(serializedId);
+
+        return new ServiceId(contextId, id);
+    }
+
+    public ContextOuterClass.SliceId serialize(SliceId sliceId) {
+        final var builder = ContextOuterClass.SliceId.newBuilder();
+
+        final var contextId = sliceId.getContextId();
+        final var id = sliceId.getId();
+
+        final var serializedContextId = serializeContextId(contextId);
+        final var serializedId = serializeUuid(id);
+
+        builder.setContextId(serializedContextId);
+        builder.setSliceUuid(serializedId);
+
+        return builder.build();
+    }
+
+    public SliceId deserialize(ContextOuterClass.SliceId serializedSliceId) {
+        final var serializedContextId = serializedSliceId.getContextId();
+        final var serializedId = serializedSliceId.getSliceUuid();
+
+        final var contextId = deserialize(serializedContextId);
+        final var id = deserialize(serializedId);
+
+        return new SliceId(contextId, id);
+    }
+
+    public ContextOuterClass.ServiceStatusEnum serialize(ServiceStatusEnum serviceStatusEnum) {
+        switch (serviceStatusEnum) {
+            case ACTIVE:
+                return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_ACTIVE;
+            case PLANNED:
+                return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_PLANNED;
+            case PENDING_REMOVAL:
+                return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL;
+            case UNDEFINED:
+                return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_UNDEFINED;
+            default:
+                return ContextOuterClass.ServiceStatusEnum.UNRECOGNIZED;
+        }
+    }
+
+    public ServiceStatusEnum deserialize(
+            ContextOuterClass.ServiceStatusEnum serializedServiceStatusEnum) {
+        switch (serializedServiceStatusEnum) {
+            case SERVICESTATUS_ACTIVE:
+                return ServiceStatusEnum.ACTIVE;
+            case SERVICESTATUS_PLANNED:
+                return ServiceStatusEnum.PLANNED;
+            case SERVICESTATUS_PENDING_REMOVAL:
+                return ServiceStatusEnum.PENDING_REMOVAL;
+            case SERVICESTATUS_UNDEFINED:
+            case UNRECOGNIZED:
+            default:
+                return ServiceStatusEnum.UNDEFINED;
+        }
+    }
+
+    public ContextOuterClass.ServiceTypeEnum serialize(ServiceTypeEnum serviceTypeEnum) {
+        switch (serviceTypeEnum) {
+            case L2NM:
+                return ContextOuterClass.ServiceTypeEnum.SERVICETYPE_L2NM;
+            case L3NM:
+                return ContextOuterClass.ServiceTypeEnum.SERVICETYPE_L3NM;
+            case TAPI_CONNECTIVITY_SERVICE:
+                return ContextOuterClass.ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE;
+            case UNKNOWN:
+                return ContextOuterClass.ServiceTypeEnum.SERVICETYPE_UNKNOWN;
+            default:
+                return ContextOuterClass.ServiceTypeEnum.UNRECOGNIZED;
+        }
+    }
+
+    public ServiceTypeEnum deserialize(ContextOuterClass.ServiceTypeEnum serializedServiceTypeEnum) {
+        switch (serializedServiceTypeEnum) {
+            case SERVICETYPE_L2NM:
+                return ServiceTypeEnum.L2NM;
+            case SERVICETYPE_L3NM:
+                return ServiceTypeEnum.L3NM;
+            case SERVICETYPE_TAPI_CONNECTIVITY_SERVICE:
+                return ServiceTypeEnum.TAPI_CONNECTIVITY_SERVICE;
+            case SERVICETYPE_UNKNOWN:
+            case UNRECOGNIZED:
+            default:
+                return ServiceTypeEnum.UNKNOWN;
+        }
+    }
+
+    public ContextOuterClass.ServiceStatus serialize(ServiceStatus serviceStatus) {
+        final var builder = ContextOuterClass.ServiceStatus.newBuilder();
+
+        final var serviceStatusEnum = serviceStatus.getServiceStatus();
+        final var serializedServiceStatusEnum = serialize(serviceStatusEnum);
+
+        builder.setServiceStatus(serializedServiceStatusEnum);
+
+        return builder.build();
+    }
+
+    public ServiceStatus deserialize(ContextOuterClass.ServiceStatus serializedServiceStatus) {
+        final var serializedServiceStatusEnum = serializedServiceStatus.getServiceStatus();
+        final var serviceStatusEnum = deserialize(serializedServiceStatusEnum);
+
+        return new ServiceStatus(serviceStatusEnum);
+    }
+
+    public ContextOuterClass.ServiceConfig serialize(ServiceConfig serviceConfig) {
+        final var builder = ContextOuterClass.ServiceConfig.newBuilder();
+
+        final var serializedConfigRules =
+                serviceConfig.getConfigRules().stream().map(this::serialize).collect(Collectors.toList());
+
+        builder.addAllConfigRules(serializedConfigRules);
+
+        return builder.build();
+    }
+
+    public ServiceConfig deserialize(ContextOuterClass.ServiceConfig serviceConfig) {
+        final var configRules =
+                serviceConfig.getConfigRulesList().stream()
+                        .map(this::deserialize)
+                        .collect(Collectors.toList());
+
+        return new ServiceConfig(configRules);
+    }
+
+    public ContextOuterClass.Service serialize(Service service) {
+        final var builder = ContextOuterClass.Service.newBuilder();
+
+        final var serviceId = service.getServiceId();
+        final var serviceType = service.getServiceType();
+        final var serviceEndPointIds = service.getServiceEndPointIds();
+        final var serviceConstraints = service.getServiceConstraints();
+        final var serviceStatus = service.getServiceStatus();
+        final var serviceConfig = service.getServiceConfig();
+
+        final var serializedServiceId = serialize(serviceId);
+        final var serializedServiceType = serialize(serviceType);
+        final var serializedServiceEndPointIds =
+                serviceEndPointIds.stream().map(this::serialize).collect(Collectors.toList());
+        final var serializedServiceConstraints =
+                serviceConstraints.stream().map(this::serialize).collect(Collectors.toList());
+        final var serializedServiceStatus = serialize(serviceStatus);
+        final var serializedServiceConfig = serialize(serviceConfig);
+
+        builder.setServiceId(serializedServiceId);
+        builder.setServiceType(serializedServiceType);
+        builder.addAllServiceEndpointIds(serializedServiceEndPointIds);
+        builder.addAllServiceConstraints(serializedServiceConstraints);
+        builder.setServiceStatus(serializedServiceStatus);
+        builder.setServiceConfig(serializedServiceConfig);
+
+        return builder.build();
+    }
+
+    public Service deserialize(ContextOuterClass.Service serializedService) {
+
+        final var serializedServiceId = serializedService.getServiceId();
+        final var serializedServiceType = serializedService.getServiceType();
+        final var serializedServiceEndPointIds = serializedService.getServiceEndpointIdsList();
+        final var serializedServiceConstraints = serializedService.getServiceConstraintsList();
+        final var serializedServiceStatus = serializedService.getServiceStatus();
+        final var serializedServiceConfig = serializedService.getServiceConfig();
+
+        final var serviceId = deserialize(serializedServiceId);
+        final var serviceType = deserialize(serializedServiceType);
+        final var serviceEndPointIds =
+                serializedServiceEndPointIds.stream().map(this::deserialize).collect(Collectors.toList());
+        final var serviceConstraints =
+                serializedServiceConstraints.stream().map(this::deserialize).collect(Collectors.toList());
+        final var serviceStatus = deserialize(serializedServiceStatus);
+        final var serviceConfig = deserialize(serializedServiceConfig);
+
+        return new Service(
+                serviceId,
+                serviceType,
+                serviceEndPointIds,
+                serviceConstraints,
+                serviceStatus,
+                serviceConfig);
+    }
+
+    public KpiSampleTypes.KpiSampleType serialize(KpiSampleType kpiSampleType) {
+        switch (kpiSampleType) {
+            case PACKETS_TRANSMITTED:
+                return KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED;
+            case PACKETS_RECEIVED:
+                return KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED;
+            case BYTES_TRANSMITTED:
+                return KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_BYTES_TRANSMITTED;
+            case BYTES_RECEIVED:
+                return KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_BYTES_RECEIVED;
+            case UNKNOWN:
+                return KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN;
+            default:
+                return KpiSampleTypes.KpiSampleType.UNRECOGNIZED;
+        }
+    }
+
+    public KpiSampleType deserialize(KpiSampleTypes.KpiSampleType serializedKpiSampleType) {
+        switch (serializedKpiSampleType) {
+            case KPISAMPLETYPE_PACKETS_TRANSMITTED:
+                return KpiSampleType.PACKETS_TRANSMITTED;
+            case KPISAMPLETYPE_PACKETS_RECEIVED:
+                return KpiSampleType.PACKETS_RECEIVED;
+            case KPISAMPLETYPE_BYTES_TRANSMITTED:
+                return KpiSampleType.BYTES_TRANSMITTED;
+            case KPISAMPLETYPE_BYTES_RECEIVED:
+                return KpiSampleType.BYTES_RECEIVED;
+            case KPISAMPLETYPE_UNKNOWN:
+            default:
+                return KpiSampleType.UNKNOWN;
+        }
+    }
+
+    public Policy.RuleState serialize(RuleState rulestate) {
+        switch (rulestate) {
+            case POLICY_FAILED:
+                return Policy.RuleState.POLICY_FAILED;
+            case POLICY_INSERTED:
+                return Policy.RuleState.POLICY_INSERTED;
+            case POLICY_VALIDATED:
+                return Policy.RuleState.POLICY_VALIDATED;
+            case POLICY_PROVISIONED:
+                return Policy.RuleState.POLICY_PROVISIONED;
+            case POLICY_ACTIVE:
+                return Policy.RuleState.POLICY_ACTIVE;
+            case POLICY_ENFORCED:
+                return Policy.RuleState.POLICY_ENFORCED;
+            case POLICY_INEFFECTIVE:
+                return Policy.RuleState.POLICY_INEFFECTIVE;
+            case POLICY_EFFECTIVE:
+                return Policy.RuleState.POLICY_EFFECTIVE;
+            case POLICY_UPDATED:
+                return Policy.RuleState.POLICY_UPDATED;
+            case POLICY_REMOVED:
+                return Policy.RuleState.POLICY_REMOVED;
+            case POLICY_UNDEFINED:
+                return Policy.RuleState.POLICY_UNDEFINED;
+            default:
+                return Policy.RuleState.UNRECOGNIZED;
+        }
+    }
+
+    public RuleState deserialize(Policy.RuleState serializedRuleState) {
+        switch (serializedRuleState) {
+            case POLICY_INSERTED:
+                return RuleState.POLICY_INSERTED;
+            case POLICY_VALIDATED:
+                return RuleState.POLICY_VALIDATED;
+            case POLICY_PROVISIONED:
+                return RuleState.POLICY_PROVISIONED;
+            case POLICY_ACTIVE:
+                return RuleState.POLICY_ACTIVE;
+            case POLICY_ENFORCED:
+                return RuleState.POLICY_ENFORCED;
+            case POLICY_INEFFECTIVE:
+                return RuleState.POLICY_INEFFECTIVE;
+            case POLICY_EFFECTIVE:
+                return RuleState.POLICY_EFFECTIVE;
+            case POLICY_UPDATED:
+                return RuleState.POLICY_UPDATED;
+            case POLICY_REMOVED:
+                return RuleState.POLICY_REMOVED;
+            case POLICY_FAILED:
+                return RuleState.POLICY_FAILED;
+            case POLICY_UNDEFINED:
+            case UNRECOGNIZED:
+            default:
+                return RuleState.POLICY_UNDEFINED;
+        }
+    }
+
+    public Policy.PolicyRuleState serialize(PolicyRuleState policyRuleState) {
+        final var builder = Policy.PolicyRuleState.newBuilder();
+
+        final var ruleState = policyRuleState.getRuleState();
+
+        final var serializedRuleState = serialize(ruleState);
+
+        builder.setPolicyRuleState(serializedRuleState);
+
+        return builder.build();
+    }
+
+    public PolicyRuleState deserialize(Policy.PolicyRuleState serializedPolicyRuleState) {
+        final var serializedRuleState = serializedPolicyRuleState.getPolicyRuleState();
+
+        final var ruleState = deserialize(serializedRuleState);
+
+        return new PolicyRuleState(ruleState);
+    }
+
+    public PolicyCondition.NumericalOperator serialize(NumericalOperator numericalOperator) {
+        switch (numericalOperator) {
+            case POLICY_RULE_CONDITION_NUMERICAL_EQUAL:
+                return PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_EQUAL;
+            case POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL:
+                return PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL;
+            case POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN:
+                return PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_LESS_THAN;
+            case POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL:
+                return PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL;
+            case POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN:
+                return PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN;
+            case POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL:
+                return PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL;
+            case POLICY_RULE_CONDITION_NUMERICAL_UNDEFINED:
+                return PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_UNDEFINED;
+            default:
+                return PolicyCondition.NumericalOperator.UNRECOGNIZED;
+        }
+    }
+
+    public NumericalOperator deserialize(
+            PolicyCondition.NumericalOperator serializedNumericalOperator) {
+        switch (serializedNumericalOperator) {
+            case POLICYRULE_CONDITION_NUMERICAL_EQUAL:
+                return NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_EQUAL;
+            case POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL:
+                return NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL;
+            case POLICYRULE_CONDITION_NUMERICAL_LESS_THAN:
+                return NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN;
+            case POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL:
+                return NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL;
+            case POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN:
+                return NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN;
+            case POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL:
+                return NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL;
+            case POLICYRULE_CONDITION_NUMERICAL_UNDEFINED:
+            case UNRECOGNIZED:
+            default:
+                return NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_UNDEFINED;
+        }
+    }
+
+    public Monitoring.KpiValue serializeStringKpiValue(KpiValue<String> kpiValue) {
+        final var builder = Monitoring.KpiValue.newBuilder();
+
+        return builder.setStringVal(kpiValue.getValue()).build();
+    }
+
+    public String deserializeStringKpiValue(Monitoring.KpiValue serializedKpiValue) {
+
+        return serializedKpiValue.getStringVal();
+    }
+
+    public Monitoring.KpiValue serializeBooleanKpiValue(KpiValue<Boolean> kpiValue) {
+        final var builder = Monitoring.KpiValue.newBuilder();
+
+        return builder.setBoolVal(kpiValue.getValue()).build();
+    }
+
+    public boolean deserializeBooleanKpiValue(Monitoring.KpiValue serializedKpiValue) {
+
+        return serializedKpiValue.getBoolVal();
+    }
+
+    public Monitoring.KpiValue serializeFloatKpiValue(KpiValue<Float> kpiValue) {
+        final var builder = Monitoring.KpiValue.newBuilder();
+
+        return builder.setFloatVal(kpiValue.getValue()).build();
+    }
+
+    public float deserializeFloatKpiValue(Monitoring.KpiValue serializedKpiValue) {
+
+        return serializedKpiValue.getFloatVal();
+    }
+
+    public Monitoring.KpiValue serializeIntegerKpiValue(KpiValue<Integer> kpiValue) {
+        final var builder = Monitoring.KpiValue.newBuilder();
+
+        return builder.setIntVal(kpiValue.getValue()).build();
+    }
+
+    public int deserializeIntegerKpiValue(Monitoring.KpiValue serializedKpiValue) {
+
+        return serializedKpiValue.getIntVal();
+    }
+
+    public Monitoring.KpiValue serialize(KpiValue<?> kpiValue) {
+        final var builder = Monitoring.KpiValue.newBuilder();
+
+        if (kpiValue.getValue() instanceof Integer) {
+            final var serializedIntegerKpiValue = serializeIntegerKpiValue((KpiValue<Integer>) kpiValue);
+            builder.setIntVal(serializedIntegerKpiValue.getIntVal());
+        }
+        if (kpiValue.getValue() instanceof Float) {
+            final var serializedFloatKpiValue = serializeFloatKpiValue((KpiValue<Float>) kpiValue);
+            builder.setFloatVal(serializedFloatKpiValue.getFloatVal());
+        }
+        if (kpiValue.getValue() instanceof String) {
+            final var serializedStringKpiValue = serializeStringKpiValue((KpiValue<String>) kpiValue);
+            builder.setStringVal(serializedStringKpiValue.getStringVal());
+        }
+        if (kpiValue.getValue() instanceof Boolean) {
+            final var serializedBooleanKpiValue = serializeBooleanKpiValue((KpiValue<Boolean>) kpiValue);
+            builder.setBoolVal(serializedBooleanKpiValue.getBoolVal());
+        }
+
+        return builder.build();
+    }
+
+    public KpiValue deserialize(Monitoring.KpiValue serializedKpiValue) {
+
+        final var typeOfKpiValue = serializedKpiValue.getValueCase();
+
+        switch (typeOfKpiValue) {
+            case INTVAL:
+                final var intValue = deserializeIntegerKpiValue(serializedKpiValue);
+                return new IntegerKpiValue(intValue);
+            case BOOLVAL:
+                final var booleanValue = deserializeBooleanKpiValue(serializedKpiValue);
+                return new BooleanKpiValue(booleanValue);
+            case FLOATVAL:
+                final var floatValue = deserializeFloatKpiValue(serializedKpiValue);
+                return new FloatKpiValue(floatValue);
+            case STRINGVAL:
+                final var stringValue = deserializeStringKpiValue(serializedKpiValue);
+                return new StringKpiValue(stringValue);
+            default:
+            case VALUE_NOT_SET:
+                throw new IllegalStateException("Kpi value not set");
+        }
+    }
+
+    public Monitoring.KpiValueRange serialize(KpiValueRange kpiValueRange) {
+        final var builder = Monitoring.KpiValueRange.newBuilder();
+
+        final var kpiValueMin = kpiValueRange.getKpiMinValue();
+        final var kpiValueMax = kpiValueRange.getKpiMaxValue();
+
+        final var serializedKpiValueMin = serialize(kpiValueMin);
+        final var serializedKpiValueMax = serialize(kpiValueMax);
+
+        builder.setKpiMinValue(serializedKpiValueMin);
+        builder.setKpiMaxValue(serializedKpiValueMax);
+
+        return builder.build();
+    }
+
+    public KpiValueRange deserialize(Monitoring.KpiValueRange serializedKpiValueRange) {
+        final var serializedMinKpiValue = serializedKpiValueRange.getKpiMinValue();
+        final var serializedMaxKpiValue = serializedKpiValueRange.getKpiMaxValue();
+
+        final var minKpiValue = deserialize(serializedMinKpiValue);
+        final var maxKpiValue = deserialize(serializedMaxKpiValue);
+
+        return new KpiValueRange(minKpiValue, maxKpiValue);
+    }
+
+    public Monitoring.AlarmDescriptor serialize(AlarmDescriptor alarmDescriptor) {
+        final var builder = Monitoring.AlarmDescriptor.newBuilder();
+
+        final var alarmDescription = alarmDescriptor.getAlarmDescription();
+        final var name = alarmDescriptor.getName();
+        final var kpiId = alarmDescriptor.getKpiId();
+        final var kpiValueRange = alarmDescriptor.getKpiValueRange();
+        final var timestamp = alarmDescriptor.getTimestamp();
+
+        final var serializedKpiIdUuid = serializeUuid(kpiId);
+        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedKpiValueRange = serialize(kpiValueRange);
+
+        builder.setAlarmDescription(alarmDescription);
+        builder.setName(name);
+        builder.setKpiId(serializedKpiId);
+        builder.setKpiValueRange(serializedKpiValueRange);
+        builder.setTimestamp(timestamp);
+
+        return builder.build();
+    }
+
+    public AlarmDescriptor deserialize(Monitoring.AlarmDescriptor serializedAlarmDescriptor) {
+
+        final var alarmDescription = serializedAlarmDescriptor.getAlarmDescription();
+        final var name = serializedAlarmDescriptor.getName();
+        final var serializedKpiId = serializedAlarmDescriptor.getKpiId();
+        final var serializedKpiValueRange = serializedAlarmDescriptor.getKpiValueRange();
+        final var timestamp = serializedAlarmDescriptor.getTimestamp();
+
+        final var kpiId = deserialize(serializedKpiId);
+        final var kpiValueRange = deserialize(serializedKpiValueRange);
+
+        return new AlarmDescriptor(alarmDescription, name, kpiId, kpiValueRange, timestamp);
+    }
+
+    public Monitoring.AlarmResponse serialize(AlarmResponse alarmResponse) {
+        final var builder = Monitoring.AlarmResponse.newBuilder();
+
+        final var alarmId = alarmResponse.getAlarmId();
+        final var text = alarmResponse.getText();
+        final var kpiValue = alarmResponse.getKpiValue();
+
+        final var serializedAlarmIdUuid = serializeUuid(alarmId);
+        final var serializedAlarmId =
+                Monitoring.AlarmID.newBuilder().setAlarmId(serializedAlarmIdUuid).build();
+        final var serializedKpiValue = serialize(kpiValue);
+
+        builder.setAlarmId(serializedAlarmId);
+        builder.setText(text);
+        builder.setKpiValue(serializedKpiValue);
+
+        return builder.build();
+    }
+
+    public AlarmResponse deserialize(Monitoring.AlarmResponse serializedAlarmResponse) {
+        final var serializedAlarmId = serializedAlarmResponse.getAlarmId().getAlarmId();
+        final var text = serializedAlarmResponse.getText();
+        final var serializedKpiValue = serializedAlarmResponse.getKpiValue();
+
+        final var alarmId = deserialize(serializedAlarmId);
+        final var kpiValue = deserialize(serializedKpiValue);
+
+        return new AlarmResponse(alarmId, text, kpiValue);
+    }
+
+    public Monitoring.SubsDescriptor serialize(SubsDescriptor subDescriptor) {
+        final var builder = Monitoring.SubsDescriptor.newBuilder();
+
+        final var kpiId = subDescriptor.getKpiId();
+        final var samplingDurationS = subDescriptor.getSamplingDurationS();
+        final var samplingIntervalS = subDescriptor.getSamplingIntervalS();
+        final var startDate = subDescriptor.getStartDate();
+        final var endDate = subDescriptor.getEndDate();
+
+        final var serializedKpiIdUuid = serializeUuid(kpiId);
+        final var serializedKpiId = Monitoring.KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+
+        builder.setKpiId(serializedKpiId);
+        builder.setSamplingDurationS(samplingDurationS);
+        builder.setSamplingIntervalS(samplingIntervalS);
+        builder.setStartDate(startDate);
+        builder.setEndDate(endDate);
+
+        return builder.build();
+    }
+
+    public SubsDescriptor deserialize(Monitoring.SubsDescriptor serializedSubDescriptor) {
+        final var serializedKpiId = serializedSubDescriptor.getKpiId();
+        final var samplingDurationS = serializedSubDescriptor.getSamplingDurationS();
+        final var samplingIntervalS = serializedSubDescriptor.getSamplingIntervalS();
+        final var startDate = serializedSubDescriptor.getStartDate();
+        final var endDate = serializedSubDescriptor.getEndDate();
+
+        final var kpiId = deserialize(serializedKpiId);
+
+        return new SubsDescriptor(kpiId, samplingDurationS, samplingIntervalS, startDate, endDate);
+    }
+
+    public PolicyCondition.PolicyRuleCondition serialize(PolicyRuleCondition policyRuleCondition) {
+        final var builder = PolicyCondition.PolicyRuleCondition.newBuilder();
+
+        final var policyRuleConditionKpiId = policyRuleCondition.getKpiId();
+        final var numericalOperator = policyRuleCondition.getNumericalOperator();
+        final var policyRuleConditionKpiValue = policyRuleCondition.getKpiValue();
+
+        final var serializedKpiIdUuid = serializeUuid(policyRuleConditionKpiId);
+        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedNumericalOperator = serialize(numericalOperator);
+        final var serializedPolicyRuleConditionKpiValue = serialize(policyRuleConditionKpiValue);
+
+        builder.setKpiId(serializedKpiId);
+        builder.setNumericalOperator(serializedNumericalOperator);
+        builder.setKpiValue(serializedPolicyRuleConditionKpiValue);
+
+        return builder.build();
+    }
+
+    public PolicyRuleCondition deserialize(
+            PolicyCondition.PolicyRuleCondition serializedPolicyRuleCondition) {
+
+        final var serializedPolicyRuleConditionKpiId =
+                serializedPolicyRuleCondition.getKpiId().getKpiId();
+        final var serializedNumericalOperator = serializedPolicyRuleCondition.getNumericalOperator();
+        final var serializedPolicyRuleConditionKpiValue = serializedPolicyRuleCondition.getKpiValue();
+
+        final var policyRuleConditionKpiId = deserialize(serializedPolicyRuleConditionKpiId);
+        final var numericalOperator = deserialize(serializedNumericalOperator);
+        final var policyRuleConditionKpiValue = deserialize(serializedPolicyRuleConditionKpiValue);
+
+        return new PolicyRuleCondition(
+                policyRuleConditionKpiId, numericalOperator, policyRuleConditionKpiValue);
+    }
+
+    public PolicyAction.PolicyRuleActionEnum serialize(PolicyRuleActionEnum policyRuleActionEnum) {
+        switch (policyRuleActionEnum) {
+            case POLICY_RULE_ACTION_SET_DEVICE_STATUS:
+                return PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_SET_DEVICE_STATUS;
+            case POLICY_RULE_ACTION_ADD_SERVICE_CONFIGRULE:
+                return PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE;
+            case POLICY_RULE_ACTION_ADD_SERVICE_CONSTRAINT:
+                return PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT;
+            case POLICY_RULE_ACTION_NO_ACTION:
+                return PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_NO_ACTION;
+            default:
+                return PolicyAction.PolicyRuleActionEnum.UNRECOGNIZED;
+        }
+    }
+
+    public PolicyRuleActionEnum deserialize(
+            PolicyAction.PolicyRuleActionEnum serializePolicyRuleActionEnum) {
+        switch (serializePolicyRuleActionEnum) {
+            case POLICYRULE_ACTION_SET_DEVICE_STATUS:
+                return PolicyRuleActionEnum.POLICY_RULE_ACTION_SET_DEVICE_STATUS;
+            case POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE:
+                return PolicyRuleActionEnum.POLICY_RULE_ACTION_ADD_SERVICE_CONFIGRULE;
+            case POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT:
+                return PolicyRuleActionEnum.POLICY_RULE_ACTION_ADD_SERVICE_CONSTRAINT;
+            case POLICYRULE_ACTION_NO_ACTION:
+            case UNRECOGNIZED:
+            default:
+                return PolicyRuleActionEnum.POLICY_RULE_ACTION_NO_ACTION;
+        }
+    }
+
+    public PolicyAction.PolicyRuleAction serialize(PolicyRuleAction policyRuleAction) {
+        final var builder = PolicyAction.PolicyRuleAction.newBuilder();
+
+        final var policyRuleActionEnum = policyRuleAction.getPolicyRuleActionEnum();
+        final var policyRuleActionParameters = policyRuleAction.getPolicyRuleActionParameters();
+
+        final var serializedPolicyRuleActionEnum = serialize(policyRuleActionEnum);
+
+        builder.setAction(serializedPolicyRuleActionEnum);
+        builder.addAllParameters(policyRuleActionParameters);
+
+        return builder.build();
+    }
+
+    public PolicyRuleAction deserialize(PolicyAction.PolicyRuleAction serializedPolicyRuleAction) {
+        final var serializedPolicyRuleActionEnum = serializedPolicyRuleAction.getAction();
+        final var policyRuleActionParameters = serializedPolicyRuleAction.getParametersList();
+
+        final var policyRuleActionEnum = deserialize(serializedPolicyRuleActionEnum);
+
+        return new PolicyRuleAction(policyRuleActionEnum, policyRuleActionParameters);
+    }
+
+    public PolicyCondition.BooleanOperator serialize(BooleanOperator booleanOperator) {
+        switch (booleanOperator) {
+            case POLICYRULE_CONDITION_BOOLEAN_AND:
+                return PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_AND;
+            case POLICYRULE_CONDITION_BOOLEAN_OR:
+                return PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_OR;
+            case POLICYRULE_CONDITION_BOOLEAN_UNDEFINED:
+                return PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED;
+            default:
+                return PolicyCondition.BooleanOperator.UNRECOGNIZED;
+        }
+    }
+
+    public BooleanOperator deserialize(PolicyCondition.BooleanOperator serializedBooleanOperator) {
+        switch (serializedBooleanOperator) {
+            case POLICYRULE_CONDITION_BOOLEAN_OR:
+                return BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_OR;
+            case POLICYRULE_CONDITION_BOOLEAN_AND:
+                return BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_AND;
+            case POLICYRULE_CONDITION_BOOLEAN_UNDEFINED:
+            case UNRECOGNIZED:
+            default:
+                return BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED;
+        }
+    }
+
+    public Policy.PolicyRuleBasic serialize(PolicyRuleBasic policyRuleBasic) {
+        final var builder = Policy.PolicyRuleBasic.newBuilder();
+
+        final var policyRuleId = policyRuleBasic.getPolicyRuleId();
+        final var policyRuleState = policyRuleBasic.getPolicyRuleState();
+        final var priority = policyRuleBasic.getPriority();
+        final var policyRuleConditions = policyRuleBasic.getPolicyRuleConditions();
+        final var booleanOperator = policyRuleBasic.getBooleanOperator();
+        final var policyRuleActions = policyRuleBasic.getPolicyRuleActions();
+
+        final var serializedPolicyRuleId = serializePolicyRuleId(policyRuleId);
+        final var serializedPolicyRuleState = serialize(policyRuleState);
+        final var serializedPolicyRuleConditions =
+                policyRuleConditions.stream().map(this::serialize).collect(Collectors.toList());
+        final var serializedBooleanOperator = serialize(booleanOperator);
+        final var serializedPolicyRuleActions =
+                policyRuleActions.stream().map(this::serialize).collect(Collectors.toList());
+
+        builder.setPolicyRuleId(serializedPolicyRuleId);
+        builder.setPolicyRuleState(serializedPolicyRuleState);
+        builder.setPriority(priority);
+        builder.addAllConditionList(serializedPolicyRuleConditions);
+        builder.setBooleanOperator(serializedBooleanOperator);
+        builder.addAllActionList(serializedPolicyRuleActions);
+
+        return builder.build();
+    }
+
+    public PolicyRuleBasic deserialize(Policy.PolicyRuleBasic serializedPolicyRuleBasic) {
+        final var serializedPolicyRuleId = serializedPolicyRuleBasic.getPolicyRuleId();
+        final var serializedPolicyRuleState = serializedPolicyRuleBasic.getPolicyRuleState();
+        final var priority = serializedPolicyRuleBasic.getPriority();
+        final var serializedPolicyRuleConditions = serializedPolicyRuleBasic.getConditionListList();
+        final var serializedBooleanOperator = serializedPolicyRuleBasic.getBooleanOperator();
+        final var serializedPolicyRuleActions = serializedPolicyRuleBasic.getActionListList();
+
+        final var policyRuleId = deserialize(serializedPolicyRuleId);
+        final var policyRuleState = deserialize(serializedPolicyRuleState);
+        final var policyRuleConditions =
+                serializedPolicyRuleConditions.stream().map(this::deserialize).collect(Collectors.toList());
+        final var booleanOperator = deserialize(serializedBooleanOperator);
+        final var policyRuleActions =
+                serializedPolicyRuleActions.stream().map(this::deserialize).collect(Collectors.toList());
+
+        return new PolicyRuleBasic(
+                policyRuleId,
+                policyRuleState,
+                priority,
+                policyRuleConditions,
+                booleanOperator,
+                policyRuleActions);
+    }
+
+    public Policy.PolicyRuleService serialize(PolicyRuleService policyRuleService) {
+        final var builder = Policy.PolicyRuleService.newBuilder();
+
+        final var policyRuleBasic = policyRuleService.getPolicyRuleBasic();
+        final var policyRuleServiceId = policyRuleService.getServiceId();
+        final var policyRuleDeviceIds = policyRuleService.getDeviceIds();
+
+        final var serializedPolicyRuleBasic = serialize(policyRuleBasic);
+        final var serializedPolicyRuleServiceId = serialize(policyRuleServiceId);
+        final var serializedPolicyRuleDeviceIds =
+                policyRuleDeviceIds.stream().map(this::serializeDeviceId).collect(Collectors.toList());
+
+        builder.setPolicyRuleBasic(serializedPolicyRuleBasic);
+        builder.setServiceId(serializedPolicyRuleServiceId);
+        builder.addAllDeviceList(serializedPolicyRuleDeviceIds);
+
+        return builder.build();
+    }
+
+    public PolicyRuleService deserialize(Policy.PolicyRuleService serializedPolicyRuleService) {
+        final var serializedPolicyRuleBasic = serializedPolicyRuleService.getPolicyRuleBasic();
+        final var serializedPolicyRuleServiceId = serializedPolicyRuleService.getServiceId();
+        final var serializedPolicyRuleDeviceIds = serializedPolicyRuleService.getDeviceListList();
+
+        final var policyRuleBasic = deserialize(serializedPolicyRuleBasic);
+        final var policyRuleServiceId = deserialize(serializedPolicyRuleServiceId);
+        final var policyRuleDeviceIds =
+                serializedPolicyRuleDeviceIds.stream().map(this::deserialize).collect(Collectors.toList());
+
+        return new PolicyRuleService(policyRuleBasic, policyRuleServiceId, policyRuleDeviceIds);
+    }
+
+    public Policy.PolicyRuleDevice serialize(PolicyRuleDevice policyRuleDevice) {
+        final var builder = Policy.PolicyRuleDevice.newBuilder();
+
+        final var policyRuleBasic = policyRuleDevice.getPolicyRuleBasic();
+        final var policyRuleDeviceIds = policyRuleDevice.getDeviceIds();
+
+        final var serializedPolicyRuleBasic = serialize(policyRuleBasic);
+        final var serializedPolicyRuleDeviceIds =
+                policyRuleDeviceIds.stream().map(this::serializeDeviceId).collect(Collectors.toList());
+
+        builder.setPolicyRuleBasic(serializedPolicyRuleBasic);
+        builder.addAllDeviceList(serializedPolicyRuleDeviceIds);
+
+        return builder.build();
+    }
+
+    public PolicyRuleDevice deserialize(Policy.PolicyRuleDevice serializedPolicyRuleDevice) {
+        final var serializedPolicyRuleBasic = serializedPolicyRuleDevice.getPolicyRuleBasic();
+        final var serializedPolicyRuleDeviceIds = serializedPolicyRuleDevice.getDeviceListList();
+
+        final var policyRuleBasic = deserialize(serializedPolicyRuleBasic);
+        final var policyRuleDeviceIds =
+                serializedPolicyRuleDeviceIds.stream().map(this::deserialize).collect(Collectors.toList());
+
+        return new PolicyRuleDevice(policyRuleBasic, policyRuleDeviceIds);
+    }
+
+    public KpiId serializeKpiId(String kpiId) {
+        final var builder = Monitoring.KpiId.newBuilder();
+
+        final var serializedKpiIdUuid = serializeUuid(kpiId);
+        builder.setKpiId(serializedKpiIdUuid);
+
+        return builder.build();
+    }
+
+    public String deserialize(KpiId serializedKpiId) {
+        final var serializedKpiIdUuid = serializedKpiId.getKpiId();
+
+        return deserialize(serializedKpiIdUuid);
+    }
+
+    public Monitoring.Kpi serialize(Kpi kpi) {
+        final var builder = Monitoring.Kpi.newBuilder();
+
+        final var kpiId = kpi.getKpiId();
+        final var timestamp = kpi.getTimestamp();
+        final var kpiValue = kpi.getKpiValue();
+
+        final var serializedKpiId = serializeKpiId(kpiId);
+        final var serializedKpiValue = serialize(kpiValue);
+
+        builder.setKpiId(serializedKpiId);
+        builder.setTimestamp(timestamp);
+        builder.setKpiValue(serializedKpiValue);
+
+        return builder.build();
+    }
+
+    public Kpi deserialize(Monitoring.Kpi serializedKpi) {
+
+        final var serializedKpiId = serializedKpi.getKpiId();
+        final var timestamp = serializedKpi.getTimestamp();
+        final var serializedKpiValue = serializedKpi.getKpiValue();
+
+        final var kpiId = deserialize(serializedKpiId);
+        final var kpiValue = deserialize(serializedKpiValue);
+
+        return new Kpi(kpiId, timestamp, kpiValue);
+    }
+
+    public Monitoring.KpiDescriptor serialize(KpiDescriptor kpiDescriptor) {
+        final var builder = Monitoring.KpiDescriptor.newBuilder();
+
+        final var kpiDescriptorDescription = kpiDescriptor.getKpiDescription();
+        final var kpiDescriptorKpiSampleType = kpiDescriptor.getKpiSampleType();
+        final var kpiDescriptorDeviceId = kpiDescriptor.getDeviceId();
+        final var kpiDescriptorEndPointId = kpiDescriptor.getEndPointId();
+        final var kpiDescriptorServiceId = kpiDescriptor.getServiceId();
+        final var kpiDescriptorSliceId = kpiDescriptor.getSliceId();
+
+        final var serializedKpiDescriptorKpiSampleType = serialize(kpiDescriptorKpiSampleType);
+        final var serializedKpiDescriptorDeviceId = serializeDeviceId(kpiDescriptorDeviceId);
+        final var serializedKpiDescriptorEndPointId = serialize(kpiDescriptorEndPointId);
+        final var serializedKpiDescriptorServiceId = serialize(kpiDescriptorServiceId);
+        final var serializedKpiDescriptorSliceId = serialize(kpiDescriptorSliceId);
+
+        builder.setKpiDescription(kpiDescriptorDescription);
+        builder.setKpiSampleType(serializedKpiDescriptorKpiSampleType);
+        builder.setDeviceId(serializedKpiDescriptorDeviceId);
+        builder.setEndpointId(serializedKpiDescriptorEndPointId);
+        builder.setServiceId(serializedKpiDescriptorServiceId);
+        builder.setSliceId(serializedKpiDescriptorSliceId);
+
+        return builder.build();
+    }
+
+    public KpiDescriptor deserialize(Monitoring.KpiDescriptor serializedKpiDescriptor) {
+
+        final var serializedKpiDescriptorDescription = serializedKpiDescriptor.getKpiDescription();
+        final var serializedKpiDescriptorKpiSampleType = serializedKpiDescriptor.getKpiSampleType();
+        final var serializedKpiDescriptorDeviceId = serializedKpiDescriptor.getDeviceId();
+        final var serializedKpiDescriptorEndPointId = serializedKpiDescriptor.getEndpointId();
+        final var serializedKpiDescriptorServiceId = serializedKpiDescriptor.getServiceId();
+        final var serializedKpiDescriptorSLiceId = serializedKpiDescriptor.getSliceId();
+
+        final var kpiSampleType = deserialize(serializedKpiDescriptorKpiSampleType);
+        final var deviceId = deserialize(serializedKpiDescriptorDeviceId);
+        final var endPointId = deserialize(serializedKpiDescriptorEndPointId);
+        final var serviceId = deserialize(serializedKpiDescriptorServiceId);
+        final var sliceId = deserialize(serializedKpiDescriptorSLiceId);
+
+        return new KpiDescriptor(
+                serializedKpiDescriptorDescription,
+                kpiSampleType,
+                deviceId,
+                endPointId,
+                serviceId,
+                sliceId);
+    }
+
+    public Uuid serializeUuid(String uuid) {
+        return Uuid.newBuilder().setUuid(uuid).build();
+    }
+
+    public String deserialize(Uuid uuid) {
+        return uuid.getUuid();
+    }
+}
diff --git a/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java b/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..20b69e422a33507a0c8465bd7597c89eeba9a6f2
--- /dev/null
+++ b/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java
@@ -0,0 +1,3179 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*provideKpiValueRanges
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+import acl.Acl;
+import context.ContextOuterClass;
+import context.ContextOuterClass.ContextId;
+import context.ContextOuterClass.DeviceId;
+import context.ContextOuterClass.Uuid;
+import eu.teraflow.policy.acl.AclAction;
+import eu.teraflow.policy.acl.AclEntry;
+import eu.teraflow.policy.acl.AclForwardActionEnum;
+import eu.teraflow.policy.acl.AclLogActionEnum;
+import eu.teraflow.policy.acl.AclMatch;
+import eu.teraflow.policy.acl.AclRuleSet;
+import eu.teraflow.policy.acl.AclRuleTypeEnum;
+import eu.teraflow.policy.context.model.ConfigActionEnum;
+import eu.teraflow.policy.context.model.ConfigRule;
+import eu.teraflow.policy.context.model.ConfigRuleAcl;
+import eu.teraflow.policy.context.model.ConfigRuleCustom;
+import eu.teraflow.policy.context.model.ConfigRuleTypeAcl;
+import eu.teraflow.policy.context.model.ConfigRuleTypeCustom;
+import eu.teraflow.policy.context.model.Constraint;
+import eu.teraflow.policy.context.model.ConstraintCustom;
+import eu.teraflow.policy.context.model.ConstraintEndPointLocation;
+import eu.teraflow.policy.context.model.ConstraintSchedule;
+import eu.teraflow.policy.context.model.ConstraintSlaAvailability;
+import eu.teraflow.policy.context.model.ConstraintSlaCapacity;
+import eu.teraflow.policy.context.model.ConstraintSlaIsolationLevel;
+import eu.teraflow.policy.context.model.ConstraintSlaLatency;
+import eu.teraflow.policy.context.model.ConstraintTypeCustom;
+import eu.teraflow.policy.context.model.ConstraintTypeEndPointLocation;
+import eu.teraflow.policy.context.model.ConstraintTypeSchedule;
+import eu.teraflow.policy.context.model.ConstraintTypeSlaAvailability;
+import eu.teraflow.policy.context.model.ConstraintTypeSlaCapacity;
+import eu.teraflow.policy.context.model.ConstraintTypeSlaIsolationLevel;
+import eu.teraflow.policy.context.model.ConstraintTypeSlaLatency;
+import eu.teraflow.policy.context.model.EndPointId;
+import eu.teraflow.policy.context.model.Event;
+import eu.teraflow.policy.context.model.EventTypeEnum;
+import eu.teraflow.policy.context.model.GpsPosition;
+import eu.teraflow.policy.context.model.IsolationLevelEnum;
+import eu.teraflow.policy.context.model.Location;
+import eu.teraflow.policy.context.model.LocationTypeGpsPosition;
+import eu.teraflow.policy.context.model.LocationTypeRegion;
+import eu.teraflow.policy.context.model.Service;
+import eu.teraflow.policy.context.model.ServiceConfig;
+import eu.teraflow.policy.context.model.ServiceId;
+import eu.teraflow.policy.context.model.ServiceStatus;
+import eu.teraflow.policy.context.model.ServiceStatusEnum;
+import eu.teraflow.policy.context.model.ServiceTypeEnum;
+import eu.teraflow.policy.context.model.SliceId;
+import eu.teraflow.policy.context.model.TopologyId;
+import eu.teraflow.policy.kpi_sample_types.model.KpiSampleType;
+import eu.teraflow.policy.model.BooleanOperator;
+import eu.teraflow.policy.model.NumericalOperator;
+import eu.teraflow.policy.model.PolicyRuleAction;
+import eu.teraflow.policy.model.PolicyRuleActionEnum;
+import eu.teraflow.policy.model.PolicyRuleBasic;
+import eu.teraflow.policy.model.PolicyRuleCondition;
+import eu.teraflow.policy.model.PolicyRuleDevice;
+import eu.teraflow.policy.model.PolicyRuleService;
+import eu.teraflow.policy.model.PolicyRuleState;
+import eu.teraflow.policy.model.RuleState;
+import eu.teraflow.policy.monitoring.model.AlarmDescriptor;
+import eu.teraflow.policy.monitoring.model.AlarmResponse;
+import eu.teraflow.policy.monitoring.model.BooleanKpiValue;
+import eu.teraflow.policy.monitoring.model.FloatKpiValue;
+import eu.teraflow.policy.monitoring.model.IntegerKpiValue;
+import eu.teraflow.policy.monitoring.model.Kpi;
+import eu.teraflow.policy.monitoring.model.KpiDescriptor;
+import eu.teraflow.policy.monitoring.model.KpiValue;
+import eu.teraflow.policy.monitoring.model.KpiValueRange;
+import eu.teraflow.policy.monitoring.model.StringKpiValue;
+import eu.teraflow.policy.monitoring.model.SubsDescriptor;
+import io.quarkus.test.junit.QuarkusTest;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.inject.Inject;
+import kpi_sample_types.KpiSampleTypes;
+import monitoring.Monitoring;
+import monitoring.Monitoring.AlarmID;
+import monitoring.Monitoring.KpiId;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import policy.Policy;
+import policy.Policy.PolicyRuleId;
+import policy.PolicyAction;
+import policy.PolicyCondition;
+
+@QuarkusTest
+class SerializerTest {
+    @Inject Serializer serializer;
+
+    private AclMatch createAclMatch(
+            int dscp,
+            int protocol,
+            String srcAddress,
+            String dstAddress,
+            int srcPort,
+            int dstPort,
+            int startMplsLabel,
+            int endMplsLabel) {
+        return new AclMatch(
+                dscp, protocol, srcAddress, dstAddress, srcPort, dstPort, startMplsLabel, endMplsLabel);
+    }
+
+    private AclAction createAclAction(
+            AclForwardActionEnum forwardActionEnum, AclLogActionEnum logActionEnum) {
+
+        return new AclAction(forwardActionEnum, logActionEnum);
+    }
+
+    private AclEntry createAclEntry(
+            int sequenceId, String description, AclMatch aclMatch, AclAction aclAction) {
+
+        return new AclEntry(sequenceId, description, aclMatch, aclAction);
+    }
+
+    private PolicyRuleBasic createPolicyRuleBasic() {
+        final var expectedPolicyRuleId = "expectedPolicyRuleId";
+        final var expectedPolicyRuleState = new PolicyRuleState(RuleState.POLICY_EFFECTIVE);
+        final var expectedPriority = 3;
+
+        final var firstKpiValue = new IntegerKpiValue(22);
+        final var secondKpiValue = new FloatKpiValue(69.1f);
+
+        final var firstExpectedPolicyRuleCondition =
+                new PolicyRuleCondition(
+                        "firstExpectedPolicyRuleConditionVariable",
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN,
+                        firstKpiValue);
+        final var secondExpectedPolicyRuleCondition =
+                new PolicyRuleCondition(
+                        "secondExpectedPolicyRuleConditionVariable",
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_EQUAL,
+                        secondKpiValue);
+
+        final var expectedPolicyRuleConditions =
+                List.of(firstExpectedPolicyRuleCondition, secondExpectedPolicyRuleCondition);
+
+        final var expectedBooleanOperator = BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_OR;
+
+        final var firstExpectedPolicyRuleAction =
+                new PolicyRuleAction(
+                        PolicyRuleActionEnum.POLICY_RULE_ACTION_SET_DEVICE_STATUS,
+                        List.of("parameter1", "parameter2"));
+
+        final var secondExpectedPolicyRuleAction =
+                new PolicyRuleAction(
+                        PolicyRuleActionEnum.POLICY_RULE_ACTION_ADD_SERVICE_CONFIGRULE,
+                        List.of("parameter3", "parameter4"));
+
+        final var expectedPolicyRuleActions =
+                List.of(firstExpectedPolicyRuleAction, secondExpectedPolicyRuleAction);
+
+        return new PolicyRuleBasic(
+                expectedPolicyRuleId,
+                expectedPolicyRuleState,
+                expectedPriority,
+                expectedPolicyRuleConditions,
+                expectedBooleanOperator,
+                expectedPolicyRuleActions);
+    }
+
+    private ConfigRule createConfigRule() {
+        final var contextIdUuid = "contextId";
+        final var topologyIdUuid = "topologyUuid";
+        final var deviceIdUuid = "deviceIdUuid";
+        final var endpointIdUuid = "endpointIdUuid";
+
+        final var topologyId = new TopologyId(contextIdUuid, topologyIdUuid);
+        final var endPointId = new EndPointId(topologyId, deviceIdUuid, endpointIdUuid);
+
+        final var aclMatch = createAclMatch(1, 1, "127.0.0.1", "127.0.0.2", 5601, 5602, 1, 2);
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+        final var aclEntry = createAclEntry(1, "aclEntryDescription", aclMatch, aclAction);
+
+        final var aclRuleSet =
+                new AclRuleSet(
+                        "aclRuleName", AclRuleTypeEnum.IPV4, "AclRuleDescription", "userId", List.of(aclEntry));
+
+        final var configRuleAcl = new ConfigRuleAcl(endPointId, aclRuleSet);
+        final var configRuleTypeAcl = new ConfigRuleTypeAcl(configRuleAcl);
+
+        return new ConfigRule(ConfigActionEnum.SET, configRuleTypeAcl);
+    }
+
+    @Test
+    void shouldSerializeDeviceId() {
+        final var deviceId = "deviceId";
+
+        final var deviceIdUuid = serializer.serializeUuid(deviceId);
+        final var expectedDeviceId =
+                ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(deviceIdUuid).build();
+
+        final var serializedDeviceId = serializer.serializeDeviceId(deviceId);
+
+        assertThat(serializedDeviceId).usingRecursiveComparison().isEqualTo(expectedDeviceId);
+    }
+
+    @Test
+    void shouldDeserializeDeviceId() {
+        final var expectedDeviceId = "expectedDeviceId";
+
+        final var serializedDeviceIdUuid = serializer.serializeUuid(expectedDeviceId);
+        final var serializedDeviceId =
+                DeviceId.newBuilder().setDeviceUuid(serializedDeviceIdUuid).build();
+
+        final var deviceId = serializer.deserialize(serializedDeviceId);
+
+        assertThat(deviceId).isEqualTo(expectedDeviceId);
+    }
+
+    @Test
+    void shouldSerializeContextId() {
+        final var contextId = "contextId";
+
+        final var contextIdUuid = serializer.serializeUuid(contextId);
+
+        final var expectedContextId =
+                ContextOuterClass.ContextId.newBuilder().setContextUuid(contextIdUuid).build();
+
+        final var serializedContextId = serializer.serializeContextId(contextId);
+
+        assertThat(serializedContextId).usingRecursiveComparison().isEqualTo(expectedContextId);
+    }
+
+    @Test
+    void shouldDeserializeContextId() {
+        final var expectedContextId = "expectedContextId";
+
+        final var serializedContextIdUuid = serializer.serializeUuid(expectedContextId);
+        final var serializedContextId =
+                ContextId.newBuilder().setContextUuid(serializedContextIdUuid).build();
+
+        final var contextId = serializer.deserialize(serializedContextId);
+
+        assertThat(contextId).isEqualTo(expectedContextId);
+    }
+
+    @Test
+    void shouldSerializePolicyRuleId() {
+        final var policyRuleId = "policyRuleId";
+
+        final var policyRuleIdUuid = serializer.serializeUuid(policyRuleId);
+        final var expectedPolicyRuleId =
+                Policy.PolicyRuleId.newBuilder().setUuid(policyRuleIdUuid).build();
+
+        final var serializedPolicyRuleId = serializer.serializePolicyRuleId(policyRuleId);
+
+        assertThat(serializedPolicyRuleId).usingRecursiveComparison().isEqualTo(expectedPolicyRuleId);
+    }
+
+    @Test
+    void shouldDeserializePolicyRuleId() {
+        final var expectedPolicyRuleId = "expectedPolicyRuleId";
+
+        final var serializedPolicyRuleIdUuid = serializer.serializeUuid(expectedPolicyRuleId);
+        final var serializedPolicyRuleId =
+                PolicyRuleId.newBuilder().setUuid(serializedPolicyRuleIdUuid).build();
+
+        final var policyRuleId = serializer.deserialize(serializedPolicyRuleId);
+
+        assertThat(policyRuleId).isEqualTo(expectedPolicyRuleId);
+    }
+
+    @Test
+    void shouldSerializeTopologyId() {
+        final var expectedContextId = "expectedContextId";
+        final var expectedId = "expectedId";
+        final var topologyId = new TopologyId(expectedContextId, expectedId);
+
+        final var serializedContextId = serializer.serializeContextId(expectedContextId);
+        final var serializedIdUuid = serializer.serializeUuid(expectedId);
+
+        final var expectedTopologyId =
+                ContextOuterClass.TopologyId.newBuilder()
+                        .setContextId(serializedContextId)
+                        .setTopologyUuid(serializedIdUuid)
+                        .build();
+
+        final var serializedTopologyId = serializer.serialize(topologyId);
+
+        assertThat(serializedTopologyId).usingRecursiveComparison().isEqualTo(expectedTopologyId);
+    }
+
+    @Test
+    void shouldDeserializeTopologyId() {
+        final var expectedContextId = "expectedContextId";
+        final var expectedId = "expectedId";
+
+        final var expectedTopologyId = new TopologyId(expectedContextId, expectedId);
+
+        final var serializedTopologyId = serializer.serialize(expectedTopologyId);
+        final var topologyId = serializer.deserialize(serializedTopologyId);
+
+        assertThat(topologyId).usingRecursiveComparison().isEqualTo(expectedTopologyId);
+    }
+
+    private static Stream<Arguments> provideConfigActionEnum() {
+        return Stream.of(
+                Arguments.of(ConfigActionEnum.SET, ContextOuterClass.ConfigActionEnum.CONFIGACTION_SET),
+                Arguments.of(
+                        ConfigActionEnum.DELETE, ContextOuterClass.ConfigActionEnum.CONFIGACTION_DELETE),
+                Arguments.of(
+                        ConfigActionEnum.UNDEFINED, ContextOuterClass.ConfigActionEnum.CONFIGACTION_UNDEFINED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideConfigActionEnum")
+    void shouldSerializeConfigActionEnum(
+            ConfigActionEnum configActionEnum,
+            ContextOuterClass.ConfigActionEnum expectedConfigActionEnum) {
+        final var serializedType = serializer.serialize(configActionEnum);
+        assertThat(serializedType.getNumber()).isEqualTo(expectedConfigActionEnum.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideConfigActionEnum")
+    void shouldDeserializeConfigActionEnum(
+            ConfigActionEnum expectedConfigActionEnum,
+            ContextOuterClass.ConfigActionEnum serializedConfigActionEnum) {
+
+        final var configActionEnum = serializer.deserialize(serializedConfigActionEnum);
+
+        assertThat(configActionEnum).isEqualTo(expectedConfigActionEnum);
+    }
+
+    private static Stream<Arguments> provideAclRuleTypeEnum() {
+        return Stream.of(
+                Arguments.of(AclRuleTypeEnum.IPV4, Acl.AclRuleTypeEnum.ACLRULETYPE_IPV4),
+                Arguments.of(AclRuleTypeEnum.IPV6, Acl.AclRuleTypeEnum.ACLRULETYPE_IPV6),
+                Arguments.of(AclRuleTypeEnum.L2, Acl.AclRuleTypeEnum.ACLRULETYPE_L2),
+                Arguments.of(AclRuleTypeEnum.MPLS, Acl.AclRuleTypeEnum.ACLRULETYPE_MPLS),
+                Arguments.of(AclRuleTypeEnum.MIXED, Acl.AclRuleTypeEnum.ACLRULETYPE_MIXED),
+                Arguments.of(AclRuleTypeEnum.UNDEFINED, Acl.AclRuleTypeEnum.ACLRULETYPE_UNDEFINED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideAclRuleTypeEnum")
+    void shouldSerializeAclRuleTypeEnum(
+            AclRuleTypeEnum aclRuleTypeEnum, Acl.AclRuleTypeEnum expectedAclRuleTypeEnum) {
+        final var serializedAclRuleTypeEnum = serializer.serialize(aclRuleTypeEnum);
+        assertThat(serializedAclRuleTypeEnum.getNumber())
+                .isEqualTo(expectedAclRuleTypeEnum.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideAclRuleTypeEnum")
+    void shouldDeserializeAclRuleTypeEnum(
+            AclRuleTypeEnum expectedAclRuleTypeEnum, Acl.AclRuleTypeEnum serializedAclRuleTypeEnum) {
+        final var aclRuleTypeEnum = serializer.deserialize(serializedAclRuleTypeEnum);
+        assertThat(aclRuleTypeEnum).isEqualTo(expectedAclRuleTypeEnum);
+    }
+
+    private static Stream<Arguments> provideAclForwardActionEnum() {
+        return Stream.of(
+                Arguments.of(AclForwardActionEnum.DROP, Acl.AclForwardActionEnum.ACLFORWARDINGACTION_DROP),
+                Arguments.of(
+                        AclForwardActionEnum.ACCEPT, Acl.AclForwardActionEnum.ACLFORWARDINGACTION_ACCEPT),
+                Arguments.of(
+                        AclForwardActionEnum.REJECT, Acl.AclForwardActionEnum.ACLFORWARDINGACTION_REJECT),
+                Arguments.of(
+                        AclForwardActionEnum.UNDEFINED,
+                        Acl.AclForwardActionEnum.ACLFORWARDINGACTION_UNDEFINED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideAclForwardActionEnum")
+    void shouldSerializeAclForwardActionEnum(
+            AclForwardActionEnum aclForwardActionEnum,
+            Acl.AclForwardActionEnum expectedAclForwardActionEnum) {
+        final var serializedAclForwardActionEnum = serializer.serialize(aclForwardActionEnum);
+        assertThat(serializedAclForwardActionEnum.getNumber())
+                .isEqualTo(expectedAclForwardActionEnum.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideAclForwardActionEnum")
+    void shouldDeserializeAclForwardActionEnum(
+            AclForwardActionEnum expectedAclForwardActionEnum,
+            Acl.AclForwardActionEnum serializedAclForwardActionEnum) {
+        final var aclForwardActionEnum = serializer.deserialize(serializedAclForwardActionEnum);
+        assertThat(aclForwardActionEnum).isEqualTo(expectedAclForwardActionEnum);
+    }
+
+    private static Stream<Arguments> provideAclLogActionEnum() {
+        return Stream.of(
+                Arguments.of(AclLogActionEnum.NO_LOG, Acl.AclLogActionEnum.ACLLOGACTION_NOLOG),
+                Arguments.of(AclLogActionEnum.SYSLOG, Acl.AclLogActionEnum.ACLLOGACTION_SYSLOG),
+                Arguments.of(AclLogActionEnum.UNDEFINED, Acl.AclLogActionEnum.ACLLOGACTION_UNDEFINED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideAclLogActionEnum")
+    void shouldSerializeAclLogActionEnum(
+            AclLogActionEnum aclLogActionEnum, Acl.AclLogActionEnum expectedAclLogActionEnum) {
+        final var serializedAclLogActionEnum = serializer.serialize(aclLogActionEnum);
+        assertThat(serializedAclLogActionEnum.getNumber())
+                .isEqualTo(expectedAclLogActionEnum.getNumber());
+    }
+
+    @Test
+    void shouldSerializeAclAction() {
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+
+        final var expectedAclAction =
+                Acl.AclAction.newBuilder()
+                        .setForwardAction(Acl.AclForwardActionEnum.ACLFORWARDINGACTION_ACCEPT)
+                        .setLogAction(Acl.AclLogActionEnum.ACLLOGACTION_SYSLOG)
+                        .build();
+
+        final var serializedAclAction = serializer.serialize(aclAction);
+
+        assertThat(serializedAclAction).usingRecursiveComparison().isEqualTo(expectedAclAction);
+    }
+
+    @Test
+    void shouldDeserializeAclAction() {
+        final var expectedAclAction =
+                createAclAction(AclForwardActionEnum.DROP, AclLogActionEnum.NO_LOG);
+
+        final var serializedAclAction = serializer.serialize(expectedAclAction);
+        final var aclAction = serializer.deserialize(serializedAclAction);
+
+        assertThat(aclAction).usingRecursiveComparison().isEqualTo(expectedAclAction);
+    }
+
+    @Test
+    void shouldSerializeAclMatch() {
+        final var aclMatch = createAclMatch(1, 1, "127.0.0.1", "127.0.0.2", 5601, 5602, 1, 2);
+
+        final var expectedAclMatch =
+                Acl.AclMatch.newBuilder()
+                        .setDscp(1)
+                        .setProtocol(1)
+                        .setSrcAddress("127.0.0.1")
+                        .setDstAddress("127.0.0.2")
+                        .setSrcPort(5601)
+                        .setDstPort(5602)
+                        .setStartMplsLabel(1)
+                        .setEndMplsLabel(2)
+                        .build();
+
+        final var serializedAclMatch = serializer.serialize(aclMatch);
+
+        assertThat(serializedAclMatch).usingRecursiveComparison().isEqualTo(expectedAclMatch);
+    }
+
+    @Test
+    void shouldDeserializeAclMatch() {
+        final var expectedAclMatch = createAclMatch(7, 2, "127.0.0.5", "127.0.0.6", 32456, 3123, 5, 10);
+
+        final var serializedAclMatch = serializer.serialize(expectedAclMatch);
+        final var aclMatch = serializer.deserialize(serializedAclMatch);
+
+        assertThat(aclMatch).usingRecursiveComparison().isEqualTo(expectedAclMatch);
+    }
+
+    @Test
+    void shouldSerializeAclEntry() {
+        final var sequenceId = 1;
+        final var description = "aclEntryDescription";
+
+        final var aclMatch = createAclMatch(1, 2, "127.0.0.1", "127.0.0.2", 5601, 5602, 5, 10);
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+        final var aclEntry = createAclEntry(sequenceId, description, aclMatch, aclAction);
+
+        final var serializedAclMatch = serializer.serialize(aclMatch);
+        final var serializedAclAction = serializer.serialize(aclAction);
+
+        final var expectedAclEntry =
+                Acl.AclEntry.newBuilder()
+                        .setSequenceId(sequenceId)
+                        .setDescription(description)
+                        .setMatch(serializedAclMatch)
+                        .setAction(serializedAclAction)
+                        .build();
+
+        final var serializedAclEntry = serializer.serialize(aclEntry);
+
+        assertThat(serializedAclEntry).usingRecursiveComparison().isEqualTo(expectedAclEntry);
+    }
+
+    @Test
+    void shouldDeserializeAclEntry() {
+        final var sequenceId = 7;
+        final var description = "aclEntryDescriptor";
+
+        final var aclMatch = createAclMatch(1, 2, "127.0.0.1", "127.0.0.2", 5601, 5602, 5, 10);
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+        final var expectedAclEntry = createAclEntry(sequenceId, description, aclMatch, aclAction);
+
+        final var serializedAclEntry = serializer.serialize(expectedAclEntry);
+        final var aclEntry = serializer.deserialize(serializedAclEntry);
+
+        assertThat(aclEntry).usingRecursiveComparison().isEqualTo(expectedAclEntry);
+    }
+
+    @Test
+    void shouldSerializeAclRuleSet() {
+        final var sequenceId = 1;
+        final var aclEntryDescription = "aclEntryDescription";
+
+        final var aclRuleSetName = "aclRuleSetName";
+        final var aclRuleSetDescription = "aclRuleSetDescription";
+        final var aclRuleSetUserId = "aclRuleSetUserId";
+
+        final var aclMatch = createAclMatch(1, 2, "127.0.0.1", "127.0.0.2", 5601, 5602, 5, 10);
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+        final var aclEntry = createAclEntry(sequenceId, aclEntryDescription, aclMatch, aclAction);
+        final var aclRuleSet =
+                new AclRuleSet(
+                        aclRuleSetName,
+                        AclRuleTypeEnum.MIXED,
+                        aclRuleSetDescription,
+                        aclRuleSetUserId,
+                        List.of(aclEntry));
+
+        final var serializedAclEntry = serializer.serialize(aclEntry);
+        final var serializedAclEntries = List.of(serializedAclEntry);
+
+        final var expectedAclRuleSet =
+                Acl.AclRuleSet.newBuilder()
+                        .setName(aclRuleSetName)
+                        .setType(Acl.AclRuleTypeEnum.ACLRULETYPE_MIXED)
+                        .setDescription(aclRuleSetDescription)
+                        .setUserId(aclRuleSetUserId)
+                        .addAllEntries(serializedAclEntries)
+                        .build();
+
+        final var serializedAclRuleset = serializer.serialize(aclRuleSet);
+
+        assertThat(serializedAclRuleset).usingRecursiveComparison().isEqualTo(expectedAclRuleSet);
+    }
+
+    @Test
+    void shouldDeserializeAclRuleSet() {
+        final var sequenceId = 1;
+        final var aclEntryDescription = "aclEntryDescription";
+
+        final var aclRuleSetName = "aclRuleSetName";
+        final var aclRuleSetDescription = "aclRuleSetDescription";
+        final var aclRuleSetUserId = "aclRuleSetUserId";
+
+        final var aclMatch = createAclMatch(1, 2, "127.0.0.1", "127.0.0.2", 5601, 5602, 5, 10);
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+        final var aclEntry = createAclEntry(sequenceId, aclEntryDescription, aclMatch, aclAction);
+        final var expectedAclRuleSet =
+                new AclRuleSet(
+                        aclRuleSetName,
+                        AclRuleTypeEnum.MIXED,
+                        aclRuleSetDescription,
+                        aclRuleSetUserId,
+                        List.of(aclEntry));
+
+        final var serializedAclRuleSet = serializer.serialize(expectedAclRuleSet);
+        final var aclRuleSet = serializer.deserialize(serializedAclRuleSet);
+
+        assertThat(aclRuleSet).usingRecursiveComparison().isEqualTo(expectedAclRuleSet);
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideAclLogActionEnum")
+    void shouldDeserializeAclLogActionEnum(
+            AclLogActionEnum expectedAclLogActionEnum, Acl.AclLogActionEnum serializedAclLogActionEnum) {
+        final var aclLogActionEnum = serializer.deserialize(serializedAclLogActionEnum);
+        assertThat(aclLogActionEnum).isEqualTo(expectedAclLogActionEnum);
+    }
+
+    @Test
+    void shouldSerializeConfigRuleAcl() {
+        final var expectedTopologyId = new TopologyId("contextId", "id");
+        final var expectedDeviceId = "expectedDeviceId";
+        final var expectedId = "expectedId";
+
+        final var sequenceId = 1;
+        final var aclEntryDescription = "aclEntryDescription";
+
+        final var aclRuleSetName = "aclRuleSetName";
+        final var aclRuleSetDescription = "aclRuleSetDescription";
+        final var aclRuleSetUserId = "aclRuleSetUserId";
+
+        final var endPointId = new EndPointId(expectedTopologyId, expectedDeviceId, expectedId);
+
+        final var aclMatch = createAclMatch(1, 2, "127.0.0.1", "127.0.0.2", 5601, 5602, 5, 10);
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+        final var aclEntry = createAclEntry(sequenceId, aclEntryDescription, aclMatch, aclAction);
+        final var aclRuleSet =
+                new AclRuleSet(
+                        aclRuleSetName,
+                        AclRuleTypeEnum.MIXED,
+                        aclRuleSetDescription,
+                        aclRuleSetUserId,
+                        List.of(aclEntry));
+
+        final var configRuleAcl = new ConfigRuleAcl(endPointId, aclRuleSet);
+
+        final var serializedEndPointId = serializer.serialize(endPointId);
+        final var serializedAclRuleSet = serializer.serialize(aclRuleSet);
+
+        final var expectedConfigRuleAcl =
+                ContextOuterClass.ConfigRule_ACL.newBuilder()
+                        .setEndpointId(serializedEndPointId)
+                        .setRuleSet(serializedAclRuleSet)
+                        .build();
+
+        final var serializedConfigRuleAcl = serializer.serialize(configRuleAcl);
+
+        assertThat(serializedConfigRuleAcl).usingRecursiveComparison().isEqualTo(expectedConfigRuleAcl);
+    }
+
+    @Test
+    void shouldDeserializeConfigRuleAcl() {
+        final var expectedTopologyId = new TopologyId("contextId", "id");
+        final var expectedDeviceId = "expectedDeviceId";
+        final var expectedId = "expectedId";
+
+        final var sequenceId = 1;
+        final var aclEntryDescription = "aclEntryDescription";
+
+        final var aclRuleSetName = "aclRuleSetName";
+        final var aclRuleSetDescription = "aclRuleSetDescription";
+        final var aclRuleSetUserId = "aclRuleSetUserId";
+
+        final var endPointId = new EndPointId(expectedTopologyId, expectedDeviceId, expectedId);
+
+        final var aclMatch = createAclMatch(1, 2, "127.0.0.1", "127.0.0.2", 5601, 5602, 5, 10);
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+        final var aclEntry = createAclEntry(sequenceId, aclEntryDescription, aclMatch, aclAction);
+        final var aclRuleSet =
+                new AclRuleSet(
+                        aclRuleSetName,
+                        AclRuleTypeEnum.MIXED,
+                        aclRuleSetDescription,
+                        aclRuleSetUserId,
+                        List.of(aclEntry));
+
+        final var expectedConfigRuleAcl = new ConfigRuleAcl(endPointId, aclRuleSet);
+
+        final var serializedConfigRuleAcl = serializer.serialize(expectedConfigRuleAcl);
+        final var configRuleAcl = serializer.deserialize(serializedConfigRuleAcl);
+
+        assertThat(configRuleAcl).usingRecursiveComparison().isEqualTo(expectedConfigRuleAcl);
+    }
+
+    @Test
+    void shouldSerializeConfigRuleCustom() {
+        final var resourceKey = "resourceKey";
+        final var resourceValue = "resourceValue";
+
+        final var configRuleCustom = new ConfigRuleCustom(resourceKey, resourceValue);
+
+        final var expectedConfigRuleCustom =
+                ContextOuterClass.ConfigRule_Custom.newBuilder()
+                        .setResourceKey(resourceKey)
+                        .setResourceValue(resourceValue)
+                        .build();
+
+        final var serializedConfigRuleCustom = serializer.serialize(configRuleCustom);
+
+        assertThat(serializedConfigRuleCustom)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConfigRuleCustom);
+    }
+
+    @Test
+    void shouldDeserializeConfigRuleCustom() {
+        final var resourceKey = "resourceKey";
+        final var resourceValue = "resourceValue";
+
+        final var expectedConfigRuleCustom = new ConfigRuleCustom(resourceKey, resourceValue);
+
+        final var serializedConfigRuleCustom = serializer.serialize(expectedConfigRuleCustom);
+        final var configRuleCustom = serializer.deserialize(serializedConfigRuleCustom);
+
+        assertThat(configRuleCustom).usingRecursiveComparison().isEqualTo(expectedConfigRuleCustom);
+    }
+
+    @Test
+    void shouldSerializeConfigRuleofTypeConfigRuleAcl() {
+        final var contextIdUuid = "contextId";
+        final var topologyIdUuid = "topologyUuid";
+        final var deviceIdUuid = "deviceIdUuid";
+        final var endpointIdUuid = "endpointIdUuid";
+
+        final var expectedSerializedContextId = serializer.serializeContextId(contextIdUuid);
+        final var expectedSerializedTopologyIdUuid = serializer.serializeUuid(topologyIdUuid);
+        final var expectedSerializedDeviceId = serializer.serializeDeviceId(deviceIdUuid);
+        final var expectedSerializedEndPointIdUuid = serializer.serializeUuid(endpointIdUuid);
+
+        final var expectedSerializedTopologyId =
+                ContextOuterClass.TopologyId.newBuilder()
+                        .setContextId(expectedSerializedContextId)
+                        .setTopologyUuid(expectedSerializedTopologyIdUuid)
+                        .build();
+
+        final var topologyId = new TopologyId(contextIdUuid, topologyIdUuid);
+
+        final var expectedSerializedEndPointId =
+                ContextOuterClass.EndPointId.newBuilder()
+                        .setTopologyId(expectedSerializedTopologyId)
+                        .setDeviceId(expectedSerializedDeviceId)
+                        .setEndpointUuid(expectedSerializedEndPointIdUuid)
+                        .build();
+
+        final var endPointId = new EndPointId(topologyId, deviceIdUuid, endpointIdUuid);
+
+        final var expectedSerializedAclMatch =
+                Acl.AclMatch.newBuilder()
+                        .setDscp(1)
+                        .setProtocol(1)
+                        .setSrcAddress("127.0.0.1")
+                        .setDstAddress("127.0.0.2")
+                        .setSrcPort(5601)
+                        .setDstPort(5602)
+                        .setStartMplsLabel(1)
+                        .setEndMplsLabel(2)
+                        .build();
+
+        final var aclMatch = createAclMatch(1, 1, "127.0.0.1", "127.0.0.2", 5601, 5602, 1, 2);
+
+        final var expectedSerializedAclAction =
+                Acl.AclAction.newBuilder()
+                        .setForwardAction(Acl.AclForwardActionEnum.ACLFORWARDINGACTION_ACCEPT)
+                        .setLogAction(Acl.AclLogActionEnum.ACLLOGACTION_SYSLOG)
+                        .build();
+
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+
+        final var expectedSerializedAclEntry =
+                Acl.AclEntry.newBuilder()
+                        .setSequenceId(1)
+                        .setDescription("aclEntryDescription")
+                        .setMatch(expectedSerializedAclMatch)
+                        .setAction(expectedSerializedAclAction)
+                        .build();
+
+        final var aclEntry = createAclEntry(1, "aclEntryDescription", aclMatch, aclAction);
+
+        final var expectedSerializedAclRuleSet =
+                Acl.AclRuleSet.newBuilder()
+                        .setName("aclRuleName")
+                        .setType(Acl.AclRuleTypeEnum.ACLRULETYPE_IPV4)
+                        .setDescription("AclRuleDescription")
+                        .setUserId("userId")
+                        .addEntries(expectedSerializedAclEntry)
+                        .build();
+
+        final var aclRuleSet =
+                new AclRuleSet(
+                        "aclRuleName", AclRuleTypeEnum.IPV4, "AclRuleDescription", "userId", List.of(aclEntry));
+
+        final var expectedSerializedConfigRuleAcl =
+                ContextOuterClass.ConfigRule_ACL.newBuilder()
+                        .setEndpointId(expectedSerializedEndPointId)
+                        .setRuleSet(expectedSerializedAclRuleSet)
+                        .build();
+
+        final var configRuleAcl = new ConfigRuleAcl(endPointId, aclRuleSet);
+
+        final var expectedConfigRule =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_SET)
+                        .setAcl(expectedSerializedConfigRuleAcl)
+                        .build();
+
+        final var configRuleTypeAcl = new ConfigRuleTypeAcl(configRuleAcl);
+        final var configRule = new ConfigRule(ConfigActionEnum.SET, configRuleTypeAcl);
+        final var serializedConfigRule = serializer.serialize(configRule);
+
+        assertThat(serializedConfigRule).isEqualTo(expectedConfigRule);
+    }
+
+    @Test
+    void shouldDeserializeConfigRuleOfTypeConfigRuleAcl() {
+        final var contextIdUuid = "contextId";
+        final var topologyIdUuid = "topologyUuid";
+        final var deviceIdUuid = "deviceIdUuid";
+        final var endpointIdUuid = "endpointIdUuid";
+
+        final var serializedContextId = serializer.serializeContextId(contextIdUuid);
+        final var serializedTopologyIdUuid = serializer.serializeUuid(topologyIdUuid);
+        final var serializedDeviceId = serializer.serializeDeviceId(deviceIdUuid);
+        final var serializedEndPointIdUuid = serializer.serializeUuid(endpointIdUuid);
+
+        final var topologyId = new TopologyId(contextIdUuid, topologyIdUuid);
+        final var serializedTopologyId =
+                ContextOuterClass.TopologyId.newBuilder()
+                        .setContextId(serializedContextId)
+                        .setTopologyUuid(serializedTopologyIdUuid)
+                        .build();
+
+        final var endPointId = new EndPointId(topologyId, deviceIdUuid, endpointIdUuid);
+        final var serializedEndPointId =
+                ContextOuterClass.EndPointId.newBuilder()
+                        .setTopologyId(serializedTopologyId)
+                        .setDeviceId(serializedDeviceId)
+                        .setEndpointUuid(serializedEndPointIdUuid)
+                        .build();
+
+        final var aclMatch = createAclMatch(1, 2, "127.0.0.1", "127.0.0.2", 5601, 5602, 5, 10);
+        final var serializedAclMatch =
+                Acl.AclMatch.newBuilder()
+                        .setDscp(1)
+                        .setProtocol(2)
+                        .setSrcAddress("127.0.0.1")
+                        .setDstAddress("127.0.0.2")
+                        .setSrcPort(5601)
+                        .setDstPort(5602)
+                        .setStartMplsLabel(5)
+                        .setEndMplsLabel(10)
+                        .build();
+
+        final var aclAction = createAclAction(AclForwardActionEnum.ACCEPT, AclLogActionEnum.SYSLOG);
+        final var serializedAclAction =
+                Acl.AclAction.newBuilder()
+                        .setForwardAction(Acl.AclForwardActionEnum.ACLFORWARDINGACTION_ACCEPT)
+                        .setLogAction(Acl.AclLogActionEnum.ACLLOGACTION_SYSLOG)
+                        .build();
+
+        final var aclEntry = createAclEntry(1, "aclEntryDescription", aclMatch, aclAction);
+
+        final var serializedAclEntry =
+                Acl.AclEntry.newBuilder()
+                        .setSequenceId(1)
+                        .setDescription("aclEntryDescription")
+                        .setMatch(serializedAclMatch)
+                        .setAction(serializedAclAction)
+                        .build();
+
+        final var aclRuleSet =
+                new AclRuleSet(
+                        "aclRuleName",
+                        eu.teraflow.policy.acl.AclRuleTypeEnum.IPV4,
+                        "AclRuleDescription",
+                        "userId",
+                        List.of(aclEntry));
+
+        final var serializedAclRuleSet =
+                Acl.AclRuleSet.newBuilder()
+                        .setName("aclRuleName")
+                        .setType(Acl.AclRuleTypeEnum.ACLRULETYPE_IPV4)
+                        .setDescription("AclRuleDescription")
+                        .setUserId("userId")
+                        .addEntries(serializedAclEntry)
+                        .build();
+
+        final var configRuleAcl = new ConfigRuleAcl(endPointId, aclRuleSet);
+        final var configRuleTypeAcl = new ConfigRuleTypeAcl(configRuleAcl);
+
+        final var expectedConfigRule = new ConfigRule(ConfigActionEnum.DELETE, configRuleTypeAcl);
+
+        final var serializedConfigRuleAcl =
+                ContextOuterClass.ConfigRule_ACL.newBuilder()
+                        .setEndpointId(serializedEndPointId)
+                        .setRuleSet(serializedAclRuleSet)
+                        .build();
+
+        final var serializedConfigRule =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_DELETE)
+                        .setAcl(serializedConfigRuleAcl)
+                        .build();
+
+        final var configRule = serializer.deserialize(serializedConfigRule);
+
+        assertThat(configRule).usingRecursiveComparison().isEqualTo(expectedConfigRule);
+    }
+
+    @Test
+    void shouldSerializeConfigRuleOfTypeConfigRuleCustom() {
+        final var expectedSerializedConfigRuleCustom =
+                ContextOuterClass.ConfigRule_Custom.newBuilder()
+                        .setResourceKey("resourceKey")
+                        .setResourceValue("resourceValue")
+                        .build();
+
+        final var configRuleCustom = new ConfigRuleCustom("resourceKey", "resourceValue");
+
+        final var expectedConfigRule =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_SET)
+                        .setCustom(expectedSerializedConfigRuleCustom)
+                        .build();
+
+        final var configRuleTypeCustom = new ConfigRuleTypeCustom(configRuleCustom);
+        final var configRule = new ConfigRule(ConfigActionEnum.SET, configRuleTypeCustom);
+        final var serializedConfigRule = serializer.serialize(configRule);
+
+        assertThat(serializedConfigRule).isEqualTo(expectedConfigRule);
+    }
+
+    @Test
+    void shouldDeserializeConfigRuleOfTypeConfigRuleCustom() {
+        final var serializedConfigRuleCustom =
+                ContextOuterClass.ConfigRule_Custom.newBuilder()
+                        .setResourceKey("resourceKey")
+                        .setResourceValue("resourceValue")
+                        .build();
+
+        final var expectedConfigRuleCustom = new ConfigRuleCustom("resourceKey", "resourceValue");
+        final var configRuleTypeCustom = new ConfigRuleTypeCustom(expectedConfigRuleCustom);
+        final var expectedConfigRule = new ConfigRule(ConfigActionEnum.SET, configRuleTypeCustom);
+
+        final var serializedConfigRule =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_SET)
+                        .setCustom(serializedConfigRuleCustom)
+                        .build();
+
+        final var configRule = serializer.deserialize(serializedConfigRule);
+
+        assertThat(configRule).usingRecursiveComparison().isEqualTo(expectedConfigRule);
+    }
+
+    @Test
+    void shouldThrowIllegalStateExceptionDuringDeserializationOfNonSpecifiedConfigRule() {
+        final var serializedConfigRule =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_SET)
+                        .build();
+
+        assertThatExceptionOfType(IllegalStateException.class)
+                .isThrownBy(() -> serializer.deserialize(serializedConfigRule));
+    }
+
+    @Test
+    void shouldSerializeConstraintCustom() {
+        final var expectedConstraintType = "constraintType";
+        final var expectedConstraintValue = "constraintValue";
+
+        final var constraintCustom =
+                new ConstraintCustom(expectedConstraintType, expectedConstraintValue);
+
+        final var expectedConstraintCustom =
+                ContextOuterClass.Constraint_Custom.newBuilder()
+                        .setConstraintType(expectedConstraintType)
+                        .setConstraintValue(expectedConstraintValue)
+                        .build();
+
+        final var serializedConstraintCustom = serializer.serialize(constraintCustom);
+
+        assertThat(serializedConstraintCustom)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintCustom);
+    }
+
+    @Test
+    void shouldDeserializeConstraintCustom() {
+        final var expectedConstraintType = "constraintType";
+        final var expectedConstraintValue = "constraintValue";
+        final var expectedConstraintCustom =
+                new ConstraintCustom(expectedConstraintType, expectedConstraintValue);
+
+        final var serializedConstraintCustom =
+                ContextOuterClass.Constraint_Custom.newBuilder()
+                        .setConstraintType(expectedConstraintType)
+                        .setConstraintValue(expectedConstraintValue)
+                        .build();
+
+        final var constraintCustom = serializer.deserialize(serializedConstraintCustom);
+
+        assertThat(constraintCustom).usingRecursiveComparison().isEqualTo(expectedConstraintCustom);
+    }
+
+    @Test
+    void shouldSerializeConstraintSchedule() {
+        final var expectedStartTimestamp = 10;
+        final var expectedDurationDays = 2.2f;
+
+        final var constraintSchedule =
+                new ConstraintSchedule(expectedStartTimestamp, expectedDurationDays);
+
+        final var expectedConstraintSchedule =
+                ContextOuterClass.Constraint_Schedule.newBuilder()
+                        .setStartTimestamp(expectedStartTimestamp)
+                        .setDurationDays(expectedDurationDays)
+                        .build();
+
+        final var serializedConstraintSchedule = serializer.serialize(constraintSchedule);
+
+        assertThat(serializedConstraintSchedule)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSchedule);
+    }
+
+    @Test
+    void shouldDeserializeConstraintSchedule() {
+        final var expectedStartTimestamp = 10;
+        final var expectedDurationDays = 2.2f;
+
+        final var expectedConstraintSchedule =
+                new ConstraintSchedule(expectedStartTimestamp, expectedDurationDays);
+
+        final var serializedConstraintSchedule =
+                ContextOuterClass.Constraint_Schedule.newBuilder()
+                        .setStartTimestamp(expectedStartTimestamp)
+                        .setDurationDays(expectedDurationDays)
+                        .build();
+
+        final var constraintSchedule = serializer.deserialize(serializedConstraintSchedule);
+
+        assertThat(constraintSchedule).usingRecursiveComparison().isEqualTo(expectedConstraintSchedule);
+    }
+
+    @Test
+    void shouldSerializeLocationOfTypeRegion() {
+        final var region = "Tokyo";
+
+        final var locationTypeRegion = new LocationTypeRegion(region);
+        final var location = new Location(locationTypeRegion);
+
+        final var expectedLocation = ContextOuterClass.Location.newBuilder().setRegion(region).build();
+
+        final var serializedLocation = serializer.serialize(location);
+
+        assertThat(serializedLocation).isEqualTo(expectedLocation);
+    }
+
+    @Test
+    void shouldDeserializeLocationOfTypeRegion() {
+        final var region = "Tokyo";
+
+        final var locationTypeRegion = new LocationTypeRegion(region);
+        final var expectedLocation = new Location(locationTypeRegion);
+
+        final var serializedLocation =
+                ContextOuterClass.Location.newBuilder().setRegion(region).build();
+
+        final var location = serializer.deserialize(serializedLocation);
+
+        assertThat(location).usingRecursiveComparison().isEqualTo(expectedLocation);
+    }
+
+    @Test
+    void shouldSerializeLocationOfTypeGpsPosition() {
+        final var latitude = 33.3f;
+        final var longitude = 86.4f;
+
+        final var gpsPosition = new GpsPosition(latitude, longitude);
+        final var locationTypeGpsPosition = new LocationTypeGpsPosition(gpsPosition);
+        final var location = new Location(locationTypeGpsPosition);
+
+        final var serializedGpsPosition =
+                ContextOuterClass.GPS_Position.newBuilder()
+                        .setLatitude(latitude)
+                        .setLongitude(longitude)
+                        .build();
+
+        final var expectedLocation =
+                ContextOuterClass.Location.newBuilder().setGpsPosition(serializedGpsPosition).build();
+
+        final var serializedLocation = serializer.serialize(location);
+
+        assertThat(serializedLocation).isEqualTo(expectedLocation);
+    }
+
+    @Test
+    void shouldDeserializeLocationOfTypeGpsPosition() {
+        final var latitude = 33.3f;
+        final var longitude = 86.4f;
+
+        final var gpsPosition = new GpsPosition(latitude, longitude);
+        final var locationTypeGpsPosition = new LocationTypeGpsPosition(gpsPosition);
+        final var expectedLocation = new Location(locationTypeGpsPosition);
+
+        final var serializedGpsPosition =
+                ContextOuterClass.GPS_Position.newBuilder()
+                        .setLatitude(latitude)
+                        .setLongitude(longitude)
+                        .build();
+
+        final var serializedLocation =
+                ContextOuterClass.Location.newBuilder().setGpsPosition(serializedGpsPosition).build();
+
+        final var location = serializer.deserialize(serializedLocation);
+
+        assertThat(location).usingRecursiveComparison().isEqualTo(expectedLocation);
+    }
+
+    @Test
+    void shouldThrowIllegalStateExceptionDuringDeserializationOfNonSpecifiedLocation() {
+        final var serializedLocation = ContextOuterClass.Location.newBuilder().build();
+
+        assertThatExceptionOfType(IllegalStateException.class)
+                .isThrownBy(() -> serializer.deserialize(serializedLocation));
+    }
+
+    private static Stream<Arguments> provideIsolationLevelEnum() {
+        return Stream.of(
+                Arguments.of(
+                        IsolationLevelEnum.NO_ISOLATION, ContextOuterClass.IsolationLevelEnum.NO_ISOLATION),
+                Arguments.of(
+                        IsolationLevelEnum.PHYSICAL_ISOLATION,
+                        ContextOuterClass.IsolationLevelEnum.PHYSICAL_ISOLATION),
+                Arguments.of(
+                        IsolationLevelEnum.LOGICAL_ISOLATION,
+                        ContextOuterClass.IsolationLevelEnum.LOGICAL_ISOLATION),
+                Arguments.of(
+                        IsolationLevelEnum.PROCESS_ISOLATION,
+                        ContextOuterClass.IsolationLevelEnum.PROCESS_ISOLATION),
+                Arguments.of(
+                        IsolationLevelEnum.PHYSICAL_MEMORY_ISOLATION,
+                        ContextOuterClass.IsolationLevelEnum.PHYSICAL_MEMORY_ISOLATION),
+                Arguments.of(
+                        IsolationLevelEnum.PHYSICAL_NETWORK_ISOLATION,
+                        ContextOuterClass.IsolationLevelEnum.PHYSICAL_NETWORK_ISOLATION),
+                Arguments.of(
+                        IsolationLevelEnum.VIRTUAL_RESOURCE_ISOLATION,
+                        ContextOuterClass.IsolationLevelEnum.VIRTUAL_RESOURCE_ISOLATION),
+                Arguments.of(
+                        IsolationLevelEnum.NETWORK_FUNCTIONS_ISOLATION,
+                        ContextOuterClass.IsolationLevelEnum.NETWORK_FUNCTIONS_ISOLATION),
+                Arguments.of(
+                        IsolationLevelEnum.SERVICE_ISOLATION,
+                        ContextOuterClass.IsolationLevelEnum.SERVICE_ISOLATION));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideIsolationLevelEnum")
+    void shouldSerializeIsolationLevelEnum(
+            IsolationLevelEnum isolationLevelEnum,
+            ContextOuterClass.IsolationLevelEnum expectedIsolationLevelEnum) {
+        final var serializedIsolationLevelEnum = serializer.serialize(isolationLevelEnum);
+
+        assertThat(serializedIsolationLevelEnum.getNumber())
+                .isEqualTo(expectedIsolationLevelEnum.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideIsolationLevelEnum")
+    void shouldDeserializeIsolationLevelEnum(
+            IsolationLevelEnum expectedIsolationLevelEnum,
+            ContextOuterClass.IsolationLevelEnum serializedIsolationLevelEnum) {
+        final var isolationLevelEnum = serializer.deserialize(serializedIsolationLevelEnum);
+
+        assertThat(isolationLevelEnum).isEqualTo(expectedIsolationLevelEnum);
+    }
+
+    @Test
+    void shouldSerializeConstraintEndPointLocation() {
+        final var expectedTopologyId = new TopologyId("contextId", "id");
+        final var expectedDeviceId = "expectedDeviceId";
+        final var expectedId = "expectedId";
+        final var endPointId = new EndPointId(expectedTopologyId, expectedDeviceId, expectedId);
+
+        final var locationType = new LocationTypeRegion("ATH");
+        final var location = new Location(locationType);
+
+        final var constraintEndPointLocation = new ConstraintEndPointLocation(endPointId, location);
+
+        final var serializedEndPointId = serializer.serialize(endPointId);
+        final var serializedLocation = serializer.serialize(location);
+
+        final var expectedConstraintEndPointLocation =
+                ContextOuterClass.Constraint_EndPointLocation.newBuilder()
+                        .setEndpointId(serializedEndPointId)
+                        .setLocation(serializedLocation)
+                        .build();
+
+        final var serializedConstraintEndPointLocation =
+                serializer.serialize(constraintEndPointLocation);
+
+        assertThat(serializedConstraintEndPointLocation)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintEndPointLocation);
+    }
+
+    @Test
+    void shouldDeserializeConstraintEndPointLocation() {
+        final var expectedTopologyId = new TopologyId("contextId", "id");
+        final var expectedDeviceId = "expectedDeviceId";
+        final var expectedId = "expectedId";
+        final var endPointId = new EndPointId(expectedTopologyId, expectedDeviceId, expectedId);
+
+        final var latitude = 54.6f;
+        final var longitude = 123.7f;
+        final var gpsPosition = new GpsPosition(latitude, longitude);
+
+        final var locationType = new LocationTypeGpsPosition(gpsPosition);
+        final var location = new Location(locationType);
+
+        final var expectedConstraintEndPointLocation =
+                new ConstraintEndPointLocation(endPointId, location);
+
+        final var serializedEndPointId = serializer.serialize(endPointId);
+        final var serializedLocation = serializer.serialize(location);
+
+        final var serializedConstraintEndPointLocation =
+                ContextOuterClass.Constraint_EndPointLocation.newBuilder()
+                        .setEndpointId(serializedEndPointId)
+                        .setLocation(serializedLocation)
+                        .build();
+
+        final var constraintEndPointLocation =
+                serializer.deserialize(serializedConstraintEndPointLocation);
+
+        assertThat(constraintEndPointLocation)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintEndPointLocation);
+    }
+
+    @Test
+    void shouldSerializeConstraintSlaAvailability() {
+        final var numDisJointPaths = 2;
+        final var isAllActive = true;
+
+        final var constraintSlaAvailability =
+                new ConstraintSlaAvailability(numDisJointPaths, isAllActive);
+
+        final var expectedConstraintSlaAvailability =
+                ContextOuterClass.Constraint_SLA_Availability.newBuilder()
+                        .setNumDisjointPaths(numDisJointPaths)
+                        .setAllActive(isAllActive)
+                        .build();
+
+        final var serializedConstraintSlaAvailability = serializer.serialize(constraintSlaAvailability);
+
+        assertThat(serializedConstraintSlaAvailability)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSlaAvailability);
+    }
+
+    @Test
+    void shouldDeserializeConstraintSlaAvailability() {
+        final var numDisJointPaths = 2;
+        final var isAllActive = true;
+
+        final var expectedConstraintSlaAvailability =
+                new ConstraintSlaAvailability(numDisJointPaths, isAllActive);
+
+        final var serializedConstraintSlaAvailability =
+                ContextOuterClass.Constraint_SLA_Availability.newBuilder()
+                        .setNumDisjointPaths(numDisJointPaths)
+                        .setAllActive(isAllActive)
+                        .build();
+
+        final var constraintSlaAvailability =
+                serializer.deserialize(serializedConstraintSlaAvailability);
+
+        assertThat(constraintSlaAvailability)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSlaAvailability);
+    }
+
+    @Test
+    void shouldSerializeConstraintSlaCapacity() {
+        final var capacityGbps = 5;
+
+        final var constraintSlaCapacity = new ConstraintSlaCapacity(capacityGbps);
+
+        final var expectedConstraintSlaCapacity =
+                ContextOuterClass.Constraint_SLA_Capacity.newBuilder()
+                        .setCapacityGbps(capacityGbps)
+                        .build();
+
+        final var serializedConstraintSlaCapacity = serializer.serialize(constraintSlaCapacity);
+
+        assertThat(serializedConstraintSlaCapacity)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSlaCapacity);
+    }
+
+    @Test
+    void shouldDeserializeConstraintSlaCapacity() {
+        final var capacityGbps = 5;
+
+        final var expectedConstraintSlaCapacity = new ConstraintSlaCapacity(capacityGbps);
+
+        final var serializedConstraintSlaCapacity =
+                ContextOuterClass.Constraint_SLA_Capacity.newBuilder()
+                        .setCapacityGbps(capacityGbps)
+                        .build();
+
+        final var constraintSlaCapacity = serializer.deserialize(serializedConstraintSlaCapacity);
+
+        assertThat(constraintSlaCapacity)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSlaCapacity);
+    }
+
+    @Test
+    void shouldSerializeConstraintSlaIsolationLevel() {
+        final var isolationLevelEnum = IsolationLevelEnum.NETWORK_FUNCTIONS_ISOLATION;
+
+        final var constraintSlaIsolationLevel = new ConstraintSlaIsolationLevel(isolationLevelEnum);
+
+        final var serializedIsolationLevelEnum = serializer.serialize(isolationLevelEnum);
+        final var expectedConstraintSlaIsolationLevel =
+                ContextOuterClass.Constraint_SLA_Isolation_level.newBuilder()
+                        .setIsolationLevel(serializedIsolationLevelEnum)
+                        .build();
+
+        final var serializedConstraintSlaIsolationLevel =
+                serializer.serialize(constraintSlaIsolationLevel);
+
+        assertThat(serializedConstraintSlaIsolationLevel)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSlaIsolationLevel);
+    }
+
+    @Test
+    void shouldDeserializeConstraintSlaIsolationLevel() {
+        final var isolationLevelEnum = IsolationLevelEnum.NETWORK_FUNCTIONS_ISOLATION;
+
+        final var expectedConstraintSlaIsolationLevel =
+                new ConstraintSlaIsolationLevel(isolationLevelEnum);
+
+        final var serializedIsolationLevelEnum = serializer.serialize(isolationLevelEnum);
+        final var serializedConstraintSlaIsolationLevel =
+                ContextOuterClass.Constraint_SLA_Isolation_level.newBuilder()
+                        .setIsolationLevel(serializedIsolationLevelEnum)
+                        .build();
+
+        final var constraintSlaIsolationLevel =
+                serializer.deserialize(serializedConstraintSlaIsolationLevel);
+
+        assertThat(constraintSlaIsolationLevel)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSlaIsolationLevel);
+    }
+
+    @Test
+    void shouldSerializeConstraintSlaLatency() {
+        final var e2eLatencyMs = 5.7f;
+
+        final var constraintSlaLatency = new ConstraintSlaLatency(e2eLatencyMs);
+
+        final var expectedConstraintSlaLatency =
+                ContextOuterClass.Constraint_SLA_Latency.newBuilder().setE2ELatencyMs(e2eLatencyMs).build();
+
+        final var serializedConstraintSlaLatency = serializer.serialize(constraintSlaLatency);
+
+        assertThat(serializedConstraintSlaLatency)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSlaLatency);
+    }
+
+    @Test
+    void shouldDeserializeConstraintSlaLatency() {
+        final var e2eLatencyMs = 5.7f;
+
+        final var expectedConstraintSlaLatency = new ConstraintSlaLatency(e2eLatencyMs);
+
+        final var serializedConstraintSlaLatency =
+                ContextOuterClass.Constraint_SLA_Latency.newBuilder().setE2ELatencyMs(e2eLatencyMs).build();
+
+        final var constraintSlaLatency = serializer.deserialize(serializedConstraintSlaLatency);
+
+        assertThat(constraintSlaLatency)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedConstraintSlaLatency);
+    }
+
+    @Test
+    void shouldSerializeConstraintOfTypeConstraintCustom() {
+        final var expectedConstraintType = "constraintType";
+        final var expectedConstraintValue = "constraintValue";
+
+        final var constraintCustom =
+                new ConstraintCustom(expectedConstraintType, expectedConstraintValue);
+        final var constraintTypeCustom = new ConstraintTypeCustom(constraintCustom);
+        final var constraint = new Constraint(constraintTypeCustom);
+
+        final var expectedConstraintCustom =
+                ContextOuterClass.Constraint_Custom.newBuilder()
+                        .setConstraintType(expectedConstraintType)
+                        .setConstraintValue(expectedConstraintValue)
+                        .build();
+
+        final var expectedConstraint =
+                ContextOuterClass.Constraint.newBuilder().setCustom(expectedConstraintCustom).build();
+
+        final var serializedConstraint = serializer.serialize(constraint);
+
+        assertThat(serializedConstraint).usingRecursiveComparison().isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldDeserializeConstraintOfTypeConstraintCustom() {
+        final var expectedConstraintType = "constraintType";
+        final var expectedConstraintValue = "constraintValue";
+
+        final var constraintCustom =
+                new ConstraintCustom(expectedConstraintType, expectedConstraintValue);
+        final var constraintTypeCustom = new ConstraintTypeCustom(constraintCustom);
+        final var expectedConstraint = new Constraint(constraintTypeCustom);
+
+        final var serializedConstraintCustom =
+                ContextOuterClass.Constraint_Custom.newBuilder()
+                        .setConstraintType(expectedConstraintType)
+                        .setConstraintValue(expectedConstraintValue)
+                        .build();
+
+        final var serializedConstraint =
+                ContextOuterClass.Constraint.newBuilder().setCustom(serializedConstraintCustom).build();
+
+        final var constraint = serializer.deserialize(serializedConstraint);
+
+        assertThat(constraint).usingRecursiveComparison().isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldSerializeConstraintOfTypeConstraintSchedule() {
+        final var startTimeSTamp = 2.2f;
+        final var durationDays = 5.73f;
+
+        final var constraintSchedule = new ConstraintSchedule(startTimeSTamp, durationDays);
+        final var constraintTypeSchedule = new ConstraintTypeSchedule(constraintSchedule);
+        final var constraint = new Constraint(constraintTypeSchedule);
+
+        final var expectedConstraintSchedule =
+                ContextOuterClass.Constraint_Schedule.newBuilder()
+                        .setStartTimestamp(startTimeSTamp)
+                        .setDurationDays(durationDays)
+                        .build();
+
+        final var expectedConstraint =
+                ContextOuterClass.Constraint.newBuilder().setSchedule(expectedConstraintSchedule).build();
+
+        final var serializedConstraint = serializer.serialize(constraint);
+
+        assertThat(serializedConstraint).isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldDeserializeConstraintOfTypeConstraintSchedule() {
+        final var startTimeSTamp = 2.2f;
+        final var durationDays = 5.73f;
+
+        final var expectedConstraintSchedule = new ConstraintSchedule(startTimeSTamp, durationDays);
+        final var expectedConstraintTypeSchedule =
+                new ConstraintTypeSchedule(expectedConstraintSchedule);
+        final var expectedConstraint = new Constraint(expectedConstraintTypeSchedule);
+
+        final var serializedConstraintSchedule =
+                ContextOuterClass.Constraint_Schedule.newBuilder()
+                        .setStartTimestamp(startTimeSTamp)
+                        .setDurationDays(durationDays)
+                        .build();
+
+        final var serializedConstraint =
+                ContextOuterClass.Constraint.newBuilder().setSchedule(serializedConstraintSchedule).build();
+
+        final var constraint = serializer.deserialize(serializedConstraint);
+
+        assertThat(constraint).usingRecursiveComparison().isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldSerializeConstraintOfTypeConstraintEndPointLocation() {
+        final var expectedTopologyId = new TopologyId("contextId", "id");
+        final var expectedDeviceId = "expectedDeviceId";
+        final var expectedId = "expectedId";
+        final var endPointId = new EndPointId(expectedTopologyId, expectedDeviceId, expectedId);
+
+        final var locationType = new LocationTypeRegion("ATH");
+        final var location = new Location(locationType);
+
+        final var constraintEndPointLocation = new ConstraintEndPointLocation(endPointId, location);
+        final var constraintTypeEndPointLocation =
+                new ConstraintTypeEndPointLocation(constraintEndPointLocation);
+        final var constraint = new Constraint(constraintTypeEndPointLocation);
+
+        final var serializedEndPointId = serializer.serialize(endPointId);
+        final var serializedLocation = serializer.serialize(location);
+
+        final var expectedConstraintEndPointLocation =
+                ContextOuterClass.Constraint_EndPointLocation.newBuilder()
+                        .setEndpointId(serializedEndPointId)
+                        .setLocation(serializedLocation)
+                        .build();
+
+        final var expectedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setEndpointLocation(expectedConstraintEndPointLocation)
+                        .build();
+
+        final var serializedConstraint = serializer.serialize(constraint);
+
+        assertThat(serializedConstraint).isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldDeserializeConstraintOfTypeConstraintEndPointLocation() {
+        final var expectedTopologyId = new TopologyId("contextId", "id");
+        final var expectedDeviceId = "expectedDeviceId";
+        final var expectedId = "expectedId";
+        final var endPointId = new EndPointId(expectedTopologyId, expectedDeviceId, expectedId);
+
+        final var locationType = new LocationTypeRegion("ATH");
+        final var location = new Location(locationType);
+
+        final var expectedConstraintEndPointLocation =
+                new ConstraintEndPointLocation(endPointId, location);
+        final var expectedConstraintTypeEndPointLocation =
+                new ConstraintTypeEndPointLocation(expectedConstraintEndPointLocation);
+        final var expectedConstraint = new Constraint(expectedConstraintTypeEndPointLocation);
+
+        final var serializedEndPointId = serializer.serialize(endPointId);
+        final var serializedLocation = serializer.serialize(location);
+
+        final var serializedEndPointLocation =
+                ContextOuterClass.Constraint_EndPointLocation.newBuilder()
+                        .setEndpointId(serializedEndPointId)
+                        .setLocation(serializedLocation)
+                        .build();
+
+        final var serializedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setEndpointLocation(serializedEndPointLocation)
+                        .build();
+
+        final var constraint = serializer.deserialize(serializedConstraint);
+
+        assertThat(constraint).usingRecursiveComparison().isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldSerializeConstraintOfTypeConstraintSlaAvailability() {
+        final var numDisjointPaths = 2;
+        final var isAllActive = true;
+
+        final var constraintSlaAvailability =
+                new ConstraintSlaAvailability(numDisjointPaths, isAllActive);
+        final var constraintTypeSlaAvailability =
+                new ConstraintTypeSlaAvailability(constraintSlaAvailability);
+        final var constraint = new Constraint(constraintTypeSlaAvailability);
+
+        final var expectedConstraintSlaAvailability =
+                ContextOuterClass.Constraint_SLA_Availability.newBuilder()
+                        .setNumDisjointPaths(numDisjointPaths)
+                        .setAllActive(isAllActive)
+                        .build();
+
+        final var expectedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setSlaAvailability(expectedConstraintSlaAvailability)
+                        .build();
+
+        final var serializedConstraint = serializer.serialize(constraint);
+
+        assertThat(serializedConstraint).isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldDeserializeConstraintOfTypeConstraintSlaAvailability() {
+        final var numDisjointPaths = 2;
+        final var isAllActive = true;
+
+        final var expectedConstraintSlaAvailability =
+                new ConstraintSlaAvailability(numDisjointPaths, isAllActive);
+        final var expectedConstraintTypeSlaAvailability =
+                new ConstraintTypeSlaAvailability(expectedConstraintSlaAvailability);
+        final var expectedConstraint = new Constraint(expectedConstraintTypeSlaAvailability);
+
+        final var serializedConstraintSlaAvailability =
+                ContextOuterClass.Constraint_SLA_Availability.newBuilder()
+                        .setNumDisjointPaths(numDisjointPaths)
+                        .setAllActive(isAllActive)
+                        .build();
+
+        final var serializedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setSlaAvailability(serializedConstraintSlaAvailability)
+                        .build();
+
+        final var constraint = serializer.deserialize(serializedConstraint);
+
+        assertThat(constraint).usingRecursiveComparison().isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldSerializeConstraintOfTypeConstraintSlaCapacity() {
+        final var capacityGbps = 77.3f;
+
+        final var constraintSlaCapacity = new ConstraintSlaCapacity(capacityGbps);
+        final var constraintTypeSlaCapacity = new ConstraintTypeSlaCapacity(constraintSlaCapacity);
+        final var constraint = new Constraint(constraintTypeSlaCapacity);
+
+        final var expectedConstraintSlaCapacity =
+                ContextOuterClass.Constraint_SLA_Capacity.newBuilder()
+                        .setCapacityGbps(capacityGbps)
+                        .build();
+
+        final var expectedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setSlaCapacity(expectedConstraintSlaCapacity)
+                        .build();
+
+        final var serializedConstraint = serializer.serialize(constraint);
+
+        assertThat(serializedConstraint).isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldDeserializeConstraintOfTypeConstraintSlaCapacity() {
+        final var capacityGbps = 77.3f;
+
+        final var expectedConstraintSlaCapacity = new ConstraintSlaCapacity(capacityGbps);
+        final var expectedConstraintTypeSlaCapacity =
+                new ConstraintTypeSlaCapacity(expectedConstraintSlaCapacity);
+        final var expectedConstraint = new Constraint(expectedConstraintTypeSlaCapacity);
+
+        final var serializedConstraintSlaCapacity =
+                ContextOuterClass.Constraint_SLA_Capacity.newBuilder()
+                        .setCapacityGbps(capacityGbps)
+                        .build();
+
+        final var serializedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setSlaCapacity(serializedConstraintSlaCapacity)
+                        .build();
+
+        final var constraint = serializer.deserialize(serializedConstraint);
+
+        assertThat(constraint).usingRecursiveComparison().isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldDeserializeConstraintOfTypeConstraintSlaIsolationLevel() {
+        final var isolationLevelEnum = IsolationLevelEnum.PHYSICAL_ISOLATION;
+
+        final var expectedConstraintSlaIsolationLevel =
+                new ConstraintSlaIsolationLevel(isolationLevelEnum);
+        final var expectedConstraintTypeSlaIsolationLevel =
+                new ConstraintTypeSlaIsolationLevel(expectedConstraintSlaIsolationLevel);
+        final var expectedConstraint = new Constraint(expectedConstraintTypeSlaIsolationLevel);
+
+        final var serializedIsolationLevelEnum = serializer.serialize(isolationLevelEnum);
+
+        final var serializedConstraintSlaIsolationLevel =
+                ContextOuterClass.Constraint_SLA_Isolation_level.newBuilder()
+                        .setIsolationLevel(serializedIsolationLevelEnum)
+                        .build();
+
+        final var serializedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setSlaIsolation(serializedConstraintSlaIsolationLevel)
+                        .build();
+
+        final var constraint = serializer.deserialize(serializedConstraint);
+
+        assertThat(constraint).usingRecursiveComparison().isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldSerializeConstraintOfTypeConstraintSlaIsolationLevel() {
+        final var isolationLevelEnum = IsolationLevelEnum.PHYSICAL_ISOLATION;
+
+        final var constraintSlaIsolationLevel = new ConstraintSlaIsolationLevel(isolationLevelEnum);
+        final var constraintTypeSlaIsolationLevel =
+                new ConstraintTypeSlaIsolationLevel(constraintSlaIsolationLevel);
+        final var constraint = new Constraint(constraintTypeSlaIsolationLevel);
+
+        final var serializedIsolationLevelEnum = serializer.serialize(isolationLevelEnum);
+
+        final var expectedConstraintSlaIsolationLevel =
+                ContextOuterClass.Constraint_SLA_Isolation_level.newBuilder()
+                        .setIsolationLevel(serializedIsolationLevelEnum)
+                        .build();
+
+        final var expectedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setSlaIsolation(expectedConstraintSlaIsolationLevel)
+                        .build();
+
+        final var serializedConstraint = serializer.serialize(constraint);
+
+        assertThat(serializedConstraint).isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldSerializeConstraintOfTypeConstraintSlaLatency() {
+        final var e2eLatencyMs = 45.32f;
+
+        final var constraintSlaLatency = new ConstraintSlaLatency(e2eLatencyMs);
+        final var constraintTypeSlaLatency = new ConstraintTypeSlaLatency(constraintSlaLatency);
+        final var constraint = new Constraint(constraintTypeSlaLatency);
+
+        final var expectedConstraintSlaLatency =
+                ContextOuterClass.Constraint_SLA_Latency.newBuilder().setE2ELatencyMs(e2eLatencyMs).build();
+
+        final var expectedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setSlaLatency(expectedConstraintSlaLatency)
+                        .build();
+
+        final var serializedConstraint = serializer.serialize(constraint);
+
+        assertThat(serializedConstraint).isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldDeserializeConstraintOfTypeConstraintSlaLatency() {
+        final var e2eLatencyMs = 45.32f;
+
+        final var expectedConstraintSlaLatency = new ConstraintSlaLatency(e2eLatencyMs);
+        final var expectedConstraintTypeSlaLatency =
+                new ConstraintTypeSlaLatency(expectedConstraintSlaLatency);
+        final var expectedConstraint = new Constraint(expectedConstraintTypeSlaLatency);
+
+        final var serializedConstraintSlaLatency =
+                ContextOuterClass.Constraint_SLA_Latency.newBuilder().setE2ELatencyMs(e2eLatencyMs).build();
+
+        final var serializedConstraint =
+                ContextOuterClass.Constraint.newBuilder()
+                        .setSlaLatency(serializedConstraintSlaLatency)
+                        .build();
+
+        final var constraint = serializer.deserialize(serializedConstraint);
+
+        assertThat(constraint).usingRecursiveComparison().isEqualTo(expectedConstraint);
+    }
+
+    @Test
+    void shouldThrowIllegalStateExceptionDuringDeserializationOfNonSpecifiedConstraint() {
+        final var serializedKpiValue = ContextOuterClass.Constraint.newBuilder().build();
+
+        assertThatExceptionOfType(IllegalStateException.class)
+                .isThrownBy(() -> serializer.deserialize(serializedKpiValue));
+    }
+
+    @Test
+    void shouldSerializeEndPointId() {
+        final var expectedTopologyId = new TopologyId("contextId", "id");
+        final var expectedDeviceId = "expectedDeviceId";
+        final var expectedId = "expectedId";
+
+        final var endPointId = new EndPointId(expectedTopologyId, expectedDeviceId, expectedId);
+
+        final var serializedTopologyId = serializer.serialize(expectedTopologyId);
+        final var serializedDeviceId = serializer.serializeDeviceId(expectedDeviceId);
+        final var serializedEndPointUuid = serializer.serializeUuid(expectedId);
+
+        final var expectedEndPointId =
+                ContextOuterClass.EndPointId.newBuilder()
+                        .setTopologyId(serializedTopologyId)
+                        .setDeviceId(serializedDeviceId)
+                        .setEndpointUuid(serializedEndPointUuid)
+                        .build();
+
+        final var serializedEndPointId = serializer.serialize(endPointId);
+
+        assertThat(serializedEndPointId).usingRecursiveComparison().isEqualTo(expectedEndPointId);
+    }
+
+    @Test
+    void shouldDeserializeEndPointId() {
+        final var expectedTopologyId = new TopologyId("contextId", "id");
+        final var expectedDeviceId = "expectedDeviceId";
+        final var expectedId = "expectedId";
+
+        final var expectedEndPointId = new EndPointId(expectedTopologyId, expectedDeviceId, expectedId);
+
+        final var serializedEndPointId = serializer.serialize(expectedEndPointId);
+        final var endPointId = serializer.deserialize(serializedEndPointId);
+
+        assertThat(endPointId).usingRecursiveComparison().isEqualTo(expectedEndPointId);
+    }
+
+    private static Stream<Arguments> provideEventTypeEnum() {
+        return Stream.of(
+                Arguments.of(EventTypeEnum.CREATE, ContextOuterClass.EventTypeEnum.EVENTTYPE_CREATE),
+                Arguments.of(EventTypeEnum.REMOVE, ContextOuterClass.EventTypeEnum.EVENTTYPE_REMOVE),
+                Arguments.of(EventTypeEnum.UNDEFINED, ContextOuterClass.EventTypeEnum.EVENTTYPE_UNDEFINED),
+                Arguments.of(EventTypeEnum.UPDATE, ContextOuterClass.EventTypeEnum.EVENTTYPE_UPDATE));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideEventTypeEnum")
+    void shouldSerializeEventType(
+            EventTypeEnum eventType, ContextOuterClass.EventTypeEnum expectedSerializedType) {
+        final var serializedType = serializer.serialize(eventType);
+
+        assertThat(serializedType.getNumber()).isEqualTo(expectedSerializedType.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideEventTypeEnum")
+    void shouldDeserializeEventType(
+            EventTypeEnum expectedEventType, ContextOuterClass.EventTypeEnum serializedEventType) {
+        final var eventType = serializer.deserialize(serializedEventType);
+
+        assertThat(eventType).isEqualTo(expectedEventType);
+    }
+
+    @Test
+    void shouldSerializeEvent() {
+        final var timestamp = ContextOuterClass.Timestamp.newBuilder().setTimestamp(1).build();
+
+        final var expectedEvent =
+                ContextOuterClass.Event.newBuilder()
+                        .setTimestamp(timestamp)
+                        .setEventType(ContextOuterClass.EventTypeEnum.EVENTTYPE_CREATE)
+                        .build();
+
+        final var event = new Event(1, EventTypeEnum.CREATE);
+        final var serializedEvent = serializer.serialize(event);
+
+        assertThat(serializedEvent).usingRecursiveComparison().isEqualTo(expectedEvent);
+    }
+
+    @Test
+    void shouldDeserializeEvent() {
+        final var expectedEvent = new Event(1, EventTypeEnum.CREATE);
+        final var timestamp = ContextOuterClass.Timestamp.newBuilder().setTimestamp(1).build();
+
+        final var serializedEvent =
+                ContextOuterClass.Event.newBuilder()
+                        .setTimestamp(timestamp)
+                        .setEventType(ContextOuterClass.EventTypeEnum.EVENTTYPE_CREATE)
+                        .build();
+        final var event = serializer.deserialize(serializedEvent);
+
+        assertThat(event).usingRecursiveComparison().isEqualTo(expectedEvent);
+    }
+
+    @Test
+    void shouldSerializeServiceId() {
+        final var expectedContextId = "expectedContextId";
+        final var expectedId = "expectedId";
+        final var serviceId = new ServiceId(expectedContextId, expectedId);
+
+        final var serializedContextId = serializer.serializeContextId(expectedContextId);
+        final var serializedIdUuid = serializer.serializeUuid(expectedId);
+
+        final var expectedServiceId =
+                ContextOuterClass.ServiceId.newBuilder()
+                        .setContextId(serializedContextId)
+                        .setServiceUuid(serializedIdUuid)
+                        .build();
+
+        final var serializedServiceId = serializer.serialize(serviceId);
+
+        assertThat(serializedServiceId).usingRecursiveComparison().isEqualTo(expectedServiceId);
+    }
+
+    @Test
+    void shouldDeserializeServiceId() {
+        final var expectedContextId = "expectedContextId";
+        final var expectedId = "expectedId";
+
+        final var expectedServiceId = new ServiceId(expectedContextId, expectedId);
+
+        final var serializedServiceId = serializer.serialize(expectedServiceId);
+
+        final var serviceId = serializer.deserialize(serializedServiceId);
+
+        assertThat(serviceId).usingRecursiveComparison().isEqualTo(expectedServiceId);
+    }
+
+    private static Stream<Arguments> provideServiceStatusEnum() {
+        return Stream.of(
+                Arguments.of(
+                        ServiceStatusEnum.ACTIVE, ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_ACTIVE),
+                Arguments.of(
+                        ServiceStatusEnum.PLANNED, ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_PLANNED),
+                Arguments.of(
+                        ServiceStatusEnum.PENDING_REMOVAL,
+                        ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL),
+                Arguments.of(
+                        ServiceStatusEnum.UNDEFINED,
+                        ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_UNDEFINED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideServiceStatusEnum")
+    void shouldSerializeServiceStatusEnum(
+            ServiceStatusEnum serviceStatusEnum,
+            ContextOuterClass.ServiceStatusEnum expectedSerializedType) {
+        final var serializedServiceStatusEnum = serializer.serialize(serviceStatusEnum);
+
+        assertThat(serializedServiceStatusEnum.getNumber())
+                .isEqualTo(expectedSerializedType.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideServiceStatusEnum")
+    void shouldDeserializeServiceStatusEnum(
+            ServiceStatusEnum expectedServiceStatusEnum,
+            ContextOuterClass.ServiceStatusEnum serializedServiceStatusEnum) {
+        final var serviceStatusEnum = serializer.deserialize(serializedServiceStatusEnum);
+
+        assertThat(serviceStatusEnum).isEqualTo(expectedServiceStatusEnum);
+    }
+
+    private static Stream<Arguments> provideServiceTypeEnum() {
+        return Stream.of(
+                Arguments.of(ServiceTypeEnum.L2NM, ContextOuterClass.ServiceTypeEnum.SERVICETYPE_L2NM),
+                Arguments.of(ServiceTypeEnum.L3NM, ContextOuterClass.ServiceTypeEnum.SERVICETYPE_L3NM),
+                Arguments.of(
+                        ServiceTypeEnum.TAPI_CONNECTIVITY_SERVICE,
+                        ContextOuterClass.ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE),
+                Arguments.of(
+                        ServiceTypeEnum.UNKNOWN, ContextOuterClass.ServiceTypeEnum.SERVICETYPE_UNKNOWN));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideServiceTypeEnum")
+    void shouldSerializeServiceTypeEnum(
+            ServiceTypeEnum serviceTypeEnum, ContextOuterClass.ServiceTypeEnum expectedSerializedType) {
+        final var serializedServiceTypeEnum = serializer.serialize(serviceTypeEnum);
+
+        assertThat(serializedServiceTypeEnum.getNumber()).isEqualTo(expectedSerializedType.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideServiceTypeEnum")
+    void shouldDeserializeServiceTypeEnum(
+            ServiceTypeEnum expectedServiceTypeEnum,
+            ContextOuterClass.ServiceTypeEnum serializedServiceTypeEnum) {
+        final var serviceTypeEnum = serializer.deserialize(serializedServiceTypeEnum);
+
+        assertThat(serviceTypeEnum).isEqualTo(expectedServiceTypeEnum);
+    }
+
+    @Test
+    void shouldSerializeServiceStatus() {
+        final var expectedServiceStatusEnum = ServiceStatusEnum.ACTIVE;
+        final var serviceStatus = new ServiceStatus(expectedServiceStatusEnum);
+
+        final var serializedServiceStatusEnum = serializer.serialize(expectedServiceStatusEnum);
+
+        final var expectedServiceStatus =
+                ContextOuterClass.ServiceStatus.newBuilder()
+                        .setServiceStatus(serializedServiceStatusEnum)
+                        .build();
+
+        final var serializedServiceStatus = serializer.serialize(serviceStatus);
+
+        assertThat(serializedServiceStatus).usingRecursiveComparison().isEqualTo(expectedServiceStatus);
+    }
+
+    @Test
+    void shouldDeserializeServiceStatus() {
+        final var expectedServiceStatus = new ServiceStatus(ServiceStatusEnum.PENDING_REMOVAL);
+
+        final var serializedServiceStatus = serializer.serialize(expectedServiceStatus);
+        final var serviceStatus = serializer.deserialize(serializedServiceStatus);
+
+        assertThat(serviceStatus).usingRecursiveComparison().isEqualTo(expectedServiceStatus);
+    }
+
+    @Test
+    void shouldSerializeServiceConfig() {
+        final var configRuleA = createConfigRule();
+        final var configRuleB = createConfigRule();
+        final var serviceConfig = new ServiceConfig(List.of(configRuleA, configRuleB));
+
+        final var expectedConfigRuleA = serializer.serialize(configRuleA);
+        final var expectedConfigRuleB = serializer.serialize(configRuleB);
+
+        final var expectedServiceConfig =
+                ContextOuterClass.ServiceConfig.newBuilder()
+                        .addAllConfigRules(List.of(expectedConfigRuleA, expectedConfigRuleB))
+                        .build();
+
+        final var serializedServiceConfig = serializer.serialize(serviceConfig);
+
+        assertThat(serializedServiceConfig).usingRecursiveComparison().isEqualTo(expectedServiceConfig);
+    }
+
+    @Test
+    void shouldDeserializeServiceConfig() {
+        final var expectedConfigRuleA = createConfigRule();
+        final var expectedConfigRuleB = createConfigRule();
+        final var expectedServiceConfig =
+                new ServiceConfig(List.of(expectedConfigRuleA, expectedConfigRuleB));
+
+        final var configRuleA = serializer.serialize(expectedConfigRuleA);
+        final var configRuleB = serializer.serialize(expectedConfigRuleB);
+        final var serializedServiceConfig =
+                ContextOuterClass.ServiceConfig.newBuilder()
+                        .addAllConfigRules(List.of(configRuleA, configRuleB))
+                        .build();
+
+        final var serviceConfig = serializer.deserialize(serializedServiceConfig);
+
+        assertThat(serviceConfig).usingRecursiveComparison().isEqualTo(expectedServiceConfig);
+    }
+
+    @Test
+    void shouldSerializeService() {
+        final var expectedServiceId = new ServiceId("contextId", "serviceId");
+        final var expectedServiceTypeEnum = ServiceTypeEnum.TAPI_CONNECTIVITY_SERVICE;
+        final var firstExpectedTopologyId = new TopologyId("contextId", "firstTopologyId");
+        final var secondExpectedTopologyId = new TopologyId("contextId", "secondTopologyId");
+
+        final var firstExpectedEndPointId =
+                new EndPointId(firstExpectedTopologyId, "firstDeviceId", "firstEndPointId");
+        final var secondExpectedEndPointId =
+                new EndPointId(secondExpectedTopologyId, "firstDeviceId", "firstEndPointId");
+        final var expectedServiceEndPointIds =
+                List.of(firstExpectedEndPointId, secondExpectedEndPointId);
+
+        final var expectedConstraintTypeA = "constraintTypeA";
+        final var expectedConstraintValueA = "constraintValueA";
+
+        final var constraintCustomA =
+                new ConstraintCustom(expectedConstraintTypeA, expectedConstraintValueA);
+        final var constraintTypeCustomA = new ConstraintTypeCustom(constraintCustomA);
+        final var firstExpectedConstraint = new Constraint(constraintTypeCustomA);
+
+        final var expectedConstraintTypeB = "constraintTypeB";
+        final var expectedConstraintValueB = "constraintValueB";
+
+        final var constraintCustomB =
+                new ConstraintCustom(expectedConstraintTypeB, expectedConstraintValueB);
+        final var constraintTypeCustomB = new ConstraintTypeCustom(constraintCustomB);
+        final var secondExpectedConstraint = new Constraint(constraintTypeCustomB);
+
+        final var expectedServiceConstraints =
+                List.of(firstExpectedConstraint, secondExpectedConstraint);
+
+        final var expectedServiceStatus = new ServiceStatus(ServiceStatusEnum.PLANNED);
+
+        final var expectedConfigRuleA = createConfigRule();
+        final var expectedConfigRuleB = createConfigRule();
+
+        final var expectedConfigRules = List.of(expectedConfigRuleA, expectedConfigRuleB);
+
+        final var expectedServiceConfig = new ServiceConfig(expectedConfigRules);
+
+        final var service =
+                new Service(
+                        expectedServiceId,
+                        expectedServiceTypeEnum,
+                        expectedServiceEndPointIds,
+                        expectedServiceConstraints,
+                        expectedServiceStatus,
+                        expectedServiceConfig);
+
+        final var serializedServiceId = serializer.serialize(expectedServiceId);
+        final var serializedServiceType = serializer.serialize(expectedServiceTypeEnum);
+        final var serializedServiceEndPointIds =
+                expectedServiceEndPointIds.stream()
+                        .map(endPointId -> serializer.serialize(endPointId))
+                        .collect(Collectors.toList());
+        final var serializedServiceConstraints =
+                expectedServiceConstraints.stream()
+                        .map(constraint -> serializer.serialize(constraint))
+                        .collect(Collectors.toList());
+        final var serializedServiceStatus = serializer.serialize(expectedServiceStatus);
+        final var serializedServiceConfig = serializer.serialize(expectedServiceConfig);
+
+        final var expectedService =
+                ContextOuterClass.Service.newBuilder()
+                        .setServiceId(serializedServiceId)
+                        .setServiceType(serializedServiceType)
+                        .addAllServiceEndpointIds(serializedServiceEndPointIds)
+                        .addAllServiceConstraints(serializedServiceConstraints)
+                        .setServiceStatus(serializedServiceStatus)
+                        .setServiceConfig(serializedServiceConfig)
+                        .build();
+
+        final var serializedService = serializer.serialize(service);
+
+        assertThat(serializedService).usingRecursiveComparison().isEqualTo(expectedService);
+    }
+
+    @Test
+    void shouldDeserializeService() {
+        final var expectedServiceId = new ServiceId("contextId", "serviceId");
+        final var expectedServiceTypeEnum = ServiceTypeEnum.TAPI_CONNECTIVITY_SERVICE;
+        final var firstExpectedTopologyId = new TopologyId("contextId", "firstTopologyId");
+        final var secondExpectedTopologyId = new TopologyId("contextId", "secondTopologyId");
+
+        final var firstExpectedEndPointId =
+                new EndPointId(firstExpectedTopologyId, "firstDeviceId", "firstEndPointId");
+        final var secondExpectedEndPointId =
+                new EndPointId(secondExpectedTopologyId, "firstDeviceId", "firstEndPointId");
+        final var expectedServiceEndPointIds =
+                List.of(firstExpectedEndPointId, secondExpectedEndPointId);
+
+        final var expectedConstraintTypeA = "constraintTypeA";
+        final var expectedConstraintValueA = "constraintValueA";
+
+        final var constraintCustomA =
+                new ConstraintCustom(expectedConstraintTypeA, expectedConstraintValueA);
+        final var constraintTypeCustomA = new ConstraintTypeCustom(constraintCustomA);
+        final var firstExpectedConstraint = new Constraint(constraintTypeCustomA);
+
+        final var expectedConstraintTypeB = "constraintTypeB";
+        final var expectedConstraintValueB = "constraintValueB";
+
+        final var constraintCustomB =
+                new ConstraintCustom(expectedConstraintTypeB, expectedConstraintValueB);
+        final var constraintTypeCustomB = new ConstraintTypeCustom(constraintCustomB);
+        final var secondExpectedConstraint = new Constraint(constraintTypeCustomB);
+
+        final var expectedServiceConstraints =
+                List.of(firstExpectedConstraint, secondExpectedConstraint);
+
+        final var expectedServiceStatus = new ServiceStatus(ServiceStatusEnum.PLANNED);
+
+        final var firstExpectedConfigRuleA = createConfigRule();
+        final var secondExpectedConfigRuleB = createConfigRule();
+
+        final var expectedConfigRules = List.of(firstExpectedConfigRuleA, secondExpectedConfigRuleB);
+
+        final var expectedServiceConfig = new ServiceConfig(expectedConfigRules);
+
+        final var expectedService =
+                new Service(
+                        expectedServiceId,
+                        expectedServiceTypeEnum,
+                        expectedServiceEndPointIds,
+                        expectedServiceConstraints,
+                        expectedServiceStatus,
+                        expectedServiceConfig);
+
+        final var serializedServiceId = serializer.serialize(expectedServiceId);
+        final var serializedServiceType = serializer.serialize(expectedServiceTypeEnum);
+        final var serializedServiceEndPointIds =
+                expectedServiceEndPointIds.stream()
+                        .map(endPointId -> serializer.serialize(endPointId))
+                        .collect(Collectors.toList());
+        final var serializedServiceConstraints =
+                expectedServiceConstraints.stream()
+                        .map(constraint -> serializer.serialize(constraint))
+                        .collect(Collectors.toList());
+        final var serializedServiceStatus = serializer.serialize(expectedServiceStatus);
+        final var serializedServiceConfig = serializer.serialize(expectedServiceConfig);
+
+        final var serializedService =
+                ContextOuterClass.Service.newBuilder()
+                        .setServiceId(serializedServiceId)
+                        .setServiceType(serializedServiceType)
+                        .addAllServiceEndpointIds(serializedServiceEndPointIds)
+                        .addAllServiceConstraints(serializedServiceConstraints)
+                        .setServiceStatus(serializedServiceStatus)
+                        .setServiceConfig(serializedServiceConfig)
+                        .build();
+
+        final var service = serializer.deserialize(serializedService);
+
+        assertThat(service).usingRecursiveComparison().isEqualTo(expectedService);
+    }
+
+    private static Stream<Arguments> provideKpiSampleType() {
+        return Stream.of(
+                Arguments.of(
+                        KpiSampleType.PACKETS_TRANSMITTED,
+                        KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED),
+                Arguments.of(
+                        KpiSampleType.PACKETS_RECEIVED,
+                        KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED),
+                Arguments.of(
+                        KpiSampleType.BYTES_TRANSMITTED,
+                        KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_BYTES_TRANSMITTED),
+                Arguments.of(
+                        KpiSampleType.BYTES_RECEIVED,
+                        KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_BYTES_RECEIVED),
+                Arguments.of(KpiSampleType.UNKNOWN, KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideKpiSampleType")
+    void shouldSerializeKpiSampleType(
+            KpiSampleType kpiSampleType, KpiSampleTypes.KpiSampleType expectedSerializedType) {
+        final var serializedKpiSampleType = serializer.serialize(kpiSampleType);
+
+        assertThat(serializedKpiSampleType.getNumber()).isEqualTo(expectedSerializedType.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideKpiSampleType")
+    void shouldDeserializeKpiSampleType(
+            KpiSampleType expectedKpiSampleType, KpiSampleTypes.KpiSampleType serializedKpiSampleType) {
+        final var kpiSampleType = serializer.deserialize(serializedKpiSampleType);
+
+        assertThat(kpiSampleType).isEqualTo(expectedKpiSampleType);
+    }
+
+    private static Stream<Arguments> provideRuleState() {
+        return Stream.of(
+                Arguments.of(RuleState.POLICY_UNDEFINED, Policy.RuleState.POLICY_UNDEFINED),
+                Arguments.of(RuleState.POLICY_FAILED, Policy.RuleState.POLICY_FAILED),
+                Arguments.of(RuleState.POLICY_INSERTED, Policy.RuleState.POLICY_INSERTED),
+                Arguments.of(RuleState.POLICY_VALIDATED, Policy.RuleState.POLICY_VALIDATED),
+                Arguments.of(RuleState.POLICY_PROVISIONED, Policy.RuleState.POLICY_PROVISIONED),
+                Arguments.of(RuleState.POLICY_ACTIVE, Policy.RuleState.POLICY_ACTIVE),
+                Arguments.of(RuleState.POLICY_ENFORCED, Policy.RuleState.POLICY_ENFORCED),
+                Arguments.of(RuleState.POLICY_INEFFECTIVE, Policy.RuleState.POLICY_INEFFECTIVE),
+                Arguments.of(RuleState.POLICY_EFFECTIVE, Policy.RuleState.POLICY_EFFECTIVE),
+                Arguments.of(RuleState.POLICY_UPDATED, Policy.RuleState.POLICY_UPDATED),
+                Arguments.of(RuleState.POLICY_REMOVED, Policy.RuleState.POLICY_REMOVED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideRuleState")
+    void shouldSerializeRuleState(RuleState ruleState, Policy.RuleState expectedSerializedType) {
+        final var serializedRuleState = serializer.serialize(ruleState);
+
+        assertThat(serializedRuleState.getNumber()).isEqualTo(expectedSerializedType.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideRuleState")
+    void shouldDeserializeRuleState(
+            RuleState expectedRuleState, Policy.RuleState serializedRuleState) {
+        final var ruleState = serializer.deserialize(serializedRuleState);
+
+        assertThat(ruleState).isEqualTo(expectedRuleState);
+    }
+
+    @Test
+    void shouldSerializePolicyRuleState() {
+        final var expectedRuleState = RuleState.POLICY_ACTIVE;
+        final var policyRuleState = new PolicyRuleState(expectedRuleState);
+
+        final var serializedRuleState = serializer.serialize(expectedRuleState);
+
+        final var expectedPolicyRuleState =
+                Policy.PolicyRuleState.newBuilder().setPolicyRuleState(serializedRuleState).build();
+
+        final var serializedPolicyRuleState = serializer.serialize(policyRuleState);
+
+        assertThat(serializedPolicyRuleState)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedPolicyRuleState);
+    }
+
+    @Test
+    void shouldDeserializePolicyRuleState() {
+        final var expectedRuleState = RuleState.POLICY_ENFORCED;
+        final var expectedPolicyRuleState = new PolicyRuleState(expectedRuleState);
+
+        final var serializedPolicyRuleState = serializer.serialize(expectedPolicyRuleState);
+
+        final var policyRuleState = serializer.deserialize(serializedPolicyRuleState);
+
+        assertThat(policyRuleState).usingRecursiveComparison().isEqualTo(expectedPolicyRuleState);
+    }
+
+    private static Stream<Arguments> provideNumericalOperator() {
+        return Stream.of(
+                Arguments.of(
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_EQUAL,
+                        PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_EQUAL),
+                Arguments.of(
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL,
+                        PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL),
+                Arguments.of(
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN,
+                        PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_LESS_THAN),
+                Arguments.of(
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL,
+                        PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL),
+                Arguments.of(
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN,
+                        PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN),
+                Arguments.of(
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL,
+                        PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL),
+                Arguments.of(
+                        NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_UNDEFINED,
+                        PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_UNDEFINED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideNumericalOperator")
+    void shouldSerializeNumericalOperator(
+            NumericalOperator numericalOperator,
+            PolicyCondition.NumericalOperator expectedNumericalOperator) {
+        final var serializedNumericalOperator = serializer.serialize(numericalOperator);
+
+        assertThat(serializedNumericalOperator).isEqualTo(expectedNumericalOperator);
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideNumericalOperator")
+    void shouldDeserializeNumericalOperator(
+            NumericalOperator expectedNumericalOperator,
+            PolicyCondition.NumericalOperator serializedNumericalOperator) {
+        final var numericalOperator = serializer.deserialize(serializedNumericalOperator);
+
+        assertThat(numericalOperator).isEqualTo(expectedNumericalOperator);
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideNumericalOperator")
+    void shouldSerializePolicyRuleConditionGivenMultipleNumericalOperators(
+            NumericalOperator expectedNumericalOperator) {
+        final var expectedPolicyRuleConditionKpiId = "expectedPolicyRuleConditionKpiId";
+        final var expectedPolicyRuleConditionKpiValue = new IntegerKpiValue(34);
+
+        final var policyRuleCondition =
+                new PolicyRuleCondition(
+                        expectedPolicyRuleConditionKpiId,
+                        expectedNumericalOperator,
+                        expectedPolicyRuleConditionKpiValue);
+
+        final var serializedPolicyRuleConditionKpiIdUuid =
+                serializer.serializeUuid(expectedPolicyRuleConditionKpiId);
+        final var serializedPolicyRuleConditionKpiId =
+                KpiId.newBuilder().setKpiId(serializedPolicyRuleConditionKpiIdUuid).build();
+        final var serializedNumericalOperator = serializer.serialize(expectedNumericalOperator);
+        final var serializedPolicyRuleConditionKpiValue =
+                serializer.serializeIntegerKpiValue(expectedPolicyRuleConditionKpiValue);
+
+        final var expectedPolicyRuleCondition =
+                PolicyCondition.PolicyRuleCondition.newBuilder()
+                        .setKpiId(serializedPolicyRuleConditionKpiId)
+                        .setNumericalOperator(serializedNumericalOperator)
+                        .setKpiValue(serializedPolicyRuleConditionKpiValue)
+                        .build();
+
+        final var serializedPolicyRuleCondition = serializer.serialize(policyRuleCondition);
+
+        assertThat(serializedPolicyRuleCondition)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedPolicyRuleCondition);
+    }
+
+    private static Stream<Arguments> provideKpiValues() {
+        return Stream.of(
+                Arguments.of(
+                        new StringKpiValue("stringKpiValue"),
+                        Monitoring.KpiValue.newBuilder().setStringVal("stringKpiValue").build()),
+                Arguments.of(
+                        new BooleanKpiValue(true), Monitoring.KpiValue.newBuilder().setBoolVal(true).build()),
+                Arguments.of(
+                        new IntegerKpiValue(44), Monitoring.KpiValue.newBuilder().setIntVal(44).build()),
+                Arguments.of(
+                        new FloatKpiValue(12.3f), Monitoring.KpiValue.newBuilder().setFloatVal(12.3f).build()));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideKpiValues")
+    void shouldSerializeKpiValues(KpiValue kpiValue, Monitoring.KpiValue expectedKpiValue) {
+        final var serializedKpiValue = serializer.serialize(kpiValue);
+
+        assertThat(serializedKpiValue).isEqualTo(expectedKpiValue);
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideKpiValues")
+    void shouldDeserializeKpiValues(
+            KpiValue expectedKpiValue, Monitoring.KpiValue serializedKpiValue) {
+        final var kpiValue = serializer.deserialize(serializedKpiValue);
+
+        assertThat(kpiValue).usingRecursiveComparison().isEqualTo(expectedKpiValue);
+    }
+
+    @Test
+    void shouldThrowIllegalStateExceptionDuringDeserializationOfNonSpecifiedKpiValue() {
+        final var serializedKpiValue = Monitoring.KpiValue.newBuilder().build();
+
+        assertThatExceptionOfType(IllegalStateException.class)
+                .isThrownBy(() -> serializer.deserialize(serializedKpiValue));
+    }
+
+    @Test
+    void shouldDeserializeIntegerKpiValue() {
+        final var expectedKpiValue = new IntegerKpiValue(66);
+
+        final var intValue = serializer.serializeIntegerKpiValue(expectedKpiValue);
+        final var deserializedKpiValue = serializer.deserializeIntegerKpiValue(intValue);
+
+        assertThat(deserializedKpiValue).isEqualTo(expectedKpiValue.getValue());
+    }
+
+    @Test
+    void shouldDeserializeStringKpiValue() {
+        final var expectedKpiValue = new StringKpiValue("StringKpiValue");
+
+        final var stringValue = serializer.serializeStringKpiValue(expectedKpiValue);
+        final var deserializedKpiValue = serializer.deserializeStringKpiValue(stringValue);
+
+        assertThat(deserializedKpiValue).isEqualTo(expectedKpiValue.getValue());
+    }
+
+    @Test
+    void shouldDeserializeFloatKpiValue() {
+        final var expectedKpiValue = new FloatKpiValue(2.2f);
+
+        final var floatValue = serializer.serializeFloatKpiValue(expectedKpiValue);
+        final var deserializedKpiValue = serializer.deserializeFloatKpiValue(floatValue);
+
+        assertThat(deserializedKpiValue).isEqualTo(expectedKpiValue.getValue());
+    }
+
+    @Test
+    void shouldDeserializeBooleanKpiValue() {
+        final var expectedKpiValue = new BooleanKpiValue(true);
+
+        final var booleanValue = serializer.serializeBooleanKpiValue(expectedKpiValue);
+        final var deserializedKpiValue = serializer.deserializeBooleanKpiValue(booleanValue);
+
+        assertThat(deserializedKpiValue).isEqualTo(expectedKpiValue.getValue());
+    }
+
+    private static Stream<Arguments> provideKpiValueRanges() {
+        return Stream.of(
+                Arguments.of(
+                        new KpiValueRange(new IntegerKpiValue(32), new IntegerKpiValue(42)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setIntVal(32).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setIntVal(42).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new IntegerKpiValue(32), new FloatKpiValue(42.2f)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setIntVal(32).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setFloatVal(42.2f).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new IntegerKpiValue(32), new BooleanKpiValue(true)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setIntVal(32).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setBoolVal(true).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new IntegerKpiValue(32), new StringKpiValue("string")),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setIntVal(32).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new FloatKpiValue(56.2f), new IntegerKpiValue(42)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setFloatVal(56.2f).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setIntVal(42).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new FloatKpiValue(56.2f), new FloatKpiValue(42.2f)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setFloatVal(56.2f).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setFloatVal(42.2f).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new FloatKpiValue(56.2f), new BooleanKpiValue(true)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setFloatVal(56.2f).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setBoolVal(true).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new FloatKpiValue(56.2f), new StringKpiValue("string")),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setFloatVal(56.2f).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new BooleanKpiValue(true), new IntegerKpiValue(42)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setBoolVal(true).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setIntVal(42).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new BooleanKpiValue(false), new FloatKpiValue(42.2f)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setBoolVal(false).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setFloatVal(42.2f).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new BooleanKpiValue(true), new BooleanKpiValue(true)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setBoolVal(true).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setBoolVal(true).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new BooleanKpiValue(false), new StringKpiValue("string")),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setBoolVal(false).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new StringKpiValue("string"), new IntegerKpiValue(42)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setIntVal(42).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new StringKpiValue("string"), new FloatKpiValue(42.2f)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setFloatVal(42.2f).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new StringKpiValue("string"), new BooleanKpiValue(true)),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setBoolVal(true).build())
+                                .build()),
+                Arguments.of(
+                        new KpiValueRange(new StringKpiValue("string"), new StringKpiValue("string")),
+                        Monitoring.KpiValueRange.newBuilder()
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
+                                .build()));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideKpiValueRanges")
+    void shouldSerializeKpiValueRange(
+            KpiValueRange kpiValueRange, Monitoring.KpiValueRange expectedKpiValueRange) {
+        final var serializedKpiValueRange = serializer.serialize(kpiValueRange);
+
+        assertThat(serializedKpiValueRange.getKpiMinValue())
+                .isEqualTo(expectedKpiValueRange.getKpiMinValue());
+        assertThat(serializedKpiValueRange.getKpiMaxValue())
+                .isEqualTo(expectedKpiValueRange.getKpiMaxValue());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideKpiValueRanges")
+    void shouldDeserializeKpiValueRange(
+            KpiValueRange expectedKpiValueRange, Monitoring.KpiValueRange serializedKpiValueRange) {
+        final var kpiValueRange = serializer.deserialize(serializedKpiValueRange);
+
+        assertThat(kpiValueRange.getKpiMinValue())
+                .usingRecursiveComparison()
+                .isEqualTo(expectedKpiValueRange.getKpiMinValue());
+        assertThat(kpiValueRange.getKpiMaxValue())
+                .usingRecursiveComparison()
+                .isEqualTo(expectedKpiValueRange.getKpiMaxValue());
+    }
+
+    @Test
+    void shouldSerializeAlarmDescriptor() {
+        final var alarmDescription = "alarmDescription";
+        final var name = "name";
+        final var kpiId = "kpiId";
+        final var timestamp = "timestamp";
+
+        final var kpiValueRange = new KpiValueRange(new IntegerKpiValue(23), new IntegerKpiValue(1800));
+        final var alarmDescriptor =
+                new AlarmDescriptor(alarmDescription, name, kpiId, kpiValueRange, timestamp);
+
+        final var serializedKpiIdUuid = serializer.serializeUuid(kpiId);
+        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedKpiValueRange = serializer.serialize(kpiValueRange);
+
+        final var expectedAlarmDescriptor =
+                Monitoring.AlarmDescriptor.newBuilder()
+                        .setAlarmDescription(alarmDescription)
+                        .setName(name)
+                        .setKpiId(serializedKpiId)
+                        .setKpiValueRange(serializedKpiValueRange)
+                        .setTimestamp(timestamp)
+                        .build();
+
+        final var serializedAlarmDescriptor = serializer.serialize(alarmDescriptor);
+
+        assertThat(serializedAlarmDescriptor).isEqualTo(expectedAlarmDescriptor);
+    }
+
+    @Test
+    void shouldDeserializeAlarmDescriptor() {
+        final var alarmDescription = "alarmDescription";
+        final var name = "name";
+        final var kpiId = "kpiId";
+        final var timestamp = "timestamp";
+
+        final var kpiValueRange = new KpiValueRange(new IntegerKpiValue(23), new IntegerKpiValue(1800));
+        final var expectedAlarmDescriptor =
+                new AlarmDescriptor(alarmDescription, name, kpiId, kpiValueRange, timestamp);
+
+        final var serializedKpiIdUuid = serializer.serializeUuid(kpiId);
+        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedKpiValueRange = serializer.serialize(kpiValueRange);
+
+        final var serializedAlarmDescriptor =
+                Monitoring.AlarmDescriptor.newBuilder()
+                        .setAlarmDescription(alarmDescription)
+                        .setName(name)
+                        .setKpiId(serializedKpiId)
+                        .setKpiValueRange(serializedKpiValueRange)
+                        .setTimestamp(timestamp)
+                        .build();
+
+        final var alarmDescriptor = serializer.deserialize(serializedAlarmDescriptor);
+
+        assertThat(alarmDescriptor).usingRecursiveComparison().isEqualTo(expectedAlarmDescriptor);
+    }
+
+    @Test
+    void shouldSerializeAlarmResponse() {
+        final var alarmId = "alarmId";
+        final var text = "text";
+        final var kpiValue = new IntegerKpiValue(12);
+
+        final var alarmResponse = new AlarmResponse(alarmId, text, kpiValue);
+
+        final var serializedAlarmIdUuid = serializer.serializeUuid(alarmId);
+        final var serializedAlarmId = AlarmID.newBuilder().setAlarmId(serializedAlarmIdUuid).build();
+        final var serializedKpiValue = serializer.serialize(kpiValue);
+
+        final var expectedAlarmResponse =
+                Monitoring.AlarmResponse.newBuilder()
+                        .setAlarmId(serializedAlarmId)
+                        .setText(text)
+                        .setKpiValue(serializedKpiValue)
+                        .build();
+
+        final var serializedAlarmResponse = serializer.serialize(alarmResponse);
+
+        assertThat(serializedAlarmResponse).isEqualTo(expectedAlarmResponse);
+    }
+
+    @Test
+    void shouldDeserializeAlarmResponse() {
+        final var alarmId = "alarmId";
+        final var text = "text";
+        final var kpiValue = new IntegerKpiValue(12);
+
+        final var expectedAlarmResponse = new AlarmResponse(alarmId, text, kpiValue);
+
+        final var serializedAlarmIdUuid = serializer.serializeUuid(alarmId);
+        final var serializedAlarmId = AlarmID.newBuilder().setAlarmId(serializedAlarmIdUuid).build();
+        final var serializedKpiValue = serializer.serialize(kpiValue);
+
+        final var serializedAlarmResponse =
+                Monitoring.AlarmResponse.newBuilder()
+                        .setAlarmId(serializedAlarmId)
+                        .setText(text)
+                        .setKpiValue(serializedKpiValue)
+                        .build();
+
+        final var alarmResponse = serializer.deserialize(serializedAlarmResponse);
+
+        assertThat(alarmResponse).usingRecursiveComparison().isEqualTo(expectedAlarmResponse);
+    }
+
+    @Test
+    void shouldSerializeSubDescriptor() {
+        final var kpiId = "kpiId";
+        final var samplingDurationS = 10f;
+        final var samplingIntervalS = 45f;
+        final var startDate = "01/07/2022";
+        final var endDate = "02/07/2022";
+
+        final var subDescriptor =
+                new SubsDescriptor(kpiId, samplingDurationS, samplingIntervalS, startDate, endDate);
+
+        final var serializedKpiIdUuid = serializer.serializeUuid(kpiId);
+        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+
+        final var expectedSubDescriptor =
+                Monitoring.SubsDescriptor.newBuilder()
+                        .setKpiId(serializedKpiId)
+                        .setSamplingDurationS(samplingDurationS)
+                        .setSamplingIntervalS(samplingIntervalS)
+                        .setStartDate(startDate)
+                        .setEndDate(endDate)
+                        .build();
+
+        final var serializedSubDescriptor = serializer.serialize(subDescriptor);
+
+        assertThat(serializedSubDescriptor).isEqualTo(expectedSubDescriptor);
+    }
+
+    @Test
+    void shouldDeserializeSubDescriptor() {
+        final var kpiId = "kpiId";
+        final var samplingDurationS = 10f;
+        final var samplingIntervalS = 45f;
+        final var startDate = "01/07/2022";
+        final var endDate = "02/07/2022";
+
+        final var expectedSubDescriptor =
+                new SubsDescriptor(kpiId, samplingDurationS, samplingIntervalS, startDate, endDate);
+
+        final var serializedKpiIdUuid = serializer.serializeUuid(kpiId);
+        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+
+        final var serializedSubDescriptor =
+                Monitoring.SubsDescriptor.newBuilder()
+                        .setKpiId(serializedKpiId)
+                        .setSamplingDurationS(samplingDurationS)
+                        .setSamplingIntervalS(samplingIntervalS)
+                        .setStartDate(startDate)
+                        .setEndDate(endDate)
+                        .build();
+
+        final var subDescriptor = serializer.deserialize(serializedSubDescriptor);
+
+        assertThat(subDescriptor).usingRecursiveComparison().isEqualTo(expectedSubDescriptor);
+    }
+
+    @Test
+    void shouldDeserializePolicyRuleCondition() {
+        final var expectedPolicyRuleConditionKpiId = "expectedPolicyRuleConditionKpiId";
+        final var expectedPolicyRuleConditionNumericalOperator =
+                NumericalOperator.POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN;
+        final var expectedPolicyRuleConditionKpiValue = new IntegerKpiValue(34);
+
+        final var expectedPolicyRuleCondition =
+                new PolicyRuleCondition(
+                        expectedPolicyRuleConditionKpiId,
+                        expectedPolicyRuleConditionNumericalOperator,
+                        expectedPolicyRuleConditionKpiValue);
+
+        final var serializedPolicyRuleCondition = serializer.serialize(expectedPolicyRuleCondition);
+
+        final var policyRuleCondition = serializer.deserialize(serializedPolicyRuleCondition);
+
+        assertThat(policyRuleCondition)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedPolicyRuleCondition);
+    }
+
+    private static Stream<Arguments> provideBooleanOperators() {
+        return Stream.of(
+                Arguments.of(
+                        BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_AND,
+                        PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_AND),
+                Arguments.of(
+                        BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_OR,
+                        PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_OR),
+                Arguments.of(
+                        BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED,
+                        PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideBooleanOperators")
+    void shouldSerializeBooleanOperator(
+            BooleanOperator booleanOperator, PolicyCondition.BooleanOperator expectedBooleanOperator) {
+        final var serializedBooleanOperator = serializer.serialize(booleanOperator);
+
+        assertThat(serializedBooleanOperator).isEqualTo(expectedBooleanOperator);
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideBooleanOperators")
+    void shouldDeserializeBooleanOperator(
+            BooleanOperator expectedBooleanOperator,
+            PolicyCondition.BooleanOperator serializedBooleanOperator) {
+        final var booleanOperator = serializer.deserialize(serializedBooleanOperator);
+
+        assertThat(booleanOperator).isEqualTo(expectedBooleanOperator);
+    }
+
+    private static Stream<Arguments> providePolicyRuleActionEnum() {
+        return Stream.of(
+                Arguments.of(
+                        PolicyRuleActionEnum.POLICY_RULE_ACTION_SET_DEVICE_STATUS,
+                        PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_SET_DEVICE_STATUS),
+                Arguments.of(
+                        PolicyRuleActionEnum.POLICY_RULE_ACTION_ADD_SERVICE_CONFIGRULE,
+                        PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE),
+                Arguments.of(
+                        PolicyRuleActionEnum.POLICY_RULE_ACTION_ADD_SERVICE_CONSTRAINT,
+                        PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT),
+                Arguments.of(
+                        PolicyRuleActionEnum.POLICY_RULE_ACTION_NO_ACTION,
+                        PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_NO_ACTION));
+    }
+
+    @ParameterizedTest
+    @MethodSource("providePolicyRuleActionEnum")
+    void shouldSerializePolicyRuleActionEnum(
+            PolicyRuleActionEnum policyRuleActionEnum,
+            PolicyAction.PolicyRuleActionEnum expectedPolicyRuleActionEnum) {
+        final var serializedPolicyRuleActionEnum = serializer.serialize(policyRuleActionEnum);
+
+        assertThat(serializedPolicyRuleActionEnum).isEqualTo(expectedPolicyRuleActionEnum);
+    }
+
+    @ParameterizedTest
+    @MethodSource("providePolicyRuleActionEnum")
+    void shouldDeserializePolicyRuleActionEnum(
+            PolicyRuleActionEnum expectedPolicyRuleActionEnum,
+            PolicyAction.PolicyRuleActionEnum serializedPolicyRuleActionEnum) {
+        final var policyRuleActionEnum = serializer.deserialize(serializedPolicyRuleActionEnum);
+
+        assertThat(policyRuleActionEnum).isEqualTo(expectedPolicyRuleActionEnum);
+    }
+
+    @Test
+    void shouldSerializePolicyRuleAction() {
+        final var expectedPolicyRuleActionEnum =
+                PolicyRuleActionEnum.POLICY_RULE_ACTION_ADD_SERVICE_CONSTRAINT;
+        final var expectedPolicyRuleActionParameters = List.of("parameter1", "parameter2");
+        final var policyRuleAction =
+                new PolicyRuleAction(expectedPolicyRuleActionEnum, expectedPolicyRuleActionParameters);
+
+        final var serializedPolicyRuleActionEnum = serializer.serialize(expectedPolicyRuleActionEnum);
+
+        final var expectedPolicyRuleAction =
+                PolicyAction.PolicyRuleAction.newBuilder()
+                        .setAction(serializedPolicyRuleActionEnum)
+                        .addAllParameters(expectedPolicyRuleActionParameters)
+                        .build();
+
+        final var serializedPolicyRuleAction = serializer.serialize(policyRuleAction);
+
+        assertThat(serializedPolicyRuleAction)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedPolicyRuleAction);
+    }
+
+    @Test
+    void shouldDeserializePolicyRuleAction() {
+        final var expectedPolicyRuleActionEnum = PolicyRuleActionEnum.POLICY_RULE_ACTION_NO_ACTION;
+        final var expectedPolicyRuleActionParameters = List.of("parameter1", "parameter2");
+        final var expectedPolicyRuleAction =
+                new PolicyRuleAction(expectedPolicyRuleActionEnum, expectedPolicyRuleActionParameters);
+
+        final var serializedPolicyRuleAction = serializer.serialize(expectedPolicyRuleAction);
+
+        final var policyRuleAction = serializer.deserialize(serializedPolicyRuleAction);
+
+        assertThat(policyRuleAction).usingRecursiveComparison().isEqualTo(expectedPolicyRuleAction);
+    }
+
+    @Test
+    void shouldSerializePolicyRuleBasic() {
+        final var policyRuleBasic = createPolicyRuleBasic();
+
+        final var expectedPolicyRuleId = policyRuleBasic.getPolicyRuleId();
+        final var expectedPolicyRuleState = policyRuleBasic.getPolicyRuleState();
+        final var expectedPriority = policyRuleBasic.getPriority();
+        final var expectedPolicyRuleConditions = policyRuleBasic.getPolicyRuleConditions();
+        final var expectedBooleanOperator = policyRuleBasic.getBooleanOperator();
+        final var expectedPolicyRuleActions = policyRuleBasic.getPolicyRuleActions();
+
+        final var serializedPolicyRuleId = serializer.serializePolicyRuleId(expectedPolicyRuleId);
+        final var serializedPolicyRuleState = serializer.serialize(expectedPolicyRuleState);
+        final var serializedPolicyRuleConditions =
+                expectedPolicyRuleConditions.stream()
+                        .map(policyRuleCondition -> serializer.serialize(policyRuleCondition))
+                        .collect(Collectors.toList());
+        final var serializedBooleanOperator = serializer.serialize(expectedBooleanOperator);
+        final var serializedPolicyRuleActions =
+                expectedPolicyRuleActions.stream()
+                        .map(policyRuleAction -> serializer.serialize(policyRuleAction))
+                        .collect(Collectors.toList());
+
+        final var expectedPolicyRuleBasic =
+                Policy.PolicyRuleBasic.newBuilder()
+                        .setPolicyRuleId(serializedPolicyRuleId)
+                        .setPolicyRuleState(serializedPolicyRuleState)
+                        .setPriority(expectedPriority)
+                        .addAllConditionList(serializedPolicyRuleConditions)
+                        .setBooleanOperator(serializedBooleanOperator)
+                        .addAllActionList(serializedPolicyRuleActions)
+                        .build();
+
+        final var serializedPolicyRuleBasic = serializer.serialize(policyRuleBasic);
+
+        assertThat(serializedPolicyRuleBasic)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedPolicyRuleBasic);
+    }
+
+    @Test
+    void shouldDeserializePolicyRuleBasic() {
+        final var expectedPolicyRuleBasic = createPolicyRuleBasic();
+
+        final var expectedPolicyRuleId = expectedPolicyRuleBasic.getPolicyRuleId();
+        final var expectedPolicyRuleState = expectedPolicyRuleBasic.getPolicyRuleState();
+        final var expectedPriority = expectedPolicyRuleBasic.getPriority();
+        final var expectedPolicyRuleConditions = expectedPolicyRuleBasic.getPolicyRuleConditions();
+        final var expectedBooleanOperator = expectedPolicyRuleBasic.getBooleanOperator();
+        final var expectedPolicyRuleActions = expectedPolicyRuleBasic.getPolicyRuleActions();
+
+        final var serializedPolicyRuleId = serializer.serializePolicyRuleId(expectedPolicyRuleId);
+        final var serializedPolicyRuleState = serializer.serialize(expectedPolicyRuleState);
+        final var serializedPolicyRuleConditions =
+                expectedPolicyRuleConditions.stream()
+                        .map(policyRuleCondition -> serializer.serialize(policyRuleCondition))
+                        .collect(Collectors.toList());
+        final var serializedBooleanOperator = serializer.serialize(expectedBooleanOperator);
+        final var serializedPolicyRuleActions =
+                expectedPolicyRuleActions.stream()
+                        .map(policyRuleAction -> serializer.serialize(policyRuleAction))
+                        .collect(Collectors.toList());
+
+        final var serializedPolicyRuleBasic =
+                Policy.PolicyRuleBasic.newBuilder()
+                        .setPolicyRuleId(serializedPolicyRuleId)
+                        .setPolicyRuleState(serializedPolicyRuleState)
+                        .setPriority(expectedPriority)
+                        .addAllConditionList(serializedPolicyRuleConditions)
+                        .setBooleanOperator(serializedBooleanOperator)
+                        .addAllActionList(serializedPolicyRuleActions)
+                        .build();
+
+        final var policyRuleBasic = serializer.deserialize(serializedPolicyRuleBasic);
+
+        assertThat(policyRuleBasic).usingRecursiveComparison().isEqualTo(expectedPolicyRuleBasic);
+    }
+
+    @Test
+    void shouldSerializePolicyRuleService() {
+        final var policyRuleBasic = createPolicyRuleBasic();
+        final var serviceId = new ServiceId("contextId", "serviceId");
+        final var deviceIds = List.of("deviceId1", "deviceId2");
+
+        final var policyRuleService = new PolicyRuleService(policyRuleBasic, serviceId, deviceIds);
+
+        final var serializedPolicyRuleBasic = serializer.serialize(policyRuleBasic);
+        final var serializedPolicyRuleServiceId = serializer.serialize(serviceId);
+        final var serializedPolicyRuleDeviceIds =
+                deviceIds.stream()
+                        .map(deviceId -> serializer.serializeDeviceId(deviceId))
+                        .collect(Collectors.toList());
+
+        final var expectedPolicyRuleService =
+                Policy.PolicyRuleService.newBuilder()
+                        .setPolicyRuleBasic(serializedPolicyRuleBasic)
+                        .setServiceId(serializedPolicyRuleServiceId)
+                        .addAllDeviceList(serializedPolicyRuleDeviceIds)
+                        .build();
+
+        final var serializedPolicyRuleService = serializer.serialize(policyRuleService);
+
+        assertThat(serializedPolicyRuleService)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedPolicyRuleService);
+    }
+
+    @Test
+    void shouldDeserializePolicyRuleService() {
+        final var expectedPolicyRuleBasic = createPolicyRuleBasic();
+        final var expectedServiceId = new ServiceId("contextId", "serviceId");
+        final var expectedDeviceIds = List.of("deviceId1", "deviceId2");
+        final var expectedPolicyRuleService =
+                new PolicyRuleService(expectedPolicyRuleBasic, expectedServiceId, expectedDeviceIds);
+
+        final var serializedPolicyRuleBasic = serializer.serialize(expectedPolicyRuleBasic);
+        final var serializedPolicyRuleServiceId = serializer.serialize(expectedServiceId);
+        final var serializedPolicyRuleDeviceIds =
+                expectedDeviceIds.stream()
+                        .map(deviceId -> serializer.serializeDeviceId(deviceId))
+                        .collect(Collectors.toList());
+
+        final var serializedPolicyRuleService =
+                Policy.PolicyRuleService.newBuilder()
+                        .setPolicyRuleBasic(serializedPolicyRuleBasic)
+                        .setServiceId(serializedPolicyRuleServiceId)
+                        .addAllDeviceList(serializedPolicyRuleDeviceIds)
+                        .build();
+
+        final var policyRuleService = serializer.deserialize(serializedPolicyRuleService);
+
+        assertThat(policyRuleService).usingRecursiveComparison().isEqualTo(expectedPolicyRuleService);
+    }
+
+    @Test
+    void shouldSerializePolicyRuleDevice() {
+        final var policyRuleBasic = createPolicyRuleBasic();
+        final var deviceIds = List.of("deviceId1", "deviceId2");
+
+        final var policyRuleDevice = new PolicyRuleDevice(policyRuleBasic, deviceIds);
+
+        final var serializedPolicyRuleBasic = serializer.serialize(policyRuleBasic);
+        final var serializedPolicyRuleDeviceIds =
+                deviceIds.stream()
+                        .map(deviceId -> serializer.serializeDeviceId(deviceId))
+                        .collect(Collectors.toList());
+
+        final var expectedPolicyRuleDevice =
+                Policy.PolicyRuleDevice.newBuilder()
+                        .setPolicyRuleBasic(serializedPolicyRuleBasic)
+                        .addAllDeviceList(serializedPolicyRuleDeviceIds)
+                        .build();
+
+        final var serializedPolicyRuleDevice = serializer.serialize(policyRuleDevice);
+
+        assertThat(serializedPolicyRuleDevice)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedPolicyRuleDevice);
+    }
+
+    @Test
+    void shouldDeserializePolicyRuleDevice() {
+        final var expectedPolicyRuleBasic = createPolicyRuleBasic();
+        final var expectedDeviceIds = List.of("deviceId1", "deviceId2");
+        final var expectedPolicyRuleDevice =
+                new PolicyRuleDevice(expectedPolicyRuleBasic, expectedDeviceIds);
+
+        final var serializedPolicyRuleBasic = serializer.serialize(expectedPolicyRuleBasic);
+        final var serializedPolicyRuleDeviceIds =
+                expectedDeviceIds.stream()
+                        .map(deviceId -> serializer.serializeDeviceId(deviceId))
+                        .collect(Collectors.toList());
+
+        final var serializedPolicyRuleDevice =
+                Policy.PolicyRuleDevice.newBuilder()
+                        .setPolicyRuleBasic(serializedPolicyRuleBasic)
+                        .addAllDeviceList(serializedPolicyRuleDeviceIds)
+                        .build();
+
+        final var policyRuleDevice = serializer.deserialize(serializedPolicyRuleDevice);
+
+        assertThat(policyRuleDevice).usingRecursiveComparison().isEqualTo(expectedPolicyRuleDevice);
+    }
+
+    @Test
+    void shouldSerializeKpiId() {
+        final var kpiId = "kpiId";
+
+        final var kpiIdUuid = serializer.serializeUuid(kpiId);
+
+        final var expectedKpiId = Monitoring.KpiId.newBuilder().setKpiId(kpiIdUuid).build();
+
+        final var serializedKpiId = serializer.serializeKpiId(kpiId);
+
+        assertThat(serializedKpiId).usingRecursiveComparison().isEqualTo(expectedKpiId);
+    }
+
+    @Test
+    void shouldDeserializeKpiId() {
+        final var expectedKpiId = "expectedKpiId";
+
+        final var serializedKpiIdUuid = serializer.serializeUuid(expectedKpiId);
+        final var serializedKpiId = Monitoring.KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+
+        final var kpiId = serializer.deserialize(serializedKpiId);
+
+        assertThat(kpiId).isEqualTo(expectedKpiId);
+    }
+
+    @Test
+    void shouldSerializeKpi() {
+        final var expectedKpiId = "expectedKpiId";
+        final var expectedTimestamp = "expectedTimestamp";
+        final var expectedKpiValue = new FloatKpiValue(643.45f);
+
+        final var kpi = new Kpi(expectedKpiId, expectedTimestamp, expectedKpiValue);
+
+        final var serializedKpiId = serializer.serializeKpiId(expectedKpiId);
+        final var serializedKpiValue = serializer.serialize(expectedKpiValue);
+
+        final var expectedKpi =
+                Monitoring.Kpi.newBuilder()
+                        .setKpiId(serializedKpiId)
+                        .setTimestamp(expectedTimestamp)
+                        .setKpiValue(serializedKpiValue)
+                        .build();
+
+        final var serializedKpi = serializer.serialize(kpi);
+
+        assertThat(serializedKpi).usingRecursiveComparison().isEqualTo(expectedKpi);
+    }
+
+    @Test
+    void shouldDeserializeKpi() {
+        final var expectedKpiId = "expectedKpiId";
+        final var expectedTimestamp = "expectedTimestamp";
+        final var expectedKpiValue = new BooleanKpiValue(true);
+        final var expectedKpi = new Kpi(expectedKpiId, expectedTimestamp, expectedKpiValue);
+
+        final var serializedKpi = serializer.serialize(expectedKpi);
+
+        final var kpi = serializer.deserialize(serializedKpi);
+
+        assertThat(kpi).usingRecursiveComparison().isEqualTo(expectedKpi);
+    }
+
+    @Test
+    void shouldSerializeKpiDescriptor() {
+        final var expectedKpiDescription = "expectedKpiDescription";
+        final var expectedKpiSampleType = KpiSampleType.BYTES_RECEIVED;
+        final var expectedDeviceId = "expectedDeviceId";
+
+        final var expectedTopologyId = new TopologyId("contextId", "topologyId");
+        final var expectedEndPointId =
+                new EndPointId(expectedTopologyId, expectedDeviceId, "endpointId");
+        final var expectedServiceId = new ServiceId("contextId", "serviceId");
+        final var expectedSliceId = new SliceId("contextId", "sliceId");
+
+        final var kpiDescriptor =
+                new KpiDescriptor(
+                        expectedKpiDescription,
+                        expectedKpiSampleType,
+                        expectedDeviceId,
+                        expectedEndPointId,
+                        expectedServiceId,
+                        expectedSliceId);
+
+        final var serializedKpiSampleType = serializer.serialize(expectedKpiSampleType);
+        final var serializedDeviceId = serializer.serializeDeviceId(expectedDeviceId);
+        final var serializedEndPointId = serializer.serialize(expectedEndPointId);
+        final var serializedServiceId = serializer.serialize(expectedServiceId);
+        final var serializedSliceId = serializer.serialize(expectedSliceId);
+
+        final var expectedKpiDescriptor =
+                Monitoring.KpiDescriptor.newBuilder()
+                        .setKpiDescription(expectedKpiDescription)
+                        .setKpiSampleType(serializedKpiSampleType)
+                        .setDeviceId(serializedDeviceId)
+                        .setEndpointId(serializedEndPointId)
+                        .setServiceId(serializedServiceId)
+                        .setSliceId(serializedSliceId)
+                        .build();
+
+        final var serializedKpiDescriptor = serializer.serialize(kpiDescriptor);
+
+        assertThat(serializedKpiDescriptor).usingRecursiveComparison().isEqualTo(expectedKpiDescriptor);
+    }
+
+    @Test
+    void shouldDeserializeKpiDescriptor() {
+        final var expectedKpiDescription = "expectedKpiDescription";
+        final var expectedKpiSampleType = KpiSampleType.BYTES_RECEIVED;
+        final var expectedDeviceId = "expectedDeviceId";
+
+        final var expectedTopologyId = new TopologyId("contextId", "topologyId");
+        final var expectedEndPointId =
+                new EndPointId(expectedTopologyId, expectedDeviceId, "endpointId");
+        final var expectedServiceId = new ServiceId("contextId", "serviceId");
+        final var expectedSliceId = new SliceId("contextId", "sliceId");
+
+        final var expectedKpiDescriptor =
+                new KpiDescriptor(
+                        expectedKpiDescription,
+                        expectedKpiSampleType,
+                        expectedDeviceId,
+                        expectedEndPointId,
+                        expectedServiceId,
+                        expectedSliceId);
+
+        final var serializedKpiSampleType = serializer.serialize(expectedKpiSampleType);
+        final var serializedDeviceId = serializer.serializeDeviceId(expectedDeviceId);
+        final var serializedEndPointId = serializer.serialize(expectedEndPointId);
+        final var serializedServiceId = serializer.serialize(expectedServiceId);
+        final var serializedSliceId = serializer.serialize(expectedSliceId);
+
+        final var serializedKpiDescriptor =
+                Monitoring.KpiDescriptor.newBuilder()
+                        .setKpiDescription(expectedKpiDescription)
+                        .setKpiSampleType(serializedKpiSampleType)
+                        .setDeviceId(serializedDeviceId)
+                        .setEndpointId(serializedEndPointId)
+                        .setServiceId(serializedServiceId)
+                        .setSliceId(serializedSliceId)
+                        .build();
+
+        final var kpiDescriptor = serializer.deserialize(serializedKpiDescriptor);
+
+        assertThat(kpiDescriptor).usingRecursiveComparison().isEqualTo(expectedKpiDescriptor);
+    }
+
+    @Test
+    void shouldSerializeUuid() {
+        final var expectedUuid = "uuid";
+
+        final var serializeUuid = serializer.serializeUuid(expectedUuid);
+
+        assertThat(serializeUuid.getUuid()).isEqualTo(expectedUuid);
+    }
+
+    @Test
+    void shouldDeserializeUuid() {
+        final var expectedUuid = "uuid";
+
+        final var uuid = serializer.deserialize(Uuid.newBuilder().setUuid(expectedUuid).build());
+
+        assertThat(uuid).isEqualTo(expectedUuid);
+    }
+}
diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml
index 248fb6143f0203cf436f2cc666da9038f97d8d54..bfd8398e80ffec1ca69ca49bf96e6faf9a15e471 100644
--- a/src/policy/target/kubernetes/kubernetes.yml
+++ b/src/policy/target/kubernetes/kubernetes.yml
@@ -3,20 +3,20 @@ apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 4244298f2625d05dce3c62d8431b03f799506e78
-    app.quarkus.io/build-timestamp: 2022-07-21 - 11:54:42 +0000
+    app.quarkus.io/commit-id: 38171d32b260b03cfa8b2beef6b85dde4471ad48
+    app.quarkus.io/build-timestamp: 2022-07-21 - 13:18:31 +0000
   labels:
     app.kubernetes.io/name: policyservice
     app: policyservice
   name: policyservice
 spec:
   ports:
-    - name: http
-      port: 8080
-      targetPort: 8080
     - name: grpc
       port: 6060
       targetPort: 6060
+    - name: http
+      port: 8080
+      targetPort: 8080
   selector:
     app.kubernetes.io/name: policyservice
   type: ClusterIP
@@ -25,8 +25,8 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 4244298f2625d05dce3c62d8431b03f799506e78
-    app.quarkus.io/build-timestamp: 2022-07-21 - 11:54:42 +0000
+    app.quarkus.io/commit-id: 38171d32b260b03cfa8b2beef6b85dde4471ad48
+    app.quarkus.io/build-timestamp: 2022-07-21 - 13:18:31 +0000
   labels:
     app: policyservice
     app.kubernetes.io/name: policyservice
@@ -39,8 +39,8 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: 4244298f2625d05dce3c62d8431b03f799506e78
-        app.quarkus.io/build-timestamp: 2022-07-21 - 11:54:42 +0000
+        app.quarkus.io/commit-id: 38171d32b260b03cfa8b2beef6b85dde4471ad48
+        app.quarkus.io/build-timestamp: 2022-07-21 - 13:18:31 +0000
       labels:
         app: policyservice
         app.kubernetes.io/name: policyservice
@@ -51,12 +51,12 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
-            - name: MONITORING_SERVICE_HOST
-              value: monitoringservice
             - name: CONTEXT_SERVICE_HOST
               value: contextservice
             - name: SERVICE_SERVICE_HOST
               value: serviceservice
+            - name: MONITORING_SERVICE_HOST
+              value: monitoringservice
           image: registry.gitlab.com/teraflow-h2020/controller/policy:0.1.0
           imagePullPolicy: Always
           livenessProbe:
@@ -71,12 +71,12 @@ spec:
             timeoutSeconds: 10
           name: policyservice
           ports:
-            - containerPort: 8080
-              name: http
-              protocol: TCP
             - containerPort: 6060
               name: grpc
               protocol: TCP
+            - containerPort: 8080
+              name: http
+              protocol: TCP
           readinessProbe:
             failureThreshold: 3
             httpGet: