# Channel Management v3
## Discriminators
Реализации дискриминаторов находятся в модуле
`core/discriminator.py`
Форматы дискриминаторов:
Строка вида `<scope>::<value>`
| Scope | Value | Описание |
| --- | --- | --- |
| `vlan` | `<vlan id>` | Фреймы 802.1Q с VLAN ID `<vlan id>`, допустимо исопльзование VLAN Filter |
| `lambda` | `<freq>-<width>` | Центральная частота `<freq>` Ghz, ширина канала `<width>` Ghz |
| `odu` | |ODU Selector, см. далее.|
Дискриминаторы задаются в модуле noc.core.discriminator и должны определять следующие методы:
* `__init__(self, value:str)`
* `__str__`
* `__contains__`
Проверка проходимости осуществляется конструкцией `d2 in d1`
### ODU
Контейнеры ODU могут группировать контейнеры меньшего размера, как показано на схеме:

Для задач мультиплексирования необходимо иметь возможность адресовать
конкретный контейнер в общей иерархии. Для этого используется дискриминатор со scope `odu`.
Синтаксис: `odu::(<ODU_TYPE>(-<index>)?)+`,
где:
* `<ODU_TYPE>` - тип ODU
* `<index>` - порядковый номер в контейнере более высокого уровня, начиная с 0. Если допустим только один элемент - то индекс опускается и считается равным `0`.
Контейнер верхнего уровня иерархии

адресуется как `odu::ODU2`. Для элемента верхнего уровня индекс всегда опускается.
Вложенный контейнер

адресуется через всех родителей: `odu::ODU2::ODU1-1`
Более глубокие уровни

иерархии адресуются аналогично: `odu::ODU2::ODU1-1::ODU0-1`
## Data Models
### TechDomain
* name
* description
* uuid
* discriminators - список дискриминаторов
Пополняется из коллекций.
Handler указывает на класс - контроллер домена
Контроллеры для TechDomain находяся в модулях
`core/channel/controllers/<name>`.
### Channel
* name
* description
* project
* supplier
* subscriber
* project
* labels
* kind - тип канала
* l1
* l2
* l3
* internet
* topology - топология
* p2p
* p2mp
* tree
* star
* protocol - для служебных каналов - опциональный протокол
* discriminators - для служебных каналов - опциональный дискриминато
### Endpoint
Возможные точки входа в TechDomain
* tech_domain
* name
* description
* model - Модель ресурса
* resource_id - id ресурса. Пустой для promise.
* slot - опциональный путь внутри ресурса (слот)
* labels
* deadline - только для типа promise, ожидаемая дата реализации.
* channels - привязанные каналы
* channel - id канала
* discriminators - опциональные discriminator
* state - опциональный state, workflow выбирается и задается контроллером
Допускается использование одного endpoint разными каналами,
если они имеют непересекающиеся дискриминаторы. Проверка делается в методе `on_save`.
### Мультиплексирование
Задается в поле Object.cross:
* `input` - имя входного слота для правила
* `input_discriminator` - входной фильтр-дискриминатор
* `output` - имя выходного слота
* `output_discriminator`:
* если пустое, совпадает с `input_discriminator`
* если не пустое, показывает отображение `input_discriminator` на выходной сигнал.
* `gain` - если непустое - задает коэффициент усиления
#### Оптический кросс
Без дискриминаторов.
#### ROADM
Используюся дискриминаторы типа `lambda`.
#### OTU
##### Add

``` json
{
"input": "Client",
"input_discriminator": "odu::ODU0",
"output": "Line1",
"output_discriminator": "odu::ODU1::ODU0-1"
}
```
#### Add + Protect

``` json
{
"input": "Client",
"input_discriminator": "odu::ODU0",
"output": "Line1",
"output_discriminator": ["odu::ODU1::ODU0-1"],
},
{
"input": "Client",
"input_discriminator": "odu::ODU0",
"output": "Line2",
"output_discriminator": "odu::ODU1::ODU0-1",
}
```
##### Transit

``` json
{
"input": "Line1",
"input_discriminator": "odu::ODU1",
"output": "Line2",
}
```
##### Transit + Protect

``` json
{
"input": "Line1",
"input_discriminator": "odu::ODU1",
"output": "Line2",
},
{
"input": "Line1",
"input_discriminator": "odu::ODU1",
"output": "Line3",
}
```
##### Drop

``` json
{
"input": "Line1",
"input_discriminator": "odu::ODU1::ODU0-1",
"output": "Client",
"output_discriminator": "odu::ODU0"
}
```
## Channel Discovery
ad-hoc channel discovery
## *Mux discovery
ad-hock *Mux discovery выполняется в box путем запуска скрипта get_mux.
```
IGetMux:
returns List[ROADMux | ODUMux | OTU]
```
## Endpoint Discovery
Запускается при создании объекта. Процесс анализирует протоколы и прочие данные на слотах модели и выдает возможные endpoint'ы.
Необходимо иметь возможность гибкой настройки по аналогии с раскраской интерфейсов.
``` python
def iter_enpoints(
self,
object: Object,
managed_object:Optional[ManagedObject]=None,
) -> Iterable[Endpoint]:...
```
где
``` python
@dataclass
class Endpoint(object):
slot: str
name: Optional[str] = None
maybe_root: Optional[bool] = None
```
## TechDomainController
``` python
class BaseController(object):
def create_channel(self, channel:Channel) -> JobRequest:...
def add_endpoint(self, channel:Channel, endpoint: ChannelEndpoit) -> JobRequest:...
def delete_endpoint(self, channel:Channel, endpoint: ChannelEndpoit) -> JobRequest:...
def delete_channel(self, channel:Channel) -> JobRequest:...
def add_mux(self, channel:Channel, mux:Document) -> JobRequest:...
def delete_mux(self, channel:Channel, mux:Document) -> JobRequest:...
def iter_paths(self, channel:Channel, endpoint:ChannelEndpoint)->Iterable[Iterable[PathItem]]:...
```