Gravitee.io: добавление кастомных плагинов, используя docker-compose

Привет, Хабр! Сегодня мы разберёмся, как добавлять кастомные плагины в Gravitee.io

Gravitee.io — open source продукт-шлюз с витриной API. Эта статья рассчитана на тех, кто уже знаком с системой. Общая информация о продукте хорошо описана в статье: Что такое системы API Management.

Большинство кейсов по работе с запросами можно сделать, используя уже имеющиеся плагины, но при желании можно писать собственные. Если в этом деле преисполниться, то приходишь к тому, что легче написать собственный плагин, чем разбираться с уже имеющимися. Иногда использование встроенных плагинов весьма сложное искусство, но если вы наткнулись на эту статью, то уже знаете это.

Также написание собственных плагинов добавляет кучу возможностей при работе с Gravitee

О чём?

В статье мы не будем рассматривать, как писать собственные плагины, будем полагаться на то, что вы учитесь это делать и достигли определенных успехов, а теперь хотите их подключить, протестировать и использовать. Бонусом мы научимся логировать в Graylog.

Приступим

Свои манипуляции я буду производить на последней версии Gravitee на момент публикации (3.20.10), но всё описанное ниже справедливо и для прошлых версий.

Для начала возьмём docker-compose.yml из официального источника и начнём вносить изменения.

Установим необходимую версию Gravitee

В раздел volumes для management_api пробросим папку для кастомных плагинов:
— ./apim-management-api/plugins:/opt/graviteeio-management-api/plugins-ext
Здесь мы задали путь папки с плагинами в рамках нашей системы, а также в рамках контейнера

В раздел environment для management_api добавим пути до наших плагинов:
— gravitee_plugins_path_0=/opt/graviteeio-management-api/plugins
— gravitee_plugins_path_1=/opt/graviteeio-management-api/plugins-ext

Аналогично в раздел volumes для gateway пробросим папку для кастомных плагинов:
— ./apim-gateway/plugins:/opt/graviteeio-gateway/plugins-ext

Аналогично в раздел environment для gateway добавим пути до наших плагинов:
— gravitee_plugins_path_0=/opt/graviteeio-gateway/plugins
— gravitee_plugins_path_1=/opt/graviteeio-gateway/plugins-ext

Готовый файл docker-compose.yml приведён ниже:

docker-compose.yml
version: '3.5'  networks:   frontend:     name: frontend   storage:     name: storage  volumes:   data-elasticsearch:   data-mongo:  services:   mongodb:     image: mongo:3.6     restart: always     ports:       - "27017:27017"     volumes:       - data-mongo:/data/db       - ./logs/apim-mongodb:/var/log/mongodb     networks:       - storage    elasticsearch:     image: docker.elastic.co/elasticsearch/elasticsearch: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:3.20.10     container_name: gio_apim_gateway     restart: always     ports:       - "8082:8082"     depends_on:       - mongodb       - elasticsearch     volumes:       - ./logs/apim-gateway:/opt/graviteeio-gateway/logs       - ./apim-gateway/plugins:/opt/graviteeio-gateway/plugins-ext     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_plugins_path_0=/opt/graviteeio-gateway/plugins       - gravitee_plugins_path_1=/opt/graviteeio-gateway/plugins-ext     networks:       - storage       - frontend    management_api:     image: graviteeio/apim-management-api:3.20.10     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       - ./apim-management-api/plugins:/opt/graviteeio-management-api/plugins-ext     environment:       - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000       - gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200       - gravitee_plugins_path_0=/opt/graviteeio-management-api/plugins       - gravitee_plugins_path_1=/opt/graviteeio-management-api/plugins-ext     networks:       - storage       - frontend    management_ui:     image: graviteeio/apim-management-ui:3.20.10     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:3.20.10     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

Следующим шагом мы поднимаем Gravitee, используя docker-compose up -d, либо в ручную создаём пути для плагинов в каталоге с нашим docker-compose.yml файлом.
Путь для gateway: /apim-gateway/plugins
Путь для managment: /apim-management-api/plugins

