Add GET /v1/space/mounts/resolve with local mount resolution tests
Add mount-aware v2 federation cursors with remote_space_id support
This commit is contained in:
parent
a870b188e9
commit
e54a9009a6
40
README.md
40
README.md
|
|
@ -82,6 +82,12 @@ string).
|
||||||
Push cursors are separate from pull cursors and live under
|
Push cursors are separate from pull cursors and live under
|
||||||
`fed/push_cursor/<peer>/head` (space scoped).
|
`fed/push_cursor/<peer>/head` (space scoped).
|
||||||
|
|
||||||
|
To avoid cursor collisions across multiple mounts to the same peer, pass
|
||||||
|
`remote_space_id=<space_id>` on cursor-aware endpoints. When provided, cursor
|
||||||
|
heads use `fed/cursor/<peer>/<remote_space_id>/head` and
|
||||||
|
`fed/push_cursor/<peer>/<remote_space_id>/head`. When omitted, the legacy v1
|
||||||
|
cursor names remain in effect for backward compatibility.
|
||||||
|
|
||||||
Read the current cursor for a peer:
|
Read the current cursor for a peer:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
@ -90,6 +96,14 @@ curl --unix-socket amduatd.sock \
|
||||||
-H 'X-Amduat-Space: demo'
|
-H 'X-Amduat-Space: demo'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Scoped to a specific remote space:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl --unix-socket amduatd.sock \
|
||||||
|
'http://localhost/v1/fed/cursor?peer=domain-2&remote_space_id=beta' \
|
||||||
|
-H 'X-Amduat-Space: demo'
|
||||||
|
```
|
||||||
|
|
||||||
Write a cursor update (CAS-safe; include `expected_ref` to enforce; omitting it
|
Write a cursor update (CAS-safe; include `expected_ref` to enforce; omitting it
|
||||||
only succeeds when the cursor is absent):
|
only succeeds when the cursor is absent):
|
||||||
|
|
||||||
|
|
@ -119,6 +133,7 @@ curl --unix-socket amduatd.sock \
|
||||||
The plan does not write artifacts, records, or cursors. It is deterministic and
|
The plan does not write artifacts, records, or cursors. It is deterministic and
|
||||||
returns only identifiers (logseq/ref), plus the next cursor candidate if the
|
returns only identifiers (logseq/ref), plus the next cursor candidate if the
|
||||||
plan were applied successfully.
|
plan were applied successfully.
|
||||||
|
Append `&remote_space_id=<space_id>` to use mount-specific cursor keying.
|
||||||
|
|
||||||
Apply a bounded batch of remote records (advances the cursor only after
|
Apply a bounded batch of remote records (advances the cursor only after
|
||||||
success):
|
success):
|
||||||
|
|
@ -131,6 +146,7 @@ curl --unix-socket amduatd.sock -X POST \
|
||||||
|
|
||||||
`/v1/fed/pull` requires the index backend and will not advance the cursor on
|
`/v1/fed/pull` requires the index backend and will not advance the cursor on
|
||||||
partial failure.
|
partial failure.
|
||||||
|
Use `remote_space_id=<space_id>` to scope the cursor to a mount.
|
||||||
|
|
||||||
### Federation push plan (sender dry run)
|
### Federation push plan (sender dry run)
|
||||||
|
|
||||||
|
|
@ -145,6 +161,7 @@ curl --unix-socket amduatd.sock \
|
||||||
|
|
||||||
`/v1/fed/push/plan` requires the index backend and uses a push cursor separate
|
`/v1/fed/push/plan` requires the index backend and uses a push cursor separate
|
||||||
from the pull cursor.
|
from the pull cursor.
|
||||||
|
Append `&remote_space_id=<space_id>` to use mount-specific cursor keying.
|
||||||
|
|
||||||
### Federation push (sender apply)
|
### Federation push (sender apply)
|
||||||
|
|
||||||
|
|
@ -159,6 +176,7 @@ curl --unix-socket amduatd.sock -X POST \
|
||||||
|
|
||||||
`/v1/fed/push` uses `/v1/fed/ingest` on the peer and only advances the push
|
`/v1/fed/push` uses `/v1/fed/ingest` on the peer and only advances the push
|
||||||
cursor after the batch completes. It requires the index backend.
|
cursor after the batch completes. It requires the index backend.
|
||||||
|
Use `remote_space_id=<space_id>` to scope the cursor to a mount.
|
||||||
|
|
||||||
### Federation sync until caught up
|
### Federation sync until caught up
|
||||||
|
|
||||||
|
|
@ -245,6 +263,10 @@ curl --unix-socket amduatd.sock \
|
||||||
-H 'X-Amduat-Space: demo'
|
-H 'X-Amduat-Space: demo'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The response groups cursor status per peer and per remote space id:
|
||||||
|
`peers:[{peer_key, remotes:[{remote_space_id, pull_cursor, push_cursor}]}]`.
|
||||||
|
`remote_space_id` is `null` for legacy v1 cursor heads.
|
||||||
|
|
||||||
## Space manifest
|
## Space manifest
|
||||||
|
|
||||||
`/v1/space/manifest` returns the space manifest rooted at the deterministic
|
`/v1/space/manifest` returns the space manifest rooted at the deterministic
|
||||||
|
|
@ -289,6 +311,8 @@ space manifest mounts with their local pull cursor state. It performs no
|
||||||
network I/O and does not mutate storage. Track mounts indicate intent; syncing
|
network I/O and does not mutate storage. Track mounts indicate intent; syncing
|
||||||
remains a separate concern.
|
remains a separate concern.
|
||||||
If no manifest head is present, the endpoint returns a 404.
|
If no manifest head is present, the endpoint returns a 404.
|
||||||
|
Track mounts report `local_tracking.cursor_namespace` (`v2` when using
|
||||||
|
`remote_space_id`-keyed cursors).
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl --unix-socket amduatd.sock \
|
curl --unix-socket amduatd.sock \
|
||||||
|
|
@ -458,14 +482,18 @@ When the daemon uses the `fs` store backend, index-only checks are reported as
|
||||||
- `GET /v1/contract` → contract bytes (JSON) (+ `X-Amduat-Contract-Ref` header)
|
- `GET /v1/contract` → contract bytes (JSON) (+ `X-Amduat-Contract-Ref` header)
|
||||||
- `GET /v1/contract?format=ref` → `{ref}`
|
- `GET /v1/contract?format=ref` → `{ref}`
|
||||||
- `GET /v1/space/doctor` → deterministic space health checks
|
- `GET /v1/space/doctor` → deterministic space health checks
|
||||||
|
- `GET /v1/space/manifest` → `{effective_space, manifest_ref, manifest}`
|
||||||
|
- `PUT /v1/space/manifest` → `{effective_space, manifest_ref, updated, previous_ref?, manifest}`
|
||||||
|
- `GET /v1/space/mounts/resolve` → `{effective_space, manifest_ref, mounts}`
|
||||||
|
- `GET /v1/space/sync/status` → `{effective_space, store_backend, federation, peers}`
|
||||||
- `GET /v1/ui` → browser UI for authoring/running programs
|
- `GET /v1/ui` → browser UI for authoring/running programs
|
||||||
- `GET /v1/fed/records?domain_id=...&from_logseq=...&limit=...` → `{domain_id, snapshot_id, log_prefix, next_logseq, records[]}` (published artifacts + tombstones + PER + TGK edges)
|
- `GET /v1/fed/records?domain_id=...&from_logseq=...&limit=...` → `{domain_id, snapshot_id, log_prefix, next_logseq, records[]}` (published artifacts + tombstones + PER + TGK edges)
|
||||||
- `GET /v1/fed/cursor?peer=...` → `{peer_key, space_id, last_logseq, last_record_hash, ref}`
|
- `GET /v1/fed/cursor?peer=...&remote_space_id=...` → `{peer_key, space_id, last_logseq, last_record_hash, ref}` (`remote_space_id` optional)
|
||||||
- `POST /v1/fed/cursor?peer=...` → `{ref}` (CAS update; `expected_ref` in body)
|
- `POST /v1/fed/cursor?peer=...&remote_space_id=...` → `{ref}` (CAS update; `expected_ref` in body; `remote_space_id` optional)
|
||||||
- `GET /v1/fed/pull/plan?peer=...&limit=...` → `{peer, effective_space, cursor, remote_scan, records, next_cursor_candidate, ...}`
|
- `GET /v1/fed/pull/plan?peer=...&limit=...&remote_space_id=...` → `{peer, effective_space, cursor, remote_scan, records, next_cursor_candidate, ...}`
|
||||||
- `GET /v1/fed/push/plan?peer=...&limit=...` → `{peer, domain_id, effective_space, cursor, scan, records, required_artifacts, next_cursor_candidate}`
|
- `GET /v1/fed/push/plan?peer=...&limit=...&remote_space_id=...` → `{peer, domain_id, effective_space, cursor, scan, records, required_artifacts, next_cursor_candidate}`
|
||||||
- `POST /v1/fed/pull?peer=...&limit=...` → `{peer, effective_space, cursor_before, plan_summary, applied, cursor_after, errors}`
|
- `POST /v1/fed/pull?peer=...&limit=...&remote_space_id=...` → `{peer, effective_space, cursor_before, plan_summary, applied, cursor_after, errors}`
|
||||||
- `POST /v1/fed/push?peer=...&limit=...` → `{peer, domain_id, effective_space, cursor_before, plan_summary, sent, cursor_after, errors}`
|
- `POST /v1/fed/push?peer=...&limit=...&remote_space_id=...` → `{peer, domain_id, effective_space, cursor_before, plan_summary, sent, cursor_after, errors}`
|
||||||
- `GET /v1/fed/artifacts/{ref}` → raw bytes for federation resolve
|
- `GET /v1/fed/artifacts/{ref}` → raw bytes for federation resolve
|
||||||
- `GET /v1/fed/status` → `{status, domain_id, registry_ref, last_tick_ms}`
|
- `GET /v1/fed/status` → `{status, domain_id, registry_ref, last_tick_ms}`
|
||||||
- `POST /v1/artifacts`
|
- `POST /v1/artifacts`
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,16 @@
|
||||||
{"method": "POST", "path": "/v1/capabilities"},
|
{"method": "POST", "path": "/v1/capabilities"},
|
||||||
{"method": "GET", "path": "/v1/cap/resolve"},
|
{"method": "GET", "path": "/v1/cap/resolve"},
|
||||||
{"method": "GET", "path": "/v1/fed/records"},
|
{"method": "GET", "path": "/v1/fed/records"},
|
||||||
|
{"method": "GET", "path": "/v1/fed/cursor"},
|
||||||
|
{"method": "POST", "path": "/v1/fed/cursor"},
|
||||||
|
{"method": "GET", "path": "/v1/fed/pull/plan"},
|
||||||
|
{"method": "GET", "path": "/v1/fed/push/plan"},
|
||||||
|
{"method": "POST", "path": "/v1/fed/pull"},
|
||||||
{"method": "GET", "path": "/v1/fed/artifacts/{ref}"},
|
{"method": "GET", "path": "/v1/fed/artifacts/{ref}"},
|
||||||
{"method": "GET", "path": "/v1/fed/status"},
|
{"method": "GET", "path": "/v1/fed/status"},
|
||||||
|
{"method": "POST", "path": "/v1/fed/ingest"},
|
||||||
{"method": "POST", "path": "/v1/fed/pull/until"},
|
{"method": "POST", "path": "/v1/fed/pull/until"},
|
||||||
|
{"method": "POST", "path": "/v1/fed/push"},
|
||||||
{"method": "POST", "path": "/v1/fed/push/until"},
|
{"method": "POST", "path": "/v1/fed/push/until"},
|
||||||
{"method": "POST", "path": "/v1/concepts"},
|
{"method": "POST", "path": "/v1/concepts"},
|
||||||
{"method": "GET", "path": "/v1/concepts"},
|
{"method": "GET", "path": "/v1/concepts"},
|
||||||
|
|
@ -241,13 +248,87 @@
|
||||||
"manifest": {"$ref": "#/schemas/space_manifest"}
|
"manifest": {"$ref": "#/schemas/space_manifest"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"space_mounts_pull_cursor": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["present"],
|
||||||
|
"properties": {
|
||||||
|
"present": {"type": "boolean"},
|
||||||
|
"last_logseq": {"type": "integer"},
|
||||||
|
"ref": {"type": "string"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"space_mounts_local_tracking": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["cursor_namespace", "cursor_scope", "remote_space_id", "pull_cursor"],
|
||||||
|
"properties": {
|
||||||
|
"cursor_namespace": {"type": "string"},
|
||||||
|
"cursor_scope": {"type": "string"},
|
||||||
|
"remote_space_id": {"type": "string"},
|
||||||
|
"pull_cursor": {"$ref": "#/schemas/space_mounts_pull_cursor"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"space_mounts_resolved_mount": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name", "peer_key", "space_id", "mode", "local_tracking"],
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"peer_key": {"type": "string"},
|
||||||
|
"space_id": {"type": "string"},
|
||||||
|
"mode": {"type": "string"},
|
||||||
|
"pinned_root_ref": {"type": "string"},
|
||||||
|
"local_tracking": {"$ref": "#/schemas/space_mounts_local_tracking"}
|
||||||
|
}
|
||||||
|
},
|
||||||
"space_mounts_resolve_response": {
|
"space_mounts_resolve_response": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": ["effective_space", "manifest_ref", "mounts"],
|
"required": ["effective_space", "manifest_ref", "mounts"],
|
||||||
"properties": {
|
"properties": {
|
||||||
"effective_space": {"type": "object"},
|
"effective_space": {"type": "object"},
|
||||||
"manifest_ref": {"type": "string"},
|
"manifest_ref": {"type": "string"},
|
||||||
"mounts": {"type": "array"}
|
"mounts": {"type": "array", "items": {"$ref": "#/schemas/space_mounts_resolved_mount"}}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"space_sync_status_cursor": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["present"],
|
||||||
|
"properties": {
|
||||||
|
"present": {"type": "boolean"},
|
||||||
|
"last_logseq": {"type": "integer"},
|
||||||
|
"ref": {"type": "string"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"space_sync_status_remote": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["remote_space_id", "pull_cursor", "push_cursor"],
|
||||||
|
"properties": {
|
||||||
|
"remote_space_id": {"type": ["string", "null"]},
|
||||||
|
"pull_cursor": {"$ref": "#/schemas/space_sync_status_cursor"},
|
||||||
|
"push_cursor": {"$ref": "#/schemas/space_sync_status_cursor"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"space_sync_status_peer": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["peer_key", "remotes"],
|
||||||
|
"properties": {
|
||||||
|
"peer_key": {"type": "string"},
|
||||||
|
"remotes": {"type": "array", "items": {"$ref": "#/schemas/space_sync_status_remote"}}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"space_sync_status_response": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["effective_space", "store_backend", "federation", "peers"],
|
||||||
|
"properties": {
|
||||||
|
"effective_space": {"type": "object"},
|
||||||
|
"store_backend": {"type": "string"},
|
||||||
|
"federation": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["enabled", "transport"],
|
||||||
|
"properties": {
|
||||||
|
"enabled": {"type": "boolean"},
|
||||||
|
"transport": {"type": "string"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"peers": {"type": "array", "items": {"$ref": "#/schemas/space_sync_status_peer"}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
656
src/amduatd.c
656
src/amduatd.c
|
|
@ -140,13 +140,12 @@ static const char k_amduatd_contract_v1_json[] =
|
||||||
"{\"method\":\"GET\",\"path\":\"/v1/fed/pull/plan\"},"
|
"{\"method\":\"GET\",\"path\":\"/v1/fed/pull/plan\"},"
|
||||||
"{\"method\":\"GET\",\"path\":\"/v1/fed/push/plan\"},"
|
"{\"method\":\"GET\",\"path\":\"/v1/fed/push/plan\"},"
|
||||||
"{\"method\":\"POST\",\"path\":\"/v1/fed/pull\"},"
|
"{\"method\":\"POST\",\"path\":\"/v1/fed/pull\"},"
|
||||||
|
"{\"method\":\"GET\",\"path\":\"/v1/fed/artifacts/{ref}\"},"
|
||||||
|
"{\"method\":\"GET\",\"path\":\"/v1/fed/status\"},"
|
||||||
|
"{\"method\":\"POST\",\"path\":\"/v1/fed/ingest\"},"
|
||||||
"{\"method\":\"POST\",\"path\":\"/v1/fed/pull/until\"},"
|
"{\"method\":\"POST\",\"path\":\"/v1/fed/pull/until\"},"
|
||||||
"{\"method\":\"POST\",\"path\":\"/v1/fed/push\"},"
|
"{\"method\":\"POST\",\"path\":\"/v1/fed/push\"},"
|
||||||
"{\"method\":\"POST\",\"path\":\"/v1/fed/push/until\"},"
|
"{\"method\":\"POST\",\"path\":\"/v1/fed/push/until\"},"
|
||||||
"{\"method\":\"POST\",\"path\":\"/v1/fed/pull\"},"
|
|
||||||
"{\"method\":\"POST\",\"path\":\"/v1/fed/ingest\"},"
|
|
||||||
"{\"method\":\"GET\",\"path\":\"/v1/fed/artifacts/{ref}\"},"
|
|
||||||
"{\"method\":\"GET\",\"path\":\"/v1/fed/status\"},"
|
|
||||||
"{\"method\":\"POST\",\"path\":\"/v1/concepts\"},"
|
"{\"method\":\"POST\",\"path\":\"/v1/concepts\"},"
|
||||||
"{\"method\":\"GET\",\"path\":\"/v1/concepts\"},"
|
"{\"method\":\"GET\",\"path\":\"/v1/concepts\"},"
|
||||||
"{\"method\":\"GET\",\"path\":\"/v1/concepts/{name}\"},"
|
"{\"method\":\"GET\",\"path\":\"/v1/concepts/{name}\"},"
|
||||||
|
|
@ -335,13 +334,87 @@ static const char k_amduatd_contract_v1_json[] =
|
||||||
"\"manifest\":{\"$ref\":\"#/schemas/space_manifest\"}"
|
"\"manifest\":{\"$ref\":\"#/schemas/space_manifest\"}"
|
||||||
"}"
|
"}"
|
||||||
"},"
|
"},"
|
||||||
|
"\"space_mounts_pull_cursor\":{"
|
||||||
|
"\"type\":\"object\","
|
||||||
|
"\"required\":[\"present\"],"
|
||||||
|
"\"properties\":{"
|
||||||
|
"\"present\":{\"type\":\"boolean\"},"
|
||||||
|
"\"last_logseq\":{\"type\":\"integer\"},"
|
||||||
|
"\"ref\":{\"type\":\"string\"}"
|
||||||
|
"}"
|
||||||
|
"},"
|
||||||
|
"\"space_mounts_local_tracking\":{"
|
||||||
|
"\"type\":\"object\","
|
||||||
|
"\"required\":[\"cursor_namespace\",\"cursor_scope\",\"remote_space_id\",\"pull_cursor\"],"
|
||||||
|
"\"properties\":{"
|
||||||
|
"\"cursor_namespace\":{\"type\":\"string\"},"
|
||||||
|
"\"cursor_scope\":{\"type\":\"string\"},"
|
||||||
|
"\"remote_space_id\":{\"type\":\"string\"},"
|
||||||
|
"\"pull_cursor\":{\"$ref\":\"#/schemas/space_mounts_pull_cursor\"}"
|
||||||
|
"}"
|
||||||
|
"},"
|
||||||
|
"\"space_mounts_resolved_mount\":{"
|
||||||
|
"\"type\":\"object\","
|
||||||
|
"\"required\":[\"name\",\"peer_key\",\"space_id\",\"mode\",\"local_tracking\"],"
|
||||||
|
"\"properties\":{"
|
||||||
|
"\"name\":{\"type\":\"string\"},"
|
||||||
|
"\"peer_key\":{\"type\":\"string\"},"
|
||||||
|
"\"space_id\":{\"type\":\"string\"},"
|
||||||
|
"\"mode\":{\"type\":\"string\"},"
|
||||||
|
"\"pinned_root_ref\":{\"type\":\"string\"},"
|
||||||
|
"\"local_tracking\":{\"$ref\":\"#/schemas/space_mounts_local_tracking\"}"
|
||||||
|
"}"
|
||||||
|
"},"
|
||||||
"\"space_mounts_resolve_response\":{"
|
"\"space_mounts_resolve_response\":{"
|
||||||
"\"type\":\"object\","
|
"\"type\":\"object\","
|
||||||
"\"required\":[\"effective_space\",\"manifest_ref\",\"mounts\"],"
|
"\"required\":[\"effective_space\",\"manifest_ref\",\"mounts\"],"
|
||||||
"\"properties\":{"
|
"\"properties\":{"
|
||||||
"\"effective_space\":{\"type\":\"object\"},"
|
"\"effective_space\":{\"type\":\"object\"},"
|
||||||
"\"manifest_ref\":{\"type\":\"string\"},"
|
"\"manifest_ref\":{\"type\":\"string\"},"
|
||||||
"\"mounts\":{\"type\":\"array\"}"
|
"\"mounts\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/schemas/space_mounts_resolved_mount\"}}"
|
||||||
|
"}"
|
||||||
|
"},"
|
||||||
|
"\"space_sync_status_cursor\":{"
|
||||||
|
"\"type\":\"object\","
|
||||||
|
"\"required\":[\"present\"],"
|
||||||
|
"\"properties\":{"
|
||||||
|
"\"present\":{\"type\":\"boolean\"},"
|
||||||
|
"\"last_logseq\":{\"type\":\"integer\"},"
|
||||||
|
"\"ref\":{\"type\":\"string\"}"
|
||||||
|
"}"
|
||||||
|
"},"
|
||||||
|
"\"space_sync_status_remote\":{"
|
||||||
|
"\"type\":\"object\","
|
||||||
|
"\"required\":[\"remote_space_id\",\"pull_cursor\",\"push_cursor\"],"
|
||||||
|
"\"properties\":{"
|
||||||
|
"\"remote_space_id\":{\"type\":[\"string\",\"null\"]},"
|
||||||
|
"\"pull_cursor\":{\"$ref\":\"#/schemas/space_sync_status_cursor\"},"
|
||||||
|
"\"push_cursor\":{\"$ref\":\"#/schemas/space_sync_status_cursor\"}"
|
||||||
|
"}"
|
||||||
|
"},"
|
||||||
|
"\"space_sync_status_peer\":{"
|
||||||
|
"\"type\":\"object\","
|
||||||
|
"\"required\":[\"peer_key\",\"remotes\"],"
|
||||||
|
"\"properties\":{"
|
||||||
|
"\"peer_key\":{\"type\":\"string\"},"
|
||||||
|
"\"remotes\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/schemas/space_sync_status_remote\"}}"
|
||||||
|
"}"
|
||||||
|
"},"
|
||||||
|
"\"space_sync_status_response\":{"
|
||||||
|
"\"type\":\"object\","
|
||||||
|
"\"required\":[\"effective_space\",\"store_backend\",\"federation\",\"peers\"],"
|
||||||
|
"\"properties\":{"
|
||||||
|
"\"effective_space\":{\"type\":\"object\"},"
|
||||||
|
"\"store_backend\":{\"type\":\"string\"},"
|
||||||
|
"\"federation\":{"
|
||||||
|
"\"type\":\"object\","
|
||||||
|
"\"required\":[\"enabled\",\"transport\"],"
|
||||||
|
"\"properties\":{"
|
||||||
|
"\"enabled\":{\"type\":\"boolean\"},"
|
||||||
|
"\"transport\":{\"type\":\"string\"}"
|
||||||
|
"}"
|
||||||
|
"},"
|
||||||
|
"\"peers\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/schemas/space_sync_status_peer\"}}"
|
||||||
"}"
|
"}"
|
||||||
"}"
|
"}"
|
||||||
"}"
|
"}"
|
||||||
|
|
@ -743,6 +816,39 @@ static bool amduatd_trim_header_value(const char *value,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool amduatd_get_remote_space_id(const amduatd_http_req_t *req,
|
||||||
|
char *buf,
|
||||||
|
size_t cap,
|
||||||
|
const char **out_remote,
|
||||||
|
const char **out_error) {
|
||||||
|
const char *remote = NULL;
|
||||||
|
if (out_remote != NULL) {
|
||||||
|
*out_remote = NULL;
|
||||||
|
}
|
||||||
|
if (out_error != NULL) {
|
||||||
|
*out_error = NULL;
|
||||||
|
}
|
||||||
|
if (req == NULL || buf == NULL || cap == 0u || out_remote == NULL) {
|
||||||
|
if (out_error != NULL) {
|
||||||
|
*out_error = "invalid remote_space_id";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (amduatd_query_param(req->path, "remote_space_id", buf, cap) == NULL ||
|
||||||
|
buf[0] == '\0') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!amduatd_space_space_id_is_valid(buf)) {
|
||||||
|
if (out_error != NULL) {
|
||||||
|
*out_error = "invalid remote_space_id";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
remote = buf;
|
||||||
|
*out_remote = remote;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool amduatd_parse_type_tag_hex(const char *text,
|
static bool amduatd_parse_type_tag_hex(const char *text,
|
||||||
bool *out_has_type_tag,
|
bool *out_has_type_tag,
|
||||||
amduat_type_tag_t *out_type_tag) {
|
amduat_type_tag_t *out_type_tag) {
|
||||||
|
|
@ -1661,12 +1767,111 @@ manifest_put_cleanup:
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *peer_key;
|
||||||
|
char *remote_space_id;
|
||||||
|
} amduatd_cursor_pair_t;
|
||||||
|
|
||||||
|
static void amduatd_cursor_pair_free(amduatd_cursor_pair_t *pair) {
|
||||||
|
if (pair == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free(pair->peer_key);
|
||||||
|
free(pair->remote_space_id);
|
||||||
|
pair->peer_key = NULL;
|
||||||
|
pair->remote_space_id = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amduatd_cursor_pair_cmp(const void *a, const void *b) {
|
||||||
|
const amduatd_cursor_pair_t *lhs = (const amduatd_cursor_pair_t *)a;
|
||||||
|
const amduatd_cursor_pair_t *rhs = (const amduatd_cursor_pair_t *)b;
|
||||||
|
const char *lhs_peer = lhs != NULL && lhs->peer_key != NULL ? lhs->peer_key
|
||||||
|
: "";
|
||||||
|
const char *rhs_peer = rhs != NULL && rhs->peer_key != NULL ? rhs->peer_key
|
||||||
|
: "";
|
||||||
|
const char *lhs_remote =
|
||||||
|
lhs != NULL && lhs->remote_space_id != NULL ? lhs->remote_space_id : "";
|
||||||
|
const char *rhs_remote =
|
||||||
|
rhs != NULL && rhs->remote_space_id != NULL ? rhs->remote_space_id : "";
|
||||||
|
int cmp = strcmp(lhs_peer, rhs_peer);
|
||||||
|
if (cmp != 0) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
return strcmp(lhs_remote, rhs_remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduatd_cursor_pair_add(amduatd_cursor_pair_t **pairs,
|
||||||
|
size_t *len,
|
||||||
|
size_t *cap,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id) {
|
||||||
|
size_t next_len;
|
||||||
|
amduatd_cursor_pair_t *next;
|
||||||
|
|
||||||
|
if (pairs == NULL || len == NULL || cap == NULL ||
|
||||||
|
peer_key == NULL || peer_key[0] == '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (size_t i = 0u; i < *len; ++i) {
|
||||||
|
const char *cur_peer = (*pairs)[i].peer_key;
|
||||||
|
const char *cur_remote = (*pairs)[i].remote_space_id;
|
||||||
|
const char *remote = remote_space_id != NULL ? remote_space_id : "";
|
||||||
|
if (cur_peer != NULL && strcmp(cur_peer, peer_key) == 0) {
|
||||||
|
if ((cur_remote == NULL || cur_remote[0] == '\0') && remote[0] == '\0') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (cur_remote != NULL && strcmp(cur_remote, remote) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*len == *cap) {
|
||||||
|
size_t next_cap = *cap != 0u ? *cap * 2u : 8u;
|
||||||
|
next = (amduatd_cursor_pair_t *)realloc(*pairs,
|
||||||
|
next_cap * sizeof(*next));
|
||||||
|
if (next == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*pairs = next;
|
||||||
|
*cap = next_cap;
|
||||||
|
}
|
||||||
|
next_len = *len + 1u;
|
||||||
|
(*pairs)[*len].peer_key = strdup(peer_key);
|
||||||
|
if ((*pairs)[*len].peer_key == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (remote_space_id != NULL && remote_space_id[0] != '\0') {
|
||||||
|
(*pairs)[*len].remote_space_id = strdup(remote_space_id);
|
||||||
|
if ((*pairs)[*len].remote_space_id == NULL) {
|
||||||
|
free((*pairs)[*len].peer_key);
|
||||||
|
(*pairs)[*len].peer_key = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*pairs)[*len].remote_space_id = NULL;
|
||||||
|
}
|
||||||
|
*len = next_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduatd_cursor_pairs_free(amduatd_cursor_pair_t *pairs,
|
||||||
|
size_t len) {
|
||||||
|
if (pairs == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (size_t i = 0u; i < len; ++i) {
|
||||||
|
amduatd_cursor_pair_free(&pairs[i]);
|
||||||
|
}
|
||||||
|
free(pairs);
|
||||||
|
}
|
||||||
|
|
||||||
static bool amduatd_sync_status_append_cursor(
|
static bool amduatd_sync_status_append_cursor(
|
||||||
amduatd_strbuf_t *b,
|
amduatd_strbuf_t *b,
|
||||||
amduat_asl_store_t *store,
|
amduat_asl_store_t *store,
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
bool push) {
|
bool push) {
|
||||||
amduatd_fed_cursor_record_t cursor;
|
amduatd_fed_cursor_record_t cursor;
|
||||||
amduat_reference_t ref;
|
amduat_reference_t ref;
|
||||||
|
|
@ -1679,18 +1884,20 @@ static bool amduatd_sync_status_append_cursor(
|
||||||
ref = amduat_reference(0u, amduat_octets(NULL, 0u));
|
ref = amduat_reference(0u, amduat_octets(NULL, 0u));
|
||||||
|
|
||||||
status = push
|
status = push
|
||||||
? amduatd_fed_push_cursor_get(store,
|
? amduatd_fed_push_cursor_get_remote(store,
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
&cursor,
|
remote_space_id,
|
||||||
&ref)
|
&cursor,
|
||||||
: amduatd_fed_cursor_get(store,
|
&ref)
|
||||||
pointer_store,
|
: amduatd_fed_cursor_get_remote(store,
|
||||||
effective_space,
|
pointer_store,
|
||||||
peer_key,
|
effective_space,
|
||||||
&cursor,
|
peer_key,
|
||||||
&ref);
|
remote_space_id,
|
||||||
|
&cursor,
|
||||||
|
&ref);
|
||||||
|
|
||||||
if (status == AMDUATD_FED_CURSOR_OK) {
|
if (status == AMDUATD_FED_CURSOR_OK) {
|
||||||
present = true;
|
present = true;
|
||||||
|
|
@ -1781,11 +1988,18 @@ static bool amduatd_handle_get_space_sync_status(
|
||||||
const char *root_path,
|
const char *root_path,
|
||||||
amduatd_store_backend_t store_backend) {
|
amduatd_store_backend_t store_backend) {
|
||||||
amduat_asl_pointer_store_t pointer_store;
|
amduat_asl_pointer_store_t pointer_store;
|
||||||
amduatd_space_roots_list_t peers;
|
amduatd_space_roots_list_t pull_heads;
|
||||||
|
amduatd_space_roots_list_t push_heads;
|
||||||
amduatd_strbuf_t b;
|
amduatd_strbuf_t b;
|
||||||
|
amduatd_cursor_pair_t *pairs = NULL;
|
||||||
|
size_t pair_len = 0u;
|
||||||
|
size_t pair_cap = 0u;
|
||||||
|
amduat_octets_t pull_prefix = amduat_octets(NULL, 0u);
|
||||||
|
amduat_octets_t push_prefix = amduat_octets(NULL, 0u);
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
memset(&peers, 0, sizeof(peers));
|
memset(&pull_heads, 0, sizeof(pull_heads));
|
||||||
|
memset(&push_heads, 0, sizeof(push_heads));
|
||||||
memset(&b, 0, sizeof(b));
|
memset(&b, 0, sizeof(b));
|
||||||
|
|
||||||
if (store == NULL || req == NULL || dcfg == NULL || fed_cfg == NULL ||
|
if (store == NULL || req == NULL || dcfg == NULL || fed_cfg == NULL ||
|
||||||
|
|
@ -1810,12 +2024,66 @@ static bool amduatd_handle_get_space_sync_status(
|
||||||
return amduatd_send_json_error(fd, 500, "Internal Server Error",
|
return amduatd_send_json_error(fd, 500, "Internal Server Error",
|
||||||
"pointer store error");
|
"pointer store error");
|
||||||
}
|
}
|
||||||
if (!amduatd_space_roots_list_cursor_peers(root_path,
|
if (!amduatd_space_scope_name(req->effective_space,
|
||||||
req->effective_space,
|
"fed/cursor",
|
||||||
&peers)) {
|
&pull_prefix) ||
|
||||||
|
!amduatd_space_scope_name(req->effective_space,
|
||||||
|
"fed/push_cursor",
|
||||||
|
&push_prefix)) {
|
||||||
return amduatd_send_json_error(fd, 500, "Internal Server Error",
|
return amduatd_send_json_error(fd, 500, "Internal Server Error",
|
||||||
"cursor scan failed");
|
"cursor scan failed");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_space_roots_list_cursor_heads(root_path,
|
||||||
|
req->effective_space,
|
||||||
|
false,
|
||||||
|
&pull_heads) ||
|
||||||
|
!amduatd_space_roots_list_cursor_heads(root_path,
|
||||||
|
req->effective_space,
|
||||||
|
true,
|
||||||
|
&push_heads)) {
|
||||||
|
amduat_octets_free(&pull_prefix);
|
||||||
|
amduat_octets_free(&push_prefix);
|
||||||
|
return amduatd_send_json_error(fd, 500, "Internal Server Error",
|
||||||
|
"cursor scan failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0u; i < pull_heads.len; ++i) {
|
||||||
|
char *peer = NULL;
|
||||||
|
char *remote = NULL;
|
||||||
|
if (amduatd_space_roots_cursor_parse((const char *)pull_prefix.data,
|
||||||
|
pull_heads.names[i],
|
||||||
|
&peer,
|
||||||
|
&remote)) {
|
||||||
|
if (!amduatd_cursor_pair_add(&pairs, &pair_len, &pair_cap,
|
||||||
|
peer, remote)) {
|
||||||
|
free(peer);
|
||||||
|
free(remote);
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
free(peer);
|
||||||
|
free(remote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0u; i < push_heads.len; ++i) {
|
||||||
|
char *peer = NULL;
|
||||||
|
char *remote = NULL;
|
||||||
|
if (amduatd_space_roots_cursor_parse((const char *)push_prefix.data,
|
||||||
|
push_heads.names[i],
|
||||||
|
&peer,
|
||||||
|
&remote)) {
|
||||||
|
if (!amduatd_cursor_pair_add(&pairs, &pair_len, &pair_cap,
|
||||||
|
peer, remote)) {
|
||||||
|
free(peer);
|
||||||
|
free(remote);
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
free(peer);
|
||||||
|
free(remote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pair_len > 1u) {
|
||||||
|
qsort(pairs, pair_len, sizeof(*pairs), amduatd_cursor_pair_cmp);
|
||||||
|
}
|
||||||
|
|
||||||
if (!amduatd_strbuf_append_cstr(&b, "{\"effective_space\":{")) {
|
if (!amduatd_strbuf_append_cstr(&b, "{\"effective_space\":{")) {
|
||||||
goto sync_cleanup;
|
goto sync_cleanup;
|
||||||
|
|
@ -1849,39 +2117,91 @@ static bool amduatd_handle_get_space_sync_status(
|
||||||
goto sync_cleanup;
|
goto sync_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0u; i < peers.len; ++i) {
|
{
|
||||||
const char *peer_key = peers.names[i];
|
const char *current_peer = NULL;
|
||||||
if (i != 0u) {
|
bool first_peer = true;
|
||||||
if (!amduatd_strbuf_append_char(&b, ',')) {
|
bool first_remote = true;
|
||||||
|
|
||||||
|
for (size_t i = 0u; i < pair_len; ++i) {
|
||||||
|
const char *peer_key = pairs[i].peer_key;
|
||||||
|
const char *remote_space_id = pairs[i].remote_space_id;
|
||||||
|
if (peer_key == NULL || peer_key[0] == '\0') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (current_peer == NULL || strcmp(current_peer, peer_key) != 0) {
|
||||||
|
if (!first_peer) {
|
||||||
|
if (!amduatd_strbuf_append_cstr(&b, "]}")) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!first_peer) {
|
||||||
|
if (!amduatd_strbuf_append_char(&b, ',')) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduatd_strbuf_append_cstr(&b, "{\"peer_key\":\"") ||
|
||||||
|
!amduatd_strbuf_append_cstr(&b, peer_key) ||
|
||||||
|
!amduatd_strbuf_append_cstr(&b, "\",\"remotes\":[")) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
current_peer = peer_key;
|
||||||
|
first_peer = false;
|
||||||
|
first_remote = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first_remote) {
|
||||||
|
if (!amduatd_strbuf_append_char(&b, ',')) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduatd_strbuf_append_cstr(&b, "{\"remote_space_id\":")) {
|
||||||
goto sync_cleanup;
|
goto sync_cleanup;
|
||||||
}
|
}
|
||||||
|
if (remote_space_id != NULL && remote_space_id[0] != '\0') {
|
||||||
|
if (!amduatd_strbuf_append_cstr(&b, "\"") ||
|
||||||
|
!amduatd_strbuf_append_cstr(&b, remote_space_id) ||
|
||||||
|
!amduatd_strbuf_append_cstr(&b, "\"")) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!amduatd_strbuf_append_cstr(&b, "null")) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduatd_strbuf_append_cstr(&b, ",\"pull_cursor\":")) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
if (!amduatd_sync_status_append_cursor(&b,
|
||||||
|
store,
|
||||||
|
&pointer_store,
|
||||||
|
req->effective_space,
|
||||||
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
|
false)) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
if (!amduatd_strbuf_append_cstr(&b, ",\"push_cursor\":")) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
if (!amduatd_sync_status_append_cursor(&b,
|
||||||
|
store,
|
||||||
|
&pointer_store,
|
||||||
|
req->effective_space,
|
||||||
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
|
true)) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
if (!amduatd_strbuf_append_cstr(&b, "}")) {
|
||||||
|
goto sync_cleanup;
|
||||||
|
}
|
||||||
|
first_remote = false;
|
||||||
}
|
}
|
||||||
if (!amduatd_strbuf_append_cstr(&b, "{\"peer_key\":\"") ||
|
|
||||||
!amduatd_strbuf_append_cstr(&b, peer_key) ||
|
if (current_peer != NULL) {
|
||||||
!amduatd_strbuf_append_cstr(&b, "\",\"pull_cursor\":")) {
|
if (!amduatd_strbuf_append_cstr(&b, "]}")) {
|
||||||
goto sync_cleanup;
|
goto sync_cleanup;
|
||||||
}
|
}
|
||||||
if (!amduatd_sync_status_append_cursor(&b,
|
|
||||||
store,
|
|
||||||
&pointer_store,
|
|
||||||
req->effective_space,
|
|
||||||
peer_key,
|
|
||||||
false)) {
|
|
||||||
goto sync_cleanup;
|
|
||||||
}
|
|
||||||
if (!amduatd_strbuf_append_cstr(&b, ",\"push_cursor\":")) {
|
|
||||||
goto sync_cleanup;
|
|
||||||
}
|
|
||||||
if (!amduatd_sync_status_append_cursor(&b,
|
|
||||||
store,
|
|
||||||
&pointer_store,
|
|
||||||
req->effective_space,
|
|
||||||
peer_key,
|
|
||||||
true)) {
|
|
||||||
goto sync_cleanup;
|
|
||||||
}
|
|
||||||
if (!amduatd_strbuf_append_cstr(&b, "}")) {
|
|
||||||
goto sync_cleanup;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1895,7 +2215,11 @@ sync_cleanup:
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
ok = amduatd_send_json_error(fd, 500, "Internal Server Error", "error");
|
ok = amduatd_send_json_error(fd, 500, "Internal Server Error", "error");
|
||||||
}
|
}
|
||||||
amduatd_space_roots_list_free(&peers);
|
amduatd_space_roots_list_free(&pull_heads);
|
||||||
|
amduatd_space_roots_list_free(&push_heads);
|
||||||
|
amduatd_cursor_pairs_free(pairs, pair_len);
|
||||||
|
amduat_octets_free(&pull_prefix);
|
||||||
|
amduat_octets_free(&push_prefix);
|
||||||
amduatd_strbuf_free(&b);
|
amduatd_strbuf_free(&b);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
@ -2586,6 +2910,9 @@ static bool amduatd_handle_get_fed_cursor(int fd,
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *root_path) {
|
const char *root_path) {
|
||||||
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
char remote_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
const char *remote_space_id = NULL;
|
||||||
|
const char *remote_error = NULL;
|
||||||
amduat_asl_pointer_store_t pointer_store;
|
amduat_asl_pointer_store_t pointer_store;
|
||||||
amduatd_fed_cursor_record_t cursor;
|
amduatd_fed_cursor_record_t cursor;
|
||||||
amduat_reference_t ref;
|
amduat_reference_t ref;
|
||||||
|
|
@ -2627,11 +2954,26 @@ static bool amduatd_handle_get_fed_cursor(int fd,
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request",
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
"missing peer");
|
"missing peer");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_get_remote_space_id(req,
|
||||||
|
remote_buf,
|
||||||
|
sizeof(remote_buf),
|
||||||
|
&remote_space_id,
|
||||||
|
&remote_error)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
|
remote_error);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
if (remote_space_id != NULL) {
|
||||||
peer_buf,
|
if (!amduatd_fed_cursor_pointer_name_v2(req->effective_space,
|
||||||
&scoped)) {
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
||||||
|
peer_buf,
|
||||||
|
&scoped)) {
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
}
|
}
|
||||||
amduat_octets_free(&scoped);
|
amduat_octets_free(&scoped);
|
||||||
|
|
@ -2644,12 +2986,13 @@ static bool amduatd_handle_get_fed_cursor(int fd,
|
||||||
|
|
||||||
amduatd_fed_cursor_record_init(&cursor);
|
amduatd_fed_cursor_record_init(&cursor);
|
||||||
memset(&ref, 0, sizeof(ref));
|
memset(&ref, 0, sizeof(ref));
|
||||||
status = amduatd_fed_cursor_get(store,
|
status = amduatd_fed_cursor_get_remote(store,
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
req->effective_space,
|
req->effective_space,
|
||||||
peer_buf,
|
peer_buf,
|
||||||
&cursor,
|
remote_space_id,
|
||||||
&ref);
|
&cursor,
|
||||||
|
&ref);
|
||||||
if (status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
if (status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
||||||
return amduatd_send_json_error(fd, 404, "Not Found", "cursor not found");
|
return amduatd_send_json_error(fd, 404, "Not Found", "cursor not found");
|
||||||
}
|
}
|
||||||
|
|
@ -2751,6 +3094,9 @@ static bool amduatd_handle_post_fed_cursor(int fd,
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *root_path) {
|
const char *root_path) {
|
||||||
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
char remote_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
const char *remote_space_id = NULL;
|
||||||
|
const char *remote_error = NULL;
|
||||||
uint8_t *body = NULL;
|
uint8_t *body = NULL;
|
||||||
const char *p = NULL;
|
const char *p = NULL;
|
||||||
const char *end = NULL;
|
const char *end = NULL;
|
||||||
|
|
@ -2804,11 +3150,26 @@ static bool amduatd_handle_post_fed_cursor(int fd,
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request",
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
"missing peer");
|
"missing peer");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_get_remote_space_id(req,
|
||||||
|
remote_buf,
|
||||||
|
sizeof(remote_buf),
|
||||||
|
&remote_space_id,
|
||||||
|
&remote_error)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
|
remote_error);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
if (remote_space_id != NULL) {
|
||||||
peer_buf,
|
if (!amduatd_fed_cursor_pointer_name_v2(req->effective_space,
|
||||||
&scoped)) {
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
||||||
|
peer_buf,
|
||||||
|
&scoped)) {
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
}
|
}
|
||||||
amduat_octets_free(&scoped);
|
amduat_octets_free(&scoped);
|
||||||
|
|
@ -2971,11 +3332,12 @@ fed_cursor_parse_fail:
|
||||||
"pointer store error");
|
"pointer store error");
|
||||||
}
|
}
|
||||||
|
|
||||||
status = amduatd_fed_cursor_cas_set(
|
status = amduatd_fed_cursor_cas_set_remote(
|
||||||
store,
|
store,
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
req->effective_space,
|
req->effective_space,
|
||||||
peer_buf,
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
have_expected_ref ? &expected_ref : NULL,
|
have_expected_ref ? &expected_ref : NULL,
|
||||||
&cursor,
|
&cursor,
|
||||||
&new_ref);
|
&new_ref);
|
||||||
|
|
@ -3713,6 +4075,9 @@ static bool amduatd_handle_get_fed_pull_plan(int fd,
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *root_path) {
|
const char *root_path) {
|
||||||
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
char remote_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
const char *remote_space_id = NULL;
|
||||||
|
const char *remote_error = NULL;
|
||||||
char limit_buf[32];
|
char limit_buf[32];
|
||||||
uint64_t limit = 128u;
|
uint64_t limit = 128u;
|
||||||
uint64_t from_logseq = 0u;
|
uint64_t from_logseq = 0u;
|
||||||
|
|
@ -3772,11 +4137,26 @@ static bool amduatd_handle_get_fed_pull_plan(int fd,
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request",
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
"missing peer");
|
"missing peer");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_get_remote_space_id(req,
|
||||||
|
remote_buf,
|
||||||
|
sizeof(remote_buf),
|
||||||
|
&remote_space_id,
|
||||||
|
&remote_error)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
|
remote_error);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
if (remote_space_id != NULL) {
|
||||||
peer_buf,
|
if (!amduatd_fed_cursor_pointer_name_v2(req->effective_space,
|
||||||
&scoped)) {
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
||||||
|
peer_buf,
|
||||||
|
&scoped)) {
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
}
|
}
|
||||||
amduat_octets_free(&scoped);
|
amduat_octets_free(&scoped);
|
||||||
|
|
@ -3802,12 +4182,13 @@ static bool amduatd_handle_get_fed_pull_plan(int fd,
|
||||||
memset(&cursor_ref, 0, sizeof(cursor_ref));
|
memset(&cursor_ref, 0, sizeof(cursor_ref));
|
||||||
{
|
{
|
||||||
amduatd_fed_cursor_status_t cursor_status;
|
amduatd_fed_cursor_status_t cursor_status;
|
||||||
cursor_status = amduatd_fed_cursor_get(store,
|
cursor_status = amduatd_fed_cursor_get_remote(store,
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
req->effective_space,
|
req->effective_space,
|
||||||
peer_buf,
|
peer_buf,
|
||||||
&cursor,
|
remote_space_id,
|
||||||
&cursor_ref);
|
&cursor,
|
||||||
|
&cursor_ref);
|
||||||
if (cursor_status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
if (cursor_status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
||||||
cursor_present = false;
|
cursor_present = false;
|
||||||
} else if (cursor_status == AMDUATD_FED_CURSOR_OK) {
|
} else if (cursor_status == AMDUATD_FED_CURSOR_OK) {
|
||||||
|
|
@ -3932,6 +4313,9 @@ static bool amduatd_handle_get_fed_push_plan(int fd,
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *root_path) {
|
const char *root_path) {
|
||||||
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
char remote_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
const char *remote_space_id = NULL;
|
||||||
|
const char *remote_error = NULL;
|
||||||
char limit_buf[32];
|
char limit_buf[32];
|
||||||
uint64_t limit = 128u;
|
uint64_t limit = 128u;
|
||||||
uint32_t domain_id = 0u;
|
uint32_t domain_id = 0u;
|
||||||
|
|
@ -3982,11 +4366,26 @@ static bool amduatd_handle_get_fed_push_plan(int fd,
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request",
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
"missing peer");
|
"missing peer");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_get_remote_space_id(req,
|
||||||
|
remote_buf,
|
||||||
|
sizeof(remote_buf),
|
||||||
|
&remote_space_id,
|
||||||
|
&remote_error)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
|
remote_error);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_push_cursor_pointer_name(req->effective_space,
|
if (remote_space_id != NULL) {
|
||||||
peer_buf,
|
if (!amduatd_fed_push_cursor_pointer_name_v2(req->effective_space,
|
||||||
&scoped)) {
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_push_cursor_pointer_name(req->effective_space,
|
||||||
|
peer_buf,
|
||||||
|
&scoped)) {
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
}
|
}
|
||||||
amduat_octets_free(&scoped);
|
amduat_octets_free(&scoped);
|
||||||
|
|
@ -4017,6 +4416,7 @@ static bool amduatd_handle_get_fed_push_plan(int fd,
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
req->effective_space,
|
req->effective_space,
|
||||||
peer_buf,
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
limit,
|
limit,
|
||||||
root_path,
|
root_path,
|
||||||
&scan);
|
&scan);
|
||||||
|
|
@ -5544,6 +5944,9 @@ static bool amduatd_handle_post_fed_pull(int fd,
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *root_path) {
|
const char *root_path) {
|
||||||
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
char remote_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
const char *remote_space_id = NULL;
|
||||||
|
const char *remote_error = NULL;
|
||||||
char limit_buf[32];
|
char limit_buf[32];
|
||||||
uint64_t limit = 128u;
|
uint64_t limit = 128u;
|
||||||
amduat_asl_pointer_store_t pointer_store;
|
amduat_asl_pointer_store_t pointer_store;
|
||||||
|
|
@ -5592,11 +5995,26 @@ static bool amduatd_handle_post_fed_pull(int fd,
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request",
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
"missing peer");
|
"missing peer");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_get_remote_space_id(req,
|
||||||
|
remote_buf,
|
||||||
|
sizeof(remote_buf),
|
||||||
|
&remote_space_id,
|
||||||
|
&remote_error)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
|
remote_error);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
if (remote_space_id != NULL) {
|
||||||
peer_buf,
|
if (!amduatd_fed_cursor_pointer_name_v2(req->effective_space,
|
||||||
&scoped)) {
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
||||||
|
peer_buf,
|
||||||
|
&scoped)) {
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
}
|
}
|
||||||
amduat_octets_free(&scoped);
|
amduat_octets_free(&scoped);
|
||||||
|
|
@ -5642,6 +6060,7 @@ static bool amduatd_handle_post_fed_pull(int fd,
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
req->effective_space,
|
req->effective_space,
|
||||||
peer_buf,
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
limit,
|
limit,
|
||||||
fed_cfg,
|
fed_cfg,
|
||||||
&pull_transport,
|
&pull_transport,
|
||||||
|
|
@ -5987,6 +6406,9 @@ static bool amduatd_handle_post_fed_pull_until(
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *root_path) {
|
const char *root_path) {
|
||||||
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
char remote_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
const char *remote_space_id = NULL;
|
||||||
|
const char *remote_error = NULL;
|
||||||
char limit_buf[32];
|
char limit_buf[32];
|
||||||
char rounds_buf[32];
|
char rounds_buf[32];
|
||||||
uint64_t limit = 128u;
|
uint64_t limit = 128u;
|
||||||
|
|
@ -6046,11 +6468,26 @@ static bool amduatd_handle_post_fed_pull_until(
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request",
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
"missing peer");
|
"missing peer");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_get_remote_space_id(req,
|
||||||
|
remote_buf,
|
||||||
|
sizeof(remote_buf),
|
||||||
|
&remote_space_id,
|
||||||
|
&remote_error)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
|
remote_error);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
if (remote_space_id != NULL) {
|
||||||
peer_buf,
|
if (!amduatd_fed_cursor_pointer_name_v2(req->effective_space,
|
||||||
&scoped)) {
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_cursor_pointer_name(req->effective_space,
|
||||||
|
peer_buf,
|
||||||
|
&scoped)) {
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
}
|
}
|
||||||
amduat_octets_free(&scoped);
|
amduat_octets_free(&scoped);
|
||||||
|
|
@ -6104,6 +6541,7 @@ static bool amduatd_handle_post_fed_pull_until(
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
req->effective_space,
|
req->effective_space,
|
||||||
peer_buf,
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
limit,
|
limit,
|
||||||
max_rounds,
|
max_rounds,
|
||||||
fed_cfg,
|
fed_cfg,
|
||||||
|
|
@ -6255,6 +6693,9 @@ static bool amduatd_handle_post_fed_push(int fd,
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *root_path) {
|
const char *root_path) {
|
||||||
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
char remote_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
const char *remote_space_id = NULL;
|
||||||
|
const char *remote_error = NULL;
|
||||||
char limit_buf[32];
|
char limit_buf[32];
|
||||||
uint64_t limit = 128u;
|
uint64_t limit = 128u;
|
||||||
uint32_t domain_id = 0u;
|
uint32_t domain_id = 0u;
|
||||||
|
|
@ -6310,11 +6751,26 @@ static bool amduatd_handle_post_fed_push(int fd,
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request",
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
"missing peer");
|
"missing peer");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_get_remote_space_id(req,
|
||||||
|
remote_buf,
|
||||||
|
sizeof(remote_buf),
|
||||||
|
&remote_space_id,
|
||||||
|
&remote_error)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
|
remote_error);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_push_cursor_pointer_name(req->effective_space,
|
if (remote_space_id != NULL) {
|
||||||
peer_buf,
|
if (!amduatd_fed_push_cursor_pointer_name_v2(req->effective_space,
|
||||||
&scoped)) {
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_push_cursor_pointer_name(req->effective_space,
|
||||||
|
peer_buf,
|
||||||
|
&scoped)) {
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
}
|
}
|
||||||
amduat_octets_free(&scoped);
|
amduat_octets_free(&scoped);
|
||||||
|
|
@ -6360,6 +6816,7 @@ static bool amduatd_handle_post_fed_push(int fd,
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
req->effective_space,
|
req->effective_space,
|
||||||
peer_buf,
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
limit,
|
limit,
|
||||||
root_path,
|
root_path,
|
||||||
fed_cfg,
|
fed_cfg,
|
||||||
|
|
@ -6682,6 +7139,9 @@ static bool amduatd_handle_post_fed_push_until(
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *root_path) {
|
const char *root_path) {
|
||||||
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
char peer_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
char remote_buf[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
const char *remote_space_id = NULL;
|
||||||
|
const char *remote_error = NULL;
|
||||||
char limit_buf[32];
|
char limit_buf[32];
|
||||||
char rounds_buf[32];
|
char rounds_buf[32];
|
||||||
uint64_t limit = 128u;
|
uint64_t limit = 128u;
|
||||||
|
|
@ -6740,11 +7200,26 @@ static bool amduatd_handle_post_fed_push_until(
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request",
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
"missing peer");
|
"missing peer");
|
||||||
}
|
}
|
||||||
|
if (!amduatd_get_remote_space_id(req,
|
||||||
|
remote_buf,
|
||||||
|
sizeof(remote_buf),
|
||||||
|
&remote_space_id,
|
||||||
|
&remote_error)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request",
|
||||||
|
remote_error);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_push_cursor_pointer_name(req->effective_space,
|
if (remote_space_id != NULL) {
|
||||||
peer_buf,
|
if (!amduatd_fed_push_cursor_pointer_name_v2(req->effective_space,
|
||||||
&scoped)) {
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_push_cursor_pointer_name(req->effective_space,
|
||||||
|
peer_buf,
|
||||||
|
&scoped)) {
|
||||||
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
return amduatd_send_json_error(fd, 400, "Bad Request", "invalid peer");
|
||||||
}
|
}
|
||||||
amduat_octets_free(&scoped);
|
amduat_octets_free(&scoped);
|
||||||
|
|
@ -6795,6 +7270,7 @@ static bool amduatd_handle_post_fed_push_until(
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
req->effective_space,
|
req->effective_space,
|
||||||
peer_buf,
|
peer_buf,
|
||||||
|
remote_space_id,
|
||||||
limit,
|
limit,
|
||||||
max_rounds,
|
max_rounds,
|
||||||
root_path,
|
root_path,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "amduat/asl/record.h"
|
#include "amduat/asl/record.h"
|
||||||
#include "amduat/enc/asl1_core_codec.h"
|
#include "amduat/enc/asl1_core_codec.h"
|
||||||
|
#include "amduatd_space.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -110,6 +111,11 @@ static bool amduatd_fed_cursor_peer_key_is_valid(const char *peer_key) {
|
||||||
return amduat_asl_pointer_name_is_valid(peer_key);
|
return amduat_asl_pointer_name_is_valid(peer_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool amduatd_fed_cursor_remote_space_id_is_valid(
|
||||||
|
const char *remote_space_id) {
|
||||||
|
return amduatd_space_space_id_is_valid(remote_space_id);
|
||||||
|
}
|
||||||
|
|
||||||
static bool amduatd_fed_cursor_pointer_name_with_prefix(
|
static bool amduatd_fed_cursor_pointer_name_with_prefix(
|
||||||
const amduatd_space_t *space,
|
const amduatd_space_t *space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
|
@ -149,6 +155,56 @@ static bool amduatd_fed_cursor_pointer_name_with_prefix(
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool amduatd_fed_cursor_pointer_name_with_prefix_v2(
|
||||||
|
const amduatd_space_t *space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
const char *prefix,
|
||||||
|
amduat_octets_t *out_name) {
|
||||||
|
const char suffix[] = "/head";
|
||||||
|
size_t peer_len;
|
||||||
|
size_t remote_len;
|
||||||
|
size_t total_len;
|
||||||
|
size_t prefix_len;
|
||||||
|
char *base = NULL;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
if (out_name != NULL) {
|
||||||
|
*out_name = amduat_octets(NULL, 0u);
|
||||||
|
}
|
||||||
|
if (out_name == NULL || prefix == NULL ||
|
||||||
|
!amduatd_fed_cursor_peer_key_is_valid(peer_key) ||
|
||||||
|
!amduatd_fed_cursor_remote_space_id_is_valid(remote_space_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
peer_len = strlen(peer_key);
|
||||||
|
remote_len = strlen(remote_space_id);
|
||||||
|
prefix_len = strlen(prefix);
|
||||||
|
if (peer_len > SIZE_MAX - prefix_len - 1u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (remote_len > SIZE_MAX - prefix_len - peer_len - 1u -
|
||||||
|
(sizeof(suffix) - 1u)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
total_len = prefix_len + peer_len + 1u + remote_len + (sizeof(suffix) - 1u);
|
||||||
|
base = (char *)malloc(total_len + 1u);
|
||||||
|
if (base == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(base, prefix, prefix_len);
|
||||||
|
memcpy(base + prefix_len, peer_key, peer_len);
|
||||||
|
base[prefix_len + peer_len] = '/';
|
||||||
|
memcpy(base + prefix_len + peer_len + 1u, remote_space_id, remote_len);
|
||||||
|
memcpy(base + prefix_len + peer_len + 1u + remote_len, suffix,
|
||||||
|
sizeof(suffix) - 1u);
|
||||||
|
base[total_len] = '\0';
|
||||||
|
|
||||||
|
ok = amduatd_space_scope_name(space, base, out_name);
|
||||||
|
free(base);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
static bool amduatd_fed_cursor_record_encode(
|
static bool amduatd_fed_cursor_record_encode(
|
||||||
const amduatd_fed_cursor_record_t *record,
|
const amduatd_fed_cursor_record_t *record,
|
||||||
amduat_octets_t *out_payload) {
|
amduat_octets_t *out_payload) {
|
||||||
|
|
@ -412,6 +468,28 @@ bool amduatd_fed_push_cursor_pointer_name(const amduatd_space_t *space,
|
||||||
out_name);
|
out_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool amduatd_fed_cursor_pointer_name_v2(const amduatd_space_t *space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
amduat_octets_t *out_name) {
|
||||||
|
return amduatd_fed_cursor_pointer_name_with_prefix_v2(space,
|
||||||
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
|
"fed/cursor/",
|
||||||
|
out_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduatd_fed_push_cursor_pointer_name_v2(const amduatd_space_t *space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
amduat_octets_t *out_name) {
|
||||||
|
return amduatd_fed_cursor_pointer_name_with_prefix_v2(space,
|
||||||
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
|
"fed/push_cursor/",
|
||||||
|
out_name);
|
||||||
|
}
|
||||||
|
|
||||||
amduatd_fed_cursor_status_t amduatd_fed_cursor_check_enabled(
|
amduatd_fed_cursor_status_t amduatd_fed_cursor_check_enabled(
|
||||||
const amduatd_fed_cfg_t *cfg) {
|
const amduatd_fed_cfg_t *cfg) {
|
||||||
if (cfg == NULL) {
|
if (cfg == NULL) {
|
||||||
|
|
@ -428,6 +506,7 @@ static amduatd_fed_cursor_status_t amduatd_fed_cursor_get_with_prefix(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
const char *prefix,
|
const char *prefix,
|
||||||
amduatd_fed_cursor_record_t *out_cursor,
|
amduatd_fed_cursor_record_t *out_cursor,
|
||||||
amduat_reference_t *out_ref) {
|
amduat_reference_t *out_ref) {
|
||||||
|
|
@ -446,10 +525,18 @@ static amduatd_fed_cursor_status_t amduatd_fed_cursor_get_with_prefix(
|
||||||
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!amduatd_fed_cursor_pointer_name_with_prefix(effective_space,
|
if (remote_space_id != NULL && remote_space_id[0] != '\0') {
|
||||||
peer_key,
|
if (!amduatd_fed_cursor_pointer_name_with_prefix_v2(effective_space,
|
||||||
prefix,
|
peer_key,
|
||||||
&pointer_name)) {
|
remote_space_id,
|
||||||
|
prefix,
|
||||||
|
&pointer_name)) {
|
||||||
|
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_cursor_pointer_name_with_prefix(effective_space,
|
||||||
|
peer_key,
|
||||||
|
prefix,
|
||||||
|
&pointer_name)) {
|
||||||
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -529,6 +616,25 @@ amduatd_fed_cursor_status_t amduatd_fed_cursor_get(
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
|
NULL,
|
||||||
|
"fed/cursor/",
|
||||||
|
out_cursor,
|
||||||
|
out_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
amduatd_fed_cursor_status_t amduatd_fed_cursor_get_remote(
|
||||||
|
amduat_asl_store_t *store,
|
||||||
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
const amduatd_space_t *effective_space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
amduatd_fed_cursor_record_t *out_cursor,
|
||||||
|
amduat_reference_t *out_ref) {
|
||||||
|
return amduatd_fed_cursor_get_with_prefix(store,
|
||||||
|
pointer_store,
|
||||||
|
effective_space,
|
||||||
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
"fed/cursor/",
|
"fed/cursor/",
|
||||||
out_cursor,
|
out_cursor,
|
||||||
out_ref);
|
out_ref);
|
||||||
|
|
@ -545,6 +651,25 @@ amduatd_fed_cursor_status_t amduatd_fed_push_cursor_get(
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
|
NULL,
|
||||||
|
"fed/push_cursor/",
|
||||||
|
out_cursor,
|
||||||
|
out_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
amduatd_fed_cursor_status_t amduatd_fed_push_cursor_get_remote(
|
||||||
|
amduat_asl_store_t *store,
|
||||||
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
const amduatd_space_t *effective_space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
amduatd_fed_cursor_record_t *out_cursor,
|
||||||
|
amduat_reference_t *out_ref) {
|
||||||
|
return amduatd_fed_cursor_get_with_prefix(store,
|
||||||
|
pointer_store,
|
||||||
|
effective_space,
|
||||||
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
"fed/push_cursor/",
|
"fed/push_cursor/",
|
||||||
out_cursor,
|
out_cursor,
|
||||||
out_ref);
|
out_ref);
|
||||||
|
|
@ -555,6 +680,7 @@ static amduatd_fed_cursor_status_t amduatd_fed_cursor_cas_set_with_prefix(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
const char *prefix,
|
const char *prefix,
|
||||||
const amduat_reference_t *expected_ref,
|
const amduat_reference_t *expected_ref,
|
||||||
const amduatd_fed_cursor_record_t *new_cursor,
|
const amduatd_fed_cursor_record_t *new_cursor,
|
||||||
|
|
@ -591,10 +717,18 @@ static amduatd_fed_cursor_status_t amduatd_fed_cursor_cas_set_with_prefix(
|
||||||
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!amduatd_fed_cursor_pointer_name_with_prefix(effective_space,
|
if (remote_space_id != NULL && remote_space_id[0] != '\0') {
|
||||||
peer_key,
|
if (!amduatd_fed_cursor_pointer_name_with_prefix_v2(effective_space,
|
||||||
prefix,
|
peer_key,
|
||||||
&pointer_name)) {
|
remote_space_id,
|
||||||
|
prefix,
|
||||||
|
&pointer_name)) {
|
||||||
|
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_cursor_pointer_name_with_prefix(effective_space,
|
||||||
|
peer_key,
|
||||||
|
prefix,
|
||||||
|
&pointer_name)) {
|
||||||
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
return AMDUATD_FED_CURSOR_ERR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -653,6 +787,27 @@ amduatd_fed_cursor_status_t amduatd_fed_cursor_cas_set(
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
|
NULL,
|
||||||
|
"fed/cursor/",
|
||||||
|
expected_ref,
|
||||||
|
new_cursor,
|
||||||
|
out_new_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
amduatd_fed_cursor_status_t amduatd_fed_cursor_cas_set_remote(
|
||||||
|
amduat_asl_store_t *store,
|
||||||
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
const amduatd_space_t *effective_space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
const amduat_reference_t *expected_ref,
|
||||||
|
const amduatd_fed_cursor_record_t *new_cursor,
|
||||||
|
amduat_reference_t *out_new_ref) {
|
||||||
|
return amduatd_fed_cursor_cas_set_with_prefix(store,
|
||||||
|
pointer_store,
|
||||||
|
effective_space,
|
||||||
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
"fed/cursor/",
|
"fed/cursor/",
|
||||||
expected_ref,
|
expected_ref,
|
||||||
new_cursor,
|
new_cursor,
|
||||||
|
|
@ -671,6 +826,27 @@ amduatd_fed_cursor_status_t amduatd_fed_push_cursor_cas_set(
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
|
NULL,
|
||||||
|
"fed/push_cursor/",
|
||||||
|
expected_ref,
|
||||||
|
new_cursor,
|
||||||
|
out_new_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
amduatd_fed_cursor_status_t amduatd_fed_push_cursor_cas_set_remote(
|
||||||
|
amduat_asl_store_t *store,
|
||||||
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
const amduatd_space_t *effective_space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
const amduat_reference_t *expected_ref,
|
||||||
|
const amduatd_fed_cursor_record_t *new_cursor,
|
||||||
|
amduat_reference_t *out_new_ref) {
|
||||||
|
return amduatd_fed_cursor_cas_set_with_prefix(store,
|
||||||
|
pointer_store,
|
||||||
|
effective_space,
|
||||||
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
"fed/push_cursor/",
|
"fed/push_cursor/",
|
||||||
expected_ref,
|
expected_ref,
|
||||||
new_cursor,
|
new_cursor,
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,16 @@ bool amduatd_fed_push_cursor_pointer_name(const amduatd_space_t *space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
amduat_octets_t *out_name);
|
amduat_octets_t *out_name);
|
||||||
|
|
||||||
|
bool amduatd_fed_cursor_pointer_name_v2(const amduatd_space_t *space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
amduat_octets_t *out_name);
|
||||||
|
|
||||||
|
bool amduatd_fed_push_cursor_pointer_name_v2(const amduatd_space_t *space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
amduat_octets_t *out_name);
|
||||||
|
|
||||||
amduatd_fed_cursor_status_t amduatd_fed_cursor_check_enabled(
|
amduatd_fed_cursor_status_t amduatd_fed_cursor_check_enabled(
|
||||||
const amduatd_fed_cfg_t *cfg);
|
const amduatd_fed_cfg_t *cfg);
|
||||||
|
|
||||||
|
|
@ -57,6 +67,15 @@ amduatd_fed_cursor_status_t amduatd_fed_cursor_get(
|
||||||
amduatd_fed_cursor_record_t *out_cursor,
|
amduatd_fed_cursor_record_t *out_cursor,
|
||||||
amduat_reference_t *out_ref);
|
amduat_reference_t *out_ref);
|
||||||
|
|
||||||
|
amduatd_fed_cursor_status_t amduatd_fed_cursor_get_remote(
|
||||||
|
amduat_asl_store_t *store,
|
||||||
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
const amduatd_space_t *effective_space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
amduatd_fed_cursor_record_t *out_cursor,
|
||||||
|
amduat_reference_t *out_ref);
|
||||||
|
|
||||||
amduatd_fed_cursor_status_t amduatd_fed_push_cursor_get(
|
amduatd_fed_cursor_status_t amduatd_fed_push_cursor_get(
|
||||||
amduat_asl_store_t *store,
|
amduat_asl_store_t *store,
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
|
@ -65,6 +84,15 @@ amduatd_fed_cursor_status_t amduatd_fed_push_cursor_get(
|
||||||
amduatd_fed_cursor_record_t *out_cursor,
|
amduatd_fed_cursor_record_t *out_cursor,
|
||||||
amduat_reference_t *out_ref);
|
amduat_reference_t *out_ref);
|
||||||
|
|
||||||
|
amduatd_fed_cursor_status_t amduatd_fed_push_cursor_get_remote(
|
||||||
|
amduat_asl_store_t *store,
|
||||||
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
const amduatd_space_t *effective_space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
amduatd_fed_cursor_record_t *out_cursor,
|
||||||
|
amduat_reference_t *out_ref);
|
||||||
|
|
||||||
amduatd_fed_cursor_status_t amduatd_fed_cursor_cas_set(
|
amduatd_fed_cursor_status_t amduatd_fed_cursor_cas_set(
|
||||||
amduat_asl_store_t *store,
|
amduat_asl_store_t *store,
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
|
@ -74,6 +102,16 @@ amduatd_fed_cursor_status_t amduatd_fed_cursor_cas_set(
|
||||||
const amduatd_fed_cursor_record_t *new_cursor,
|
const amduatd_fed_cursor_record_t *new_cursor,
|
||||||
amduat_reference_t *out_new_ref);
|
amduat_reference_t *out_new_ref);
|
||||||
|
|
||||||
|
amduatd_fed_cursor_status_t amduatd_fed_cursor_cas_set_remote(
|
||||||
|
amduat_asl_store_t *store,
|
||||||
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
const amduatd_space_t *effective_space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
const amduat_reference_t *expected_ref,
|
||||||
|
const amduatd_fed_cursor_record_t *new_cursor,
|
||||||
|
amduat_reference_t *out_new_ref);
|
||||||
|
|
||||||
amduatd_fed_cursor_status_t amduatd_fed_push_cursor_cas_set(
|
amduatd_fed_cursor_status_t amduatd_fed_push_cursor_cas_set(
|
||||||
amduat_asl_store_t *store,
|
amduat_asl_store_t *store,
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
|
@ -83,6 +121,16 @@ amduatd_fed_cursor_status_t amduatd_fed_push_cursor_cas_set(
|
||||||
const amduatd_fed_cursor_record_t *new_cursor,
|
const amduatd_fed_cursor_record_t *new_cursor,
|
||||||
amduat_reference_t *out_new_ref);
|
amduat_reference_t *out_new_ref);
|
||||||
|
|
||||||
|
amduatd_fed_cursor_status_t amduatd_fed_push_cursor_cas_set_remote(
|
||||||
|
amduat_asl_store_t *store,
|
||||||
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
|
const amduatd_space_t *effective_space,
|
||||||
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
|
const amduat_reference_t *expected_ref,
|
||||||
|
const amduatd_fed_cursor_record_t *new_cursor,
|
||||||
|
amduat_reference_t *out_new_ref);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,7 @@ amduatd_fed_pull_apply_status_t amduatd_fed_pull_apply(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
const amduatd_fed_cfg_t *fed_cfg,
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
const amduatd_fed_pull_transport_t *transport,
|
const amduatd_fed_pull_transport_t *transport,
|
||||||
|
|
@ -234,9 +235,17 @@ amduatd_fed_pull_apply_status_t amduatd_fed_pull_apply(
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_cursor_pointer_name(effective_space,
|
if (remote_space_id != NULL && remote_space_id[0] != '\0') {
|
||||||
peer_key,
|
if (!amduatd_fed_cursor_pointer_name_v2(effective_space,
|
||||||
&scoped)) {
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
amduatd_fed_pull_report_error(out_report, "invalid peer");
|
||||||
|
return AMDUATD_FED_PULL_APPLY_ERR_INVALID;
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_cursor_pointer_name(effective_space,
|
||||||
|
peer_key,
|
||||||
|
&scoped)) {
|
||||||
amduatd_fed_pull_report_error(out_report, "invalid peer");
|
amduatd_fed_pull_report_error(out_report, "invalid peer");
|
||||||
return AMDUATD_FED_PULL_APPLY_ERR_INVALID;
|
return AMDUATD_FED_PULL_APPLY_ERR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
@ -256,12 +265,13 @@ amduatd_fed_pull_apply_status_t amduatd_fed_pull_apply(
|
||||||
memset(&cursor_ref, 0, sizeof(cursor_ref));
|
memset(&cursor_ref, 0, sizeof(cursor_ref));
|
||||||
{
|
{
|
||||||
amduatd_fed_cursor_status_t cursor_status;
|
amduatd_fed_cursor_status_t cursor_status;
|
||||||
cursor_status = amduatd_fed_cursor_get(store,
|
cursor_status = amduatd_fed_cursor_get_remote(store,
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
&cursor,
|
remote_space_id,
|
||||||
&cursor_ref);
|
&cursor,
|
||||||
|
&cursor_ref);
|
||||||
if (cursor_status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
if (cursor_status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
||||||
cursor_present = false;
|
cursor_present = false;
|
||||||
} else if (cursor_status == AMDUATD_FED_CURSOR_OK) {
|
} else if (cursor_status == AMDUATD_FED_CURSOR_OK) {
|
||||||
|
|
@ -471,14 +481,16 @@ amduatd_fed_pull_apply_status_t amduatd_fed_pull_apply(
|
||||||
memset(&next_ref, 0, sizeof(next_ref));
|
memset(&next_ref, 0, sizeof(next_ref));
|
||||||
{
|
{
|
||||||
amduatd_fed_cursor_status_t cursor_status;
|
amduatd_fed_cursor_status_t cursor_status;
|
||||||
cursor_status = amduatd_fed_cursor_cas_set(store,
|
cursor_status = amduatd_fed_cursor_cas_set_remote(store,
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
cursor_present ? &cursor_ref
|
remote_space_id,
|
||||||
: NULL,
|
cursor_present
|
||||||
&next_cursor,
|
? &cursor_ref
|
||||||
&next_ref);
|
: NULL,
|
||||||
|
&next_cursor,
|
||||||
|
&next_ref);
|
||||||
if (cursor_status == AMDUATD_FED_CURSOR_ERR_CONFLICT) {
|
if (cursor_status == AMDUATD_FED_CURSOR_ERR_CONFLICT) {
|
||||||
transport->free_records(transport->ctx, records, record_len_total);
|
transport->free_records(transport->ctx, records, record_len_total);
|
||||||
amduatd_fed_cursor_record_free(&cursor);
|
amduatd_fed_cursor_record_free(&cursor);
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ amduatd_fed_pull_apply_status_t amduatd_fed_pull_apply(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
const amduatd_fed_cfg_t *fed_cfg,
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
const amduatd_fed_pull_transport_t *transport,
|
const amduatd_fed_pull_transport_t *transport,
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ amduatd_fed_push_apply_status_t amduatd_fed_push_apply(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
const char *root_path,
|
const char *root_path,
|
||||||
const amduatd_fed_cfg_t *fed_cfg,
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
|
|
@ -133,9 +134,17 @@ amduatd_fed_push_apply_status_t amduatd_fed_push_apply(
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
if (!amduatd_fed_push_cursor_pointer_name(effective_space,
|
if (remote_space_id != NULL && remote_space_id[0] != '\0') {
|
||||||
peer_key,
|
if (!amduatd_fed_push_cursor_pointer_name_v2(effective_space,
|
||||||
&scoped)) {
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
|
&scoped)) {
|
||||||
|
amduatd_fed_push_report_error(out_report, "invalid peer");
|
||||||
|
return AMDUATD_FED_PUSH_APPLY_ERR_INVALID;
|
||||||
|
}
|
||||||
|
} else if (!amduatd_fed_push_cursor_pointer_name(effective_space,
|
||||||
|
peer_key,
|
||||||
|
&scoped)) {
|
||||||
amduatd_fed_push_report_error(out_report, "invalid peer");
|
amduatd_fed_push_report_error(out_report, "invalid peer");
|
||||||
return AMDUATD_FED_PUSH_APPLY_ERR_INVALID;
|
return AMDUATD_FED_PUSH_APPLY_ERR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
@ -153,6 +162,7 @@ amduatd_fed_push_apply_status_t amduatd_fed_push_apply(
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
limit,
|
limit,
|
||||||
root_path,
|
root_path,
|
||||||
&scan) != AMDUATD_FED_PUSH_PLAN_OK) {
|
&scan) != AMDUATD_FED_PUSH_PLAN_OK) {
|
||||||
|
|
@ -303,15 +313,16 @@ amduatd_fed_push_apply_status_t amduatd_fed_push_apply(
|
||||||
memset(&next_ref, 0, sizeof(next_ref));
|
memset(&next_ref, 0, sizeof(next_ref));
|
||||||
{
|
{
|
||||||
amduatd_fed_cursor_status_t st;
|
amduatd_fed_cursor_status_t st;
|
||||||
st = amduatd_fed_push_cursor_cas_set(store,
|
st = amduatd_fed_push_cursor_cas_set_remote(store,
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
scan.cursor_present
|
remote_space_id,
|
||||||
? &scan.cursor_ref
|
scan.cursor_present
|
||||||
: NULL,
|
? &scan.cursor_ref
|
||||||
&next_cursor,
|
: NULL,
|
||||||
&next_ref);
|
&next_cursor,
|
||||||
|
&next_ref);
|
||||||
amduatd_fed_cursor_record_free(&next_cursor);
|
amduatd_fed_cursor_record_free(&next_cursor);
|
||||||
if (st == AMDUATD_FED_CURSOR_ERR_CONFLICT) {
|
if (st == AMDUATD_FED_CURSOR_ERR_CONFLICT) {
|
||||||
amduatd_fed_push_plan_scan_free(&scan);
|
amduatd_fed_push_plan_scan_free(&scan);
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ amduatd_fed_push_apply_status_t amduatd_fed_push_apply(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
const char *root_path,
|
const char *root_path,
|
||||||
const amduatd_fed_cfg_t *fed_cfg,
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,7 @@ amduatd_fed_push_plan_status_t amduatd_fed_push_plan_scan(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
const char *root_path,
|
const char *root_path,
|
||||||
amduatd_fed_push_plan_scan_t *out_scan) {
|
amduatd_fed_push_plan_scan_t *out_scan) {
|
||||||
|
|
@ -256,12 +257,13 @@ amduatd_fed_push_plan_status_t amduatd_fed_push_plan_scan(
|
||||||
|
|
||||||
{
|
{
|
||||||
amduatd_fed_cursor_status_t cursor_status;
|
amduatd_fed_cursor_status_t cursor_status;
|
||||||
cursor_status = amduatd_fed_push_cursor_get(store,
|
cursor_status = amduatd_fed_push_cursor_get_remote(store,
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
&out_scan->cursor,
|
remote_space_id,
|
||||||
&out_scan->cursor_ref);
|
&out_scan->cursor,
|
||||||
|
&out_scan->cursor_ref);
|
||||||
if (cursor_status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
if (cursor_status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
||||||
out_scan->cursor_present = false;
|
out_scan->cursor_present = false;
|
||||||
} else if (cursor_status == AMDUATD_FED_CURSOR_OK) {
|
} else if (cursor_status == AMDUATD_FED_CURSOR_OK) {
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ amduatd_fed_push_plan_status_t amduatd_fed_push_plan_scan(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
const char *root_path,
|
const char *root_path,
|
||||||
amduatd_fed_push_plan_scan_t *out_scan);
|
amduatd_fed_push_plan_scan_t *out_scan);
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ amduatd_fed_pull_apply_status_t amduatd_fed_pull_until(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
uint64_t max_rounds,
|
uint64_t max_rounds,
|
||||||
const amduatd_fed_cfg_t *fed_cfg,
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
|
|
@ -100,6 +101,7 @@ amduatd_fed_pull_apply_status_t amduatd_fed_pull_until(
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
limit,
|
limit,
|
||||||
fed_cfg,
|
fed_cfg,
|
||||||
transport,
|
transport,
|
||||||
|
|
@ -154,6 +156,7 @@ amduatd_fed_push_apply_status_t amduatd_fed_push_until(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
uint64_t max_rounds,
|
uint64_t max_rounds,
|
||||||
const char *root_path,
|
const char *root_path,
|
||||||
|
|
@ -185,6 +188,7 @@ amduatd_fed_push_apply_status_t amduatd_fed_push_until(
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
peer_key,
|
peer_key,
|
||||||
|
remote_space_id,
|
||||||
limit,
|
limit,
|
||||||
root_path,
|
root_path,
|
||||||
fed_cfg,
|
fed_cfg,
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ amduatd_fed_pull_apply_status_t amduatd_fed_pull_until(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
uint64_t max_rounds,
|
uint64_t max_rounds,
|
||||||
const amduatd_fed_cfg_t *fed_cfg,
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
|
|
@ -49,6 +50,7 @@ amduatd_fed_push_apply_status_t amduatd_fed_push_until(
|
||||||
amduat_asl_pointer_store_t *pointer_store,
|
amduat_asl_pointer_store_t *pointer_store,
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
const char *peer_key,
|
const char *peer_key,
|
||||||
|
const char *remote_space_id,
|
||||||
uint64_t limit,
|
uint64_t limit,
|
||||||
uint64_t max_rounds,
|
uint64_t max_rounds,
|
||||||
const char *root_path,
|
const char *root_path,
|
||||||
|
|
|
||||||
|
|
@ -99,17 +99,19 @@ static amduatd_space_mounts_status_t amduatd_space_mounts_append_tracking(
|
||||||
amduatd_fed_cursor_status_t status;
|
amduatd_fed_cursor_status_t status;
|
||||||
bool cursor_present = false;
|
bool cursor_present = false;
|
||||||
char *cursor_ref_hex = NULL;
|
char *cursor_ref_hex = NULL;
|
||||||
|
const char *cursor_namespace = "none";
|
||||||
|
|
||||||
amduatd_fed_cursor_record_init(&cursor);
|
amduatd_fed_cursor_record_init(&cursor);
|
||||||
cursor_ref = amduat_reference(0u, amduat_octets(NULL, 0u));
|
cursor_ref = amduat_reference(0u, amduat_octets(NULL, 0u));
|
||||||
|
|
||||||
if (mount->mode == AMDUATD_SPACE_MANIFEST_MOUNT_TRACK) {
|
if (mount->mode == AMDUATD_SPACE_MANIFEST_MOUNT_TRACK) {
|
||||||
status = amduatd_fed_cursor_get(store,
|
status = amduatd_fed_cursor_get_remote(store,
|
||||||
pointer_store,
|
pointer_store,
|
||||||
effective_space,
|
effective_space,
|
||||||
mount->peer_key,
|
mount->peer_key,
|
||||||
&cursor,
|
mount->space_id,
|
||||||
&cursor_ref);
|
&cursor,
|
||||||
|
&cursor_ref);
|
||||||
if (status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
if (status == AMDUATD_FED_CURSOR_ERR_NOT_FOUND) {
|
||||||
cursor_present = false;
|
cursor_present = false;
|
||||||
} else if (status == AMDUATD_FED_CURSOR_OK) {
|
} else if (status == AMDUATD_FED_CURSOR_OK) {
|
||||||
|
|
@ -123,12 +125,15 @@ static amduatd_space_mounts_status_t amduatd_space_mounts_append_tracking(
|
||||||
amduat_reference_free(&cursor_ref);
|
amduat_reference_free(&cursor_ref);
|
||||||
return AMDUATD_SPACE_MOUNTS_ERR_STORE;
|
return AMDUATD_SPACE_MOUNTS_ERR_STORE;
|
||||||
}
|
}
|
||||||
|
cursor_namespace = "v2";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!amduatd_mounts_buf_append_cstr(b, ",\"local_tracking\":{") ||
|
if (!amduatd_mounts_buf_append_cstr(b, ",\"local_tracking\":{") ||
|
||||||
|
!amduatd_mounts_buf_append_cstr(b, "\"cursor_namespace\":\"") ||
|
||||||
|
!amduatd_mounts_buf_append_cstr(b, cursor_namespace) ||
|
||||||
!amduatd_mounts_buf_append_cstr(
|
!amduatd_mounts_buf_append_cstr(
|
||||||
b,
|
b,
|
||||||
"\"cursor_scope\":\"per-peer-per-local-space\","
|
"\",\"cursor_scope\":\"per-peer-per-local-space\","
|
||||||
"\"remote_space_id\":\"") ||
|
"\"remote_space_id\":\"") ||
|
||||||
!amduatd_mounts_buf_append_cstr(b, mount->space_id) ||
|
!amduatd_mounts_buf_append_cstr(b, mount->space_id) ||
|
||||||
!amduatd_mounts_buf_append_cstr(b, "\",\"pull_cursor\":{") ||
|
!amduatd_mounts_buf_append_cstr(b, "\",\"pull_cursor\":{") ||
|
||||||
|
|
|
||||||
|
|
@ -312,24 +312,40 @@ static bool amduatd_space_roots_append_cursor_heads(
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool amduatd_space_roots_cursor_peer_from_name(
|
bool amduatd_space_roots_cursor_parse(const char *prefix,
|
||||||
const char *prefix,
|
const char *pointer_name,
|
||||||
const char *pointer_name,
|
char **out_peer,
|
||||||
char **out_peer) {
|
char **out_remote_space_id) {
|
||||||
const char suffix[] = "/head";
|
const char suffix[] = "/head";
|
||||||
size_t prefix_len;
|
size_t prefix_len;
|
||||||
size_t name_len;
|
size_t name_len;
|
||||||
|
size_t name_len_full;
|
||||||
size_t suffix_len = sizeof(suffix) - 1u;
|
size_t suffix_len = sizeof(suffix) - 1u;
|
||||||
size_t peer_len;
|
size_t peer_len;
|
||||||
|
size_t remote_len = 0u;
|
||||||
char *peer;
|
char *peer;
|
||||||
|
char *remote = NULL;
|
||||||
|
const char *segment = NULL;
|
||||||
|
const char *remote_start = NULL;
|
||||||
|
const char *name_end = NULL;
|
||||||
|
|
||||||
|
if (out_peer != NULL) {
|
||||||
|
*out_peer = NULL;
|
||||||
|
}
|
||||||
|
if (out_remote_space_id != NULL) {
|
||||||
|
*out_remote_space_id = NULL;
|
||||||
|
}
|
||||||
if (prefix == NULL || pointer_name == NULL || out_peer == NULL) {
|
if (prefix == NULL || pointer_name == NULL || out_peer == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*out_peer = NULL;
|
|
||||||
prefix_len = strlen(prefix);
|
prefix_len = strlen(prefix);
|
||||||
name_len = strlen(pointer_name);
|
name_len_full = strlen(pointer_name);
|
||||||
if (name_len <= prefix_len + 1u + suffix_len) {
|
name_len = name_len_full;
|
||||||
|
if (name_len_full >= suffix_len &&
|
||||||
|
strcmp(pointer_name + name_len_full - suffix_len, suffix) == 0) {
|
||||||
|
name_len = name_len_full - suffix_len;
|
||||||
|
}
|
||||||
|
if (name_len <= prefix_len + 1u) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (strncmp(pointer_name, prefix, prefix_len) != 0) {
|
if (strncmp(pointer_name, prefix, prefix_len) != 0) {
|
||||||
|
|
@ -338,10 +354,18 @@ static bool amduatd_space_roots_cursor_peer_from_name(
|
||||||
if (pointer_name[prefix_len] != '/') {
|
if (pointer_name[prefix_len] != '/') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (strcmp(pointer_name + name_len - suffix_len, suffix) != 0) {
|
segment = pointer_name + prefix_len + 1u;
|
||||||
return false;
|
name_end = pointer_name + name_len;
|
||||||
|
remote_start = memchr(segment, '/', (size_t)(name_end - segment));
|
||||||
|
if (remote_start != NULL) {
|
||||||
|
peer_len = (size_t)(remote_start - segment);
|
||||||
|
if (remote_start + 1u >= name_end) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
remote_len = (size_t)(name_end - (remote_start + 1u));
|
||||||
|
} else {
|
||||||
|
peer_len = (size_t)(name_end - segment);
|
||||||
}
|
}
|
||||||
peer_len = name_len - prefix_len - 1u - suffix_len;
|
|
||||||
if (peer_len == 0u) {
|
if (peer_len == 0u) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -349,8 +373,18 @@ static bool amduatd_space_roots_cursor_peer_from_name(
|
||||||
if (peer == NULL) {
|
if (peer == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(peer, pointer_name + prefix_len + 1u, peer_len);
|
memcpy(peer, segment, peer_len);
|
||||||
peer[peer_len] = '\0';
|
peer[peer_len] = '\0';
|
||||||
|
if (remote_len != 0u && out_remote_space_id != NULL) {
|
||||||
|
remote = (char *)malloc(remote_len + 1u);
|
||||||
|
if (remote == NULL) {
|
||||||
|
free(peer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(remote, remote_start + 1u, remote_len);
|
||||||
|
remote[remote_len] = '\0';
|
||||||
|
*out_remote_space_id = remote;
|
||||||
|
}
|
||||||
*out_peer = peer;
|
*out_peer = peer;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -552,10 +586,10 @@ bool amduatd_space_roots_list_cursor_peers(
|
||||||
|
|
||||||
for (size_t i = 0u; i < pull_heads.len; ++i) {
|
for (size_t i = 0u; i < pull_heads.len; ++i) {
|
||||||
char *peer = NULL;
|
char *peer = NULL;
|
||||||
if (amduatd_space_roots_cursor_peer_from_name(
|
if (amduatd_space_roots_cursor_parse((const char *)pull_prefix.data,
|
||||||
(const char *)pull_prefix.data,
|
pull_heads.names[i],
|
||||||
pull_heads.names[i],
|
&peer,
|
||||||
&peer)) {
|
NULL)) {
|
||||||
if (!amduatd_space_roots_list_add(out_list, peer)) {
|
if (!amduatd_space_roots_list_add(out_list, peer)) {
|
||||||
free(peer);
|
free(peer);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
@ -565,10 +599,10 @@ bool amduatd_space_roots_list_cursor_peers(
|
||||||
}
|
}
|
||||||
for (size_t i = 0u; i < push_heads.len; ++i) {
|
for (size_t i = 0u; i < push_heads.len; ++i) {
|
||||||
char *peer = NULL;
|
char *peer = NULL;
|
||||||
if (amduatd_space_roots_cursor_peer_from_name(
|
if (amduatd_space_roots_cursor_parse((const char *)push_prefix.data,
|
||||||
(const char *)push_prefix.data,
|
push_heads.names[i],
|
||||||
push_heads.names[i],
|
&peer,
|
||||||
&peer)) {
|
NULL)) {
|
||||||
if (!amduatd_space_roots_list_add(out_list, peer)) {
|
if (!amduatd_space_roots_list_add(out_list, peer)) {
|
||||||
free(peer);
|
free(peer);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,11 @@ bool amduatd_space_roots_list_cursor_peers(
|
||||||
const amduatd_space_t *effective_space,
|
const amduatd_space_t *effective_space,
|
||||||
amduatd_space_roots_list_t *out_list);
|
amduatd_space_roots_list_t *out_list);
|
||||||
|
|
||||||
|
bool amduatd_space_roots_cursor_parse(const char *prefix,
|
||||||
|
const char *pointer_name,
|
||||||
|
char **out_peer,
|
||||||
|
char **out_remote_space_id);
|
||||||
|
|
||||||
void amduatd_space_roots_list_free(amduatd_space_roots_list_t *list);
|
void amduatd_space_roots_list_free(amduatd_space_roots_list_t *list);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,42 @@ int main(void) {
|
||||||
amduat_octets_free(&name);
|
amduat_octets_free(&name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
amduat_octets_t name = amduat_octets(NULL, 0u);
|
||||||
|
bool ok = amduatd_fed_cursor_pointer_name_v2(&space,
|
||||||
|
"peer-a",
|
||||||
|
"beta",
|
||||||
|
&name);
|
||||||
|
expect(ok, "v2 cursor pointer name ok");
|
||||||
|
expect(strcmp((const char *)name.data,
|
||||||
|
"space/alpha/fed/cursor/peer-a/beta/head") == 0,
|
||||||
|
"v2 cursor pointer name matches");
|
||||||
|
amduat_octets_free(&name);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
amduat_octets_t name = amduat_octets(NULL, 0u);
|
||||||
|
bool ok = amduatd_fed_push_cursor_pointer_name_v2(&space,
|
||||||
|
"peer-a",
|
||||||
|
"beta",
|
||||||
|
&name);
|
||||||
|
expect(ok, "v2 push cursor pointer name ok");
|
||||||
|
expect(strcmp((const char *)name.data,
|
||||||
|
"space/alpha/fed/push_cursor/peer-a/beta/head") == 0,
|
||||||
|
"v2 push cursor pointer name matches");
|
||||||
|
amduat_octets_free(&name);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
amduat_octets_t name = amduat_octets(NULL, 0u);
|
||||||
|
bool ok = amduatd_fed_cursor_pointer_name_v2(&space,
|
||||||
|
"peer-a",
|
||||||
|
"bad/space",
|
||||||
|
&name);
|
||||||
|
expect(!ok, "remote space validation rejects invalid id");
|
||||||
|
amduat_octets_free(&name);
|
||||||
|
}
|
||||||
|
|
||||||
free(root);
|
free(root);
|
||||||
return failures == 0 ? 0 : 1;
|
return failures == 0 ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -375,6 +375,7 @@ int main(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"1",
|
"1",
|
||||||
|
NULL,
|
||||||
2u,
|
2u,
|
||||||
&fed_cfg,
|
&fed_cfg,
|
||||||
&transport,
|
&transport,
|
||||||
|
|
@ -478,6 +479,7 @@ int main(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"1",
|
"1",
|
||||||
|
NULL,
|
||||||
2u,
|
2u,
|
||||||
&fed_cfg,
|
&fed_cfg,
|
||||||
&transport,
|
&transport,
|
||||||
|
|
@ -550,6 +552,7 @@ int main(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"1",
|
"1",
|
||||||
|
NULL,
|
||||||
1u,
|
1u,
|
||||||
&fed_cfg,
|
&fed_cfg,
|
||||||
&transport,
|
&transport,
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,7 @@ static int amduatd_test_pull_until_zero(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"1",
|
"1",
|
||||||
|
NULL,
|
||||||
16u,
|
16u,
|
||||||
3u,
|
3u,
|
||||||
&fed_cfg,
|
&fed_cfg,
|
||||||
|
|
@ -391,6 +392,7 @@ static int amduatd_test_pull_until_multi(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"1",
|
"1",
|
||||||
|
NULL,
|
||||||
2u,
|
2u,
|
||||||
5u,
|
5u,
|
||||||
&fed_cfg,
|
&fed_cfg,
|
||||||
|
|
@ -483,6 +485,7 @@ static int amduatd_test_pull_until_error(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"1",
|
"1",
|
||||||
|
NULL,
|
||||||
1u,
|
1u,
|
||||||
4u,
|
4u,
|
||||||
&fed_cfg,
|
&fed_cfg,
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,7 @@ int main(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"2",
|
"2",
|
||||||
|
NULL,
|
||||||
16u,
|
16u,
|
||||||
root,
|
root,
|
||||||
&fed_cfg,
|
&fed_cfg,
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,7 @@ static int amduatd_test_push_until_zero(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"2",
|
"2",
|
||||||
|
NULL,
|
||||||
8u,
|
8u,
|
||||||
3u,
|
3u,
|
||||||
root,
|
root,
|
||||||
|
|
@ -308,6 +309,7 @@ static int amduatd_test_push_until_multi(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"2",
|
"2",
|
||||||
|
NULL,
|
||||||
1u,
|
1u,
|
||||||
5u,
|
5u,
|
||||||
root,
|
root,
|
||||||
|
|
@ -410,6 +412,7 @@ static int amduatd_test_push_until_error(void) {
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"2",
|
"2",
|
||||||
|
NULL,
|
||||||
1u,
|
1u,
|
||||||
4u,
|
4u,
|
||||||
root,
|
root,
|
||||||
|
|
|
||||||
|
|
@ -274,13 +274,15 @@ static int amduatd_test_mounts_resolve(void) {
|
||||||
cursor.has_record_ref = true;
|
cursor.has_record_ref = true;
|
||||||
cursor.last_record_ref = cursor_last_ref;
|
cursor.last_record_ref = cursor_last_ref;
|
||||||
memset(&cursor_ref, 0, sizeof(cursor_ref));
|
memset(&cursor_ref, 0, sizeof(cursor_ref));
|
||||||
if (amduatd_fed_cursor_cas_set(&store,
|
if (amduatd_fed_cursor_cas_set_remote(&store,
|
||||||
&pointer_store,
|
&pointer_store,
|
||||||
&space,
|
&space,
|
||||||
"peer-1",
|
"peer-1",
|
||||||
NULL,
|
"beta",
|
||||||
&cursor,
|
NULL,
|
||||||
&cursor_ref) != AMDUATD_FED_CURSOR_OK) {
|
&cursor,
|
||||||
|
&cursor_ref) !=
|
||||||
|
AMDUATD_FED_CURSOR_OK) {
|
||||||
fprintf(stderr, "failed to set cursor\n");
|
fprintf(stderr, "failed to set cursor\n");
|
||||||
amduatd_fed_cursor_record_free(&cursor);
|
amduatd_fed_cursor_record_free(&cursor);
|
||||||
amduat_reference_free(&cursor_ref);
|
amduat_reference_free(&cursor_ref);
|
||||||
|
|
@ -322,6 +324,8 @@ static int amduatd_test_mounts_resolve(void) {
|
||||||
"pinned mode present");
|
"pinned mode present");
|
||||||
expect(strstr(mounts_json, "\"pinned_root_ref\":\"") != NULL,
|
expect(strstr(mounts_json, "\"pinned_root_ref\":\"") != NULL,
|
||||||
"pinned root ref present");
|
"pinned root ref present");
|
||||||
|
expect(strstr(mounts_json, "\"cursor_namespace\":\"v2\"") != NULL,
|
||||||
|
"cursor namespace present");
|
||||||
expect(strstr(mounts_json, "\"cursor_scope\":\"per-peer-per-local-space\"") != NULL,
|
expect(strstr(mounts_json, "\"cursor_scope\":\"per-peer-per-local-space\"") != NULL,
|
||||||
"cursor scope present");
|
"cursor scope present");
|
||||||
expect(strstr(mounts_json, "\"remote_space_id\":\"beta\"") != NULL,
|
expect(strstr(mounts_json, "\"remote_space_id\":\"beta\"") != NULL,
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,8 @@ static int amduatd_test_cursor_roots(void) {
|
||||||
amduat_reference_t none_ref;
|
amduat_reference_t none_ref;
|
||||||
amduat_octets_t cursor_name = amduat_octets(NULL, 0u);
|
amduat_octets_t cursor_name = amduat_octets(NULL, 0u);
|
||||||
amduat_octets_t push_name = amduat_octets(NULL, 0u);
|
amduat_octets_t push_name = amduat_octets(NULL, 0u);
|
||||||
|
amduat_octets_t cursor_v2 = amduat_octets(NULL, 0u);
|
||||||
|
amduat_octets_t push_v2 = amduat_octets(NULL, 0u);
|
||||||
amduat_octets_t edges_collection = amduat_octets(NULL, 0u);
|
amduat_octets_t edges_collection = amduat_octets(NULL, 0u);
|
||||||
amduat_octets_t edges_index_head = amduat_octets(NULL, 0u);
|
amduat_octets_t edges_index_head = amduat_octets(NULL, 0u);
|
||||||
char *collection_head = NULL;
|
char *collection_head = NULL;
|
||||||
|
|
@ -237,7 +239,15 @@ static int amduatd_test_cursor_roots(void) {
|
||||||
amduat_artifact_free(&none_artifact);
|
amduat_artifact_free(&none_artifact);
|
||||||
|
|
||||||
if (!amduatd_fed_cursor_pointer_name(&space, "peer-a", &cursor_name) ||
|
if (!amduatd_fed_cursor_pointer_name(&space, "peer-a", &cursor_name) ||
|
||||||
!amduatd_fed_push_cursor_pointer_name(&space, "peer-b", &push_name)) {
|
!amduatd_fed_push_cursor_pointer_name(&space, "peer-b", &push_name) ||
|
||||||
|
!amduatd_fed_cursor_pointer_name_v2(&space,
|
||||||
|
"peer-a",
|
||||||
|
"beta",
|
||||||
|
&cursor_v2) ||
|
||||||
|
!amduatd_fed_push_cursor_pointer_name_v2(&space,
|
||||||
|
"peer-b",
|
||||||
|
"beta",
|
||||||
|
&push_v2)) {
|
||||||
fprintf(stderr, "failed to build cursor names\n");
|
fprintf(stderr, "failed to build cursor names\n");
|
||||||
free(root);
|
free(root);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -254,10 +264,24 @@ static int amduatd_test_cursor_roots(void) {
|
||||||
false,
|
false,
|
||||||
NULL,
|
NULL,
|
||||||
&none_ref,
|
&none_ref,
|
||||||
|
&swapped) != AMDUAT_ASL_POINTER_OK || !swapped ||
|
||||||
|
amduat_asl_pointer_cas(&pointer_store,
|
||||||
|
(const char *)cursor_v2.data,
|
||||||
|
false,
|
||||||
|
NULL,
|
||||||
|
&none_ref,
|
||||||
|
&swapped) != AMDUAT_ASL_POINTER_OK || !swapped ||
|
||||||
|
amduat_asl_pointer_cas(&pointer_store,
|
||||||
|
(const char *)push_v2.data,
|
||||||
|
false,
|
||||||
|
NULL,
|
||||||
|
&none_ref,
|
||||||
&swapped) != AMDUAT_ASL_POINTER_OK || !swapped) {
|
&swapped) != AMDUAT_ASL_POINTER_OK || !swapped) {
|
||||||
fprintf(stderr, "failed to seed cursor pointers\n");
|
fprintf(stderr, "failed to seed cursor pointers\n");
|
||||||
amduat_octets_free(&cursor_name);
|
amduat_octets_free(&cursor_name);
|
||||||
amduat_octets_free(&push_name);
|
amduat_octets_free(&push_name);
|
||||||
|
amduat_octets_free(&cursor_v2);
|
||||||
|
amduat_octets_free(&push_v2);
|
||||||
free(root);
|
free(root);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -266,6 +290,8 @@ static int amduatd_test_cursor_roots(void) {
|
||||||
fprintf(stderr, "roots list failed\n");
|
fprintf(stderr, "roots list failed\n");
|
||||||
amduat_octets_free(&cursor_name);
|
amduat_octets_free(&cursor_name);
|
||||||
amduat_octets_free(&push_name);
|
amduat_octets_free(&push_name);
|
||||||
|
amduat_octets_free(&cursor_v2);
|
||||||
|
amduat_octets_free(&push_v2);
|
||||||
free(root);
|
free(root);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -284,9 +310,11 @@ static int amduatd_test_cursor_roots(void) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list.len != 5u ||
|
if (list.len != 7u ||
|
||||||
!amduatd_list_contains(&list, (const char *)cursor_name.data) ||
|
!amduatd_list_contains(&list, (const char *)cursor_name.data) ||
|
||||||
!amduatd_list_contains(&list, (const char *)push_name.data) ||
|
!amduatd_list_contains(&list, (const char *)push_name.data) ||
|
||||||
|
!amduatd_list_contains(&list, (const char *)cursor_v2.data) ||
|
||||||
|
!amduatd_list_contains(&list, (const char *)push_v2.data) ||
|
||||||
!amduatd_list_contains(&list, (const char *)edges_index_head.data) ||
|
!amduatd_list_contains(&list, (const char *)edges_index_head.data) ||
|
||||||
!amduatd_list_contains(&list, collection_head) ||
|
!amduatd_list_contains(&list, collection_head) ||
|
||||||
!amduatd_list_contains(&list, collection_log_head) ||
|
!amduatd_list_contains(&list, collection_log_head) ||
|
||||||
|
|
@ -294,6 +322,8 @@ static int amduatd_test_cursor_roots(void) {
|
||||||
fprintf(stderr, "unexpected cursor roots list\n");
|
fprintf(stderr, "unexpected cursor roots list\n");
|
||||||
amduat_octets_free(&cursor_name);
|
amduat_octets_free(&cursor_name);
|
||||||
amduat_octets_free(&push_name);
|
amduat_octets_free(&push_name);
|
||||||
|
amduat_octets_free(&cursor_v2);
|
||||||
|
amduat_octets_free(&push_v2);
|
||||||
amduat_octets_free(&edges_collection);
|
amduat_octets_free(&edges_collection);
|
||||||
amduat_octets_free(&edges_index_head);
|
amduat_octets_free(&edges_index_head);
|
||||||
free(collection_head);
|
free(collection_head);
|
||||||
|
|
@ -305,6 +335,8 @@ static int amduatd_test_cursor_roots(void) {
|
||||||
|
|
||||||
amduat_octets_free(&cursor_name);
|
amduat_octets_free(&cursor_name);
|
||||||
amduat_octets_free(&push_name);
|
amduat_octets_free(&push_name);
|
||||||
|
amduat_octets_free(&cursor_v2);
|
||||||
|
amduat_octets_free(&push_v2);
|
||||||
amduat_octets_free(&edges_collection);
|
amduat_octets_free(&edges_collection);
|
||||||
amduat_octets_free(&edges_index_head);
|
amduat_octets_free(&edges_index_head);
|
||||||
free(collection_head);
|
free(collection_head);
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,9 @@ static int amduatd_test_peer_discovery(void) {
|
||||||
!amduatd_list_contains(&peers, "2") ||
|
!amduatd_list_contains(&peers, "2") ||
|
||||||
!amduatd_list_sorted(&peers)) {
|
!amduatd_list_sorted(&peers)) {
|
||||||
fprintf(stderr, "unexpected peers list\n");
|
fprintf(stderr, "unexpected peers list\n");
|
||||||
|
for (size_t i = 0u; i < peers.len; ++i) {
|
||||||
|
fprintf(stderr, " peer[%zu]=%s\n", i, peers.names[i]);
|
||||||
|
}
|
||||||
amduatd_space_roots_list_free(&peers);
|
amduatd_space_roots_list_free(&peers);
|
||||||
amduat_octets_free(&pull_name);
|
amduat_octets_free(&pull_name);
|
||||||
amduat_octets_free(&push_name);
|
amduat_octets_free(&push_name);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue