Skip to content
This repository was archived by the owner on Mar 27, 2023. It is now read-only.

Commit d7aa555

Browse files
author
Michel Zimmer
committed
Switch from API host to path prefix
- Remove configuration - Add integrated mock server
1 parent 2cd688d commit d7aa555

20 files changed

+201
-91
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
**/*
22
!index.html
3+
!mocks/
34
!nginx.conf
45
!package.json
56
!public/
67
!src/
78
!tsconfig.json
89
!tsconfig.node.json
10+
!vite-plugin-serve-handler/
911
!vite.config.ts
1012
!yarn.lock

.env.development

Lines changed: 0 additions & 1 deletion
This file was deleted.

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ COPY --chown=node:node \
1111
tsconfig.node.json \
1212
vite.config.ts \
1313
./
14+
COPY --chown=node:node mocks ./mocks
1415
COPY --chown=node:node public ./public
1516
COPY --chown=node:node src ./src
17+
COPY --chown=node:node vite-plugin-serve-handler ./vite-plugin-serve-handler
1618
RUN yarn build
1719
FROM nginxinc/nginx-unprivileged:alpine
1820
COPY nginx.conf /etc/nginx/templates/default.conf.template
@@ -24,5 +26,5 @@ LABEL org.opencontainers.image.vendor="neuland – Büro für Informatik GmbH"
2426
LABEL org.opencontainers.image.licenses="MIT"
2527
LABEL org.opencontainers.image.title="bandwhichd-ui"
2628
LABEL org.opencontainers.image.description="bandwhichd ui displaying network topology and statistics"
27-
LABEL org.opencontainers.image.version="0.3.0"
29+
LABEL org.opencontainers.image.version="0.4.0"
2830
COPY --from=build --chown=root:root /home/node/dist /usr/share/nginx/html

docker-compose.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ services:
22
main:
33
build:
44
context: .
5-
env_file:
6-
- .env.development
7-
ports:
8-
- 3000:8080
5+
environment:
6+
BANDWHICHD_API_SERVER: http://127.0.0.1:8080
7+
network_mode: host

index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
<meta charset="UTF-8" />
55
<meta name="description" content="bandwhichd ui displaying network topology and statistics" />
66
<title>bandwhichd-ui</title>
7-
<script>document.configuration={apiServer:"PLACEHOLDER_API_SERVER"}</script>
87
</head>
98
<body>
109
<noscript>You need to enable JavaScript to run this app.</noscript>

mock-server.mjs

Lines changed: 0 additions & 47 deletions
This file was deleted.

mocks/apiHandler.ts

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import fs from "fs"
2+
import http from "http";
3+
import path from "path"
4+
import process from "process"
5+
import type { Connect, ResolvedConfig } from "vite";
6+
7+
import { ServeHandler } from "../vite-plugin-serve-handler";
8+
9+
const isApiRoute: (url: string) => boolean =
10+
(url) => url === "/api" || url.startsWith("/api?") || url.startsWith("/api/");
11+
12+
const bandwhichdApiServerFromEnv: (viteConfig: ResolvedConfig) => URL | null =
13+
(viteConfig) => {
14+
const bandwhichdApiServer = viteConfig.env["BANDWHICHD_API_SERVER"];
15+
try {
16+
return new URL(bandwhichdApiServer);
17+
} catch (_) {
18+
return null;
19+
}
20+
};
21+
22+
const handleWithMocks =
23+
(request: Connect.IncomingMessage, response: http.ServerResponse) => {
24+
const chunks = [];
25+
request.on("data", chunk => {
26+
chunks.push(chunk);
27+
});
28+
29+
request.on("end", () => {
30+
if (request.method !== "GET"
31+
|| request.url !== "/api/v1/stats") {
32+
response.writeHead(404);
33+
response.end();
34+
return;
35+
}
36+
37+
if (chunks.length > 0) {
38+
response.writeHead(400);
39+
response.end();
40+
return;
41+
}
42+
43+
const format =
44+
request.headers.accept === "text/vnd.graphviz; q=1.0"
45+
? "dot"
46+
: "json";
47+
48+
const filePath = path.join(process.cwd(), 'mocks', `stats.${format}`);
49+
const fileStat = fs.statSync(filePath);
50+
51+
response.writeHead(200, {
52+
"Access-Control-Allow-Origin": "*",
53+
"Content-Length": fileStat.size,
54+
});
55+
fs.createReadStream(filePath).pipe(response);
56+
});
57+
};
58+
59+
const handleWithServer =
60+
(request: Connect.IncomingMessage, response: http.ServerResponse, viteConfig: ResolvedConfig, bandwhichdApiServer: URL) => {
61+
const upstreamRequestOptions: http.RequestOptions = {
62+
protocol: bandwhichdApiServer.protocol,
63+
host: bandwhichdApiServer.hostname,
64+
port: bandwhichdApiServer.port,
65+
method: request.method,
66+
path: request.url.substring("/api".length),
67+
headers: {
68+
...request.headers,
69+
host: `${bandwhichdApiServer.host}`,
70+
},
71+
};
72+
73+
request.pipe(http.request(upstreamRequestOptions, (upstreamResponse) => {
74+
upstreamResponse.pipe(response).on("error", (error) => {
75+
viteConfig.logger.error("mocks/apiHandler: Error proxying response", {
76+
error,
77+
timestamp: true
78+
});
79+
response.end();
80+
});
81+
})).on("error", (error) => {
82+
viteConfig.logger.error("mocks/apiHandler: Error proxying request", {
83+
error,
84+
timestamp: true
85+
});
86+
response.end();
87+
});
88+
};
89+
90+
export const apiHandler: ServeHandler.Handler =
91+
(request, response, viteConfig) => {
92+
if (!isApiRoute(request.url)) {
93+
return false;
94+
}
95+
96+
const bandwhichdApiServer = bandwhichdApiServerFromEnv(viteConfig);
97+
98+
if (bandwhichdApiServer === null) {
99+
handleWithMocks(request, response);
100+
} else {
101+
handleWithServer(request, response, viteConfig, bandwhichdApiServer);
102+
}
103+
104+
return true;
105+
};
File renamed without changes.

mocks/stats.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"hosts":{"28e9f9f4-c9ec-7448-d591-f8fce34086ce":{"hostname":"spring-db1","additional_hostnames":[],"connections":{}},"d416fa7d-edef-ded2-5074-3244110a5a3d":{"hostname":"spring-mongodb","additional_hostnames":[],"connections":{}},"fda7ecc9-eb5f-002d-2d11-eb4ab88ef9e4":{"hostname":"spring-logging","additional_hostnames":[],"connections":{}},"b110d228-d4c9-667b-c4da-913425b25175":{"hostname":"ecom-nginx-services","additional_hostnames":[],"connections":{}},"3509c6bc-b535-a72a-2bc1-f5b585e03063":{"hostname":"ecom-cache2","additional_hostnames":[],"connections":{}},"dda70a41-0ee2-8e2c-dc15-1a12cd46b7e4":{"hostname":"ecom-app-live1","additional_hostnames":[],"connections":{}},"f6541cc6-8eea-8e2c-d40b-959e18660923":{"hostname":"ecom-cache","additional_hostnames":[],"connections":{}},"55faca59-16af-34b8-9f0d-882b6531e82d":{"hostname":"spring-staging","additional_hostnames":[],"connections":{}},"2b09a772-335d-d36b-1cfb-eb75f6c9bea1":{"hostname":"spring-app-live2","additional_hostnames":[],"connections":{}},"fd4760d6-baa4-3b27-3bf0-a83174eb5014":{"hostname":"spring-web-live6","additional_hostnames":[],"connections":{}},"35b2b94f-41f9-c120-8852-af0665d5b628":{"hostname":"spring-cache","additional_hostnames":[],"connections":{}},"6075cc26-5b1b-5f01-f0d8-2a78e139a0d2":{"hostname":"spring-cache2","additional_hostnames":[],"connections":{}},"1c9684d1-cb83-501e-63da-9077e9868a98":{"hostname":"spring-services1","additional_hostnames":[],"connections":{}},"2000044d-80c2-fb2f-80a7-30345cea90ff":{"hostname":"ecom-services1","additional_hostnames":[],"connections":{}},"eebbdbb0-1fdc-7802-8b35-6a5f84699eb5":{"hostname":"ecom-services2","additional_hostnames":[],"connections":{}},"045c74d2-e4f6-6c5d-76fa-a55a3b23be6e":{"hostname":"ecom-logging","additional_hostnames":[],"connections":{}},"0ead0515-5d04-9c5a-9a8d-9724d34882ee":{"hostname":"ecom-app-live2","additional_hostnames":[],"connections":{}},"78334682-0244-2adb-6cf2-c243717a3f58":{"hostname":"ecom-web-live3","additional_hostnames":[],"connections":{}},"71d66f34-2bc1-7853-bc9d-0ee87a963264":{"hostname":"ecom-web-live6","additional_hostnames":[],"connections":{}},"a5a0f816-8cb2-a634-9dc5-6d28dbbef6e3":{"hostname":"spring-staging2","additional_hostnames":[],"connections":{}},"40b13e86-8d85-816d-bbe4-09d223eaf94c":{"hostname":"spring-nginx-services","additional_hostnames":[],"connections":{}},"0add42fd-d09b-13ad-62d0-9d7edf87e7b1":{"hostname":"spring-app-live1","additional_hostnames":[],"connections":{}},"98bc86ae-6dd9-05a0-4119-851e82b84dc2":{"hostname":"spring-services2","additional_hostnames":[],"connections":{}},"2c22b189-ed70-9ad1-b758-54bd5b1aef4b":{"hostname":"spring-web-live3","additional_hostnames":[],"connections":{}}},"unmonitoredHosts":{}}

nginx.conf

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
server {
2-
listen 8080;
3-
listen [::]:8080;
2+
listen 3000;
3+
listen [::]:3000;
4+
5+
location ~ ^/api(/.*)?$ {
6+
proxy_pass ${BANDWHICHD_API_SERVER}$1;
7+
proxy_set_header Host $host;
8+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
9+
proxy_set_header X-Real-IP $remote_addr;
10+
}
411

512
location / {
613
root /usr/share/nginx/html;
714
index index.html;
8-
sub_filter 'PLACEHOLDER_API_SERVER' '${BANDWHICHD_API_SERVER}';
915
}
1016
}

0 commit comments

Comments
 (0)