Skip to content

Commit a303c0d

Browse files
committed
feat: add a docker-compose in quick setup to test distributed sync process with redis
1 parent 2bd7e21 commit a303c0d

File tree

20 files changed

+2620
-0
lines changed

20 files changed

+2620
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
management:
2+
type: http
3+
http:
4+
url: http://gateway-server:18092
5+
6+
ratelimit:
7+
type: mongodb
8+
mongodb:
9+
uri: mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000
10+
11+
cluster:
12+
type: hazelcast
13+
hazelcast:
14+
config-path: /opt/graviteeio-gateway/config/hazelcast.xml
15+
16+
distributed-sync:
17+
type: redis
18+
redis:
19+
host: redis-stack
20+
port: 6379
21+
22+
services:
23+
sync:
24+
repository:
25+
enabled: true
26+
distributed:
27+
enabled: true
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!--
4+
The following is given as a simple example to enable hazelcast cluster on local environment.
5+
It will be used when cluster.type: hazelcast is set in gravitee.yml.
6+
7+
For advanced configuration, please refer to official documentation: https://docs.hazelcast.com/imdg/4.2/clusters/discovery-mechanisms
8+
-->
9+
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
10+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
11+
xsi:schemaLocation="http://www.hazelcast.com/schema/config
12+
http://www.hazelcast.com/schema/config/hazelcast-config-5.3.xsd">
13+
14+
<cluster-name>gio-apim-gateway-cluster-bridge</cluster-name>
15+
<network>
16+
<port auto-increment="true" port-count="100">5701</port>
17+
<join>
18+
<auto-detection enabled="true"/>
19+
<multicast enabled="false"/>
20+
<tcp-ip enabled="true">
21+
<member>gateway_client</member>
22+
<member>gateway_client_2</member>
23+
<member>management_api</member>
24+
</tcp-ip>
25+
</join>
26+
</network>
27+
</hazelcast>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!--
4+
~ Copyright (c) 2015-2016, The Gravitee team (http://www.gravitee.io)
5+
~
6+
~ Licensed under the Apache License, Version 2.0 (the "License");
7+
~ you may not use this file except in compliance with the License.
8+
~ You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
-->
18+
19+
<configuration>
20+
21+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
22+
<!-- encoders are assigned the type
23+
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
24+
<encoder>
25+
<pattern>%d{HH:mm:ss.SSS} [%thread] [%X{api}] %-5level %logger{36} - %msg%n</pattern>
26+
</encoder>
27+
</appender>
28+
29+
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
30+
<file>${gravitee.home}/logs/gravitee.log</file>
31+
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
32+
<!-- daily rollover -->
33+
<fileNamePattern>${gravitee.home}/logs/gravitee_%d{yyyy-MM-dd}.log</fileNamePattern>
34+
35+
<!-- keep 30 days' worth of history -->
36+
<maxHistory>30</maxHistory>
37+
</rollingPolicy>
38+
39+
<encoder>
40+
<pattern>%d{HH:mm:ss.SSS} [%thread] [%X{api}] %-5level %logger{36} - %msg%n</pattern>
41+
</encoder>
42+
</appender>
43+
44+
<appender name="async-file" class="ch.qos.logback.classic.AsyncAppender">
45+
<appender-ref ref="FILE" />
46+
</appender>
47+
48+
<appender name="async-console" class="ch.qos.logback.classic.AsyncAppender">
49+
<appender-ref ref="STDOUT" />
50+
</appender>
51+
52+
<logger name="io.gravitee" level="INFO" />
53+
<logger name="com.graviteesource" level="INFO" />
54+
<logger name="org.reflections" level="WARN" />
55+
<logger name="org.springframework" level="WARN" />
56+
<logger name="org.eclipse.jetty" level="WARN" />
57+
58+
<!-- Strictly speaking, the level attribute is not necessary since -->
59+
<!-- the level of the root level is set to DEBUG by default. -->
60+
<root level="WARN">
61+
<appender-ref ref="async-console" />
62+
<appender-ref ref="async-file" />
63+
</root>
64+
65+
</configuration>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# MAPI as Bridge HTTP and Distributed Sync
2+
3+
Here is a docker-compose to run APIM with two or three gateways:
4+
- One as a **Bridge Server.** It can make calls to the database and expose HTTP endpoints to be able to call the database.
5+
- Two as a **Bridge Client.** It calls the Gateway Bridge Server through HTTP to fetch data.
6+
7+
You can classically call your apis through any of your client gateway, for example: `http://localhost:8082/myapi` or `http://localhost:8081/myapi` .
8+
9+
To test the **Bridge Server**, you can call, for example, `http://localhost:18092/_bridge/apis` to list all the apis directly from database.
10+
11+
## How to run ?
12+
13+
⚠️ You need a license file to be able to run Enterprise Edition of APIM. Do not forget to add your license file into `./.license`.
14+
15+
`APIM_VERSION={APIM_VERSION} docker-compose up -d `
16+
17+
To be sure to fetch last version of images, you can do
18+
`export APIM_VERSION={APIM_VERSION} && docker-compose down -v && docker-compose pull && docker-compose up`
19+
20+
If you want to run only one client gateway first and then the other, you can do
21+
`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`
22+
23+
and then to start the second client gateway, you can do
24+
`export APIM_REGISTRY=graviteeio.azurecr.io && export APIM_VERSION=master-latest && docker compose up -d gateway_client_2`
25+
26+
To see what is inside Redis, for example the distributed sync data, you can do
27+
`redis-cli`
28+
29+
and then inside redis-cli, you can do
30+
`Keys distributed*`
31+
32+
## Scenario Testing
33+
34+
Below is the scenario to test distributed sync process with MAPI as Bridge Server. Logs/Info/Success messages are printed as output.
35+
36+
### Scenario: Test that a new gateway must sync without access to DB
37+
38+
Run the script `test-bridge-crash-new-gateway-sync.sh`.
39+
40+
The script above starts all the services along with bridge server.
41+
It then kills the bridge server and the database, adds a new gateway and verifies that it synced via redis.
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
networks:
2+
frontend:
3+
name: frontend
4+
storage:
5+
name: storage
6+
7+
volumes:
8+
data-elasticsearch:
9+
data-mongo:
10+
11+
services:
12+
redis-stack:
13+
image: 'redis/redis-stack:latest'
14+
container_name: redis_stack
15+
ports:
16+
- '6379:6379'
17+
networks:
18+
- storage
19+
- frontend
20+
21+
mongodb:
22+
image: mongo:${MONGODB_VERSION:-6.0}
23+
container_name: gio_apim_mongodb
24+
restart: always
25+
volumes:
26+
- data-mongo:/data/db
27+
- ./.logs/apim-mongodb:/var/log/mongodb
28+
healthcheck:
29+
test: mongosh --eval 'db.runCommand({serverStatus:1}).ok' --quiet | grep 1
30+
interval: 5s
31+
timeout: 3s
32+
retries: 10
33+
networks:
34+
- storage
35+
36+
elasticsearch:
37+
image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-8.17.2}
38+
container_name: gio_apim_elasticsearch
39+
restart: always
40+
volumes:
41+
- data-elasticsearch:/usr/share/elasticsearch/data
42+
environment:
43+
- http.host=0.0.0.0
44+
- transport.host=0.0.0.0
45+
- xpack.security.enabled=false
46+
- cluster.name=elasticsearch
47+
- bootstrap.memory_lock=true
48+
- discovery.type=single-node
49+
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
50+
ulimits:
51+
memlock:
52+
soft: -1
53+
hard: -1
54+
nofile: 65536
55+
healthcheck:
56+
test: [ "CMD", "curl", "-f", "http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=5s" ]
57+
interval: 5s
58+
timeout: 3s
59+
retries: 10
60+
networks:
61+
- storage
62+
63+
gateway_client:
64+
image: ${APIM_REGISTRY:-graviteeio}/apim-gateway:${APIM_VERSION:-latest}
65+
container_name: gio_apim_gateway_client
66+
restart: always
67+
ports:
68+
- "8082:8082"
69+
links:
70+
# Workaround used because of call to URI.create(uri) in WebClientFactory. If host contains "_", then host is null and the connection cannot be done.
71+
- "management_api:gateway-server"
72+
depends_on:
73+
mongodb:
74+
condition: service_healthy
75+
elasticsearch:
76+
condition: service_healthy
77+
volumes:
78+
- ./.logs/apim-gateway-client:/opt/graviteeio-gateway/logs
79+
- ./.license:/opt/graviteeio-gateway/license
80+
- ./.config:/opt/graviteeio-gateway/config
81+
environment:
82+
- gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200
83+
networks:
84+
- storage
85+
- frontend
86+
87+
gateway_client_2:
88+
image: ${APIM_REGISTRY:-graviteeio}/apim-gateway:${APIM_VERSION:-latest}
89+
container_name: gio_apim_gateway_client_2
90+
restart: always
91+
ports:
92+
- "8081:8082"
93+
links:
94+
# Workaround used because of call to URI.create(uri) in WebClientFactory. If host contains "_", then host is null and the connection cannot be done.
95+
- "management_api:gateway-server"
96+
depends_on:
97+
mongodb:
98+
condition: service_healthy
99+
elasticsearch:
100+
condition: service_healthy
101+
volumes:
102+
- ./.logs/apim-gateway-client:/opt/graviteeio-gateway/logs
103+
- ./.license:/opt/graviteeio-gateway/license
104+
- ./.config:/opt/graviteeio-gateway/config
105+
environment:
106+
- gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200
107+
networks:
108+
- storage
109+
- frontend
110+
111+
management_api:
112+
image: ${APIM_REGISTRY:-graviteeio}/apim-management-api:${APIM_VERSION:-latest}
113+
container_name: gio_apim_management_api
114+
restart: always
115+
ports:
116+
- "8083:8083"
117+
- "18092:18092"
118+
links:
119+
- mongodb
120+
- elasticsearch
121+
depends_on:
122+
mongodb:
123+
condition: service_healthy
124+
elasticsearch:
125+
condition: service_healthy
126+
volumes:
127+
- ./.logs/apim-management-api:/opt/graviteeio-management-api/logs
128+
- ./.license:/opt/graviteeio-management-api/license
129+
environment:
130+
- gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000
131+
- gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200
132+
- gravitee_services_bridge_http_enabled=true
133+
- gravitee_services_bridge_http_port=18092
134+
- gravitee_services_bridge_http_host=0.0.0.0
135+
- gravitee_services_bridge_http_authentication_type=none
136+
- gravitee_services_bridge_http_secured=false
137+
- gravitee_services_bridge_http_ssl_clientAuth=false
138+
networks:
139+
- storage
140+
- frontend
141+
142+
management_ui:
143+
image: ${APIM_REGISTRY:-graviteeio}/apim-management-ui:${APIM_VERSION:-latest}
144+
container_name: gio_apim_management_ui
145+
restart: always
146+
ports:
147+
- "8084:8080"
148+
depends_on:
149+
- management_api
150+
environment:
151+
- MGMT_API_URL=http://localhost:8083/management/
152+
volumes:
153+
- ./.logs/apim-management-ui:/var/log/nginx
154+
networks:
155+
- frontend

0 commit comments

Comments
 (0)