python

Продолжаем знакомство с APIM Gravitee

  • пятница, 28 мая 2021 г. в 00:36:16
https://habr.com/ru/company/X5RetailGroup/blog/559686/
  • Блог компании X5 Retail Group
  • Python
  • MongoDB
  • API
  • Apache


Всем привет! Меня всё ещё зовут Антон. В предыдущей  статье я провел небольшой обзор APIM Gravitee и в целом систем типа API Management. В этой статье я расскажу, как поднять ознакомительный стенд APIM Gravitee (https://www.gravitee.io), рассмотрим архитектуру системы, содержимое docker compose file, добавим некоторые параметры, запустим APIM Gravitee и сделаем первую API. Статья немного погружает в технические аспекты и может быть полезна администраторам и инженерам, чтобы начать разбираться в системе.

Архитектура

Для ознакомительного стенда будем использовать простейшую архитектуру

Все в докере, в том числе и MongoDB и Elasticsearch. Чтобы сделать полноценную среду для тестирования крайне желательно компоненты MongoDB и Elasticsearch вынести за пределы Docker. Также для простоты манипулирования настройками можно вынести конфигурационные файлы Gateway и Management API: logback.xml и gravitee.yml.

docker-compose.yml

Среду для начальных шагов будем поднимать, используя docker-compose file, предоставленный разработчиками на github. Правда, внесем несколько корректив.

docker-compose.yml

# Copyright (C) 2015 The Gravitee team (<http://gravitee.io>)

#

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

#

version: '3.5'

 

networks:

  frontend:

    name: frontend

  storage:

    name: storage

 

volumes:

  data-elasticsearch:

  data-mongo:

 

services:

  mongodb:

    image: mongo:${MONGODB_VERSION:-3.6}

    container_name: gio_apim_mongodb

    restart: always

    volumes:

      - data-mongo:/data/db

      - ./logs/apim-mongodb:/var/log/mongodb

    networks:

      - storage

 

  elasticsearch:

    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0}

    container_name: gio_apim_elasticsearch

    restart: always

    volumes:

      - data-elasticsearch:/usr/share/elasticsearch/data

    environment:

      - http.host=0.0.0.0

      - transport.host=0.0.0.0

      - xpack.security.enabled=false

      - xpack.monitoring.enabled=false

      - cluster.name=elasticsearch

      - bootstrap.memory_lock=true

      - discovery.type=single-node

      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"

    ulimits:

      memlock:

        soft: -1

        hard: -1

      nofile: 65536

    networks:

      - storage

 

  gateway:

    image: graviteeio/apim-gateway:${APIM_VERSION:-3}

    container_name: gio_apim_gateway

    restart: always

    ports:

      - "8082:8082"

    depends_on:

      - mongodb

      - elasticsearch

    volumes:

      - ./logs/apim-gateway:/opt/graviteeio-gateway/logs

    environment:

      - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000

      - gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000

      - gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200

    networks:

      - storage

      - frontend

 

  management_api:

    image: graviteeio/apim-management-api:${APIM_VERSION:-3}

    container_name: gio_apim_management_api

    restart: always

    ports:

      - "8083:8083"

    links:

      - mongodb

      - elasticsearch

    depends_on:

      - mongodb

      - elasticsearch

    volumes:

      - ./logs/apim-management-api:/opt/graviteeio-management-api/logs

    environment:

      - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000

      - gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200

    networks:

      - storage

      - frontend

 

  management_ui:

    image: graviteeio/apim-management-ui:${APIM_VERSION:-3}

    container_name: gio_apim_management_ui

    restart: always

    ports:

      - "8084:8080"

    depends_on:

      - management_api

    environment:

      - MGMT_API_URL=http://localhost:8083/management/organizations/DEFAULT/environments/DEFAULT/

    volumes:

      - ./logs/apim-management-ui:/var/log/nginx

    networks:

      - frontend

 

  portal_ui:

    image: graviteeio/apim-portal-ui:${APIM_VERSION:-3}

    container_name: gio_apim_portal_ui

    restart: always

    ports:

      - "8085:8080"

    depends_on:

      - management_api

    environment:

      - PORTAL_API_URL=http://localhost:8083/portal/environments/DEFAULT

    volumes:

      - ./logs/apim-portal-ui:/var/log/nginx

    networks:

      - frontend

