Skip to content

Commit 758eddd

Browse files
mikemcdougallMike McDougall
andauthored
feat: replace legacy metadata with resource model (#250) (#254)
* Replace legacy metadata with resource model * Fix formatting for metadata resources * Make metadata JSON storage AOT-safe --------- Co-authored-by: Mike McDougall <[email protected]>
1 parent ee24346 commit 758eddd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3526
-3773
lines changed

.devcontainer/docker-compose.dev.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ services:
3737

3838
# PostgreSQL - Development database
3939
postgres:
40-
image: postgis/postgis:17-3.5-alpine
40+
image: postgis/postgis:17-3.6-alpine
41+
command: ["-c", "max_connections=200"]
4142
environment:
4243
POSTGRES_DB: honua_dev
4344
POSTGRES_USER: honua_user
@@ -191,4 +192,4 @@ volumes:
191192
loki_dev_data:
192193
honua-dev-nuget:
193194
honua-dev-cache:
194-
honua-dev-dotnet:
195+
honua-dev-dotnet:

Dockerfile.dev

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ RUN apt-get update && apt-get install -y \
1919
&& rm -rf /var/lib/apt/lists/*
2020

2121
# Install localstack AWS CLI wrapper for emulator tests
22-
RUN python3 -m pip install --no-cache-dir awscli-local
22+
RUN python3 -m pip install --no-cache-dir --break-system-packages awscli awscli-local
2323

2424
# Install development tools
2525
RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh && rm get-docker.sh
@@ -44,9 +44,15 @@ ENV PATH="$PATH:/root/.dotnet/tools"
4444
# Create workspace directory
4545
WORKDIR /workspace
4646

47-
# Create non-root user for development
48-
RUN groupadd --gid 1000 vscode \
49-
&& useradd --uid 1000 --gid 1000 -m vscode \
47+
# Create non-root user for development (idempotent for base images that already define gid 1000)
48+
RUN if ! getent group 1000 >/dev/null; then groupadd --gid 1000 vscode; fi \
49+
&& if ! id -u vscode >/dev/null 2>&1; then \
50+
if getent passwd 1000 >/dev/null; then \
51+
useradd --uid 1000 --gid 1000 --non-unique -m vscode; \
52+
else \
53+
useradd --uid 1000 --gid 1000 -m vscode; \
54+
fi; \
55+
fi \
5056
&& apt-get update \
5157
&& apt-get install -y sudo \
5258
&& echo vscode ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/vscode \

docs/API_EXAMPLES.md

Lines changed: 65 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -403,15 +403,15 @@ API key authentication is supported for CLI/server-to-server automation only.
403403
export HONUA_ADMIN_TOKEN="your-oidc-access-token"
404404

405405
# Use OIDC token for admin endpoints
406-
curl "http://localhost:8080/api/v1/admin/metadata/services" \
406+
curl "http://localhost:8080/api/v1/admin/version" \
407407
-H "Authorization: Bearer $HONUA_ADMIN_TOKEN"
408408
```
409409

410410
```bash
411411
# API key (automation only, not for browser UI)
412412
export HONUA_ADMIN_PASSWORD="your-secure-password"
413413

414-
curl "http://localhost:8080/api/v1/admin/metadata/services" \
414+
curl "http://localhost:8080/api/v1/admin/version" \
415415
-H "X-API-Key: $HONUA_ADMIN_PASSWORD"
416416
```
417417

@@ -429,136 +429,97 @@ curl "http://localhost:8080/api/v1/admin/connections/test/tables" \
429429
-H "X-API-Key: your-secure-password"
430430
```
431431

432-
#### Admin Metadata API v1 - Services
432+
#### Admin Metadata API v1 - Resource Model
433433

434434
```bash
435-
# List all services
436-
curl "http://localhost:8080/api/v1/admin/metadata/services" \
435+
# Server version + supported metadata API versions
436+
curl "http://localhost:8080/api/v1/admin/version" \
437437
-H "X-API-Key: your-secure-password"
438438

439-
# Get service details
440-
curl "http://localhost:8080/api/v1/admin/metadata/services/my-service" \
439+
curl "http://localhost:8080/api/v1/admin/capabilities" \
441440
-H "X-API-Key: your-secure-password"
442441

443-
# Create a new service
444-
curl -X POST "http://localhost:8080/api/v1/admin/metadata/services" \
445-
-H "X-API-Key: your-secure-password" \
446-
-H "Content-Type: application/json" \
447-
-d '{
448-
"name": "parcels",
449-
"description": "Land parcel data service",
450-
"spatialReferenceSrid": 4326,
451-
"maxRecordCount": 1000
452-
}'
453-
454-
# Update a service
455-
curl -X PUT "http://localhost:8080/api/v1/admin/metadata/services/parcels" \
456-
-H "X-API-Key: your-secure-password" \
457-
-H "Content-Type: application/json" \
458-
-d '{
459-
"description": "Updated parcel description",
460-
"maxRecordCount": 2000
461-
}'
462-
463-
# Delete a service
464-
curl -X DELETE "http://localhost:8080/api/v1/admin/metadata/services/parcels" \
465-
-H "X-API-Key: your-secure-password"
466-
467-
# Bind a layer to a service
468-
curl -X POST "http://localhost:8080/api/v1/admin/metadata/services/parcels/layers" \
469-
-H "X-API-Key: your-secure-password" \
470-
-H "Content-Type: application/json" \
471-
-d '{"layerId": 1}'
472-
473-
# Unbind a layer from a service
474-
curl -X DELETE "http://localhost:8080/api/v1/admin/metadata/services/parcels/layers/1" \
475-
-H "X-API-Key: your-secure-password"
476-
```
477-
478-
#### Admin Metadata API v1 - Layers
479-
480-
```bash
481-
# List all layers
482-
curl "http://localhost:8080/api/v1/admin/metadata/layers" \
483-
-H "X-API-Key: your-secure-password"
484-
485-
# Get layer details
486-
curl "http://localhost:8080/api/v1/admin/metadata/layers/1" \
442+
# List metadata resources (filter by kind/namespace)
443+
curl "http://localhost:8080/api/v1/admin/metadata/resources?kind=Layer&namespace=default" \
487444
-H "X-API-Key: your-secure-password"
488445

489-
# Create a layer from database table
490-
curl -X POST "http://localhost:8080/api/v1/admin/metadata/layers" \
446+
# Create a Layer metadata resource
447+
curl -X POST "http://localhost:8080/api/v1/admin/metadata/resources" \
491448
-H "X-API-Key: your-secure-password" \
492449
-H "Content-Type: application/json" \
493450
-d '{
494-
"tableName": "parcels",
495-
"schemaName": "public",
496-
"displayName": "Land Parcels",
497-
"description": "Property boundaries"
498-
}'
499-
500-
# Update a layer
501-
curl -X PUT "http://localhost:8080/api/v1/admin/metadata/layers/1" \
502-
-H "X-API-Key: your-secure-password" \
503-
-H "Content-Type: application/json" \
504-
-d '{
505-
"displayName": "Updated Layer Name",
506-
"minScale": 0,
507-
"maxScale": 100000,
508-
"defaultVisibility": true
451+
"apiVersion": "honua.io/v1alpha1",
452+
"kind": "Layer",
453+
"metadata": {
454+
"name": "parcels",
455+
"namespace": "default",
456+
"labels": { "env": "dev" }
457+
},
458+
"spec": {
459+
"tableName": "parcels",
460+
"schemaName": "public",
461+
"geometryType": "Polygon",
462+
"srid": 4326
463+
}
509464
}'
510465

511-
# Refresh layer metadata from database
512-
curl -X POST "http://localhost:8080/api/v1/admin/metadata/layers/1/refresh" \
513-
-H "X-API-Key: your-secure-password"
514-
515-
# Delete a layer
516-
curl -X DELETE "http://localhost:8080/api/v1/admin/metadata/layers/1" \
517-
-H "X-API-Key: your-secure-password"
518-
```
519-
520-
#### Admin Metadata API v1 - Relationships
521-
522-
```bash
523-
# List relationships for a layer
524-
curl "http://localhost:8080/api/v1/admin/metadata/layers/1/relationships" \
525-
-H "X-API-Key: your-secure-password"
466+
# Update a resource (If-Match required)
467+
etag=$(curl -sI "http://localhost:8080/api/v1/admin/metadata/resources/Layer/default/parcels" \
468+
-H "X-API-Key: your-secure-password" | awk '/ETag/ {print $2}' | tr -d '\r')
526469

527-
# Create a relationship
528-
curl -X POST "http://localhost:8080/api/v1/admin/metadata/layers/1/relationships" \
470+
curl -X PUT "http://localhost:8080/api/v1/admin/metadata/resources/Layer/default/parcels" \
529471
-H "X-API-Key: your-secure-password" \
472+
-H "If-Match: $etag" \
530473
-H "Content-Type: application/json" \
531474
-d '{
532-
"relatedLayerId": 2,
533-
"name": "parcel_owners",
534-
"relationshipType": "OneToMany",
535-
"originForeignKeyField": "parcel_id",
536-
"destinationForeignKeyField": "id"
475+
"apiVersion": "honua.io/v1alpha1",
476+
"kind": "Layer",
477+
"metadata": {
478+
"name": "parcels",
479+
"namespace": "default"
480+
},
481+
"spec": {
482+
"tableName": "parcels",
483+
"schemaName": "public",
484+
"geometryType": "Polygon",
485+
"srid": 4326,
486+
"description": "Updated parcel description"
487+
}
537488
}'
538489

539-
# Delete a relationship
540-
curl -X DELETE "http://localhost:8080/api/v1/admin/metadata/layers/1/relationships/1" \
541-
-H "X-API-Key: your-secure-password"
490+
# Delete a resource (If-Match required)
491+
curl -X DELETE "http://localhost:8080/api/v1/admin/metadata/resources/Layer/default/parcels" \
492+
-H "X-API-Key: your-secure-password" \
493+
-H "If-Match: $etag"
542494
```
543495

544-
#### Admin Metadata API v1 - Styles
496+
#### Admin Metadata API v1 - Manifest (GitOps)
545497

546498
```bash
547-
# Get layer style
548-
curl "http://localhost:8080/api/v1/admin/metadata/layers/1/style" \
499+
# Export a full manifest snapshot
500+
curl "http://localhost:8080/api/v1/admin/manifest" \
549501
-H "X-API-Key: your-secure-password"
550502

551-
# Update layer style
552-
curl -X PUT "http://localhost:8080/api/v1/admin/metadata/layers/1/style" \
503+
# Apply a manifest (supports dryRun/prune)
504+
curl -X POST "http://localhost:8080/api/v1/admin/manifest/apply" \
553505
-H "X-API-Key: your-secure-password" \
554506
-H "Content-Type: application/json" \
555507
-d '{
556-
"mapLibreStyle": {
557-
"layers": [{"id": "fill", "type": "fill", "paint": {"fill-color": "#088"}}]
558-
},
559-
"drawingInfo": {
560-
"renderer": {"type": "simple", "symbol": {"type": "esriSFS"}}
561-
}
508+
"dryRun": true,
509+
"prune": false,
510+
"resources": [
511+
{
512+
"apiVersion": "honua.io/v1alpha1",
513+
"kind": "Layer",
514+
"metadata": { "name": "parcels", "namespace": "default" },
515+
"spec": {
516+
"tableName": "parcels",
517+
"schemaName": "public",
518+
"geometryType": "Polygon",
519+
"srid": 4326
520+
}
521+
}
522+
]
562523
}'
563524
```
564525

0 commit comments

Comments
 (0)