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.'