Первичные системы, на основе которых строится весь остальной сервис:<o:p>

  1. MongoDB - хранение настроек системы, API, Application, групп, пользователей и журнала аудита.

  2. Elasticsearch(Open Distro for Elasticsearch) - хранение логов, метрик, данных мониторинга.

MongoDB

docker-compose.yml:mongodb

mongodb:

    image: mongo:${MONGODB_VERSION:-3.6}<o:p>

    container_name: gio_apim_mongodb<o:p>

    restart: always<o:p>

    volumes:<o:p>

      - data-mongo:/data/db<o:p>

      - ./logs/apim-mongodb:/var/log/mongodb<o:p>

    networks:<o:p>

      - storage <o:p>

С MongoDB всё просто — поднимается единственный экземпляр версии 3.6, если не указано иное, с volume для логов самой MongoDB и для данных в MongoDB.<o:p>

Elasticsearch

docker-compose.yml:elasticsearch

elasticsearch:

    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0}<o:p>

    container_name: gio_apim_elasticsearch

    restart: always

    volumes:

      - data-elasticsearch:/usr/share/elasticsearch/data

    environment:

      - http.host=0.0.0.0

      - transport.host=0.0.0.0<o:p>

      - xpack.security.enabled=false

      - xpack.monitoring.enabled=false

      - cluster.name=elasticsearch

      - bootstrap.memory_lock=true

      - discovery.type=single-node

      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"

    ulimits

      memlock:

        soft: -1

        hard: -1

      nofile: 65536

    networks:

      - storage

  elasticsearch:

elasticsearch:

    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0}
    container_name: gio_apim_elasticsearch

    restart: always

    volumes:

      - data-elasticsearch:/usr/share/elasticsearch/data<o:p>

    environment:

      - http.host=0.0.0.0

      - transport.host=0.0.0.0

      - xpack.security.enabled=false

      - xpack.monitoring.enabled=false

      - cluster.name=elasticsearch

      - bootstrap.memory_lock=true

      - discovery.type=single-node

      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"

    ulimits:

      memlock:

        soft: -1

        hard: -1

      nofile: 65536

    networks:

      - storage

   С Elasticsearch также всё просто — поднимается единственный экземпляр версии 7.7.0, если не указано иное, с volume для данных в Elasticsearch. Сразу стоит убрать строки xpack.security.enabled=false и xpack.monitoring.enabled=false, так как хоть они и указаны как false, Elasticsearch пытается найти XPack и падает. Исправили ли этот баг в новых версиях не понятно, так что просто убираем их, или комментируем. Также стоит обратить внимание на секцию ulimits, так как она требуется для нормальной работы Elasticsearch в docker.<o:p>

Дальше уже поднимаются компоненты сервиса:

  1. Gateway

  2. Management API

  3. Management UI

  4. Portal UI

Gateway/APIM Gateway

docker-compose.yml:gateway

  gateway:

    image: graviteeio/apim-gateway:${APIM_VERSION:-3}

    container_name: gio_apim_gateway

    restart: always

    ports:

      - "8082:8082"

    depends_on:

      - mongodb

      - elasticsearch

    volumes:

      - ./logs/apim-gateway:/opt/graviteeio-gateway/logs
      
    environment:
    
      - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000
      
      - gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000
      - gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200
    networks:

      - storage

      - frontend<o:p>

С Gateway всё несколько сложнее — поднимается единственный экземпляр версии 3, если не указано иное. Если мы посмотрим, что лежит на hub.docker.com, то увидим, что у версий 3 и latest совпадают хеши. Дальше мы видим, что запуск данного сервиса, зависит от того, как будут работать сервисы MongoDB и Elasticsearch. Самое интересное, что если Gateway запустился и забрал данные по настроенным API из mongodb, то дальше связь с mongodb и elasticsearch не обязательна. Только в логи будут ошибки сыпаться, но сам сервис будет работать и соединения обрабатывать согласно той версии настроек, которую последний раз закачал в себя Gateway. В секции environment можно указать параметры, которые будут использоваться в работе самого Gateway, для переписывания данных из главного файла настроек: gravitee.yml. Как вариант можно поставить теги, тенанты для разграничения пространств, если используется Open Distro for Elasticsearch вместо ванильного Elasticsearch. Например, так мы можем добавить теги, тенанты и включить подсистему вывода данных о работе шлюза.

