Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

gRPC-запросы формируются на основе proto-файлов.

Note
titleВнимание!

Описанный способ выполнения прямых gRPC-запросов применим только для стандартного типа установки ПК Интеллект Х Сервер и клиент. В отказоустойчивом режиме сертификаты хранятся в Consul, поэтому прямое подключение к gRPC-сервису на порту 20109 без дополнительной настройки не поддерживается.

Подготовка окружения

Перед началом работы необходимо:

  1. Установить интерпретатор языка Python и при необходимости IDE.
  2. Через pip установить зависимости:

    Code Block
    pip>=21.1.2
    grpcio-tools>=1.38.0
    googleapis-common-protos
    pyOpenSSL==19.1.0

Создание proto-классов

Для создания proto-классов необходимо:

  1. Получить в службе технической поддержки proto-файлы.
  2. Сохранить скрипт в виде py-файла:

  3.  
  4. script.py.

  5. В папке со скриптом создать папку grpc-proto-files. В эту папку поместить папки ITV и Google вместе с их содержимым из полученного архива с proto-файлами.
  6. Запустить скрипт.

В результате в папке со скриптом появится папка ITV с proto-классами, которые будут использоваться для работы через gRPC-канал.

...

Авторизация возможна только к Серверу серверу из сертификата.

Ниже приводится пример авторизации и пример запроса ConfigurationService.ListUnits для получения корневого юнита.

Expand
titleПример авторизации и запроса ConfigurationService.ListUnits
Code Block
import grpc

from OpenSSL import crypto
from grpc._channel import _InactiveRpcError

from axxonsoft.bl.config.ConfigurationService_pb2 import ListUnitsRequest
from axxonsoft.bl.config.ConfigurationService_pb2_grpc import ConfigurationServiceStub
from axxonsoft.bl.auth.Authentication_pb2 import AuthenticateRequest
from axxonsoft.bl.auth.Authentication_pb2_grpc import AuthenticationServiceStub


def get_channel_credentials(cert_path):
    with open(cert_path, 'rb') as f:
        certificate = f.read()

    creds = grpc.ssl_channel_credentials(root_certificates=certificate)

    cert = crypto.load_certificate(crypto.FILETYPE_PEM, certificate)
    common_name = cert.get_subject().CN

    return creds, common_name


def get_ssl_channel(server, channel_creds, override_cn, auth_creds=None):
    channel_creds = grpc.composite_channel_credentials(channel_creds, auth_creds) if auth_creds else channel_creds
    return grpc.secure_channel(server, channel_creds, options=(('grpc.ssl_target_name_override', override_cn),))


def get_auth_credentials(simple_channel, username, password):
    client = AuthenticationServiceStub(simple_channel)
    auth_request = AuthenticateRequest(user_name=username, password=password)
    response = client.Authenticate(auth_request)
    auth_header = (response.token_name, response.token_value)
    auth_creds = grpc.metadata_call_credentials(
        lambda _, cb: cb([auth_header], None))
    return auth_creds


def get_authorized_channel(certificate_path, ip="127.0.0.1", port=20109, username="root", password="root"):
    server = f"{ip}:{port}"
    channel_creds, cert_common_name = get_channel_credentials(certificate_path)
    try:
        simple_channel = get_ssl_channel(server, channel_creds, cert_common_name)
        auth_creds = get_auth_credentials(simple_channel, username, password)
        return get_ssl_channel(server, channel_creds, cert_common_name, auth_creds)
    except _InactiveRpcError as ex:
        print(f"Unable to connect to server. Details:\n{ex.details()}")


if __name__ == '__main__':
    print('This script need to provide a path to the certificate')
    path = r"C:\ProgramData\ITV\IntellectX\Tickets\Node.crt"
    channel = get_authorized_channel(path)
    config_service = ConfigurationServiceStub(channel)
    request = ListUnitsRequest(unit_uids=["root"])
    response = config_service.ListUnits(request)
    print(f"Found {len(response.units)} units:\n{response.units}")


Функция get_authorized_channel в качестве параметров принимает:

  1. certificate_path
  2. путь к сертификату;
  3. ip – IP-адрес Сервера (по умолчанию "127.0.0.1");
  4. port – порт gRPC API (по умолчанию 20109);
  5. username – имя пользователя (по умолчанию "root");
  6. password – пароль пользователя (по умолчанию "root").
Info
titleПримечание

Импортируемые proto-классы из папки ITV были созданы на предыдущем шаге.

Выполнение прямых gRPC-запросов с помощью ПО Postman

Стандартные gRPC-запросы (gRPC API) выполняются через web-сервер (порт 80). Также поддерживается отправка прямых gRPC-запросов на порт 20109 с использованием ПО Postman.

Для выполнения прямых gRPC-запросов с помощью ПО Postman требуется:

  • запрос AuthenticationService / Authenticate — для получения токена аутентификации (время жизни токена – 5 минут);

  • целевой gRPC-запрос — использует полученный токен.

Настройка запроса в Postman

  1. В ПО Postman нужно нажать на кнопку New → gRPC.

  2. На вкладке Service definition:

    • импортировать требуемый .proto-файл;

    • указать путь ко всем gRPC proto-файлам.

  3. Нажать на кнопку Next.

  4. В поле Enter URL указать адрес сервера с портом 20109. Например, 127.0.0.1:20109.

  5. В поле Select a method выбрать требуемый метод из списка доступных.

  6. Нажать на вкладку Message и задать тело запроса.
    Info
    titleПримечание

    Пример для метода ListUnitsStream:

    Code Block
    {
        "unit_uids": [
            "hosts/SERVER1/MultimediaStorage.AliceBlue"
        ]
    }
  7. Нажать на вкладку Authorization и задать параметры аутентификации:
    • В поле Auth Type выбрать значение API Key.
    • В поле Key указать имя токена.
    • В поле Value указать значение токена.
  8. Выполнить запрос, нажав на кнопку Invoke.

В результате в интерфейсе отобразится:

  • стрелка вверх — отправленный запрос;

  • стрелка вниз — ответ сервера.

Сохранение токена аутентификации в системные переменные Postman

В ПО Postman время жизни токена составляет 5 минут. Для использования токена в запросах без необходимости вводить его вручную каждый раз заново, токен можно сохранить в системные переменные. Для это нужно:

  1. На вкладке Message задать тело запроса. В параметре password указать пароль пользователя Интеллект Х, в параметре user_name – имя пользователя.
    Code Block
    {
        "password": "your_root_password",
        "user_name": "root"
    }
  2. На вкладке Authorization в поле Auth Type выбрать значение No Auth.
  3. На вкладке Scripts нужно:
    1. Выбрать значение After response
    2. В области для кода ввести:
      Code Block
      var data = pm.response.messages.idx(0).data
      pm.globals.set("token_name", data.token_name);
      pm.globals.set("token_value", data.token_value);
      где в параметрах "token_name" и "token_value" указать имя и значение токена.

После выполнения запроса токен сохранится в системные переменные Postman. Токен действителен в течение 5 минут.