diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d627359e93ea57b865c91f211f5683ee7b5a8a07..3ab9ceb24c672d96f5cad9c48d7b32b8dfeb028e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -15,5 +15,6 @@ include:
   - local: '/src/context/.gitlab-ci.yml'
   - local: '/src/device/.gitlab-ci.yml'
   - local: '/src/service/.gitlab-ci.yml'
+  #- local: '/src/slice/.gitlab-ci.yml'
   - local: '/src/tester_integration/.gitlab-ci.yml'
   - local: '/src/tester_functional/.gitlab-ci.yml'
diff --git a/manifests/sliceservice.yaml b/manifests/sliceservice.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6cd81e61a447aa6893322003b0a245e85bfda697
--- /dev/null
+++ b/manifests/sliceservice.yaml
@@ -0,0 +1,54 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: sliceservice
+spec:
+  selector:
+    matchLabels:
+      app: sliceservice
+  template:
+    metadata:
+      labels:
+        app: sliceservice
+    spec:
+      terminationGracePeriodSeconds: 5
+      containers:
+      - name: server
+        image: registry.gitlab.com/teraflow-h2020/controller/slice:latest
+        imagePullPolicy: Always
+        ports:
+        - containerPort: 4040
+        env:
+        - name: DB_ENGINE
+          value: "redis"
+        - name: REDIS_DATABASE_ID
+          value: "0"
+        - name: LOG_LEVEL
+          value: "DEBUG"
+        readinessProbe:
+          exec:
+            command: ["/bin/grpc_health_probe", "-addr=:4040"]
+        livenessProbe:
+          exec:
+            command: ["/bin/grpc_health_probe", "-addr=:4040"]
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: sliceservice
+spec:
+  type: ClusterIP
+  selector:
+    app: sliceservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 4040
+    targetPort: 4040
diff --git a/report_coverage_slice.sh b/report_coverage_slice.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f783ec069329a9efe100154a2702a72a93e0ad8a
--- /dev/null
+++ b/report_coverage_slice.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+./report_coverage_all.sh | grep --color -E -i "^slice/.*$|$"
diff --git a/run_local_tests.sh b/run_local_tests.sh
index 59aef4c79f8e179e432db74b37cfc9cc01a201b2..82db9bd15f0e6f2af5c52a97b1f42b5373e98c3d 100755
--- a/run_local_tests.sh
+++ b/run_local_tests.sh
@@ -22,6 +22,9 @@ coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
     service/tests/test_unitary.py
 
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    slice/tests/test_unitary.py
+
 # Run integration tests and analyze coverage of code at same time
 export DB_ENGINE='redis'
 export REDIS_SERVICE_HOST='10.1.7.194'
diff --git a/src/common/database/api/context/slice/SliceStatus.py b/src/common/database/api/context/slice/SliceStatus.py
new file mode 100644
index 0000000000000000000000000000000000000000..d97b3944999e58cc2ad54f28ed6e22232b5fcd71
--- /dev/null
+++ b/src/common/database/api/context/slice/SliceStatus.py
@@ -0,0 +1,31 @@
+from enum import Enum
+
+class SliceStatus(Enum):
+    PLANNED = 0
+    INIT    = 1
+    ACTIVE  = 2
+    DEINIT  = 3
+
+ANY_TO_ENUM = {
+    0: SliceStatus.PLANNED,
+    1: SliceStatus.INIT,
+    2: SliceStatus.ACTIVE,
+    3: SliceStatus.DEINIT,
+
+    '0': SliceStatus.PLANNED,
+    '1': SliceStatus.INIT,
+    '2': SliceStatus.ACTIVE,
+    '3': SliceStatus.DEINIT,
+
+    'planned': SliceStatus.PLANNED,
+    'init': SliceStatus.INIT,
+    'active': SliceStatus.ACTIVE,
+    'deinit': SliceStatus.DEINIT,
+}
+
+def slicestatus_enum_values():
+    return {m.value for m in SliceStatus.__members__.values()}
+
+def to_slicestatus_enum(int_or_str):
+    if isinstance(int_or_str, str): int_or_str = int_or_str.lower()
+    return ANY_TO_ENUM.get(int_or_str)
diff --git a/src/common/database/api/context/slice/__init__.py b/src/common/database/api/context/slice/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/common/tools/service/ConstraintsChecker.py b/src/common/tools/service/ConstraintsChecker.py
new file mode 100644
index 0000000000000000000000000000000000000000..c4af21b4af3ff3887ac5397f405e3f3975ef16f9
--- /dev/null
+++ b/src/common/tools/service/ConstraintsChecker.py
@@ -0,0 +1,38 @@
+import grpc, logging
+from typing import Dict, List, Set, Tuple
+from common.Checkers import chk_string
+from common.exceptions.ServiceException import ServiceException
+from service.proto.context_pb2 import Constraint
+
+def check_constraint(
+    logger : logging.Logger, constraint_number : int, parent_name : str, constraint : Constraint,
+    add_constraints : Dict[str, Dict[str, Set[str]]]) -> Tuple[str, str]:
+
+    try:
+        constraint_type  = chk_string('constraint[#{}].constraint_type'.format(constraint_number),
+                                      constraint.constraint_type,
+                                      allow_empty=False)
+        constraint_value = chk_string('constraint[#{}].constraint_value'.format(constraint_number),
+                                      constraint.constraint_value,
+                                      allow_empty=False)
+    except Exception as e:
+        logger.exception('Invalid arguments:')
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+    if constraint_type in add_constraints:
+        msg = 'Duplicated ConstraintType({}) in {}.'
+        msg = msg.format(constraint_type, parent_name)
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+
+    add_constraints[constraint_type] = constraint_value
+    return constraint_type, constraint_value
+
+def check_constraints(logger : logging.Logger, parent_name : str, constraints):
+    add_constraints : Dict[str, str] = {}
+    constraint_tuples : List[Tuple[str, str]] = []
+    for constraint_number,constraint in enumerate(constraints):
+        parent_name = 'Constraint(#{}) of {}'.format(constraint_number, parent_name)
+        constraint_type, constraint_value = check_constraint(
+            logger, constraint_number, parent_name, constraint, add_constraints)
+        constraint_tuples.append((constraint_type, constraint_value))
+    return constraint_tuples
diff --git a/src/common/tools/service/DeviceCheckers.py b/src/common/tools/service/DeviceCheckers.py
index 9233b683e91ef26c112990dee139e21b3cc4a0c2..80d8398b00b21c59046072df4e12cc7eae5f1305 100644
--- a/src/common/tools/service/DeviceCheckers.py
+++ b/src/common/tools/service/DeviceCheckers.py
@@ -1,12 +1,13 @@
 import grpc
 from common.database.api.Database import Database
+from common.database.api.context.topology.device.Device import Device
 from common.database.api.context.topology.device.Endpoint import Endpoint
 from common.exceptions.ServiceException import ServiceException
 
-def check_device_exists(database : Database, context_id : str, topology_id : str, device_id : str):
+def check_device_exists(database : Database, context_id : str, topology_id : str, device_id : str) -> Device:
     db_context = database.context(context_id).create()
     db_topology = db_context.topology(topology_id).create()
-    if db_topology.devices.contains(device_id): return
+    if db_topology.devices.contains(device_id): return db_topology.device(device_id)
     msg = 'Context({})/Topology({})/Device({}) does not exist in the database.'
     msg = msg.format(context_id, topology_id, device_id)
     raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
diff --git a/src/common/tools/service/EndpointIdCheckers.py b/src/common/tools/service/EndpointIdCheckers.py
index 5ac0fe92dd458f38778d9a62011c4279b42ed918..1b04d5f39ea7f48e92033d4f62367a8104dde851 100644
--- a/src/common/tools/service/EndpointIdCheckers.py
+++ b/src/common/tools/service/EndpointIdCheckers.py
@@ -3,9 +3,10 @@ from typing import Dict, Set, Tuple, Union
 from common.Checkers import chk_string
 from common.exceptions.ServiceException import ServiceException
 from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID
+from context.proto.context_pb2 import EndPointId
 
 def check_endpoint_id(
-    logger : logging.Logger, endpoint_number : int, parent_name : str, endpoint_id : 'EndpointId',
+    logger : logging.Logger, endpoint_number : int, parent_name : str, endpoint_id : 'EndPointId',
     add_topology_devices_endpoints : Dict[str, Dict[str, Set[str]]],
     predefined_context_id : str = DEFAULT_CONTEXT_ID, acceptable_context_ids : Set[str] = set([DEFAULT_CONTEXT_ID]),
     predefined_topology_id : str = DEFAULT_TOPOLOGY_ID, acceptable_topology_ids : Set[str] = set([DEFAULT_TOPOLOGY_ID]),
diff --git a/src/common/tools/service/LinkCheckers.py b/src/common/tools/service/LinkCheckers.py
index a65046dbf065286547b1885239ad7578fa69a562..fb668c87fbc6b0fae7424501c74420f6fc3af35d 100644
--- a/src/common/tools/service/LinkCheckers.py
+++ b/src/common/tools/service/LinkCheckers.py
@@ -1,11 +1,12 @@
 import grpc
 from common.database.api.Database import Database
+from common.database.api.context.topology.link.Link import Link
 from common.exceptions.ServiceException import ServiceException
 
-def check_link_exists(database : Database, context_id : str, topology_id : str, link_id : str):
+def check_link_exists(database : Database, context_id : str, topology_id : str, link_id : str) -> Link:
     db_context = database.context(context_id).create()
     db_topology = db_context.topology(topology_id).create()
-    if db_topology.links.contains(link_id): return
+    if db_topology.links.contains(link_id): return db_topology.link(link_id)
     msg = 'Context({})/Topology({})/Link({}) does not exist in the database.'
     msg = msg.format(context_id, topology_id, link_id)
     raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
diff --git a/src/common/tools/service/ServiceCheckers.py b/src/common/tools/service/ServiceCheckers.py
index d8bafd1c03db0b1b330633062456752da7cd93c9..0cc5d15c6765a4c8310a3257d84313f3a41c23e5 100644
--- a/src/common/tools/service/ServiceCheckers.py
+++ b/src/common/tools/service/ServiceCheckers.py
@@ -9,7 +9,8 @@ def check_service_exists(database : Database, context_id : str, service_id : str
         raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
 
     db_context = database.context(context_id)
-    if db_context.services.contains(service_id): return
+    if db_context.services.contains(service_id):
+        return db_context.service(service_id)
 
     msg = 'Context({})/Service({}) does not exist in the database.'
     msg = msg.format(context_id, service_id)
diff --git a/src/common/tools/service/SliceCheckers.py b/src/common/tools/service/SliceCheckers.py
new file mode 100644
index 0000000000000000000000000000000000000000..bac9766b8595c64f9f8d68954707cc5f1efc68e0
--- /dev/null
+++ b/src/common/tools/service/SliceCheckers.py
@@ -0,0 +1,18 @@
+import grpc
+from common.database.api.Database import Database
+from common.database.api.context.slice.Slice import Slice
+from common.exceptions.ServiceException import ServiceException
+
+def check_slice_exists(database : Database, context_id : str, slice_id : str) -> Slice:
+    db_context = database.context(context_id).create()
+    if db_context.slices.contains(slice_id): return db_context.slice(slice_id)
+    msg = 'Context({})/Slice({}) does not exist in the database.'
+    msg = msg.format(context_id, slice_id)
+    raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
+
+def check_slice_not_exists(database : Database, context_id : str, slice_id : str):
+    db_context = database.context(context_id).create()
+    if not db_context.slices.contains(slice_id): return
+    msg = 'Context({})/Slice({}) already exists in the database.'
+    msg = msg.format(context_id, slice_id)
+    raise ServiceException(grpc.StatusCode.ALREADY_EXISTS, msg)
diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py
index 26b5a5d90c34d7e23e52e12642178b18338891b2..1c42c245628c5b1599015be04debdd4931e20473 100644
--- a/src/device/service/Tools.py
+++ b/src/device/service/Tools.py
@@ -25,12 +25,12 @@ def _check_device_exists(method_name : str, database : Database, device_id : str
     elif method_name in ['UpdateDevice', 'DeleteDevice']:
         check_device_exists(database, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id)
     else:                                       # pragma: no cover (test requires malforming the code)
-        msg = 'Unexpected condition [_check_device_exists(method_name={}, device_id={})]'
+        msg = 'Unexpected condition: _check_device_exists(method_name={}, device_id={})'
         msg = msg.format(str(method_name), str(device_id))
         raise ServiceException(grpc.StatusCode.UNIMPLEMENTED, msg)
 
 def _check_device_endpoint_exists_or_get_pointer(
-    method_name : str, database : Database, parent_name : str, device_id : str, endpoint_id : str):
+    method_name : str, database : Database, parent_name : str, device_id : str, endpoint_id : str) -> Endpoint:
 
     if method_name in ['AddDevice']:
         db_context = database.context(DEFAULT_CONTEXT_ID)
@@ -41,8 +41,9 @@ def _check_device_endpoint_exists_or_get_pointer(
         return check_device_endpoint_exists(
             database, parent_name, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id, endpoint_id)
     else:                                       # pragma: no cover (test requires malforming the code)
-        msg = 'Unexpected condition [_check_device_exists(method_name={}, device_id={})]'
-        msg = msg.format(str(method_name), str(device_id))
+        msg = 'Unexpected condition: _check_device_endpoint_exists_or_get_pointer(method_name={}, ' \
+              'parent_name={}, device_id={}, endpoint_id={})'
+        msg = msg.format(str(method_name), str(parent_name), str(device_id), str(endpoint_id))
         raise ServiceException(grpc.StatusCode.UNIMPLEMENTED, msg)
 
 def check_device_operational_status(method_name : str, value : str) -> OperationalStatus:
diff --git a/src/service/service/Tools.py b/src/service/service/Tools.py
index 62d602c058a55cdd229050cf3ba6301b4519fdb3..2e3b7a8b1f7b0e19d453364df8308982e5a9107d 100644
--- a/src/service/service/Tools.py
+++ b/src/service/service/Tools.py
@@ -2,17 +2,16 @@ import grpc, logging
 from typing import Dict, List, Set, Tuple
 from common.Checkers import chk_options, chk_string
 from common.database.api.Database import Database
-from common.database.api.context.Constants import DEFAULT_TOPOLOGY_ID
 from common.database.api.context.topology.device.Endpoint import Endpoint
 from common.database.api.context.service.ServiceState import ServiceState, servicestate_enum_values, \
     to_servicestate_enum
 from common.database.api.context.service.ServiceType import ServiceType, servicetype_enum_values, to_servicetype_enum
 from common.exceptions.ServiceException import ServiceException
+from common.tools.service.ConstraintsChecker import check_constraints
 from common.tools.service.DeviceCheckers import check_device_endpoint_exists
 from common.tools.service.EndpointIdCheckers import check_endpoint_id
 from common.tools.service.EnumCheckers import check_enum
 from common.tools.service.ServiceCheckers import check_service_exists, check_service_not_exists
-from service.proto.context_pb2 import Constraint
 from service.proto.service_pb2 import Service, ServiceId
 
 # For each method name, define acceptable service types. Empty set means accept all.
@@ -43,29 +42,6 @@ def check_service_type(method_name : str, value : str) -> ServiceType:
 def check_service_state(method_name : str, value : str) -> ServiceState:
     return check_enum('ServiceState', method_name, value, to_servicestate_enum, ACCEPTED_SERVICE_STATES)
 
-def check_service_constraint(
-    logger : logging.Logger, constraint_number : int, parent_name : str, constraint : Constraint,
-    add_constraints : Dict[str, Dict[str, Set[str]]]) -> Tuple[str, str]:
-
-    try:
-        constraint_type  = chk_string('constraint[#{}].constraint_type'.format(constraint_number),
-                                      constraint.constraint_type,
-                                      allow_empty=False)
-        constraint_value = chk_string('constraint[#{}].constraint_value'.format(constraint_number),
-                                      constraint.constraint_value,
-                                      allow_empty=False)
-    except Exception as e:
-        logger.exception('Invalid arguments:')
-        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
-
-    if constraint_type in add_constraints:
-        msg = 'Duplicated ConstraintType({}) in {}.'
-        msg = msg.format(constraint_type, parent_name)
-        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
-
-    add_constraints[constraint_type] = constraint_value
-    return constraint_type, constraint_value
-
 def check_service_request(
     method_name : str, request : Service, database : Database, logger : logging.Logger
     ) -> Tuple[str, str, ServiceType, str, ServiceState, List[Endpoint], List[Tuple[str, str]]]:
@@ -94,18 +70,13 @@ def check_service_request(
     service_type = check_service_type(method_name, service_type)
     service_state = check_service_state(method_name, service_state)
 
+    # ----- Parse constraints ------------------------------------------------------------------------------------------
+    parent_name = 'Context({})/Service({})'.format(context_id, service_id)
+    constraint_tuples : List[Tuple[str, str]] = check_constraints(logger, parent_name, request.constraint)
+
     # ----- Check if service exists in database ------------------------------------------------------------------------
     _check_service_exists(method_name, database, context_id, service_id)
 
-    # ----- Parse constraints ------------------------------------------------------------------------------------------
-    add_constraints : Dict[str, str] = {}
-    constraint_tuples : List[Tuple[str, str]] = []
-    for constraint_number,constraint in enumerate(request.constraint):
-        parent_name = 'Constraint(#{}) of Context({})/Service({})'.format(constraint_number, context_id, service_id)
-        constraint_type, constraint_value = check_service_constraint(
-            logger, constraint_number, parent_name, constraint, add_constraints)
-        constraint_tuples.append((constraint_type, constraint_value))
-
     # ----- Parse endpoints and check if they exist in the database as device endpoints --------------------------------
     add_topology_devices_endpoints : Dict[str, Dict[str, Set[str]]] = {}
     db_endpoints : List[Endpoint] = []
diff --git a/src/slice/.gitlab-ci.yml b/src/slice/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3ba7429f94a5e888f1f6f8c95b46f8df1bf9f971
--- /dev/null
+++ b/src/slice/.gitlab-ci.yml
@@ -0,0 +1,60 @@
+# Build, tag, and push the Docker images to the GitLab Docker registry
+build slice:
+  variables:
+    IMAGE_NAME: 'slice' # name of the microservice
+    IMAGE_NAME_TEST: 'slice-test' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: build
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+  script:
+    - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile ./src/
+    - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+  rules:
+    - changes:
+      - src/$IMAGE_NAME/**
+      - .gitlab-ci.yml
+
+# Pull, execute, and run unitary tests for the Docker image from the GitLab registry
+unit_test slice:
+  variables:
+    IMAGE_NAME: 'slice' # name of the microservice
+    IMAGE_NAME_TEST: 'slice-test' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: unit_test
+  needs:
+    - build slice
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create -d bridge teraflowbridge; fi  
+  script:
+    - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    - docker run -d -p 4040:4040 --name $IMAGE_NAME --network=teraflowbridge "$IMAGE_NAME:$IMAGE_TAG"
+    - docker ps -a
+    - sleep 5
+    - docker ps -a
+    - docker logs $IMAGE_NAME
+    - docker exec -i $IMAGE_NAME bash -c "pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py"
+  after_script:
+    - docker stop $IMAGE_NAME
+    - docker rm $IMAGE_NAME
+  rules:
+    - changes:
+      - src/$IMAGE_NAME/**
+      - .gitlab-ci.yml
+
+# Deployment of the service in Kubernetes Cluster
+deploy slice:
+  stage: deploy
+  needs:
+    - build slice
+    - unit_test slice
+    - dependencies all
+    - integ_test execute
+  script:
+    - kubectl version
+    - kubectl get all
+    - kubectl apply -f "manifests/sliceservice.yaml"
+    - kubectl delete pods --selector app=sliceservice
+    - kubectl get all
diff --git a/src/slice/Config.py b/src/slice/Config.py
new file mode 100644
index 0000000000000000000000000000000000000000..6787413a881b4d84ed6b4ecb5e041901399a4ae6
--- /dev/null
+++ b/src/slice/Config.py
@@ -0,0 +1,12 @@
+import logging
+
+# General settings
+LOG_LEVEL = logging.WARNING
+
+# gRPC settings
+GRPC_SERVICE_PORT = 2020
+GRPC_MAX_WORKERS  = 10
+GRPC_GRACE_PERIOD = 60
+
+# Prometheus settings
+METRICS_PORT = 9192
diff --git a/src/slice/Dockerfile b/src/slice/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..081d60ecde9bdd19d973a058fd1baa4bcf97a29c
--- /dev/null
+++ b/src/slice/Dockerfile
@@ -0,0 +1,35 @@
+FROM python:3-slim
+
+# Install dependencies
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install wget g++ && \
+    rm -rf /var/lib/apt/lists/*
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Download the gRPC health probe
+RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \
+    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
+    chmod +x /bin/grpc_health_probe
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip setuptools wheel pip-tools
+
+# Set working directory
+WORKDIR /var/teraflow
+
+# Create module sub-folders
+RUN mkdir -p /var/teraflow/slice
+
+# Get Python packages per module
+COPY slice/requirements.in slice/requirements.in
+RUN pip-compile --output-file=slice/requirements.txt slice/requirements.in
+RUN python3 -m pip install -r slice/requirements.in
+
+# Add files into working directory
+COPY common/. common
+COPY slice/. slice
+
+# Start slice service
+ENTRYPOINT ["python", "-m", "slice.service"]
diff --git a/src/slice/__init__.py b/src/slice/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/slice/client/SliceClient.py b/src/slice/client/SliceClient.py
new file mode 100644
index 0000000000000000000000000000000000000000..b45aa3032746126a267c03d2e85b6ef72d3a189f
--- /dev/null
+++ b/src/slice/client/SliceClient.py
@@ -0,0 +1,41 @@
+import grpc, logging
+from common.tools.client.RetryDecorator import retry, delay_exponential
+from slice.proto.context_pb2 import Empty
+from slice.proto.slice_pb2 import TransportSlice, SliceStatus
+from slice.proto.slice_pb2_grpc import SliceServiceStub
+
+LOGGER = logging.getLogger(__name__)
+MAX_RETRIES = 15
+DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
+
+class SliceClient:
+    def __init__(self, address, port):
+        self.endpoint = '{}:{}'.format(address, port)
+        LOGGER.debug('Creating channel to {}...'.format(self.endpoint))
+        self.channel = None
+        self.stub = None
+        self.connect()
+        LOGGER.debug('Channel created')
+
+    def connect(self):
+        self.channel = grpc.insecure_channel(self.endpoint)
+        self.stub = SliceServiceStub(self.channel)
+
+    def close(self):
+        if(self.channel is not None): self.channel.close()
+        self.channel = None
+        self.stub = None
+
+    @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
+    def CreateUpdateSlice(self, request : TransportSlice) -> SliceStatus:
+        LOGGER.debug('CreateUpdateSlice request: {}'.format(request))
+        response = self.stub.CreateUpdateSlice(request)
+        LOGGER.debug('CreateUpdateSlice result: {}'.format(response))
+        return response
+
+    @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
+    def DeleteSlice(self, request : TransportSlice) -> Empty:
+        LOGGER.debug('DeleteSlice request: {}'.format(request))
+        response = self.stub.DeleteSlice(request)
+        LOGGER.debug('DeleteSlice result: {}'.format(response))
+        return response
diff --git a/src/slice/client/__init__.py b/src/slice/client/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/slice/genproto.sh b/src/slice/genproto.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b2e38b43aebc6560ac24981ed738469efbffc001
--- /dev/null
+++ b/src/slice/genproto.sh
@@ -0,0 +1,36 @@
+#!/bin/bash -eu
+#
+# Copyright 2018 Google LLC
+#
+# 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.
+
+#!/bin/bash -e
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+rm -rf proto/*.py
+rm -rf proto/__pycache__
+touch proto/__init__.py
+
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto service.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto slice.proto
+
+rm proto/context_pb2_grpc.py
+rm proto/service_pb2_grpc.py
+
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/service_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/slice_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/slice_pb2_grpc.py
diff --git a/src/slice/proto/__init__.py b/src/slice/proto/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/slice/proto/context_pb2.py b/src/slice/proto/context_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..a41b1de47f4df97a6e90b42a02fab7556feafd34
--- /dev/null
+++ b/src/slice/proto/context_pb2.py
@@ -0,0 +1,880 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: context.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='context.proto',
+  package='context',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\"\x07\n\x05\x45mpty\"{\n\x07\x43ontext\x12%\n\tcontextId\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x1f\n\x04topo\x18\x02 \x01(\x0b\x32\x11.context.Topology\x12(\n\x03\x63tl\x18\x03 \x01(\x0b\x32\x1b.context.TeraFlowController\"/\n\tContextId\x12\"\n\x0b\x63ontextUuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"m\n\x08Topology\x12#\n\x06topoId\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\x12\x1f\n\x06\x64\x65vice\x18\x03 \x03(\x0b\x32\x0f.context.Device\x12\x1b\n\x04link\x18\x04 \x03(\x0b\x32\r.context.Link\"S\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12)\n\x0c\x65ndpointList\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"R\n\nTopologyId\x12%\n\tcontextId\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x1d\n\x06topoId\x18\x02 \x01(\x0b\x32\r.context.Uuid\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"\xda\x01\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12>\n\x14\x64\x65vOperationalStatus\x18\x04 \x01(\x0e\x32 .context.DeviceOperationalStatus\x12\'\n\x0c\x65ndpointList\x18\x05 \x03(\x0b\x32\x11.context.EndPoint\"%\n\x0c\x44\x65viceConfig\x12\x15\n\rdevice_config\x18\x01 \x01(\t\"C\n\x08\x45ndPoint\x12$\n\x07port_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x11\n\tport_type\x18\x02 \x01(\t\"t\n\nEndPointId\x12#\n\x06topoId\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12!\n\x06\x64\x65v_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12\x1e\n\x07port_id\x18\x03 \x01(\x0b\x32\r.context.Uuid\",\n\x08\x44\x65viceId\x12 \n\tdevice_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"(\n\x06LinkId\x12\x1e\n\x07link_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"K\n\x12TeraFlowController\x12\"\n\x06\x63tl_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x11\n\tipaddress\x18\x02 \x01(\t\"Q\n\x14\x41uthenticationResult\x12\"\n\x06\x63tl_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*N\n\x17\x44\x65viceOperationalStatus\x12\x0f\n\x0bKEEP_STATUS\x10\x00\x12\x15\n\x08\x44ISABLED\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x0b\n\x07\x45NABLED\x10\x01\x32\xa2\x01\n\x0e\x43ontextService\x12\x32\n\x0bGetTopology\x12\x0e.context.Empty\x1a\x11.context.Topology\"\x00\x12+\n\x07\x41\x64\x64Link\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nDeleteLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
+)
+
+_DEVICEOPERATIONALSTATUS = _descriptor.EnumDescriptor(
+  name='DeviceOperationalStatus',
+  full_name='context.DeviceOperationalStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='KEEP_STATUS', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DISABLED', index=1, number=-1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ENABLED', index=2, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=1271,
+  serialized_end=1349,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUS)
+
+DeviceOperationalStatus = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUS)
+KEEP_STATUS = 0
+DISABLED = -1
+ENABLED = 1
+
+
+
+_EMPTY = _descriptor.Descriptor(
+  name='Empty',
+  full_name='context.Empty',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=26,
+  serialized_end=33,
+)
+
+
+_CONTEXT = _descriptor.Descriptor(
+  name='Context',
+  full_name='context.Context',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contextId', full_name='context.Context.contextId', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topo', full_name='context.Context.topo', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ctl', full_name='context.Context.ctl', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=35,
+  serialized_end=158,
+)
+
+
+_CONTEXTID = _descriptor.Descriptor(
+  name='ContextId',
+  full_name='context.ContextId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contextUuid', full_name='context.ContextId.contextUuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=160,
+  serialized_end=207,
+)
+
+
+_TOPOLOGY = _descriptor.Descriptor(
+  name='Topology',
+  full_name='context.Topology',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topoId', full_name='context.Topology.topoId', index=0,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device', full_name='context.Topology.device', index=1,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link', full_name='context.Topology.link', index=2,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=209,
+  serialized_end=318,
+)
+
+
+_LINK = _descriptor.Descriptor(
+  name='Link',
+  full_name='context.Link',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.Link.link_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpointList', full_name='context.Link.endpointList', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=320,
+  serialized_end=403,
+)
+
+
+_TOPOLOGYID = _descriptor.Descriptor(
+  name='TopologyId',
+  full_name='context.TopologyId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contextId', full_name='context.TopologyId.contextId', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topoId', full_name='context.TopologyId.topoId', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=405,
+  serialized_end=487,
+)
+
+
+_CONSTRAINT = _descriptor.Descriptor(
+  name='Constraint',
+  full_name='context.Constraint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='constraint_type', full_name='context.Constraint.constraint_type', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='constraint_value', full_name='context.Constraint.constraint_value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=489,
+  serialized_end=552,
+)
+
+
+_DEVICE = _descriptor.Descriptor(
+  name='Device',
+  full_name='context.Device',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.Device.device_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_type', full_name='context.Device.device_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_config', full_name='context.Device.device_config', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='devOperationalStatus', full_name='context.Device.devOperationalStatus', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpointList', full_name='context.Device.endpointList', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=555,
+  serialized_end=773,
+)
+
+
+_DEVICECONFIG = _descriptor.Descriptor(
+  name='DeviceConfig',
+  full_name='context.DeviceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_config', full_name='context.DeviceConfig.device_config', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=775,
+  serialized_end=812,
+)
+
+
+_ENDPOINT = _descriptor.Descriptor(
+  name='EndPoint',
+  full_name='context.EndPoint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='port_id', full_name='context.EndPoint.port_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='port_type', full_name='context.EndPoint.port_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=814,
+  serialized_end=881,
+)
+
+
+_ENDPOINTID = _descriptor.Descriptor(
+  name='EndPointId',
+  full_name='context.EndPointId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topoId', full_name='context.EndPointId.topoId', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='dev_id', full_name='context.EndPointId.dev_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='port_id', full_name='context.EndPointId.port_id', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=883,
+  serialized_end=999,
+)
+
+
+_DEVICEID = _descriptor.Descriptor(
+  name='DeviceId',
+  full_name='context.DeviceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.DeviceId.device_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1001,
+  serialized_end=1045,
+)
+
+
+_LINKID = _descriptor.Descriptor(
+  name='LinkId',
+  full_name='context.LinkId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.LinkId.link_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1047,
+  serialized_end=1087,
+)
+
+
+_UUID = _descriptor.Descriptor(
+  name='Uuid',
+  full_name='context.Uuid',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uuid', full_name='context.Uuid.uuid', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1089,
+  serialized_end=1109,
+)
+
+
+_TERAFLOWCONTROLLER = _descriptor.Descriptor(
+  name='TeraFlowController',
+  full_name='context.TeraFlowController',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ctl_id', full_name='context.TeraFlowController.ctl_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ipaddress', full_name='context.TeraFlowController.ipaddress', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1111,
+  serialized_end=1186,
+)
+
+
+_AUTHENTICATIONRESULT = _descriptor.Descriptor(
+  name='AuthenticationResult',
+  full_name='context.AuthenticationResult',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ctl_id', full_name='context.AuthenticationResult.ctl_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='authenticated', full_name='context.AuthenticationResult.authenticated', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1188,
+  serialized_end=1269,
+)
+
+_CONTEXT.fields_by_name['contextId'].message_type = _CONTEXTID
+_CONTEXT.fields_by_name['topo'].message_type = _TOPOLOGY
+_CONTEXT.fields_by_name['ctl'].message_type = _TERAFLOWCONTROLLER
+_CONTEXTID.fields_by_name['contextUuid'].message_type = _UUID
+_TOPOLOGY.fields_by_name['topoId'].message_type = _TOPOLOGYID
+_TOPOLOGY.fields_by_name['device'].message_type = _DEVICE
+_TOPOLOGY.fields_by_name['link'].message_type = _LINK
+_LINK.fields_by_name['link_id'].message_type = _LINKID
+_LINK.fields_by_name['endpointList'].message_type = _ENDPOINTID
+_TOPOLOGYID.fields_by_name['contextId'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['topoId'].message_type = _UUID
+_DEVICE.fields_by_name['device_id'].message_type = _DEVICEID
+_DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG
+_DEVICE.fields_by_name['devOperationalStatus'].enum_type = _DEVICEOPERATIONALSTATUS
+_DEVICE.fields_by_name['endpointList'].message_type = _ENDPOINT
+_ENDPOINT.fields_by_name['port_id'].message_type = _ENDPOINTID
+_ENDPOINTID.fields_by_name['topoId'].message_type = _TOPOLOGYID
+_ENDPOINTID.fields_by_name['dev_id'].message_type = _DEVICEID
+_ENDPOINTID.fields_by_name['port_id'].message_type = _UUID
+_DEVICEID.fields_by_name['device_id'].message_type = _UUID
+_LINKID.fields_by_name['link_id'].message_type = _UUID
+_TERAFLOWCONTROLLER.fields_by_name['ctl_id'].message_type = _CONTEXTID
+_AUTHENTICATIONRESULT.fields_by_name['ctl_id'].message_type = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
+DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT
+DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY
+DESCRIPTOR.message_types_by_name['Link'] = _LINK
+DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID
+DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT
+DESCRIPTOR.message_types_by_name['Device'] = _DEVICE
+DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG
+DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT
+DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID
+DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID
+DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID
+DESCRIPTOR.message_types_by_name['Uuid'] = _UUID
+DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER
+DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT
+DESCRIPTOR.enum_types_by_name['DeviceOperationalStatus'] = _DEVICEOPERATIONALSTATUS
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
+  'DESCRIPTOR' : _EMPTY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Empty)
+  })
+_sym_db.RegisterMessage(Empty)
+
+Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Context)
+  })
+_sym_db.RegisterMessage(Context)
+
+ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextId)
+  })
+_sym_db.RegisterMessage(ContextId)
+
+Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Topology)
+  })
+_sym_db.RegisterMessage(Topology)
+
+Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), {
+  'DESCRIPTOR' : _LINK,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Link)
+  })
+_sym_db.RegisterMessage(Link)
+
+TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyId)
+  })
+_sym_db.RegisterMessage(TopologyId)
+
+Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), {
+  'DESCRIPTOR' : _CONSTRAINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Constraint)
+  })
+_sym_db.RegisterMessage(Constraint)
+
+Device = _reflection.GeneratedProtocolMessageType('Device', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Device)
+  })
+_sym_db.RegisterMessage(Device)
+
+DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceConfig)
+  })
+_sym_db.RegisterMessage(DeviceConfig)
+
+EndPoint = _reflection.GeneratedProtocolMessageType('EndPoint', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPoint)
+  })
+_sym_db.RegisterMessage(EndPoint)
+
+EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPointId)
+  })
+_sym_db.RegisterMessage(EndPointId)
+
+DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceId)
+  })
+_sym_db.RegisterMessage(DeviceId)
+
+LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), {
+  'DESCRIPTOR' : _LINKID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkId)
+  })
+_sym_db.RegisterMessage(LinkId)
+
+Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), {
+  'DESCRIPTOR' : _UUID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Uuid)
+  })
+_sym_db.RegisterMessage(Uuid)
+
+TeraFlowController = _reflection.GeneratedProtocolMessageType('TeraFlowController', (_message.Message,), {
+  'DESCRIPTOR' : _TERAFLOWCONTROLLER,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TeraFlowController)
+  })
+_sym_db.RegisterMessage(TeraFlowController)
+
+AuthenticationResult = _reflection.GeneratedProtocolMessageType('AuthenticationResult', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHENTICATIONRESULT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.AuthenticationResult)
+  })
+_sym_db.RegisterMessage(AuthenticationResult)
+
+
+
+_CONTEXTSERVICE = _descriptor.ServiceDescriptor(
+  name='ContextService',
+  full_name='context.ContextService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=1352,
+  serialized_end=1514,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='GetTopology',
+    full_name='context.ContextService.GetTopology',
+    index=0,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_TOPOLOGY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='AddLink',
+    full_name='context.ContextService.AddLink',
+    index=1,
+    containing_service=None,
+    input_type=_LINK,
+    output_type=_LINKID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='DeleteLink',
+    full_name='context.ContextService.DeleteLink',
+    index=2,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE)
+
+DESCRIPTOR.services_by_name['ContextService'] = _CONTEXTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/slice/proto/service_pb2.py b/src/slice/proto/service_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..ed248a038c6f6550994ebb204cbb4f626292c65c
--- /dev/null
+++ b/src/slice/proto/service_pb2.py
@@ -0,0 +1,617 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: service.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import context_pb2 as context__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='service.proto',
+  package='service',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto\"+\n\x0bServiceList\x12\x1c\n\x02\x63s\x18\x01 \x03(\x0b\x32\x10.service.Service\"\x87\x02\n\x07Service\x12!\n\x05\x63s_id\x18\x01 \x01(\x0b\x32\x12.service.ServiceId\x12)\n\x0bserviceType\x18\x02 \x01(\x0e\x32\x14.service.ServiceType\x12)\n\x0c\x65ndpointList\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\'\n\nconstraint\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12+\n\x0cserviceState\x18\x05 \x01(\x0b\x32\x15.service.ServiceState\x12-\n\rserviceConfig\x18\x06 \x01(\x0b\x32\x16.service.ServiceConfig\"&\n\rServiceConfig\x12\x15\n\rserviceConfig\x18\x01 \x01(\t\"P\n\tServiceId\x12%\n\tcontextId\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x1c\n\x05\x63s_id\x18\x02 \x01(\x0b\x32\r.context.Uuid\":\n\rServiceIdList\x12)\n\rserviceIdList\x18\x01 \x03(\x0b\x32\x12.service.ServiceId\"?\n\x0cServiceState\x12/\n\x0cserviceState\x18\x01 \x01(\x0e\x32\x19.service.ServiceStateEnum\"=\n\x0e\x43onnectionList\x12+\n\x0e\x63onnectionList\x18\x01 \x03(\x0b\x32\x13.service.Connection\"\x84\x01\n\nConnection\x12%\n\x06\x63on_id\x18\x01 \x01(\x0b\x32\x15.service.ConnectionId\x12,\n\x10relatedServiceId\x18\x02 \x01(\x0b\x32\x12.service.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"-\n\x0c\x43onnectionId\x12\x1d\n\x06\x63on_id\x18\x01 \x01(\x0b\x32\r.context.Uuid*M\n\x0bServiceType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04L3NM\x10\x01\x12\x08\n\x04L2NM\x10\x02\x12\x1d\n\x19TAPI_CONNECTIVITY_SERVICE\x10\x03*@\n\x10ServiceStateEnum\x12\x0b\n\x07PLANNED\x10\x00\x12\n\n\x06\x41\x43TIVE\x10\x01\x12\x13\n\x0fPENDING_REMOVAL\x10\x02\x32\xed\x02\n\x0eServiceService\x12\x38\n\x0eGetServiceList\x12\x0e.context.Empty\x1a\x14.service.ServiceList\"\x00\x12\x37\n\rCreateService\x12\x10.service.Service\x1a\x12.service.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.service.Service\x1a\x12.service.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.service.ServiceId\x1a\x0e.context.Empty\"\x00\x12\x38\n\x0eGetServiceById\x12\x12.service.ServiceId\x1a\x10.service.Service\"\x00\x12>\n\x11GetConnectionList\x12\x0e.context.Empty\x1a\x17.service.ConnectionList\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,])
+
+_SERVICETYPE = _descriptor.EnumDescriptor(
+  name='ServiceType',
+  full_name='service.ServiceType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='L3NM', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='L2NM', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='TAPI_CONNECTIVITY_SERVICE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=844,
+  serialized_end=921,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICETYPE)
+
+ServiceType = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPE)
+_SERVICESTATEENUM = _descriptor.EnumDescriptor(
+  name='ServiceStateEnum',
+  full_name='service.ServiceStateEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='PLANNED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ACTIVE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='PENDING_REMOVAL', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=923,
+  serialized_end=987,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICESTATEENUM)
+
+ServiceStateEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATEENUM)
+UNKNOWN = 0
+L3NM = 1
+L2NM = 2
+TAPI_CONNECTIVITY_SERVICE = 3
+PLANNED = 0
+ACTIVE = 1
+PENDING_REMOVAL = 2
+
+
+
+_SERVICELIST = _descriptor.Descriptor(
+  name='ServiceList',
+  full_name='service.ServiceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='cs', full_name='service.ServiceList.cs', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=41,
+  serialized_end=84,
+)
+
+
+_SERVICE = _descriptor.Descriptor(
+  name='Service',
+  full_name='service.Service',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='cs_id', full_name='service.Service.cs_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='serviceType', full_name='service.Service.serviceType', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpointList', full_name='service.Service.endpointList', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='constraint', full_name='service.Service.constraint', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='serviceState', full_name='service.Service.serviceState', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='serviceConfig', full_name='service.Service.serviceConfig', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=87,
+  serialized_end=350,
+)
+
+
+_SERVICECONFIG = _descriptor.Descriptor(
+  name='ServiceConfig',
+  full_name='service.ServiceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='serviceConfig', full_name='service.ServiceConfig.serviceConfig', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=352,
+  serialized_end=390,
+)
+
+
+_SERVICEID = _descriptor.Descriptor(
+  name='ServiceId',
+  full_name='service.ServiceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contextId', full_name='service.ServiceId.contextId', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='cs_id', full_name='service.ServiceId.cs_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=392,
+  serialized_end=472,
+)
+
+
+_SERVICEIDLIST = _descriptor.Descriptor(
+  name='ServiceIdList',
+  full_name='service.ServiceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='serviceIdList', full_name='service.ServiceIdList.serviceIdList', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=474,
+  serialized_end=532,
+)
+
+
+_SERVICESTATE = _descriptor.Descriptor(
+  name='ServiceState',
+  full_name='service.ServiceState',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='serviceState', full_name='service.ServiceState.serviceState', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=534,
+  serialized_end=597,
+)
+
+
+_CONNECTIONLIST = _descriptor.Descriptor(
+  name='ConnectionList',
+  full_name='service.ConnectionList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connectionList', full_name='service.ConnectionList.connectionList', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=599,
+  serialized_end=660,
+)
+
+
+_CONNECTION = _descriptor.Descriptor(
+  name='Connection',
+  full_name='service.Connection',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='con_id', full_name='service.Connection.con_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='relatedServiceId', full_name='service.Connection.relatedServiceId', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='path', full_name='service.Connection.path', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=663,
+  serialized_end=795,
+)
+
+
+_CONNECTIONID = _descriptor.Descriptor(
+  name='ConnectionId',
+  full_name='service.ConnectionId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='con_id', full_name='service.ConnectionId.con_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=797,
+  serialized_end=842,
+)
+
+_SERVICELIST.fields_by_name['cs'].message_type = _SERVICE
+_SERVICE.fields_by_name['cs_id'].message_type = _SERVICEID
+_SERVICE.fields_by_name['serviceType'].enum_type = _SERVICETYPE
+_SERVICE.fields_by_name['endpointList'].message_type = context__pb2._ENDPOINTID
+_SERVICE.fields_by_name['constraint'].message_type = context__pb2._CONSTRAINT
+_SERVICE.fields_by_name['serviceState'].message_type = _SERVICESTATE
+_SERVICE.fields_by_name['serviceConfig'].message_type = _SERVICECONFIG
+_SERVICEID.fields_by_name['contextId'].message_type = context__pb2._CONTEXTID
+_SERVICEID.fields_by_name['cs_id'].message_type = context__pb2._UUID
+_SERVICEIDLIST.fields_by_name['serviceIdList'].message_type = _SERVICEID
+_SERVICESTATE.fields_by_name['serviceState'].enum_type = _SERVICESTATEENUM
+_CONNECTIONLIST.fields_by_name['connectionList'].message_type = _CONNECTION
+_CONNECTION.fields_by_name['con_id'].message_type = _CONNECTIONID
+_CONNECTION.fields_by_name['relatedServiceId'].message_type = _SERVICEID
+_CONNECTION.fields_by_name['path'].message_type = context__pb2._ENDPOINTID
+_CONNECTIONID.fields_by_name['con_id'].message_type = context__pb2._UUID
+DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
+DESCRIPTOR.message_types_by_name['Service'] = _SERVICE
+DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
+DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID
+DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
+DESCRIPTOR.message_types_by_name['ServiceState'] = _SERVICESTATE
+DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST
+DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
+DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
+DESCRIPTOR.enum_types_by_name['ServiceType'] = _SERVICETYPE
+DESCRIPTOR.enum_types_by_name['ServiceStateEnum'] = _SERVICESTATEENUM
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICELIST,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.ServiceList)
+  })
+_sym_db.RegisterMessage(ServiceList)
+
+Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICE,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.Service)
+  })
+_sym_db.RegisterMessage(Service)
+
+ServiceConfig = _reflection.GeneratedProtocolMessageType('ServiceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICECONFIG,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.ServiceConfig)
+  })
+_sym_db.RegisterMessage(ServiceConfig)
+
+ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEID,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.ServiceId)
+  })
+_sym_db.RegisterMessage(ServiceId)
+
+ServiceIdList = _reflection.GeneratedProtocolMessageType('ServiceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEIDLIST,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.ServiceIdList)
+  })
+_sym_db.RegisterMessage(ServiceIdList)
+
+ServiceState = _reflection.GeneratedProtocolMessageType('ServiceState', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICESTATE,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.ServiceState)
+  })
+_sym_db.RegisterMessage(ServiceState)
+
+ConnectionList = _reflection.GeneratedProtocolMessageType('ConnectionList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONLIST,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.ConnectionList)
+  })
+_sym_db.RegisterMessage(ConnectionList)
+
+Connection = _reflection.GeneratedProtocolMessageType('Connection', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTION,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.Connection)
+  })
+_sym_db.RegisterMessage(Connection)
+
+ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONID,
+  '__module__' : 'service_pb2'
+  # @@protoc_insertion_point(class_scope:service.ConnectionId)
+  })
+_sym_db.RegisterMessage(ConnectionId)
+
+
+
+_SERVICESERVICE = _descriptor.ServiceDescriptor(
+  name='ServiceService',
+  full_name='service.ServiceService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=990,
+  serialized_end=1355,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='GetServiceList',
+    full_name='service.ServiceService.GetServiceList',
+    index=0,
+    containing_service=None,
+    input_type=context__pb2._EMPTY,
+    output_type=_SERVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='CreateService',
+    full_name='service.ServiceService.CreateService',
+    index=1,
+    containing_service=None,
+    input_type=_SERVICE,
+    output_type=_SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='UpdateService',
+    full_name='service.ServiceService.UpdateService',
+    index=2,
+    containing_service=None,
+    input_type=_SERVICE,
+    output_type=_SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='DeleteService',
+    full_name='service.ServiceService.DeleteService',
+    index=3,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=context__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetServiceById',
+    full_name='service.ServiceService.GetServiceById',
+    index=4,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_SERVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnectionList',
+    full_name='service.ServiceService.GetConnectionList',
+    index=5,
+    containing_service=None,
+    input_type=context__pb2._EMPTY,
+    output_type=_CONNECTIONLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_SERVICESERVICE)
+
+DESCRIPTOR.services_by_name['ServiceService'] = _SERVICESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/slice/proto/slice_pb2.py b/src/slice/proto/slice_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..06160c4263715d9f4c278a906fdcf2b9d51eef0f
--- /dev/null
+++ b/src/slice/proto/slice_pb2.py
@@ -0,0 +1,331 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: slice.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import context_pb2 as context__pb2
+from . import service_pb2 as service__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='slice.proto',
+  package='slice',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x0bslice.proto\x12\x05slice\x1a\rcontext.proto\x1a\rservice.proto\"3\n\rSliceEndpoint\x12\"\n\x07port_id\x18\x01 \x01(\x0b\x32\x11.context.EndPoint\"\xf4\x01\n\x0eTransportSlice\x12 \n\x08slice_id\x18\x01 \x01(\x0b\x32\x0e.slice.SliceId\x12\'\n\tendpoints\x18\x02 \x03(\x0b\x32\x14.slice.SliceEndpoint\x12(\n\x0b\x63onstraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12$\n\x08services\x18\x04 \x03(\x0b\x32\x12.service.ServiceId\x12#\n\x0bsubSlicesId\x18\x05 \x03(\x0b\x32\x0e.slice.SliceId\x12\"\n\x06status\x18\x06 \x01(\x0b\x32\x12.slice.SliceStatus\"Q\n\x07SliceId\x12%\n\tcontextId\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x1f\n\x08slice_id\x18\x02 \x01(\x0b\x32\r.context.Uuid\"W\n\x0bSliceStatus\x12 \n\x08slice_id\x18\x01 \x01(\x0b\x32\x0e.slice.SliceId\x12&\n\x06status\x18\x02 \x01(\x0e\x32\x16.slice.SliceStatusEnum*@\n\x0fSliceStatusEnum\x12\x0b\n\x07PLANNED\x10\x00\x12\x08\n\x04INIT\x10\x01\x12\n\n\x06\x41\x43TIVE\x10\x02\x12\n\n\x06\x44\x45INIT\x10\x03\x32\x88\x01\n\x0cSliceService\x12@\n\x11\x43reateUpdateSlice\x12\x15.slice.TransportSlice\x1a\x12.slice.SliceStatus\"\x00\x12\x36\n\x0b\x44\x65leteSlice\x12\x15.slice.TransportSlice\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,service__pb2.DESCRIPTOR,])
+
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='slice.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='PLANNED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='INIT', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ACTIVE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEINIT', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=524,
+  serialized_end=588,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
+PLANNED = 0
+INIT = 1
+ACTIVE = 2
+DEINIT = 3
+
+
+
+_SLICEENDPOINT = _descriptor.Descriptor(
+  name='SliceEndpoint',
+  full_name='slice.SliceEndpoint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='port_id', full_name='slice.SliceEndpoint.port_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=52,
+  serialized_end=103,
+)
+
+
+_TRANSPORTSLICE = _descriptor.Descriptor(
+  name='TransportSlice',
+  full_name='slice.TransportSlice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='slice.TransportSlice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoints', full_name='slice.TransportSlice.endpoints', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='constraints', full_name='slice.TransportSlice.constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='services', full_name='slice.TransportSlice.services', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='subSlicesId', full_name='slice.TransportSlice.subSlicesId', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='slice.TransportSlice.status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=106,
+  serialized_end=350,
+)
+
+
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='slice.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contextId', full_name='slice.SliceId.contextId', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='slice.SliceId.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=352,
+  serialized_end=433,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='slice.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='slice.SliceStatus.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='slice.SliceStatus.status', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=435,
+  serialized_end=522,
+)
+
+_SLICEENDPOINT.fields_by_name['port_id'].message_type = context__pb2._ENDPOINT
+_TRANSPORTSLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_TRANSPORTSLICE.fields_by_name['endpoints'].message_type = _SLICEENDPOINT
+_TRANSPORTSLICE.fields_by_name['constraints'].message_type = context__pb2._CONSTRAINT
+_TRANSPORTSLICE.fields_by_name['services'].message_type = service__pb2._SERVICEID
+_TRANSPORTSLICE.fields_by_name['subSlicesId'].message_type = _SLICEID
+_TRANSPORTSLICE.fields_by_name['status'].message_type = _SLICESTATUS
+_SLICEID.fields_by_name['contextId'].message_type = context__pb2._CONTEXTID
+_SLICEID.fields_by_name['slice_id'].message_type = context__pb2._UUID
+_SLICESTATUS.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICESTATUS.fields_by_name['status'].enum_type = _SLICESTATUSENUM
+DESCRIPTOR.message_types_by_name['SliceEndpoint'] = _SLICEENDPOINT
+DESCRIPTOR.message_types_by_name['TransportSlice'] = _TRANSPORTSLICE
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+SliceEndpoint = _reflection.GeneratedProtocolMessageType('SliceEndpoint', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEENDPOINT,
+  '__module__' : 'slice_pb2'
+  # @@protoc_insertion_point(class_scope:slice.SliceEndpoint)
+  })
+_sym_db.RegisterMessage(SliceEndpoint)
+
+TransportSlice = _reflection.GeneratedProtocolMessageType('TransportSlice', (_message.Message,), {
+  'DESCRIPTOR' : _TRANSPORTSLICE,
+  '__module__' : 'slice_pb2'
+  # @@protoc_insertion_point(class_scope:slice.TransportSlice)
+  })
+_sym_db.RegisterMessage(TransportSlice)
+
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'slice_pb2'
+  # @@protoc_insertion_point(class_scope:slice.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'slice_pb2'
+  # @@protoc_insertion_point(class_scope:slice.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+
+
+_SLICESERVICE = _descriptor.ServiceDescriptor(
+  name='SliceService',
+  full_name='slice.SliceService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=591,
+  serialized_end=727,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='CreateUpdateSlice',
+    full_name='slice.SliceService.CreateUpdateSlice',
+    index=0,
+    containing_service=None,
+    input_type=_TRANSPORTSLICE,
+    output_type=_SLICESTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='DeleteSlice',
+    full_name='slice.SliceService.DeleteSlice',
+    index=1,
+    containing_service=None,
+    input_type=_TRANSPORTSLICE,
+    output_type=context__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_SLICESERVICE)
+
+DESCRIPTOR.services_by_name['SliceService'] = _SLICESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/slice/proto/slice_pb2_grpc.py b/src/slice/proto/slice_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..e7762a9104765af5d7a16c778c2f458050ce2eaf
--- /dev/null
+++ b/src/slice/proto/slice_pb2_grpc.py
@@ -0,0 +1,100 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from . import context_pb2 as context__pb2
+from . import slice_pb2 as slice__pb2
+
+
+class SliceServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.CreateUpdateSlice = channel.unary_unary(
+                '/slice.SliceService/CreateUpdateSlice',
+                request_serializer=slice__pb2.TransportSlice.SerializeToString,
+                response_deserializer=slice__pb2.SliceStatus.FromString,
+                )
+        self.DeleteSlice = channel.unary_unary(
+                '/slice.SliceService/DeleteSlice',
+                request_serializer=slice__pb2.TransportSlice.SerializeToString,
+                response_deserializer=context__pb2.Empty.FromString,
+                )
+
+
+class SliceServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def CreateUpdateSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def DeleteSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_SliceServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'CreateUpdateSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.CreateUpdateSlice,
+                    request_deserializer=slice__pb2.TransportSlice.FromString,
+                    response_serializer=slice__pb2.SliceStatus.SerializeToString,
+            ),
+            'DeleteSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.DeleteSlice,
+                    request_deserializer=slice__pb2.TransportSlice.FromString,
+                    response_serializer=context__pb2.Empty.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'slice.SliceService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class SliceService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def CreateUpdateSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/slice.SliceService/CreateUpdateSlice',
+            slice__pb2.TransportSlice.SerializeToString,
+            slice__pb2.SliceStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def DeleteSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/slice.SliceService/DeleteSlice',
+            slice__pb2.TransportSlice.SerializeToString,
+            context__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/slice/requirements.in b/src/slice/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..25abdad1b5767117956a88b816399635348884c7
--- /dev/null
+++ b/src/slice/requirements.in
@@ -0,0 +1,6 @@
+grpcio-health-checking
+grpcio
+prometheus-client
+pytest
+pytest-benchmark
+redis
diff --git a/src/slice/service/SliceService.py b/src/slice/service/SliceService.py
new file mode 100644
index 0000000000000000000000000000000000000000..2335cdd313ed20693ad941d969d1da0822667a55
--- /dev/null
+++ b/src/slice/service/SliceService.py
@@ -0,0 +1,55 @@
+import grpc
+import logging
+from concurrent import futures
+from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
+from grpc_health.v1.health_pb2 import HealthCheckResponse
+from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
+from slice.proto.slice_pb2_grpc import add_SliceServiceServicer_to_server
+from slice.service.SliceServiceServicerImpl import SliceServiceServicerImpl
+from slice.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+
+BIND_ADDRESS = '0.0.0.0'
+LOGGER = logging.getLogger(__name__)
+
+class SliceService:
+    def __init__(self, database, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS,
+                 grace_period=GRPC_GRACE_PERIOD):
+        self.database = database
+        self.address = address
+        self.port = port
+        self.endpoint = None
+        self.max_workers = max_workers
+        self.grace_period = grace_period
+        self.slice_servicer = None
+        self.health_servicer = None
+        self.pool = None
+        self.server = None
+
+    def start(self):
+        self.endpoint = '{}:{}'.format(self.address, self.port)
+        LOGGER.debug('Starting Service (tentative endpoint: {}, max_workers: {})...'.format(
+            self.endpoint, self.max_workers))
+
+        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
+        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
+
+        self.slice_servicer = SliceServiceServicerImpl(self.database)
+        add_SliceServiceServicer_to_server(self.slice_servicer, self.server)
+
+        self.health_servicer = HealthServicer(
+            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
+        add_HealthServicer_to_server(self.health_servicer, self.server)
+
+        port = self.server.add_insecure_port(self.endpoint)
+        self.endpoint = '{}:{}'.format(self.address, port)
+        LOGGER.info('Listening on {}...'.format(self.endpoint))
+        self.server.start()
+        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
+
+        LOGGER.debug('Service started')
+
+    def stop(self):
+        LOGGER.debug('Stopping service (grace period {} seconds)...'.format(self.grace_period))
+        self.health_servicer.enter_graceful_shutdown()
+        self.server.stop(self.grace_period)
+        LOGGER.debug('Service stopped')
diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py
new file mode 100644
index 0000000000000000000000000000000000000000..6822aa4f15d217606c66186ceaf1ba8555f5eb17
--- /dev/null
+++ b/src/slice/service/SliceServiceServicerImpl.py
@@ -0,0 +1,93 @@
+import grpc, logging
+from prometheus_client import Counter, Histogram
+from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID
+from common.database.api.Database import Database
+from common.exceptions.ServiceException import ServiceException
+from slice.proto.context_pb2 import Empty
+from slice.proto.slice_pb2 import SliceStatus, TransportSlice
+from slice.proto.slice_pb2_grpc import SliceServiceServicer
+
+LOGGER = logging.getLogger(__name__)
+
+CREATEUPDATESLICE_COUNTER_STARTED    = Counter  ('slice_createupdateslice_counter_started',
+                                                 'Slice:CreateUpdateSlice counter of requests started'  )
+CREATEUPDATESLICE_COUNTER_COMPLETED  = Counter  ('slice_createupdateslice_counter_completed',
+                                                 'Slice:CreateUpdateSlice counter of requests completed')
+CREATEUPDATESLICE_COUNTER_FAILED     = Counter  ('slice_createupdateslice_counter_failed',
+                                                 'Slice:CreateUpdateSlice counter of requests failed'   )
+CREATEUPDATESLICE_HISTOGRAM_DURATION = Histogram('slice_createupdateslice_histogram_duration',
+                                                 'Slice:CreateUpdateSlice histogram of request duration')
+
+DELETESLICE_COUNTER_STARTED    = Counter  ('slice_DeleteSlice_counter_started',
+                                           'Slice:DeleteSlice counter of requests started'  )
+DELETESLICE_COUNTER_COMPLETED  = Counter  ('slice_DeleteSlice_counter_completed',
+                                           'Slice:DeleteSlice counter of requests completed')
+DELETESLICE_COUNTER_FAILED     = Counter  ('slice_DeleteSlice_counter_failed',
+                                           'Slice:DeleteSlice counter of requests failed'   )
+DELETESLICE_HISTOGRAM_DURATION = Histogram('slice_DeleteSlice_histogram_duration',
+                                           'Slice:DeleteSlice histogram of request duration')
+
+class SliceServiceServicerImpl(SliceServiceServicer):
+    def __init__(self, database : Database):
+        LOGGER.debug('Creating Servicer...')
+        self.database = database
+        LOGGER.debug('Servicer Created')
+
+    @CREATEUPDATESLICE_HISTOGRAM_DURATION.time()
+    def CreateUpdateSlice(self, request : TransportSlice, grpc_context : grpc.ServicerContext) -> SliceStatus:
+        CREATEUPDATESLICE_COUNTER_STARTED.inc()
+        try:
+            LOGGER.debug('CreateUpdateSlice request: {}'.format(str(request)))
+
+            # ----- Validate request data and pre-conditions -----------------------------------------------------------
+            device_id, device_type, device_config, device_opstat, db_endpoints_ports = \
+                check_slice_request('CreateUpdateSlice', request, self.database, LOGGER)
+
+            # ----- Implement changes in the database ------------------------------------------------------------------
+            db_context = self.database.context(DEFAULT_CONTEXT_ID).create()
+            db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID).create()
+            db_device = db_topology.device(device_id).create(device_type, device_config, device_opstat)
+            for db_endpoint,port_type in db_endpoints_ports:
+                db_endpoint.create(port_type)
+
+            # ----- Compose reply --------------------------------------------------------------------------------------
+            reply = SliceStatus(**db_device.dump_id())
+            LOGGER.debug('CreateUpdateSlice reply: {}'.format(str(reply)))
+            CREATEUPDATESLICE_COUNTER_COMPLETED.inc()
+            return reply
+        except ServiceException as e:
+            LOGGER.exception('CreateUpdateSlice exception')
+            CREATEUPDATESLICE_COUNTER_FAILED.inc()
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:                                      # pragma: no cover
+            LOGGER.exception('CreateUpdateSlice exception')
+            CREATEUPDATESLICE_COUNTER_FAILED.inc()
+            grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
+
+    @DELETESLICE_HISTOGRAM_DURATION.time()
+    def DeleteSlice(self, request : TransportSlice, grpc_context : grpc.ServicerContext) -> Empty:
+        DELETESLICE_COUNTER_STARTED.inc()
+        try:
+            LOGGER.debug('DeleteSlice request: {}'.format(str(request)))
+
+            # ----- Validate request data and pre-conditions -----------------------------------------------------------
+            device_id = check_slice_id_request('DeleteSlice', request, self.database, LOGGER)
+
+            # ----- Implement changes in the database ------------------------------------------------------------------
+            db_context = self.database.context(DEFAULT_CONTEXT_ID).create()
+            db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID).create()
+            db_topology.device(device_id).delete()
+
+            # ----- Compose reply --------------------------------------------------------------------------------------
+            reply = Empty()
+            LOGGER.debug('DeleteSlice reply: {}'.format(str(reply)))
+            DELETESLICE_COUNTER_COMPLETED.inc()
+            return reply
+        except ServiceException as e:
+            LOGGER.exception('DeleteSlice exception')
+            DELETESLICE_COUNTER_FAILED.inc()
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:                                      # pragma: no cover
+            LOGGER.exception('DeleteSlice exception')
+            DELETESLICE_COUNTER_FAILED.inc()
+            grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
diff --git a/src/slice/service/Tools.py b/src/slice/service/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..d31fed6cb69df54d708c516ee269fe732c55e8de
--- /dev/null
+++ b/src/slice/service/Tools.py
@@ -0,0 +1,199 @@
+import grpc, logging
+from typing import Dict, List, Set, Tuple
+from common.Checkers import chk_options, chk_string
+from common.database.api.Database import Database
+from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID
+from common.database.api.context.service.Service import Service
+from common.database.api.context.slice.SliceStatus import SliceStatus, slicestatus_enum_values, to_slicestatus_enum
+from common.database.api.context.topology.device.Endpoint import Endpoint
+from common.exceptions.ServiceException import ServiceException
+from common.tools.service.ConstraintsChecker import check_constraints
+from common.tools.service.EndpointIdCheckers import check_endpoint_id
+from common.tools.service.DeviceCheckers import check_device_endpoint_exists
+from common.tools.service.EnumCheckers import check_enum
+from common.tools.service.ServiceCheckers import check_service_exists
+from common.tools.service.SliceCheckers import check_slice_exists #, check_slice_not_exists
+from slice.proto.slice_pb2 import TransportSlice
+
+# For each method name, define acceptable slice statuses. Empty set means accept all.
+ACCEPTED_SLICE_STATUSES : Dict[str, Set[SliceStatus]] = {
+    'CreateUpdateSlice': set([SliceStatus.PLANNED, SliceStatus.INIT, SliceStatus.ACTIVE]),
+    'DeleteSlice': set([SliceStatus.PLANNED, SliceStatus.DEINIT]),
+}
+
+def _check_slice_exists(method_name : str, database : Database, context_id : str, slice_id : str):
+    if method_name in ['CreateUpdateSlice']:
+        # Do nothing; creation implies checking slice does not exist. However, if it exists, we can perform an update.
+        #check_slice_not_exists(database, context_id, slice_id)
+        pass
+    elif method_name in ['DeleteSlice']:
+        check_slice_exists(database, context_id, slice_id)
+    else:                                       # pragma: no cover (test requires malforming the code)
+        msg = 'Unexpected condition [_check_slice_exists(method_name={}, slice_id={})]'
+        msg = msg.format(str(method_name), str(slice_id))
+        raise ServiceException(grpc.StatusCode.UNIMPLEMENTED, msg)
+
+def _check_slice_endpoints(
+    logger : logging.Logger, database : Database, context_id : str, slice_id : str, slice_endpoints
+    ) -> List[Tuple[Endpoint, str]]:
+
+    add_topology_devices_endpoints : Dict[str, Dict[str, Set[str]]] = {}
+    db_endpoints__port_types : List[Tuple[Endpoint, str]] = []
+    for endpoint_number,slice_endpoint in enumerate(slice_endpoints):
+        parent_name = 'SliceEndpoint(#{}) of Context({})/Slice({})'
+        parent_name = parent_name.format(endpoint_number, context_id, slice_id)
+
+        ep_topology_id, ep_device_id, ep_port_id = check_endpoint_id(
+            logger, endpoint_number, parent_name, slice_endpoint.port_id.port_id, add_topology_devices_endpoints,
+            acceptable_context_ids=set([context_id]), prevent_same_device_multiple_times=False)
+
+        try:
+            ep_port_type = chk_string('endpoint[#{}].port_type'.format(endpoint_number),
+                                      slice_endpoint.port_id.port_type,
+                                      allow_empty=False)
+        except Exception as e:
+            logger.exception('Invalid arguments:')
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+        db_endpoint = check_device_endpoint_exists(
+            database, parent_name, context_id, ep_topology_id, ep_device_id, ep_port_id)
+        db_endpoints__port_types.append((db_endpoint, ep_port_type))
+    return db_endpoints__port_types
+
+def _check_services(
+    logger : logging.Logger, database : Database, parent_name : str, context_id : str, slice_service_ids
+    ) -> List[Service]:
+
+    add_context_services : Dict[str, Set[str]] = {}
+    db_services : List[Service] = []
+    for service_number,service_id in enumerate(slice_service_ids):
+        # ----- Parse attributes ---------------------------------------------------------------------------------------
+        try:
+            service_context_id = chk_string ('services[#{}].contextId.contextUuid.uuid'.format(service_number),
+                                             service_id.contextId.contextUuid.uuid,
+                                             allow_empty=True)
+            service_id         = chk_string ('services[#{}].cs_id.uuid'.format(service_number),
+                                             service_id.cs_id.uuid,
+                                             allow_empty=False)
+        except Exception as e:
+            logger.exception('Invalid arguments:')
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+        if len(service_context_id) == 0: service_context_id = context_id
+
+        add_services = add_context_services.setdefault(context_id, dict())
+        if service_id in add_services:
+            msg = 'Duplicated Context({})/Service({}) in {}.'
+            msg = msg.format(service_context_id, service_id, parent_name)
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+
+        db_service = check_service_exists(database, service_context_id, service_id)
+        db_services.append(db_service)
+        add_services.add(service_id)
+    return db_services
+
+def _check_subslices(
+    logger : logging.Logger, database : Database, parent_name : str, context_id : str, slice_subslice_ids
+    ) -> List[Slice]:
+
+    add_context_subslices : Dict[str, Set[str]] = {}
+    db_subslices : List[Slice] = []
+    for subslice_number,subslice_id in enumerate(slice_subslice_ids):
+        # ----- Parse attributes ---------------------------------------------------------------------------------------
+        try:
+            subslice_context_id = chk_string ('subSlicesId[#{}].contextId.contextUuid.uuid'.format(subslice_number),
+                                             subslice_id.contextId.contextUuid.uuid,
+                                             allow_empty=True)
+            subslice_id         = chk_string ('subSlicesId[#{}].slice_id.uuid'.format(subslice_number),
+                                             subslice_id.slice_id.uuid,
+                                             allow_empty=False)
+        except Exception as e:
+            logger.exception('Invalid arguments:')
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+        if len(subslice_context_id) == 0: subslice_context_id = context_id
+
+        add_subslices = add_context_subslices.setdefault(context_id, dict())
+        if subslice_id in add_subslices:
+            msg = 'Duplicated Context({})/Slice({}) in {}.'
+            msg = msg.format(subslice_context_id, subslice_id, parent_name)
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+
+        db_subslice = check_slice_exists(database, subslice_context_id, subslice_id)
+        db_subslices.append(db_subslice)
+        add_subslices.add(subslice_id)
+    return db_subslices
+
+def check_slice_status(method_name : str, value : str) -> SliceStatus:
+    return check_enum(
+        'SliceStatus', method_name, value, to_slicestatus_enum, ACCEPTED_SLICE_STATUSES)
+
+def check_slice_request(
+    method_name : str, request : TransportSlice, database : Database, logger : logging.Logger
+    ): # -> Tuple[str, str, str, OperationalStatus, List[Tuple[Endpoint, str]]]:
+
+    # ----- Parse attributes -------------------------------------------------------------------------------------------
+    try:
+        context_id        = chk_string ('slice.slice_id.contextId.contextUuid.uuid',
+                                        request.slice_id.contextId.contextUuid.uuid,
+                                        allow_empty=True)
+        slice_id          = chk_string ('slice.slice_id.slice_id.uuid',
+                                        request.slice_id.slice_id.uuid,
+                                        allow_empty=False)
+        status_context_id = chk_string ('slice.status.slice_id.contextId.contextUuid.uuid',
+                                        request.status.slice_id.contextId.contextUuid.uuid,
+                                        allow_empty=True)
+        status_slice_id   = chk_string ('slice.status.slice_id.slice_id.uuid',
+                                        request.status.slice_id.slice_id.uuid,
+                                        allow_empty=True)
+        slice_status      = chk_options('slice.status.status',
+                                        request.status.status,
+                                        slicestatus_enum_values())
+    except Exception as e:
+        logger.exception('Invalid arguments:')
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+    if len(context_id) == 0: context_id = DEFAULT_CONTEXT_ID
+
+    if (len(status_context_id) > 0) and (status_context_id != context_id):
+        msg = ' '.join([
+            'slice.status.slice_id.contextId.contextUuid.uuid({})',
+            'is not empty and is different than',
+            'slice.slice_id.contextId.contextUuid.uuid({}).',
+            'Optionally, leave field empty to use slice.slice_id.contextId.contextUuid.uuid({}), if set,',
+            'or, otherwise, the default Context({})'
+        ])
+        msg = msg.format(
+            status_context_id, context_id, context_id, DEFAULT_CONTEXT_ID)
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+        
+    if (len(status_slice_id) > 0) and (status_slice_id != slice_id):
+        msg = ' '.join([
+            'slice.status.slice_id.slice_id.uuid({})',
+            'is not empty and is different than',
+            'slice.slice_id.slice_id.uuid({}).',
+            'Optionally, leave field empty to use slice.slice_id.slice_id.uuid({}).',
+        ])
+        msg = msg.format(
+            status_slice_id, slice_id, slice_id)
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+
+    slice_status = check_slice_status(method_name, slice_status)
+
+    # ----- Check if slice exists in database --------------------------------------------------------------------------
+    _check_slice_exists(method_name, database, context_id, slice_id)
+
+    # ----- Parse endpoints and check if they exist in the database as device endpoints --------------------------------
+    db_endpoints__port_types = _check_slice_endpoints(logger, database, context_id, slice_id, request.endpoints)
+
+    # ----- Parse constraints ------------------------------------------------------------------------------------------
+    parent_name = 'Context({})/Slice({})'.format(context_id, slice_id)
+    constraint_tuples : List[Tuple[str, str]] = check_constraints(logger, parent_name, request.constraints)
+
+    # ----- Parse Service Ids ------------------------------------------------------------------------------------------
+    db_services = _check_services(logger, database, parent_name, context_id, request.services)
+
+    # ----- Parse SubSlice Ids -----------------------------------------------------------------------------------------
+    db_subslices = _check_subslices(logger, database, parent_name, context_id, request.subSlicesId)
+
+    return context_id, slice_id, slice_status, db_endpoints__port_types, constraint_tuples, db_services, db_subslices
diff --git a/src/slice/service/__init__.py b/src/slice/service/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/slice/service/__main__.py b/src/slice/service/__main__.py
new file mode 100644
index 0000000000000000000000000000000000000000..f3979d188682ce626d1cf808d1a549736a592bf2
--- /dev/null
+++ b/src/slice/service/__main__.py
@@ -0,0 +1,52 @@
+import logging, os, signal, sys, threading
+from prometheus_client import start_http_server
+from common.database.Factory import get_database
+from slice.service.SliceService import SliceService
+from slice.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT
+
+terminate = threading.Event()
+logger = None
+
+def signal_handler(signal, frame):
+    global terminate, logger
+    logger.warning('Terminate signal received')
+    terminate.set()
+
+def main():
+    global terminate, logger
+
+    service_port = os.environ.get('SLICESERVICE_SERVICE_PORT_GRPC', GRPC_SERVICE_PORT)
+    max_workers  = os.environ.get('MAX_WORKERS',                    GRPC_MAX_WORKERS )
+    grace_period = os.environ.get('GRACE_PERIOD',                   GRPC_GRACE_PERIOD)
+    log_level    = os.environ.get('LOG_LEVEL',                      LOG_LEVEL        )
+    metrics_port = os.environ.get('METRICS_PORT',                   METRICS_PORT     )
+
+    logging.basicConfig(level=log_level)
+    logger = logging.getLogger(__name__)
+
+    signal.signal(signal.SIGINT,  signal_handler)
+    signal.signal(signal.SIGTERM, signal_handler)
+
+    logger.info('Starting...')
+
+    # Start metrics server
+    start_http_server(metrics_port)
+
+    # Get database instance
+    database = get_database()
+
+    # Starting device service
+    grpc_service = SliceService(database, port=service_port, max_workers=max_workers, grace_period=grace_period)
+    grpc_service.start()
+
+    # Wait for Ctrl+C or termination signal
+    while not terminate.wait(timeout=0.1): pass
+
+    logger.info('Terminating...')
+    grpc_service.stop()
+
+    logger.info('Bye')
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/src/slice/tests/__init__.py b/src/slice/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/slice/tests/test_unitary.py b/src/slice/tests/test_unitary.py
new file mode 100644
index 0000000000000000000000000000000000000000..60850502ca97dfe974a08dad84985bc4aa258962
--- /dev/null
+++ b/src/slice/tests/test_unitary.py
@@ -0,0 +1,37 @@
+import copy, grpc, logging, pytest
+from common.database.Factory import get_database, DatabaseEngineEnum
+from slice.client.SliceClient import SliceClient
+from slice.proto.slice_pb2 import TransportSlice
+from slice.service.SliceService import SliceService
+from slice.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+
+port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+@pytest.fixture(scope='session')
+def slice_database():
+    _database = get_database(engine=DatabaseEngineEnum.INMEMORY)
+    return _database
+
+@pytest.fixture(scope='session')
+def slice_service(slice_database):
+    _service = SliceService(
+        slice_database, port=port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD)
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def slice_client(slice_service):
+    _client = SliceClient(address='127.0.0.1', port=port)
+    yield _client
+    _client.close()
+
+def test_add_device_wrong_attributes(slice_client : SliceClient):
+    # should fail with slice uuid is empty
+    with pytest.raises(grpc._channel._InactiveRpcError) as e:
+        slice_client.CreateUpdateSlice(TransportSlice())
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    assert e.value.details() == 'slice.slice_id.slice_id.uuid() string is empty.'