Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • tfs/controller
1 result
Show changes
Showing
with 958 additions and 2155 deletions
......@@ -882,6 +882,37 @@ public final class ContextServiceGrpc {
return getSetServiceMethod;
}
private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Service,
context.ContextOuterClass.ServiceId> getUnsetServiceMethod;
@io.grpc.stub.annotations.RpcMethod(
fullMethodName = SERVICE_NAME + '/' + "UnsetService",
requestType = context.ContextOuterClass.Service.class,
responseType = context.ContextOuterClass.ServiceId.class,
methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
public static io.grpc.MethodDescriptor<context.ContextOuterClass.Service,
context.ContextOuterClass.ServiceId> getUnsetServiceMethod() {
io.grpc.MethodDescriptor<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId> getUnsetServiceMethod;
if ((getUnsetServiceMethod = ContextServiceGrpc.getUnsetServiceMethod) == null) {
synchronized (ContextServiceGrpc.class) {
if ((getUnsetServiceMethod = ContextServiceGrpc.getUnsetServiceMethod) == null) {
ContextServiceGrpc.getUnsetServiceMethod = getUnsetServiceMethod =
io.grpc.MethodDescriptor.<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId>newBuilder()
.setType(io.grpc.MethodDescriptor.MethodType.UNARY)
.setFullMethodName(generateFullMethodName(SERVICE_NAME, "UnsetService"))
.setSampledToLocalTracing(true)
.setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
context.ContextOuterClass.Service.getDefaultInstance()))
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
context.ContextOuterClass.ServiceId.getDefaultInstance()))
.setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("UnsetService"))
.build();
}
}
}
return getUnsetServiceMethod;
}
private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
context.ContextOuterClass.Empty> getRemoveServiceMethod;
......@@ -1068,6 +1099,37 @@ public final class ContextServiceGrpc {
return getSetSliceMethod;
}
private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Slice,
context.ContextOuterClass.SliceId> getUnsetSliceMethod;
@io.grpc.stub.annotations.RpcMethod(
fullMethodName = SERVICE_NAME + '/' + "UnsetSlice",
requestType = context.ContextOuterClass.Slice.class,
responseType = context.ContextOuterClass.SliceId.class,
methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
public static io.grpc.MethodDescriptor<context.ContextOuterClass.Slice,
context.ContextOuterClass.SliceId> getUnsetSliceMethod() {
io.grpc.MethodDescriptor<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId> getUnsetSliceMethod;
if ((getUnsetSliceMethod = ContextServiceGrpc.getUnsetSliceMethod) == null) {
synchronized (ContextServiceGrpc.class) {
if ((getUnsetSliceMethod = ContextServiceGrpc.getUnsetSliceMethod) == null) {
ContextServiceGrpc.getUnsetSliceMethod = getUnsetSliceMethod =
io.grpc.MethodDescriptor.<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId>newBuilder()
.setType(io.grpc.MethodDescriptor.MethodType.UNARY)
.setFullMethodName(generateFullMethodName(SERVICE_NAME, "UnsetSlice"))
.setSampledToLocalTracing(true)
.setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
context.ContextOuterClass.Slice.getDefaultInstance()))
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
context.ContextOuterClass.SliceId.getDefaultInstance()))
.setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("UnsetSlice"))
.build();
}
}
}
return getUnsetSliceMethod;
}
private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
context.ContextOuterClass.Empty> getRemoveSliceMethod;
......@@ -1560,6 +1622,13 @@ public final class ContextServiceGrpc {
io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetServiceMethod(), responseObserver);
}
/**
*/
public void unsetService(context.ContextOuterClass.Service request,
io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnsetServiceMethod(), responseObserver);
}
/**
*/
public void removeService(context.ContextOuterClass.ServiceId request,
......@@ -1602,6 +1671,13 @@ public final class ContextServiceGrpc {
io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetSliceMethod(), responseObserver);
}
/**
*/
public void unsetSlice(context.ContextOuterClass.Slice request,
io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnsetSliceMethod(), responseObserver);
}
/**
*/
public void removeSlice(context.ContextOuterClass.SliceId request,
......@@ -1856,6 +1932,13 @@ public final class ContextServiceGrpc {
context.ContextOuterClass.Service,
context.ContextOuterClass.ServiceId>(
this, METHODID_SET_SERVICE)))
.addMethod(
getUnsetServiceMethod(),
io.grpc.stub.ServerCalls.asyncUnaryCall(
new MethodHandlers<
context.ContextOuterClass.Service,
context.ContextOuterClass.ServiceId>(
this, METHODID_UNSET_SERVICE)))
.addMethod(
getRemoveServiceMethod(),
io.grpc.stub.ServerCalls.asyncUnaryCall(
......@@ -1898,6 +1981,13 @@ public final class ContextServiceGrpc {
context.ContextOuterClass.Slice,
context.ContextOuterClass.SliceId>(
this, METHODID_SET_SLICE)))
.addMethod(
getUnsetSliceMethod(),
io.grpc.stub.ServerCalls.asyncUnaryCall(
new MethodHandlers<
context.ContextOuterClass.Slice,
context.ContextOuterClass.SliceId>(
this, METHODID_UNSET_SLICE)))
.addMethod(
getRemoveSliceMethod(),
io.grpc.stub.ServerCalls.asyncUnaryCall(
......@@ -2196,6 +2286,14 @@ public final class ContextServiceGrpc {
getChannel().newCall(getSetServiceMethod(), getCallOptions()), request, responseObserver);
}
/**
*/
public void unsetService(context.ContextOuterClass.Service request,
io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
io.grpc.stub.ClientCalls.asyncUnaryCall(
getChannel().newCall(getUnsetServiceMethod(), getCallOptions()), request, responseObserver);
}
/**
*/
public void removeService(context.ContextOuterClass.ServiceId request,
......@@ -2244,6 +2342,14 @@ public final class ContextServiceGrpc {
getChannel().newCall(getSetSliceMethod(), getCallOptions()), request, responseObserver);
}
/**
*/
public void unsetSlice(context.ContextOuterClass.Slice request,
io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
io.grpc.stub.ClientCalls.asyncUnaryCall(
getChannel().newCall(getUnsetSliceMethod(), getCallOptions()), request, responseObserver);
}
/**
*/
public void removeSlice(context.ContextOuterClass.SliceId request,
......@@ -2523,6 +2629,13 @@ public final class ContextServiceGrpc {
getChannel(), getSetServiceMethod(), getCallOptions(), request);
}
/**
*/
public context.ContextOuterClass.ServiceId unsetService(context.ContextOuterClass.Service request) {
return io.grpc.stub.ClientCalls.blockingUnaryCall(
getChannel(), getUnsetServiceMethod(), getCallOptions(), request);
}
/**
*/
public context.ContextOuterClass.Empty removeService(context.ContextOuterClass.ServiceId request) {
......@@ -2566,6 +2679,13 @@ public final class ContextServiceGrpc {
getChannel(), getSetSliceMethod(), getCallOptions(), request);
}
/**
*/
public context.ContextOuterClass.SliceId unsetSlice(context.ContextOuterClass.Slice request) {
return io.grpc.stub.ClientCalls.blockingUnaryCall(
getChannel(), getUnsetSliceMethod(), getCallOptions(), request);
}
/**
*/
public context.ContextOuterClass.Empty removeSlice(context.ContextOuterClass.SliceId request) {
......@@ -2831,6 +2951,14 @@ public final class ContextServiceGrpc {
getChannel().newCall(getSetServiceMethod(), getCallOptions()), request);
}
/**
*/
public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.ServiceId> unsetService(
context.ContextOuterClass.Service request) {
return io.grpc.stub.ClientCalls.futureUnaryCall(
getChannel().newCall(getUnsetServiceMethod(), getCallOptions()), request);
}
/**
*/
public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> removeService(
......@@ -2871,6 +2999,14 @@ public final class ContextServiceGrpc {
getChannel().newCall(getSetSliceMethod(), getCallOptions()), request);
}
/**
*/
public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceId> unsetSlice(
context.ContextOuterClass.Slice request) {
return io.grpc.stub.ClientCalls.futureUnaryCall(
getChannel().newCall(getUnsetSliceMethod(), getCallOptions()), request);
}
/**
*/
public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> removeSlice(
......@@ -2948,20 +3084,22 @@ public final class ContextServiceGrpc {
private static final int METHODID_LIST_SERVICES = 25;
private static final int METHODID_GET_SERVICE = 26;
private static final int METHODID_SET_SERVICE = 27;
private static final int METHODID_REMOVE_SERVICE = 28;
private static final int METHODID_GET_SERVICE_EVENTS = 29;
private static final int METHODID_LIST_SLICE_IDS = 30;
private static final int METHODID_LIST_SLICES = 31;
private static final int METHODID_GET_SLICE = 32;
private static final int METHODID_SET_SLICE = 33;
private static final int METHODID_REMOVE_SLICE = 34;
private static final int METHODID_GET_SLICE_EVENTS = 35;
private static final int METHODID_LIST_CONNECTION_IDS = 36;
private static final int METHODID_LIST_CONNECTIONS = 37;
private static final int METHODID_GET_CONNECTION = 38;
private static final int METHODID_SET_CONNECTION = 39;
private static final int METHODID_REMOVE_CONNECTION = 40;
private static final int METHODID_GET_CONNECTION_EVENTS = 41;
private static final int METHODID_UNSET_SERVICE = 28;
private static final int METHODID_REMOVE_SERVICE = 29;
private static final int METHODID_GET_SERVICE_EVENTS = 30;
private static final int METHODID_LIST_SLICE_IDS = 31;
private static final int METHODID_LIST_SLICES = 32;
private static final int METHODID_GET_SLICE = 33;
private static final int METHODID_SET_SLICE = 34;
private static final int METHODID_UNSET_SLICE = 35;
private static final int METHODID_REMOVE_SLICE = 36;
private static final int METHODID_GET_SLICE_EVENTS = 37;
private static final int METHODID_LIST_CONNECTION_IDS = 38;
private static final int METHODID_LIST_CONNECTIONS = 39;
private static final int METHODID_GET_CONNECTION = 40;
private static final int METHODID_SET_CONNECTION = 41;
private static final int METHODID_REMOVE_CONNECTION = 42;
private static final int METHODID_GET_CONNECTION_EVENTS = 43;
private static final class MethodHandlers<Req, Resp> implements
io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
......@@ -3092,6 +3230,10 @@ public final class ContextServiceGrpc {
serviceImpl.setService((context.ContextOuterClass.Service) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver);
break;
case METHODID_UNSET_SERVICE:
serviceImpl.unsetService((context.ContextOuterClass.Service) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver);
break;
case METHODID_REMOVE_SERVICE:
serviceImpl.removeService((context.ContextOuterClass.ServiceId) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
......@@ -3116,6 +3258,10 @@ public final class ContextServiceGrpc {
serviceImpl.setSlice((context.ContextOuterClass.Slice) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver);
break;
case METHODID_UNSET_SLICE:
serviceImpl.unsetSlice((context.ContextOuterClass.Slice) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver);
break;
case METHODID_REMOVE_SLICE:
serviceImpl.removeSlice((context.ContextOuterClass.SliceId) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
......@@ -3237,12 +3383,14 @@ public final class ContextServiceGrpc {
.addMethod(getListServicesMethod())
.addMethod(getGetServiceMethod())
.addMethod(getSetServiceMethod())
.addMethod(getUnsetServiceMethod())
.addMethod(getRemoveServiceMethod())
.addMethod(getGetServiceEventsMethod())
.addMethod(getListSliceIdsMethod())
.addMethod(getListSlicesMethod())
.addMethod(getGetSliceMethod())
.addMethod(getSetSliceMethod())
.addMethod(getUnsetSliceMethod())
.addMethod(getRemoveSliceMethod())
.addMethod(getGetSliceEventsMethod())
.addMethod(getListConnectionIdsMethod())
......
......@@ -156,6 +156,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
}
public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::unsetService);
}
public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::removeService);
}
......@@ -181,6 +186,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
}
public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(context.ContextOuterClass.Slice request) {
return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::unsetSlice);
}
public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::removeSlice);
}
......@@ -383,6 +393,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
}
public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
......@@ -408,6 +423,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
}
public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(context.ContextOuterClass.Slice request) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
......@@ -670,6 +690,13 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
context.ContextOuterClass.Service,
context.ContextOuterClass.ServiceId>(
this, METHODID_SET_SERVICE, compression)))
.addMethod(
context.ContextServiceGrpc.getUnsetServiceMethod(),
asyncUnaryCall(
new MethodHandlers<
context.ContextOuterClass.Service,
context.ContextOuterClass.ServiceId>(
this, METHODID_UNSET_SERVICE, compression)))
.addMethod(
context.ContextServiceGrpc.getRemoveServiceMethod(),
asyncUnaryCall(
......@@ -712,6 +739,13 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
context.ContextOuterClass.Slice,
context.ContextOuterClass.SliceId>(
this, METHODID_SET_SLICE, compression)))
.addMethod(
context.ContextServiceGrpc.getUnsetSliceMethod(),
asyncUnaryCall(
new MethodHandlers<
context.ContextOuterClass.Slice,
context.ContextOuterClass.SliceId>(
this, METHODID_UNSET_SLICE, compression)))
.addMethod(
context.ContextServiceGrpc.getRemoveSliceMethod(),
asyncUnaryCall(
......@@ -800,20 +834,22 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
private static final int METHODID_LIST_SERVICES = 25;
private static final int METHODID_GET_SERVICE = 26;
private static final int METHODID_SET_SERVICE = 27;
private static final int METHODID_REMOVE_SERVICE = 28;
private static final int METHODID_GET_SERVICE_EVENTS = 29;
private static final int METHODID_LIST_SLICE_IDS = 30;
private static final int METHODID_LIST_SLICES = 31;
private static final int METHODID_GET_SLICE = 32;
private static final int METHODID_SET_SLICE = 33;
private static final int METHODID_REMOVE_SLICE = 34;
private static final int METHODID_GET_SLICE_EVENTS = 35;
private static final int METHODID_LIST_CONNECTION_IDS = 36;
private static final int METHODID_LIST_CONNECTIONS = 37;
private static final int METHODID_GET_CONNECTION = 38;
private static final int METHODID_SET_CONNECTION = 39;
private static final int METHODID_REMOVE_CONNECTION = 40;
private static final int METHODID_GET_CONNECTION_EVENTS = 41;
private static final int METHODID_UNSET_SERVICE = 28;
private static final int METHODID_REMOVE_SERVICE = 29;
private static final int METHODID_GET_SERVICE_EVENTS = 30;
private static final int METHODID_LIST_SLICE_IDS = 31;
private static final int METHODID_LIST_SLICES = 32;
private static final int METHODID_GET_SLICE = 33;
private static final int METHODID_SET_SLICE = 34;
private static final int METHODID_UNSET_SLICE = 35;
private static final int METHODID_REMOVE_SLICE = 36;
private static final int METHODID_GET_SLICE_EVENTS = 37;
private static final int METHODID_LIST_CONNECTION_IDS = 38;
private static final int METHODID_LIST_CONNECTIONS = 39;
private static final int METHODID_GET_CONNECTION = 40;
private static final int METHODID_SET_CONNECTION = 41;
private static final int METHODID_REMOVE_CONNECTION = 42;
private static final int METHODID_GET_CONNECTION_EVENTS = 43;
private static final class MethodHandlers<Req, Resp> implements
io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
......@@ -1002,6 +1038,12 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
compression,
serviceImpl::setService);
break;
case METHODID_UNSET_SERVICE:
io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Service) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver,
compression,
serviceImpl::unsetService);
break;
case METHODID_REMOVE_SERVICE:
io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ServiceId) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
......@@ -1038,6 +1080,12 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
compression,
serviceImpl::setSlice);
break;
case METHODID_UNSET_SLICE:
io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Slice) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver,
compression,
serviceImpl::unsetSlice);
break;
case METHODID_REMOVE_SLICE:
io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.SliceId) request,
(io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
......
......@@ -56,3 +56,11 @@ class OperationFailedException(ServiceException):
details = 'Operation({:s}) failed'.format(str(operation))
super().__init__(grpc.StatusCode.INTERNAL, details, extra_details=extra_details)
class NotImplementedException(ServiceException):
def __init__(
self, operation : str, extra_details : Union[str, Iterable[str]] = None
) -> None:
details = 'Operation({:s}) not implemented'.format(str(operation))
super().__init__(grpc.StatusCode.UNIMPLEMENTED, details, extra_details=extra_details)
......@@ -15,7 +15,7 @@
import json, logging
from typing import Dict, List, Tuple
from common.proto.context_pb2 import (
ConnectionEvent, ContextEvent, DeviceEvent, EventTypeEnum, LinkEvent, ServiceEvent, TopologyEvent)
ConnectionEvent, ContextEvent, DeviceEvent, EventTypeEnum, LinkEvent, ServiceEvent, SliceEvent, TopologyEvent)
from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.EventsCollector import EventsCollector
......@@ -32,6 +32,7 @@ CLASSNAME_CONTEXT_EVENT = class_to_classname(ContextEvent)
CLASSNAME_TOPOLOGY_EVENT = class_to_classname(TopologyEvent)
CLASSNAME_DEVICE_EVENT = class_to_classname(DeviceEvent)
CLASSNAME_LINK_EVENT = class_to_classname(LinkEvent)
CLASSNAME_SLICE_EVENT = class_to_classname(SliceEvent)
CLASSNAME_SERVICE_EVENT = class_to_classname(ServiceEvent)
CLASSNAME_CONNECTION_EVENT = class_to_classname(ConnectionEvent)
......@@ -40,6 +41,7 @@ EVENT_CLASS_NAME__TO__ENTITY_ID_SELECTOR = {
CLASSNAME_TOPOLOGY_EVENT : lambda event: event.topology_id,
CLASSNAME_DEVICE_EVENT : lambda event: event.device_id,
CLASSNAME_LINK_EVENT : lambda event: event.link_id,
CLASSNAME_SLICE_EVENT : lambda event: event.slice_id,
CLASSNAME_SERVICE_EVENT : lambda event: event.service_id,
CLASSNAME_CONNECTION_EVENT: lambda event: event.connection_id,
}
......
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# MutexQueues:
# ------------
# This class enables to schedule and serialize operations concurrently issued
# over a number of resources. For instance, when multiple components want to
# configure devices through the Device component, configuration operations
# have to be serialized to prevent data corruptions, and race conditions, etc.
# Usage Example:
# class Servicer():
# def __init__(self):
# # init other stuff
# self.drivers = dict()
# self.mutex_queues = MutexQueues()
#
# def configure_device(self, device_uuid, settings):
# self.mutex_queues.wait_my_turn(device_uuid)
# driver = self.drivers.get(device_uuid)
# if driver is None:
# driver = Driver(device_uuid)
# self.drivers[device_uuid] = driver
# driver.configure(settings)
# self.mutex_queues.signal_done(device_uuid)
import threading
from queue import Queue
from typing import Dict
class MutexQueues:
def __init__(self) -> None:
# lock to protect dictionary updates
self.lock = threading.Lock()
# dictionaty of queues of mutexes: queue_name => queue[mutex]
# first mutex is the running one
self.mutex_queues : Dict[str, Queue[threading.Event]] = dict()
def wait_my_turn(self, queue_name : str) -> None:
# create my mutex and enqueue it
mutex = threading.Event()
with self.lock:
queue : Queue = self.mutex_queues.setdefault(queue_name, Queue())
first_in_queue = (queue.qsize() == 0)
queue.put_nowait(mutex)
# if I'm the first in the queue upon addition, means there are no running tasks
# directly return without waiting
if first_in_queue: return
# otherwise, wait for my turn in the queue
mutex.wait()
def signal_done(self, queue_name : str) -> None:
# I'm done with my work
with self.lock:
queue : Queue = self.mutex_queues.setdefault(queue_name, Queue())
# remove muself from the queue
queue.get_nowait()
# if there are no other tasks queued, return
if queue.qsize() == 0: return
# otherwise, signal the next task in the queue to start
next_mutex : threading.Event = queue.queue[0]
next_mutex.set()
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
......@@ -44,10 +44,20 @@ def json_service(
def json_service_l3nm_planned(
service_uuid : str, endpoint_ids : List[Dict] = [], constraints : List[Dict] = [],
config_rules : List[Dict] = []
config_rules : List[Dict] = [], context_uuid : str = DEFAULT_CONTEXT_UUID
):
return json_service(
service_uuid, ServiceTypeEnum.SERVICETYPE_L3NM, context_id=json_context_id(DEFAULT_CONTEXT_UUID),
service_uuid, ServiceTypeEnum.SERVICETYPE_L3NM, context_id=json_context_id(context_uuid),
status=ServiceStatusEnum.SERVICESTATUS_PLANNED, endpoint_ids=endpoint_ids, constraints=constraints,
config_rules=config_rules)
def json_service_tapi_planned(
service_uuid : str, endpoint_ids : List[Dict] = [], constraints : List[Dict] = [],
config_rules : List[Dict] = [], context_uuid : str = DEFAULT_CONTEXT_UUID
):
return json_service(
service_uuid, ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, context_id=json_context_id(context_uuid),
status=ServiceStatusEnum.SERVICESTATUS_PLANNED, endpoint_ids=endpoint_ids, constraints=constraints,
config_rules=config_rules)
......@@ -39,6 +39,8 @@ def main():
wait_for_environment_variables([
get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST ),
get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_HOST ),
get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
])
signal.signal(signal.SIGINT, signal_handler)
......
......@@ -16,12 +16,11 @@ import logging
from flask import request
from flask.json import jsonify
from flask_restful import Resource
from common.Constants import DEFAULT_CONTEXT_UUID
from common.proto.context_pb2 import ServiceId, ServiceStatusEnum, SliceStatusEnum
from common.proto.context_pb2 import SliceStatusEnum
from context.client.ContextClient import ContextClient
from service.client.ServiceClient import ServiceClient
from slice.client.SliceClient import SliceClient
from .tools.Authentication import HTTP_AUTH
from .tools.ContextMethods import get_service, get_slice
from .tools.ContextMethods import get_slice
from .tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR
LOGGER = logging.getLogger(__name__)
......@@ -32,31 +31,22 @@ class L2VPN_Service(Resource):
LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
LOGGER.debug('Request: {:s}'.format(str(request)))
response = jsonify({})
try:
context_client = ContextClient()
target = get_service(context_client, vpn_id)
if target is not None:
if target.service_id.service_uuid.uuid != vpn_id: # pylint: disable=no-member
raise Exception('Service retrieval failed. Wrong Service Id was returned')
service_ready_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
service_status = target.service_status.service_status # pylint: disable=no-member
response.status_code = HTTP_OK if service_status == service_ready_status else HTTP_GATEWAYTIMEOUT
return response
target = get_slice(context_client, vpn_id)
if target is not None:
if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member
raise Exception('Slice retrieval failed. Wrong Slice Id was returned')
slice_ready_status = SliceStatusEnum.SLICESTATUS_ACTIVE
slice_status = target.slice_status.slice_status # pylint: disable=no-member
response.status_code = HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT
return response
if target is None:
raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member
raise Exception('Slice retrieval failed. Wrong Slice Id was returned')
slice_ready_status = SliceStatusEnum.SLICESTATUS_ACTIVE
slice_status = target.slice_status.slice_status # pylint: disable=no-member
response = jsonify({})
response.status_code = HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Something went wrong Retrieving VPN({:s})'.format(str(request)))
LOGGER.exception('Something went wrong Retrieving VPN({:s})'.format(str(vpn_id)))
response = jsonify({'error': str(e)})
response.status_code = HTTP_SERVERERROR
return response
......@@ -66,18 +56,21 @@ class L2VPN_Service(Resource):
LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
LOGGER.debug('Request: {:s}'.format(str(request)))
# pylint: disable=no-member
service_id_request = ServiceId()
service_id_request.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
service_id_request.service_uuid.uuid = vpn_id
try:
service_client = ServiceClient()
service_client.DeleteService(service_id_request)
context_client = ContextClient()
target = get_slice(context_client, vpn_id)
if target is None:
LOGGER.warning('VPN({:s}) not found in database. Nothing done.'.format(str(vpn_id)))
else:
if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member
raise Exception('Slice retrieval failed. Wrong Slice Id was returned')
slice_client = SliceClient()
slice_client.DeleteSlice(target.slice_id)
response = jsonify({})
response.status_code = HTTP_NOCONTENT
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('Something went wrong Deleting Service {:s}'.format(str(request)))
LOGGER.exception('Something went wrong Deleting VPN({:s})'.format(str(vpn_id)))
response = jsonify({'error': str(e)})
response.status_code = HTTP_SERVERERROR
return response
......@@ -19,8 +19,7 @@ from flask.json import jsonify
from flask_restful import Resource
from werkzeug.exceptions import UnsupportedMediaType
from common.Constants import DEFAULT_CONTEXT_UUID
from common.proto.context_pb2 import Service, ServiceStatusEnum, ServiceTypeEnum, SliceStatusEnum, Slice
from service.client.ServiceClient import ServiceClient
from common.proto.context_pb2 import SliceStatusEnum, Slice
from slice.client.SliceClient import SliceClient
from .schemas.vpn_service import SCHEMA_VPN_SERVICE
from .tools.Authentication import HTTP_AUTH
......@@ -44,30 +43,16 @@ class L2VPN_Services(Resource):
vpn_services : List[Dict] = request_data['ietf-l2vpn-svc:vpn-service']
for vpn_service in vpn_services:
try:
vpn_service_type = vpn_service['vpn-svc-type']
if vpn_service_type == 'vpws':
# pylint: disable=no-member
service_request = Service()
service_request.service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
service_request.service_id.service_uuid.uuid = vpn_service['vpn-id']
service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
service_client = ServiceClient()
service_reply = service_client.CreateService(service_request)
if service_reply != service_request.service_id: # pylint: disable=no-member
raise Exception('Service creation failed. Wrong Service Id was returned')
elif vpn_service_type == 'vpls':
# pylint: disable=no-member
slice_request = Slice()
slice_request.slice_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
slice_request.slice_id.slice_uuid.uuid = vpn_service['vpn-id']
slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
slice_client = SliceClient()
slice_reply = slice_client.CreateSlice(slice_request)
if slice_reply != slice_request.slice_id: # pylint: disable=no-member
raise Exception('Slice creation failed. Wrong Slice Id was returned')
# pylint: disable=no-member
slice_request = Slice()
slice_request.slice_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
slice_request.slice_id.slice_uuid.uuid = vpn_service['vpn-id']
slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
slice_client = SliceClient()
slice_reply = slice_client.CreateSlice(slice_request)
if slice_reply != slice_request.slice_id: # pylint: disable=no-member
raise Exception('Slice creation failed. Wrong Slice Id was returned')
response = jsonify({})
response.status_code = HTTP_CREATED
......
......@@ -12,169 +12,113 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from ctypes import Union
import json, logging
from typing import Dict
import logging
from typing import Dict, Optional
from flask import request
from flask.json import jsonify
from flask.wrappers import Response
from flask_restful import Resource
from werkzeug.exceptions import UnsupportedMediaType
from common.proto.context_pb2 import ConfigActionEnum, Service, Slice
from common.proto.context_pb2 import Slice
from common.tools.grpc.ConfigRules import update_config_rule_custom
from common.tools.grpc.Constraints import (
update_constraint_custom, update_constraint_endpoint_location, update_constraint_endpoint_priority,
update_constraint_sla_availability)
from common.tools.grpc.EndPointIds import update_endpoint_ids
from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient
from service.client.ServiceClient import ServiceClient
from slice.client.SliceClient import SliceClient
from .schemas.site_network_access import SCHEMA_SITE_NETWORK_ACCESS
from .tools.Authentication import HTTP_AUTH
from .tools.ContextMethods import get_service, get_slice
from .tools.ContextMethods import get_slice
from .tools.HttpStatusCodes import HTTP_NOCONTENT, HTTP_SERVERERROR
from .tools.Validator import validate_message
from .Constants import BEARER_MAPPINGS, DEFAULT_ADDRESS_FAMILIES, DEFAULT_BGP_AS, DEFAULT_BGP_ROUTE_TARGET, DEFAULT_MTU
from .Constants import (
BEARER_MAPPINGS, DEFAULT_ADDRESS_FAMILIES, DEFAULT_BGP_AS, DEFAULT_BGP_ROUTE_TARGET, DEFAULT_MTU)
LOGGER = logging.getLogger(__name__)
def process_site_network_access(context_client : ContextClient, site_network_access : Dict) -> Service:
def process_site_network_access(context_client : ContextClient, site_id : str, site_network_access : Dict) -> Slice:
vpn_id = site_network_access['vpn-attachment']['vpn-id']
cvlan_id = site_network_access['connection']['tagged-interface']['dot1q-vlan-tagged']['cvlan-id']
encapsulation_type = site_network_access['connection']['encapsulation-type']
cvlan_id = site_network_access['connection']['tagged-interface'][encapsulation_type]['cvlan-id']
bearer_reference = site_network_access['bearer']['bearer-reference']
access_priority : Optional[int] = site_network_access.get('availability', {}).get('access-priority')
single_active : bool = len(site_network_access.get('availability', {}).get('single-active', [])) > 0
all_active : bool = len(site_network_access.get('availability', {}).get('all-active', [])) > 0
diversity_constraints = site_network_access.get('access-diversity', {}).get('constraints', {}).get('constraint', [])
raise_if_differs = True
diversity_constraints = {
constraint['constraint-type']:([
target[0]
for target in constraint['target'].items()
if len(target[1]) == 1
][0], raise_if_differs)
for constraint in diversity_constraints
}
mapping = BEARER_MAPPINGS.get(bearer_reference)
if mapping is None:
msg = 'Specified Bearer({:s}) is not configured.'
raise Exception(msg.format(str(bearer_reference)))
device_uuid,endpoint_uuid,router_id,route_distinguisher,sub_if_index,address_ip,address_prefix = mapping
(
device_uuid, endpoint_uuid, router_id, route_dist, sub_if_index,
address_ip, address_prefix, remote_router, circuit_id
) = mapping
target : Union[Service, Slice, None] = None
if target is None: target = get_service(context_client, vpn_id)
if target is None: target = get_slice (context_client, vpn_id)
target = get_slice(context_client, vpn_id)
if target is None: raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
# pylint: disable=no-member
endpoint_ids = target.service_endpoint_ids if isinstance(target, Service) else target.slice_endpoint_ids
for endpoint_id in endpoint_ids:
if endpoint_id.device_id.device_uuid.uuid != device_uuid: continue
if endpoint_id.endpoint_uuid.uuid != endpoint_uuid: continue
break # found, do nothing
else:
# not found, add it
endpoint_id = endpoint_ids.add()
endpoint_id.device_id.device_uuid.uuid = device_uuid
endpoint_id.endpoint_uuid.uuid = endpoint_uuid
if isinstance(target, Slice): return target
for config_rule in target.service_config.config_rules: # pylint: disable=no-member
if config_rule.WhichOneof('config_rule') != 'custom': continue
if config_rule.custom.resource_key != '/settings': continue
json_settings = json.loads(config_rule.custom.resource_value)
if 'mtu' not in json_settings: # missing, add it
json_settings['mtu'] = DEFAULT_MTU
elif json_settings['mtu'] != DEFAULT_MTU: # differs, raise exception
msg = 'Specified MTU({:s}) differs from Service MTU({:s})'
raise Exception(msg.format(str(json_settings['mtu']), str(DEFAULT_MTU)))
if 'address_families' not in json_settings: # missing, add it
json_settings['address_families'] = DEFAULT_ADDRESS_FAMILIES
elif json_settings['address_families'] != DEFAULT_ADDRESS_FAMILIES: # differs, raise exception
msg = 'Specified AddressFamilies({:s}) differs from Service AddressFamilies({:s})'
raise Exception(msg.format(str(json_settings['address_families']), str(DEFAULT_ADDRESS_FAMILIES)))
if 'bgp_as' not in json_settings: # missing, add it
json_settings['bgp_as'] = DEFAULT_BGP_AS
elif json_settings['bgp_as'] != DEFAULT_BGP_AS: # differs, raise exception
msg = 'Specified BgpAs({:s}) differs from Service BgpAs({:s})'
raise Exception(msg.format(str(json_settings['bgp_as']), str(DEFAULT_BGP_AS)))
if 'bgp_route_target' not in json_settings: # missing, add it
json_settings['bgp_route_target'] = DEFAULT_BGP_ROUTE_TARGET
elif json_settings['bgp_route_target'] != DEFAULT_BGP_ROUTE_TARGET: # differs, raise exception
msg = 'Specified BgpRouteTarget({:s}) differs from Service BgpRouteTarget({:s})'
raise Exception(msg.format(str(json_settings['bgp_route_target']), str(DEFAULT_BGP_ROUTE_TARGET)))
config_rule.custom.resource_value = json.dumps(json_settings, sort_keys=True)
break
else:
# not found, add it
config_rule = target.service_config.config_rules.add() # pylint: disable=no-member
config_rule.action = ConfigActionEnum.CONFIGACTION_SET
config_rule.custom.resource_key = '/settings'
config_rule.custom.resource_value = json.dumps({
'mtu' : DEFAULT_MTU,
'address_families': DEFAULT_ADDRESS_FAMILIES,
'bgp_as' : DEFAULT_BGP_AS,
'bgp_route_target': DEFAULT_BGP_ROUTE_TARGET,
}, sort_keys=True)
endpoint_ids = target.slice_endpoint_ids # pylint: disable=no-member
config_rules = target.slice_config.config_rules # pylint: disable=no-member
constraints = target.slice_constraints # pylint: disable=no-member
endpoint_id = update_endpoint_ids(endpoint_ids, device_uuid, endpoint_uuid)
service_settings_key = '/settings'
update_config_rule_custom(config_rules, service_settings_key, {
'mtu' : (DEFAULT_MTU, True),
'address_families': (DEFAULT_ADDRESS_FAMILIES, True),
'bgp_as' : (DEFAULT_BGP_AS, True),
'bgp_route_target': (DEFAULT_BGP_ROUTE_TARGET, True),
})
endpoint_settings_key = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
for config_rule in target.service_config.config_rules: # pylint: disable=no-member
if config_rule.WhichOneof('config_rule') != 'custom': continue
if config_rule.custom.resource_key != endpoint_settings_key: continue
json_settings = json.loads(config_rule.custom.resource_value)
if 'router_id' not in json_settings: # missing, add it
json_settings['router_id'] = router_id
elif json_settings['router_id'] != router_id: # differs, raise exception
msg = 'Specified RouterId({:s}) differs from Service RouterId({:s})'
raise Exception(msg.format(str(json_settings['router_id']), str(router_id)))
if 'route_distinguisher' not in json_settings: # missing, add it
json_settings['route_distinguisher'] = route_distinguisher
elif json_settings['route_distinguisher'] != route_distinguisher: # differs, raise exception
msg = 'Specified RouteDistinguisher({:s}) differs from Service RouteDistinguisher({:s})'
raise Exception(msg.format(str(json_settings['route_distinguisher']), str(route_distinguisher)))
if 'sub_interface_index' not in json_settings: # missing, add it
json_settings['sub_interface_index'] = sub_if_index
elif json_settings['sub_interface_index'] != sub_if_index: # differs, raise exception
msg = 'Specified SubInterfaceIndex({:s}) differs from Service SubInterfaceIndex({:s})'
raise Exception(msg.format(
str(json_settings['sub_interface_index']), str(sub_if_index)))
if 'vlan_id' not in json_settings: # missing, add it
json_settings['vlan_id'] = cvlan_id
elif json_settings['vlan_id'] != cvlan_id: # differs, raise exception
msg = 'Specified VLANId({:s}) differs from Service VLANId({:s})'
raise Exception(msg.format(
str(json_settings['vlan_id']), str(cvlan_id)))
if 'address_ip' not in json_settings: # missing, add it
json_settings['address_ip'] = address_ip
elif json_settings['address_ip'] != address_ip: # differs, raise exception
msg = 'Specified AddressIP({:s}) differs from Service AddressIP({:s})'
raise Exception(msg.format(
str(json_settings['address_ip']), str(address_ip)))
if 'address_prefix' not in json_settings: # missing, add it
json_settings['address_prefix'] = address_prefix
elif json_settings['address_prefix'] != address_prefix: # differs, raise exception
msg = 'Specified AddressPrefix({:s}) differs from Service AddressPrefix({:s})'
raise Exception(msg.format(
str(json_settings['address_prefix']), str(address_prefix)))
config_rule.custom.resource_value = json.dumps(json_settings, sort_keys=True)
break
else:
# not found, add it
config_rule = target.service_config.config_rules.add() # pylint: disable=no-member
config_rule.action = ConfigActionEnum.CONFIGACTION_SET
config_rule.custom.resource_key = endpoint_settings_key
config_rule.custom.resource_value = json.dumps({
'router_id': router_id,
'route_distinguisher': route_distinguisher,
'sub_interface_index': sub_if_index,
'vlan_id': cvlan_id,
'address_ip': address_ip,
'address_prefix': address_prefix,
}, sort_keys=True)
field_updates = {}
if router_id is not None: field_updates['router_id' ] = (router_id, True)
if route_dist is not None: field_updates['route_distinguisher'] = (route_dist, True)
if sub_if_index is not None: field_updates['sub_interface_index'] = (sub_if_index, True)
if cvlan_id is not None: field_updates['vlan_id' ] = (cvlan_id, True)
if address_ip is not None: field_updates['address_ip' ] = (address_ip, True)
if address_prefix is not None: field_updates['address_prefix' ] = (address_prefix, True)
if remote_router is not None: field_updates['remote_router' ] = (remote_router, True)
if circuit_id is not None: field_updates['circuit_id' ] = (circuit_id, True)
update_config_rule_custom(config_rules, endpoint_settings_key, field_updates)
if len(diversity_constraints) > 0:
update_constraint_custom(constraints, 'diversity', diversity_constraints)
update_constraint_endpoint_location(constraints, endpoint_id, region=site_id)
if access_priority is not None: update_constraint_endpoint_priority(constraints, endpoint_id, access_priority)
if single_active or all_active:
# assume 1 disjoint path per endpoint/location included in service/slice
location_endpoints = {}
for constraint in constraints:
if constraint.WhichOneof('constraint') != 'endpoint_location': continue
str_endpoint_id = grpc_message_to_json_string(constraint.endpoint_location.endpoint_id)
str_location_id = grpc_message_to_json_string(constraint.endpoint_location.location)
location_endpoints.setdefault(str_location_id, set()).add(str_endpoint_id)
num_endpoints_per_location = {len(endpoints) for endpoints in location_endpoints.values()}
num_disjoint_paths = min(num_endpoints_per_location)
update_constraint_sla_availability(constraints, num_disjoint_paths, all_active)
return target
def process_list_site_network_access(
context_client : ContextClient, service_client : ServiceClient, slice_client : SliceClient,
request_data : Dict
context_client : ContextClient, slice_client : SliceClient, site_id : str, request_data : Dict
) -> Response:
LOGGER.debug('Request: {:s}'.format(str(request_data)))
......@@ -182,21 +126,14 @@ def process_list_site_network_access(
errors = []
for site_network_access in request_data['ietf-l2vpn-svc:site-network-access']:
sna_request = process_site_network_access(context_client, site_network_access)
sna_request = process_site_network_access(context_client, site_id, site_network_access)
LOGGER.debug('sna_request = {:s}'.format(grpc_message_to_json_string(sna_request)))
try:
if isinstance(sna_request, Service):
sna_reply = service_client.UpdateService(sna_request)
if sna_reply != sna_request.service_id: # pylint: disable=no-member
raise Exception('Service update failed. Wrong Service Id was returned')
elif isinstance(sna_request, Slice):
sna_reply = slice_client.UpdateSlice(sna_request)
if sna_reply != sna_request.slice_id: # pylint: disable=no-member
raise Exception('Slice update failed. Wrong Slice Id was returned')
else:
raise NotImplementedError('Support for Class({:s}) not implemented'.format(str(type(sna_request))))
sna_reply = slice_client.UpdateSlice(sna_request)
if sna_reply != sna_request.slice_id: # pylint: disable=no-member
raise Exception('Slice update failed. Wrong Slice Id was returned')
except Exception as e: # pylint: disable=broad-except
msg = 'Something went wrong Updating Service {:s}'
msg = 'Something went wrong Updating VPN {:s}'
LOGGER.exception(msg.format(grpc_message_to_json_string(sna_request)))
errors.append({'error': str(e)})
......@@ -210,15 +147,13 @@ class L2VPN_SiteNetworkAccesses(Resource):
if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
LOGGER.debug('Site_Id: {:s}'.format(str(site_id)))
context_client = ContextClient()
service_client = ServiceClient()
slice_client = SliceClient()
return process_list_site_network_access(context_client, service_client, slice_client, request.json)
return process_list_site_network_access(context_client, slice_client, site_id, request.json)
@HTTP_AUTH.login_required
def put(self, site_id : str):
if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
LOGGER.debug('Site_Id: {:s}'.format(str(site_id)))
context_client = ContextClient()
service_client = ServiceClient()
slice_client = SliceClient()
return process_list_site_network_access(context_client, service_client, slice_client, request.json)
return process_list_site_network_access(context_client, slice_client, site_id, request.json)
......@@ -33,6 +33,7 @@ the Layer 2 service.
import requests
import uuid
import logging
import copy
#from osm_ro_plugin.sdnconn import SdnConnectorBase, SdnConnectorError
from .sdnconn import SdnConnectorBase, SdnConnectorError
......@@ -222,8 +223,29 @@ class WimconnectorIETFL2VPN(SdnConnectorBase):
http_code=response_service_creation.status_code,
)
"""Second step, create the connections and vpn attachments"""
self.logger.info('connection_points = {:s}'.format(str(connection_points)))
# Check if protected paths are requested
extended_connection_points = []
for connection_point in connection_points:
extended_connection_points.append(connection_point)
connection_point_wan_info = self.search_mapp(connection_point)
service_mapping_info = connection_point_wan_info.get('service_mapping_info', {})
redundant_service_endpoint_ids = service_mapping_info.get('redundant')
if redundant_service_endpoint_ids is None: continue
if len(redundant_service_endpoint_ids) == 0: continue
for redundant_service_endpoint_id in redundant_service_endpoint_ids:
redundant_connection_point = copy.deepcopy(connection_point)
redundant_connection_point['service_endpoint_id'] = redundant_service_endpoint_id
extended_connection_points.append(redundant_connection_point)
self.logger.info('extended_connection_points = {:s}'.format(str(extended_connection_points)))
"""Second step, create the connections and vpn attachments"""
for connection_point in extended_connection_points:
connection_point_wan_info = self.search_mapp(connection_point)
site_network_access = {}
connection = {}
......@@ -264,6 +286,23 @@ class WimconnectorIETFL2VPN(SdnConnectorBase):
site_network_access["bearer"] = connection_point_wan_info[
"service_mapping_info"
]["bearer"]
access_priority = connection_point_wan_info["service_mapping_info"].get("priority")
if access_priority is not None:
availability = {}
availability["access-priority"] = access_priority
availability["single-active"] = [None]
site_network_access["availability"] = availability
constraint = {}
constraint['constraint-type'] = 'end-to-end-diverse'
constraint['target'] = {'all-other-accesses': [None]}
access_diversity = {}
access_diversity['constraints'] = {'constraint': []}
access_diversity['constraints']['constraint'].append(constraint)
site_network_access["access-diversity"] = access_diversity
site_network_accesses = {}
site_network_access_list = []
site_network_access_list.append(site_network_access)
......@@ -332,7 +371,7 @@ class WimconnectorIETFL2VPN(SdnConnectorBase):
self.delete_connectivity_service(vpn_service["vpn-id"])
raise SdnConnectorError(
"Request no accepted",
"Request not accepted",
http_code=response_endpoint_site_network_access_creation.status_code,
)
except requests.exceptions.ConnectionError:
......
This diff is collapsed.
......@@ -10,6 +10,9 @@ pytz==2021.3
redis==4.1.2
requests==2.27.1
xmltodict==0.12.0
tabulate
ipaddress
macaddress
# pip's dependency resolver does not take into account installed packages.
# p4runtime does not specify the version of grpcio/protobuf it needs, so it tries to install latest one
......
......@@ -23,10 +23,15 @@ from .driver_api.DriverInstanceCache import DriverInstanceCache
from .DeviceServiceServicerImpl import DeviceServiceServicerImpl
from .MonitoringLoops import MonitoringLoops
# Custom gRPC settings
# Multiple clients might keep connections alive waiting for RPC methods to be executed.
# Requests needs to be serialized to ensure correct device configurations
GRPC_MAX_WORKERS = 200
class DeviceService(GenericGrpcService):
def __init__(self, driver_instance_cache : DriverInstanceCache, cls_name: str = __name__) -> None:
port = get_service_port_grpc(ServiceNameEnum.DEVICE)
super().__init__(port, cls_name=cls_name)
super().__init__(port, max_workers=GRPC_MAX_WORKERS, cls_name=cls_name)
database = Database(get_database_backend(backend=BackendEnum.INMEMORY))
self.monitoring_loops = MonitoringLoops(database)
self.device_servicer = DeviceServiceServicerImpl(database, driver_instance_cache, self.monitoring_loops)
......
......@@ -34,7 +34,7 @@ def main():
global LOGGER # pylint: disable=global-statement
log_level = get_log_level()
logging.basicConfig(level=log_level)
logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
logging.getLogger('monitoring-client').setLevel(logging.WARNING)
......
......@@ -34,7 +34,6 @@ class EndPointModel(Model):
device_fk = ForeignKeyField(DeviceModel)
endpoint_uuid = StringField(required=True, allow_empty=False)
endpoint_type = StringField()
resource_key = StringField(required=True, allow_empty=False)
def dump_id(self) -> Dict:
device_id = DeviceModel(self.database, self.device_fk).dump_id()
......@@ -74,13 +73,7 @@ def set_endpoint_monitors(database : Database, db_endpoint : EndPointModel, grpc
for kpi_sample_type in grpc_endpoint_kpi_sample_types:
orm_kpi_sample_type = grpc_to_enum__kpi_sample_type(kpi_sample_type)
str_endpoint_kpi_sample_type_key = key_to_str([db_endpoint_pk, str(orm_kpi_sample_type.value)])
#db_endpoint_kpi_sample_type = EndPointMonitorModel(database, str_endpoint_kpi_sample_type_key)
#db_endpoint_kpi_sample_type.endpoint_fk = db_endpoint
#db_endpoint_kpi_sample_type.resource_key = '' # during initialization, allow empty value
#db_endpoint_kpi_sample_type.kpi_sample_type = orm_kpi_sample_type
#db_endpoint_kpi_sample_type.save()
update_or_create_object(database, EndPointMonitorModel, str_endpoint_kpi_sample_type_key, {
'endpoint_fk' : db_endpoint,
#'resource_key' : '', # during initialization, allow empty value
'kpi_sample_type': orm_kpi_sample_type,
})
This diff is collapsed.
......@@ -61,11 +61,13 @@ class NetconfSessionHandler:
self.__port = int(port)
self.__username = settings.get('username')
self.__password = settings.get('password')
self.__vendor = settings.get('vendor')
self.__key_filename = settings.get('key_filename')
self.__hostkey_verify = settings.get('hostkey_verify', True)
self.__look_for_keys = settings.get('look_for_keys', True)
self.__allow_agent = settings.get('allow_agent', True)
self.__force_running = settings.get('force_running', False)
self.__commit_per_delete = settings.get('delete_rule', False)
self.__device_params = settings.get('device_params', {})
self.__manager_params = settings.get('manager_params', {})
self.__nc_params = settings.get('nc_params', {})
......@@ -90,6 +92,12 @@ class NetconfSessionHandler:
@property
def use_candidate(self): return self.__candidate_supported and not self.__force_running
@property
def commit_per_rule(self): return self.__commit_per_delete
@property
def vendor(self): return self.__vendor
@RETRY_DECORATOR
def get(self, filter=None, with_defaults=None): # pylint: disable=redefined-builtin
with self.__lock:
......@@ -181,8 +189,9 @@ def do_sampling(samples_cache : SamplesCache, resource_key : str, out_samples :
LOGGER.exception('Error retrieving samples')
def edit_config(
netconf_handler : NetconfSessionHandler, resources : List[Tuple[str, Any]], delete=False, target='running',
default_operation='merge', test_option=None, error_option=None, format='xml' # pylint: disable=redefined-builtin
netconf_handler : NetconfSessionHandler, resources : List[Tuple[str, Any]], delete=False, commit_per_rule= False,
target='running', default_operation='merge', test_option=None, error_option=None,
format='xml' # pylint: disable=redefined-builtin
):
str_method = 'DeleteConfig' if delete else 'SetConfig'
LOGGER.info('[{:s}] resources = {:s}'.format(str_method, str(resources)))
......@@ -195,13 +204,16 @@ def edit_config(
chk_length(str_resource_name, resource, min_length=2, max_length=2)
resource_key,resource_value = resource
chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
str_config_message = compose_config(resource_key, resource_value, delete=delete)
str_config_message = compose_config(
resource_key, resource_value, delete=delete, vendor=netconf_handler.vendor)
if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
LOGGER.info('[{:s}] str_config_message[{:d}] = {:s}'.format(
str_method, len(str_config_message), str(str_config_message)))
netconf_handler.edit_config(
config=str_config_message, target=target, default_operation=default_operation,
test_option=test_option, error_option=error_option, format=format)
if commit_per_rule:
netconf_handler.commit()
results[i] = True
except Exception as e: # pylint: disable=broad-except
str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
......@@ -278,12 +290,15 @@ class OpenConfigDriver(_Driver):
with self.__lock:
if self.__netconf_handler.use_candidate:
with self.__netconf_handler.locked(target='candidate'):
results = edit_config(self.__netconf_handler, resources, target='candidate')
try:
self.__netconf_handler.commit()
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('[SetConfig] Exception commiting resources: {:s}'.format(str(resources)))
results = [e for _ in resources] # if commit fails, set exception in each resource
if self.__netconf_handler.commit_per_rule:
results = edit_config(self.__netconf_handler, resources, target='candidate', commit_per_rule= True)
else:
results = edit_config(self.__netconf_handler, resources, target='candidate')
try:
self.__netconf_handler.commit()
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('[SetConfig] Exception commiting resources: {:s}'.format(str(resources)))
results = [e for _ in resources] # if commit fails, set exception in each resource
else:
results = edit_config(self.__netconf_handler, resources)
return results
......@@ -294,12 +309,15 @@ class OpenConfigDriver(_Driver):
with self.__lock:
if self.__netconf_handler.use_candidate:
with self.__netconf_handler.locked(target='candidate'):
results = edit_config(self.__netconf_handler, resources, target='candidate', delete=True)
try:
self.__netconf_handler.commit()
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('[DeleteConfig] Exception commiting resources: {:s}'.format(str(resources)))
results = [e for _ in resources] # if commit fails, set exception in each resource
if self.__netconf_handler.commit_per_rule:
results = edit_config(self.__netconf_handler, resources, target='candidate', delete=True, commit_per_rule= True)
else:
results = edit_config(self.__netconf_handler, resources, target='candidate', delete=True)
try:
self.__netconf_handler.commit()
except Exception as e: # pylint: disable=broad-except
LOGGER.exception('[DeleteConfig] Exception commiting resources: {:s}'.format(str(resources)))
results = [e for _ in resources] # if commit fails, set exception in each resource
else:
results = edit_config(self.__netconf_handler, resources, delete=True)
return results
......