Добавление плагина

После создания необходимых путей нам необходимо собрать наш плагин. Перейти в папку target и взять zip архив, полученный при сборке. Плагин на основе которого я работал будет доступен на GitHub

Теперь мы помещаем наш плагин в оба созданных каталога и запускаем/перезапускаем Gravitee. Важное уточнение: после каждого обновления\добавления плагина необходимо будет перезагрузить Gravitee либо отдельно его модули gateway и managment-api

После запуска нам необходимо создать API, перейти на вкладку Design и в правом списке найти наш плагин. Как это выглядит в моём случае:

Отображение Custom plugin

Отображение Custom plugin

Категория плагина зависит от того, в какую категорию вы его поместите с помощью plugin.properties

Теперь ваш плагин готов к использованию! Можно приступить к конфигурированию. Не забывайте делать «deploy your api» после каждого изменения конфигурации плагина.

Бонус

Логирование в Graylog нельзя настроить отдельно для какого-то определённого плагина, но можно для отдельного компонента например managment, gateway и другие.

В каждом компоненте присутствует директория для конфигураций, в которой находятся файл logback.xml, который мы и будем рассматривать, а также gravitee.yml (важный конфигурационный файл) и некоторые другие файлы в зависимости от модуля, который мы не будем рассматривать.

Изначально файл logback.xml выглядит вот так:

logback.xml
<!--   ~ Copyright (c) 2015-2016, The Gravitee team (http://www.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.   -->  <configuration>      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">         <!-- encoders are assigned the type              ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->         <encoder>             <pattern>%d{HH:mm:ss.SSS} [%thread] [%X{api}] %-5level %logger{36} - %msg%n</pattern>         </encoder>     </appender>      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">         <file>${gravitee.home}/logs/gravitee.log</file>         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">             <!-- daily rollover -->             <fileNamePattern>${gravitee.home}/logs/gravitee_%d{yyyy-MM-dd}.log</fileNamePattern>              <!-- keep 30 days' worth of history -->             <maxHistory>30</maxHistory>         </rollingPolicy>          <encoder>             <pattern>%d{HH:mm:ss.SSS} [%thread] [%X{api}] %-5level %logger{36} - %msg%n</pattern>         </encoder>     </appender>      <appender name="async-file" class="ch.qos.logback.classic.AsyncAppender">         <appender-ref ref="FILE" />     </appender>      <appender name="async-console" class="ch.qos.logback.classic.AsyncAppender">         <appender-ref ref="STDOUT" />     </appender>      <logger name="io.gravitee" level="INFO" />     <logger name="com.graviteesource" level="INFO" />     <logger name="org.reflections" level="WARN" />     <logger name="org.springframework" level="WARN" />     <logger name="org.eclipse.jetty" level="WARN" />      <!-- Strictly speaking, the level attribute is not necessary since -->     <!-- the level of the root level is set to DEBUG by default.       -->     <root level="WARN">         <appender-ref ref="async-console" />         <appender-ref ref="async-file" />     </root>  </configuration>

Нам необходимо добавить конфигурации в зависимости от того, каким образом мы будем логировать в Graylog. Например, в случае с UDP мы допишем:

    <appender name="GELF" class="biz.paluch.logging.gelf.logback.GelfLogbackAppender">         <host>udp:host</host>         <port>port</port>         <facility>НАЗВАНИЕ КОМПОНЕНТА</facility>         <extractStackTrace>true</extractStackTrace>         <filterStackTrace>true</filterStackTrace>         <includeFullMdc>true</includeFullMdc>     </appender>       <logger name="io.gravitee.rest.api.service.impl.upgrade" level="INFO">         <appender-ref ref="FILE-UPGRADERS"/>     </logger>     <logger name="io.gravitee" level="INFO"/>     <logger name="org.eclipse.jetty" level="INFO"/>     <logger name="org.reflections" level="WARN" />     <logger name="org.springframework" level="WARN" />     <logger name="org.eclipse.jetty" level="WARN" />      <!-- Strictly speaking, the level attribute is not necessary since -->     <!-- the level of the root level is set to DEBUG by default.       -->     <root level="WARN">         <appender-ref ref="GELF"/>         <appender-ref ref="async-console" />         <appender-ref ref="async-file" />     </root>
Дополненный logback.xml
<!--   ~ Copyright (c) 2015-2016, The Gravitee team (http://www.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.   -->  <configuration>      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">         <!-- encoders are assigned the type              ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->         <encoder>             <pattern>%d{HH:mm:ss.SSS} [%thread] [%X{api}] %-5level %logger{36} - %msg%n</pattern>         </encoder>     </appender>      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">         <file>${gravitee.home}/logs/gravitee.log</file>         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">             <!-- daily rollover -->             <fileNamePattern>${gravitee.home}/logs/gravitee_%d{yyyy-MM-dd}.log</fileNamePattern>              <!-- keep 30 days' worth of history -->             <maxHistory>30</maxHistory>         </rollingPolicy>          <encoder>             <pattern>%d{HH:mm:ss.SSS} [%thread] [%X{api}] %-5level %logger{36} - %msg%n</pattern>         </encoder>     </appender>      <appender name="async-file" class="ch.qos.logback.classic.AsyncAppender">         <appender-ref ref="FILE" />     </appender>      <appender name="async-console" class="ch.qos.logback.classic.AsyncAppender">         <appender-ref ref="STDOUT" />     </appender>      <appender name="GELF" class="biz.paluch.logging.gelf.logback.GelfLogbackAppender">         <host>udp:host</host>         <port>port</port>         <facility>НАЗВАНИЕ КОМПОНЕНТА</facility>         <extractStackTrace>true</extractStackTrace>         <filterStackTrace>true</filterStackTrace>         <includeFullMdc>true</includeFullMdc>     </appender>       <logger name="io.gravitee.rest.api.service.impl.upgrade" level="INFO">         <appender-ref ref="FILE-UPGRADERS"/>     </logger>     <logger name="io.gravitee" level="INFO"/>     <logger name="org.eclipse.jetty" level="INFO"/>     <logger name="org.reflections" level="WARN" />     <logger name="org.springframework" level="WARN" />     <logger name="org.eclipse.jetty" level="WARN" />      <!-- Strictly speaking, the level attribute is not necessary since -->     <!-- the level of the root level is set to DEBUG by default.       -->     <root level="WARN">         <appender-ref ref="GELF"/>         <appender-ref ref="async-console" />         <appender-ref ref="async-file" />     </root>  </configuration>

Теперь осталось лишь дополнить docker-compose.yml , пробросив папку config внутрь контейнера. Например для managment-api это будет так:

- .\apim-management-api\config:/opt/apim-management-api/config

Данную конфигурацию можно применить для всех модулей Gravitee и все дружно будут писать в Graylog.

Следующим шагом будет «обогащение» нашего Gravitee библиотекой biz.paluch.logging.logstash-gelf. Для этого мы обратимся на maven-central, где получим jar библиотеки и поместим по пути /opt/название компонента/lib (в рамках контейнера). Для этого мы вновь «пробросим» папку наружу, для отдельного или всех компонентов. Например для компонента gateway:

- .\apim-gateway\lib:/opt/graviteeio-gateway/lib

Осталось лишь сконфигурировать Graylog, что я оставлю на совести читателя

Заключение

В статье мы рассмотрели способ добавления кастомных плагинов в Gravitee.io, используя docker-compose.yml. Также бонусом научили наш Gravitee писать в Graylog. Исходный код плагина и docker-compose.yml (версия до бонуса) доступен на GitHub


ссылка на оригинал статьи https://habr.com/ru/articles/741034/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *