---
# System prepended metadata

title: Channel Management

---

# 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 могут группировать контейнеры меньшего размера, как показано на схеме:

![](https://i.imgur.com/kGFaLhL.png)

Для задач мультиплексирования необходимо иметь возможность адресовать
конкретный контейнер в общей иерархии. Для этого используется дискриминатор со scope `odu`.

Синтаксис: `odu::(<ODU_TYPE>(-<index>)?)+`,
где:

* `<ODU_TYPE>` - тип ODU
* `<index>` - порядковый номер в контейнере более высокого уровня, начиная с 0. Если допустим только один элемент - то индекс опускается и считается равным `0`.

Контейнер верхнего уровня иерархии

![](https://i.imgur.com/ctYZPRu.png)

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

Вложенный контейнер

![](https://i.imgur.com/hRiJplr.png)

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

Более глубокие уровни 

![](https://i.imgur.com/2NABbbF.png)


иерархии адресуются аналогично: `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

![](https://i.imgur.com/gZccp7O.png)


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

#### Add + Protect

![](https://i.imgur.com/5tAnPQq.png)

``` 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

![](https://i.imgur.com/WVXXZUr.png)

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

##### Transit + Protect

![](https://i.imgur.com/FA9zfyp.png)

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

```

##### Drop

![](https://i.imgur.com/WOrvB7M.png)

``` 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]]:...
```