fix: serve index.html for docs directory, update README with testing instructions
This commit is contained in:
@@ -7,7 +7,7 @@ WebSocket API gateway for vehicle (TRex), HMI, and mobile app connections.
|
|||||||
- Authenticates WebSocket connections via JWT
|
- Authenticates WebSocket connections via JWT
|
||||||
- Routes messages to Kafka topics
|
- Routes messages to Kafka topics
|
||||||
- Manages connection state in Redis
|
- Manages connection state in Redis
|
||||||
- Serves Swagger docs
|
- Serves AsyncAPI docs
|
||||||
|
|
||||||
## Ports
|
## Ports
|
||||||
|
|
||||||
@@ -18,37 +18,56 @@ WebSocket API gateway for vehicle (TRex), HMI, and mobile app connections.
|
|||||||
|
|
||||||
## WebSocket Endpoints
|
## WebSocket Endpoints
|
||||||
|
|
||||||
- `/ws/trex` - Vehicle connections
|
| Endpoint | Purpose | User-Agent |
|
||||||
- `/ws/hmi` - HMI connections
|
|----------|---------|------------|
|
||||||
- `/ws/mobile` - Mobile app connections
|
| `/session` | Vehicle (TRex) and HMI connections | `Fisker Ocean T.Rex x.x.x.x` or `HMI x.x.x.x` |
|
||||||
|
| `/secret_mobile` | Mobile app connections | `Mobile x.x.x` or `iOS x.x.x` or `Android x.x.x` |
|
||||||
|
|
||||||
|
## API Documentation
|
||||||
|
|
||||||
|
AsyncAPI specs available at `/docs/`:
|
||||||
|
- `/docs/asyncapi_mobile.yaml` - Mobile API
|
||||||
|
- `/docs/asyncapi_hmi.yaml` - HMI API
|
||||||
|
- `/docs/asyncapi_trex.yaml` - T-Rex API
|
||||||
|
- `/docs/index.html` - Interactive UI
|
||||||
|
|
||||||
|
## Testing WebSocket Connections
|
||||||
|
|
||||||
|
Install websocat:
|
||||||
|
```bash
|
||||||
|
brew install websocat
|
||||||
|
```
|
||||||
|
|
||||||
|
Test mobile endpoint:
|
||||||
|
```bash
|
||||||
|
# Connect to mobile websocket
|
||||||
|
websocat -H="User-Agent: Mobile 1.0.0" wss://gateway.mini.cloud.fiskerinc.com/secret_mobile
|
||||||
|
|
||||||
|
# Send verify message (after connecting)
|
||||||
|
{"handler":"verify","data":{"token":"<jwt_token>"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Test vehicle endpoint (requires VIN in SSL cert or header):
|
||||||
|
```bash
|
||||||
|
websocat -H="User-Agent: Fisker Ocean T.Rex 1.0.0.0 ABC123" \
|
||||||
|
-H="X-VIN: YH7DR1EA1PA000001" \
|
||||||
|
wss://gateway.mini.cloud.fiskerinc.com/session
|
||||||
|
```
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Local
|
# From cloud-services root
|
||||||
go build .
|
docker build --platform linux/arm64 -t gateway:latest -f services/gateway/Dockerfile .
|
||||||
|
|
||||||
# Docker
|
|
||||||
docker build -t gateway -f Dockerfile ../..
|
|
||||||
```
|
|
||||||
|
|
||||||
## Run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Required env vars
|
|
||||||
export KAFKA_HOSTS=localhost:9092
|
|
||||||
export REDIS_HOST=localhost
|
|
||||||
export JWK_URL=https://keycloak.example.com/realms/consumer/protocol/openid-connect/certs
|
|
||||||
|
|
||||||
./gateway
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
See `deploy/base/configmap-common.yaml` for all options.
|
See `deploy/base/config.env` for all environment variables.
|
||||||
|
|
||||||
Key settings:
|
Key settings:
|
||||||
- `KAFKA_HOSTS` - Kafka bootstrap servers
|
- `KAFKA_HOSTS` - Kafka bootstrap servers
|
||||||
- `REDIS_HOST/PORT` - Redis for session state
|
- `REDIS_HOST/PORT` - Redis for session state
|
||||||
- `JWK_URL` - JWKS endpoint for JWT validation
|
- `JWK_URL` - JWKS endpoint for JWT validation
|
||||||
|
- `DOCS` - Path to docs directory (default: `/docs`)
|
||||||
- `LOG_LEVEL` - debug, info, warn, error
|
- `LOG_LEVEL` - debug, info, warn, error
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
"github.com/fiskerinc/cloud-services/pkg/utils/envtool"
|
"github.com/fiskerinc/cloud-services/pkg/utils/envtool"
|
||||||
)
|
)
|
||||||
@@ -12,6 +14,23 @@ func DocsHandler() http.Handler {
|
|||||||
if fp == "" {
|
if fp == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
fs := http.FileServer(http.Dir(fp))
|
|
||||||
return fs
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Get the requested path
|
||||||
|
reqPath := r.URL.Path
|
||||||
|
if reqPath == "" || reqPath == "/" {
|
||||||
|
reqPath = "/index.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build full file path
|
||||||
|
fullPath := path.Join(fp, reqPath)
|
||||||
|
|
||||||
|
// Check if it's a directory, serve index.html
|
||||||
|
info, err := os.Stat(fullPath)
|
||||||
|
if err == nil && info.IsDir() {
|
||||||
|
fullPath = path.Join(fullPath, "index.html")
|
||||||
|
}
|
||||||
|
|
||||||
|
http.ServeFile(w, r, fullPath)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user