Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
management:
type: http
http:
url: http://gateway-server:18092

ratelimit:
type: mongodb
mongodb:
uri: mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000

cluster:
type: hazelcast
hazelcast:
config-path: /opt/graviteeio-gateway/config/hazelcast.xml

distributed-sync:
type: redis
redis:
host: redis-stack
port: 6379

services:
sync:
repository:
enabled: true
distributed:
enabled: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--
The following is given as a simple example to enable hazelcast cluster on local environment.
It will be used when cluster.type: hazelcast is set in gravitee.yml.

For advanced configuration, please refer to official documentation: https://docs.hazelcast.com/imdg/4.2/clusters/discovery-mechanisms
-->
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config
http://www.hazelcast.com/schema/config/hazelcast-config-5.3.xsd">

<cluster-name>gio-apim-gateway-cluster-bridge</cluster-name>
<network>
<port auto-increment="true" port-count="100">5701</port>
<join>
<auto-detection enabled="true"/>
<multicast enabled="false"/>
<tcp-ip enabled="true">
<member>gateway_client</member>
<member>gateway_client_2</member>
<member>management_api</member>
</tcp-ip>
</join>
</network>
</hazelcast>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--
~ 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>
41 changes: 41 additions & 0 deletions docker/quick-setup/distributed-sync-bridge-mapi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# MAPI as Bridge HTTP and Distributed Sync

Here is a docker-compose to run APIM with two or three gateways:
- One as a **Bridge Server.** It can make calls to the database and expose HTTP endpoints to be able to call the database.
- Two as a **Bridge Client.** It calls the Gateway Bridge Server through HTTP to fetch data.

You can classically call your apis through any of your client gateway, for example: `http://localhost:8082/myapi` or `http://localhost:8081/myapi` .

To test the **Bridge Server**, you can call, for example, `http://localhost:18092/_bridge/apis` to list all the apis directly from database.

## How to run ?

⚠️ You need a license file to be able to run Enterprise Edition of APIM. Do not forget to add your license file into `./.license`.

`APIM_VERSION={APIM_VERSION} docker-compose up -d `

To be sure to fetch last version of images, you can do
`export APIM_VERSION={APIM_VERSION} && docker-compose down -v && docker-compose pull && docker-compose up`

If you want to run only one client gateway first and then the other, you can do
`export APIM_REGISTRY=graviteeio.azurecr.io && export APIM_VERSION=master-latest && docker compose up -d redis-stack mongodb elasticsearch gateway_client management_api management_ui`

and then to start the second client gateway, you can do
`export APIM_REGISTRY=graviteeio.azurecr.io && export APIM_VERSION=master-latest && docker compose up -d gateway_client_2`

To see what is inside Redis, for example the distributed sync data, you can do
`redis-cli`

and then inside redis-cli, you can do
`Keys distributed*`

## Scenario Testing

Below is the scenario to test distributed sync process with MAPI as Bridge Server. Logs/Info/Success messages are printed as output.

### Scenario: Test that a new gateway must sync without access to DB

Run the script `test-bridge-crash-new-gateway-sync.sh`.

The script above starts all the services along with bridge server.
It then kills the bridge server and the database, adds a new gateway and verifies that it synced via redis.
155 changes: 155 additions & 0 deletions docker/quick-setup/distributed-sync-bridge-mapi/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
networks:
frontend:
name: frontend
storage:
name: storage

volumes:
data-elasticsearch:
data-mongo:

services:
redis-stack:
image: 'redis/redis-stack:latest'
container_name: redis_stack
ports:
- '6379:6379'
networks:
- storage
- frontend

mongodb:
image: mongo:${MONGODB_VERSION:-6.0}
container_name: gio_apim_mongodb
restart: always
volumes:
- data-mongo:/data/db
- ./.logs/apim-mongodb:/var/log/mongodb
healthcheck:
test: mongosh --eval 'db.runCommand({serverStatus:1}).ok' --quiet | grep 1
interval: 5s
timeout: 3s
retries: 10
networks:
- storage

elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-8.17.2}
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
- cluster.name=elasticsearch
- bootstrap.memory_lock=true
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
nofile: 65536
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=5s" ]
interval: 5s
timeout: 3s
retries: 10
networks:
- storage

gateway_client:
image: ${APIM_REGISTRY:-graviteeio}/apim-gateway:${APIM_VERSION:-latest}
container_name: gio_apim_gateway_client
restart: always
ports:
- "8082:8082"
links:
# Workaround used because of call to URI.create(uri) in WebClientFactory. If host contains "_", then host is null and the connection cannot be done.
- "management_api:gateway-server"
depends_on:
mongodb:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes:
- ./.logs/apim-gateway-client:/opt/graviteeio-gateway/logs
- ./.license:/opt/graviteeio-gateway/license
- ./.config:/opt/graviteeio-gateway/config
environment:
- gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200
networks:
- storage
- frontend

gateway_client_2:
image: ${APIM_REGISTRY:-graviteeio}/apim-gateway:${APIM_VERSION:-latest}
container_name: gio_apim_gateway_client_2
restart: always
ports:
- "8081:8082"
links:
# Workaround used because of call to URI.create(uri) in WebClientFactory. If host contains "_", then host is null and the connection cannot be done.
- "management_api:gateway-server"
depends_on:
mongodb:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes:
- ./.logs/apim-gateway-client:/opt/graviteeio-gateway/logs
- ./.license:/opt/graviteeio-gateway/license
- ./.config:/opt/graviteeio-gateway/config
environment:
- gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200
networks:
- storage
- frontend

management_api:
image: ${APIM_REGISTRY:-graviteeio}/apim-management-api:${APIM_VERSION:-latest}
container_name: gio_apim_management_api
restart: always
ports:
- "8083:8083"
- "18092:18092"
links:
- mongodb
- elasticsearch
depends_on:
mongodb:
condition: service_healthy
elasticsearch:
condition: service_healthy
volumes:
- ./.logs/apim-management-api:/opt/graviteeio-management-api/logs
- ./.license:/opt/graviteeio-management-api/license
environment:
- gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000
- gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200
- gravitee_services_bridge_http_enabled=true
- gravitee_services_bridge_http_port=18092
- gravitee_services_bridge_http_host=0.0.0.0
- gravitee_services_bridge_http_authentication_type=none
- gravitee_services_bridge_http_secured=false
- gravitee_services_bridge_http_ssl_clientAuth=false
networks:
- storage
- frontend

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