environment:

  - gravitee_tags=service-tag # включаем тег: service-tag

  - gravitee_tenant=service-space # включаем тенант: service-space

  - gravitee_services_core_http_enabled=true # включаем сервис выдачи данных по работе Gateway
  
  - gravitee_services_core_http_port=18082 # порт сервиса

  - gravitee_services_core_http_host=0.0.0.0 # адрес сервиса 

  - gravitee_services_core_http_authentication_type=basic # аутентификация либо нет, либо basic - логин + пароль
  
  - gravitee_services_core_http_authentication_type_users_admin=password # логин: admin, пароль: password
  
Чтобы к подсистеме мониторинга был доступ из вне, надо ещё открыть порт 18082.

ports:

  - "18082:18082"

Management API/APIM API

docker-compose.yml:management_api

  management_api:

    image: graviteeio/apim-management-api:${APIM_VERSION:-3}

    container_name: gio_apim_management_api

    restart: always

    ports:

      - "8083:8083"

    links:

      - mongodb

      - elasticsearch

    depends_on:

      - mongodb

      - elasticsearch

    volumes:

      - ./logs/apim-management-api:/opt/graviteeio-management-api/logs

    environment:

      - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000
 
 - gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200
 
    networks:
    
      - storage

      - frontend

Management API — это ядро всей системы и предоставляет службы для управления и настройки API, логи, аналитики и веб-интерфейсов Management UI и Portal UI. Зависит от MongoDB и Elasticsearch. Также можно через секцию environment указать параметры, которые будут использоваться в работе самого ядра системы. Дополним наши настройки:

environment:

  - gravitee_email_enable=true # включаем возможность отправлять письма

  - gravitee_email_host=smtp.domain.example # указываем сервер через который будем отправлять письма
  - gravitee_email_port=25 # указываем порт для сервера

  - gravitee_email_username=domain.example/gravitee # логин для сервера

  - gravitee_email_password=password # пароль для логина от сервера
  
  - gravitee_email_from=noreply@domain.example # указываем от чьего имени будут письма 
  - gravitee_email_subject="[Gravitee.io] %s" # указываем тему письма

Management UI/APIM Console

docker-compose.yml:apim_console

  management_ui:

    image: graviteeio/apim-management-ui:${APIM_VERSION:-3}

    container_name: gio_apim_management_ui

    restart: always

    ports:

      - "8084:8080"

    depends_on:

      - management_api

    environment:

      - MGMT_API_URL=http://localhost:8083/management/organizations/DEFAULT/environments/DEFAULT/
      
    volumes:
    
      - ./logs/apim-management-ui:/var/log/nginx

    networks:

      - frontend

Management UI предоставляет интерфейс для работы администраторам и разработчикам. Все основные функции можно осуществлять и выполняя запросы непосредственно к REST API. По опыту могу сказать, что в переменной MGMT_API_URL вместо localhost надо указать IP адрес или название сервера, где вы это поднимаете, иначе контейнер не найдет Management API.

Portal UI/APIM Portal

docker-compose.yml:apim_portal

  portal_ui:

    image: graviteeio/apim-portal-ui:${APIM_VERSION:-3}

    container_name: gio_apim_portal_ui

    restart: always

    ports:

      - "8085:8080"

    depends_on:

      - management_api

    environment:

      - PORTAL_API_URL=http://localhost:8083/portal/environments/DEFAULT

    volumes:

      - ./logs/apim-portal-ui:/var/log/nginx
    networks:

      - frontend

Portal UI — это портал для менеджеров. Предоставляет доступ к логам, метрикам и документации по опубликованным API. По опыту могу сказать, что в переменной PORTAL_API_URL вместо localhost надо указать IP-адрес или название сервера, где вы это поднимаете, иначе контейнер не найдет Management API.<o:p>

Теперь соберем весь файл вместе.

docker-compose.yml

# Copyright (C) 2015 The Gravitee team (<http://gravitee.io>)
#
# 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.
#
version: '3.5'

networks:
  frontend:
    name: frontend
  storage:
    name: storage

volumes:
  data-elasticsearch:
  data-mongo:

services:
  mongodb:
    image: mongo:${MONGODB_VERSION:-3.6}
    container_name: gio_apim_mongodb
    restart: always
    volumes:
      - data-mongo:/data/db
      - ./logs/apim-mongodb:/var/log/mongodb
    networks:
      - storage

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-7.7.0}
    container_name: gio_apim_elasticsearch
    restart: always
    volumes:
      - data-elasticsearch:/usr/share/elasticsearch/data
    environment:
      - http.host=0.0.0.0
      - transport.host=0.0.0.0
      - cluster.name=elasticsearch
      - bootstrap.memory_lock=true
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile: 65536
    networks:
      - storage

  gateway:
    image: graviteeio/apim-gateway:${APIM_VERSION:-3}
    container_name: gio_apim_gateway
    restart: always
    ports:
      - "8082:8082"
      - "18082:18082"
    depends_on:
      - mongodb
      - elasticsearch
    volumes:
      - ./logs/apim-gateway:/opt/graviteeio-gateway/logs
    environment:
      - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000
      - gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000
      - gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200
         - gravitee_tags=service-tag # включаем тег: service-tag
         - gravitee_tenant=service-space # включаем тенант: service-space
         - gravitee_services_core_http_enabled=true # включаем сервис выдачи данных по работе Gateway
         - gravitee_services_core_http_port=18082 # порт сервиса
         - gravitee_services_core_http_host=0.0.0.0 # адрес сервиса 
         - gravitee_services_core_http_authentication_type=basic # аутентификация либо нет, либо basic - логин + пароль
         - gravitee_services_core_http_authentication_type_users_admin=password # логин: admin, пароль: password

    networks:
      - storage
      - frontend

  management_api:
    image: graviteeio/apim-management-api:${APIM_VERSION:-3}
    container_name: gio_apim_management_api
    restart: always
    ports:
      - "8083:8083"
    links:
      - mongodb
      - elasticsearch
    depends_on:
      - mongodb
      - elasticsearch
    volumes:
      - ./logs/apim-management-api:/opt/graviteeio-management-api/logs
    environment:
      - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000
      - gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200
         - gravitee_email_enable=true # включаем возможность отправлять письма
         - gravitee_email_host=smtp.domain.example # указываем сервер через который будем отправлять письма
         - gravitee_email_port=25 # указываем порт для сервера
         - gravitee_email_username=domain.example/gravitee # логин для сервера
         - gravitee_email_password=password # пароль для логина от сервера
         - gravitee_email_from=noreply@domain.example # указываем от чьего имени будут письма 
         - gravitee_email_subject="[Gravitee.io] %s" # указываем тему письма

    networks:
      - storage
      - frontend

  management_ui:
    image: graviteeio/apim-management-ui:${APIM_VERSION:-3}
    container_name: gio_apim_management_ui
    restart: always
    ports:
      - "8084:8080"
    depends_on:
      - management_api
    environment:
      - MGMT_API_URL=http://localhost:8083/management/organizations/DEFAULT/environments/DEFAULT/
    volumes:
      - ./logs/apim-management-ui:/var/log/nginx
    networks:
      - frontend

  portal_ui:
    image: graviteeio/apim-portal-ui:${APIM_VERSION:-3}
    container_name: gio_apim_portal_ui
    restart: always
    ports:
      - "8085:8080"
    depends_on:
      - management_api
    environment:
      - PORTAL_API_URL=http://localhost:8083/portal/environments/DEFAULT
    volumes:
      - ./logs/apim-portal-ui:/var/log/nginx
    networks:
      - frontend

Запускаем

Итоговый файл закидываем на сервер с примерно следующими характеристиками:

vCPU: 4

RAM: 4 GB

HDD: 50-100 GB

Для работы Elasticsearch, MongoDB и Gravitee Gateway нужно примерно по 0.5 vCPU, больше только лучше. Примерно тоже самое и с оперативной памятью - RAM. Остальные сервисы по остаточному принципу. Для хранения настроек много места не требуется, но учитывайте, что в MongoDB еще хранятся логи аудита системы. На начальном этапе это будет в пределах 100 MB. Остальное место потребуется для хранения логов в Elasticsearch.

docker-compose up -d # если не хотите видеть логи
docker-compose up # если хотите видеть логи и как это все работает

Как только в логах увидите строки:

gio_apim_management_api_dev | 19:57:12.615 [graviteeio-node] INFO  i.g.r.a.s.node.GraviteeApisNode - Gravitee.io - Rest APIs id[5728f320-ba2b-4a39-a8f3-20ba2bda39ac] version[3.5.3] pid[1] build[23#2f1cec123ad1fae2ef96f1242dddc0846592d222] jvm[AdoptOpenJDK/OpenJDK 64-Bit Server VM/11.0.10+9] started in 31512 ms.

Можно переходить по адресу: http://ваш_адрес:8084/.

Нужно учесть, что Elasticsearch может подниматься несколько дольше, поэтому не пугайтесь если увидите такое "приглашение":

Надо просто ещё немного подождать. Если ошибка не ушла, то надо закапываться в логи и смотреть, что там за ошибки. Видим такое приглашение — отлично!

Вводим стандартный логин и пароль: admin/admin и мы в системе!

Первичная настройка

Настройки самой системы

Переходим в меню Settings → PORTAL → Settings

Здесь можно настроить некоторый параметры системы. Например: доступные методы аутентификации наших клиентов: Keyless, API_KEY, Oauth2 или JWT. Подробно их мы рассмотрим скорее всего в третьей статье, а пока оставим как есть. Можно подключить Google Analytics. Время обновления по задачам и нотификациям. Где лежит документация и много ещё чего по мелочи.

Добавление tags и tenant

Переходим в меню Settings → GATEWAY → Shardings Tags

Здесь надо добавить теги, по которым у нас будут различаться шлюзы. Нажимаем "+" и добавляем тег и его описание.

Сохраняем. Также здесь можно тег закрепить за какой-либо командой, чтобы только они могли пользоваться теми шлюзами, которые зарегистрированы с указанными тегами.

Переходим в меню Settings → GATEWAY → Tenants

То же самое и с настройкой тенантов. Только тут нет кнопки "+", но есть серенькая надпись "New tenant", которую надо нажать для добавления нового тенанта. Естественно, данный тенант должен быть создан в Open Distro for Elasticsearch, и к нему должны быть выданы права.

Добавление пользователей

Переходим в Settings → USER MANAGEMENT → Users

Здесь можно добавлять пользователей, вот только работать это будет, если у нас настроена рассылка по email. Иначе новым пользователям не придёт рассылка от системы со ссылкой на сброс пароля. Есть ещё один способ добавить пользователя, но это прям хардкод-хардкод!

В файле настроек Management API: gravitee.yml есть такой кусочек настроек:

security:
  providers:  # authentication providers
    - type: memory
      # password encoding/hashing algorithm. One of:
      # - bcrypt : passwords are hashed with bcrypt (supports only $2a$ algorithm)
      # - none : passwords are not hashed/encrypted
      # default value is bcrypt
      password-encoding-algo: bcrypt
      users:
        - user:
          username: admin
          password: $2a$10$Ihk05VSds5rUSgMdsMVi9OKMIx2yUvMz7y9VP3rJmQeizZLrhLMyq
          roles: ORGANIZATION:ADMIN,ENVIRONMENT:ADMIN

Здесь перечислены типы хранилищ для пользователей: memory, gravitee и ldap. Данные из хранилища memoryберутся из файла настроек: gravitee.yml. Данные из хранилища gravitee  хранятся в MongoDB. Для хранения пользовательских паролей, по умолчанию используется тип хеширования BCrypt с алгоритмом $2a$. В представленных настройках мы видим пользователя: admin с хешированным паролем: admin и его роли. Если мы будем добавлять пользователей через UI, то пользователи будут храниться в MongoDB и тип их будет уже gravitee.

Создание групп пользователей

Переходим в Settings → USER MANAGEMENT → Groups

При нажатии на "+" получаем возможность добавить группу и пользователей в эту группу.

Проверка доступных шлюзов

При переходе в меню Gateways у нас отображаются все шлюзы, которые у нас есть в доступе.

Здесь мы видим настройки шлюза. В частности, Sharding tags и Tenant. Их мы добавили чуть раньше.

Естественно, есть возможность мониторинга состояния шлюза. Данные по мониторингу хранятся в Elasticsearch в отдельном индексе.

Публикация первого API

Для публикации первого API нам сначала потребуется сделать какой-нибудь backend с API.

BackEnd с API, балеринами и Swagger.

Возьмём FastAPI и сделаем простейшее backend с API.

#!/bin/env python3
import uvicorn
from fastapi import FastAPI

app = FastAPI()


@app.get('/')
@app.get('/{name}')
def read_root(name: str = None):
    """
    Hello world
    :return: str = Hello world
    """
    if name:
        return {"Hello": name}
    return {"Hello": "World"}


@app.get("/items/{item_id}")
@app.post("/items/{item_id}")
@app.put("/items/{item_id}")
def gpp_item(item_id: str):
    """
    Get items
    :param item_id: id
    :return: dict
    """
    return {"item_id": item_id}


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

Это и API можно назвать с трудом, но для примера работы вполне хватит.

Теперь запустим его! Можно даже на том же сервере.

python3 main.py

Теперь, если мы зайдем на этот сервер http://backend_server:8000/, мы увидим приветствие миру! Если подставим своё имя, типа так: http://backend_server:8000/Anton, то приветствовать уже будут вас! Если же хотите познать всю мощь FastAPI, то сразу заходите на адрес: http://backend_server:8000/docs или http://backend_server:8000/redoc . На этих страницах можно найти все методы, с которым работает данное API и также ссылку на swagger файл. Копируем URL до swagger файла.

В прошлый раз мы создавали наш план вручную. Было несколько утомительно. Сегодня мы сделаем все быстрее, через импорт swagger файла!

На главном экране Gravitee нажимаем большой "+", выбираем "IMPORT FROM LINK", вставляем URL и нажимаем "IMPORT".

Получается как-то так

Нажимаем "IMPORT"!

Почти полностью сформированный API! Теперь немного доработаем напильником...

Для начала нажимаем "START THE API" чтобы API запустить.

Переходим в "Plans" и нажимаем "+".

Создаем тестовый план.

Тип аутентификации выбираем Keyless (public) и нажимаем "NEXT".

Ограничения по количеству запросов и путям пропускаем. Нажимаем "NEXT".

Политики нам тоже пока не нужны. Нажимаем "SAVE".

План создан, но пока находиться в стадии "Staging"

Нажимаем на кнопку публикации плана - синее облачко со стрелочкой вверх! Подтверждаем кнопкой "PUBLISH"

И получаем опубликованный план и какую-то желтую полоску с призывом синхронизировать новую версию API.

Нажимаем "deploy your API" и подтверждаем наше желание "OK"

Переходим в APIs → Proxy → Entrypoints

Здесь можно указать точки входа для нашего API и URL пути. У нас указан только путь "/fastapi". Можно переключиться в режим "virtual-hosts" и тогда нам будет доступен вариант с указанием конкретных серверов и IP. Это может быть актуально для серверов с несколькими сетевыми интерфейсами.

В APIs → Proxy → GENERAL → CORS можно произвести настройки Cross-origin resource sharing.

В APIs → Proxy → GENERAL → Deployments надо указать все sharding tags, которые будут использоваться этимAPI.

В APIs → Proxy → BACKEND SERVICES → Endpoints можно указать дополнительные точки API и настроить параметры работы с ними.

Сейчас нас интересуют настройки конкретной Endpoint, поэтому нажимаем на нижнюю шестеренку.

Исправляем "Target" на http://backend_server:8000/, устанавливаем tenant, сохраняем и деплоим!

В APIs → Proxy → Deployments надо указать те sharding tags, которые могут использовать данное API. После этого необходимо вернуться в созданный план и в списке Sharding tags выбрать тег "service-tag".

В APIs → Design можно указать политики, которые будут отрабатывать при обработке запросов.

В APIs → Analytics → Overview можно смотреть статистику по работе данного конкретного API.

В APIs → Analytics → Logs можно настроить логи и потом их смотреть.

В APIs → Audit можно посмотреть, как изменялись настройки API.

Остальное пока рассматривать не будем, на работу оно не влияет.

После всего, что мы тут сделали, можно пойти проверять, как работает наш шлюз и API.

Переходим на http://gravitee_host:8082/fastapi/  , и вам покажется приветствие миру:

Также сразу можно заглянуть в APIs → Analytics → Overview/Logs для просмотра статистики обработки запросов.

Заключение

Итак, поздравляю всех, кто дочитал до сюда и остался в живых! Теперь вы знаете, как поднять ознакомительный стенд APIM Gravitee, как его настроить, создать новое API из swagger файла и проверить, что всё работает. Вариантов настройки шлюзов, точек входа и выхода, сертификатов, балансировок нагрузки и записи логов много. В одной статье всего и не расскажешь. Так что в следующей статье я расскажу о более продвинутых настройках системы APIM Gravitee. В Телеграмме есть канал по данной системе: https://t.me/gravitee_ru, вопросы по нюансам настройки можно задавать туда.