Skip to content

Commit 1afce90

Browse files
committed
feat(housekeeping): Support for retrieving default Realm replication settings via API
Expose the default ScyllaDB replication settings (SimpleStrategy or NetworkTopologyStrategy) configured in the Astarte instance. This allows administrators to query the fallback parameters used during Realm creation. Changes: - Implement `RealmController.get_default_replication/2` to fetch and return replication config. - Update Router to include the new `/realm-defaults/replication` path. - Update OpenAPI specification with the new endpoint and `DefaultReplication` schema. - Fix YAML indentation for existing response codes in `astarte_housekeeping_api.yaml`. Signed-off-by: Eddy Babetto <eddy.babetto@secomind.com>
1 parent 06837cb commit 1afce90

4 files changed

Lines changed: 108 additions & 0 deletions

File tree

apps/astarte_housekeeping/lib/astarte_housekeeping_web/controllers/realm_controller.ex

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ defmodule Astarte.HousekeepingWeb.RealmController do
2020
use Astarte.HousekeepingWeb, :controller
2121
use OpenApiSpex.ControllerSpecs
2222

23+
alias Astarte.Housekeeping.Config
2324
alias Astarte.Housekeeping.Realms
2425
alias Astarte.Housekeeping.Realms.Realm
2526
alias OpenApiSpex.{Reference, Schema}
@@ -171,6 +172,19 @@ defmodule Astarte.HousekeepingWeb.RealmController do
171172
unprocessable_entity: "Connected devices present"
172173
]
173174

175+
operation :get_default_replication,
176+
summary: "Get default Realm replication settings",
177+
description: "Retrieves the default DB replication settings applied to new Realms.",
178+
operation_id: "getDefaultReplication",
179+
responses: [
180+
ok:
181+
{"Success", "application/json",
182+
%Reference{"$ref": "#/components/schemas/DefaultReplication"}},
183+
unauthorized: %Reference{"$ref": "#/components/responses/Unauthorized"},
184+
forbidden: %Reference{"$ref": "#/components/responses/AuthorizationPathNotMatched"},
185+
service_unavailable: "Astarte is unable to retrieve the replication settings."
186+
]
187+
174188
def index(conn, _params) do
175189
with {:ok, realms} <- Realms.list_realms() do
176190
render(conn, "index.json", realms: realms)
@@ -224,6 +238,27 @@ defmodule Astarte.HousekeepingWeb.RealmController do
224238
end
225239
end
226240

241+
def get_default_replication(conn, _params) do
242+
# TODO: this function needs to retrieve the default replication from the db
243+
# to change once the appropriate pr has been merged
244+
replication =
245+
case Config.astarte_keyspace_replication_strategy!() do
246+
:simple_strategy ->
247+
%{
248+
replication_class: :simple_strategy,
249+
replication_factor: Config.astarte_keyspace_replication_factor!()
250+
}
251+
252+
:network_topology_strategy ->
253+
%{
254+
replication_class: :network_topology_strategy,
255+
datacenter_replication_factor: Config.astarte_keyspace_network_replication_map!()
256+
}
257+
end
258+
259+
render(conn, "replication.json", replication: replication)
260+
end
261+
227262
defp normalize_update_attrs(update_attrs) when is_map(update_attrs) do
228263
update_attrs
229264
|> Map.replace_lazy(:device_registration_limit, &normalize_integer_or_nil/1)

apps/astarte_housekeeping/lib/astarte_housekeeping_web/router.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ defmodule Astarte.HousekeepingWeb.Router do
2828
pipe_through :api
2929

3030
get "/version", VersionController, :show
31+
get "/realm-defaults/replication", RealmController, :get_default_replication
3132

3233
resources "/realms", RealmController,
3334
except: [:new, :edit, :update],

apps/astarte_housekeeping/lib/astarte_housekeeping_web/views/realm_view.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ defmodule Astarte.HousekeepingWeb.RealmView do
3434
realm.realm_name
3535
end
3636

37+
def render("replication.json", %{replication: replication}) do
38+
%{data: replication}
39+
end
40+
3741
def render("realm.json", %{realm: %Realm{replication_class: "SimpleStrategy"} = realm}) do
3842
%{
3943
data: %{

apps/astarte_housekeeping/priv/static/astarte_housekeeping_api.yaml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,55 @@ paths:
212212
detail: Not found
213213
requestBody:
214214
$ref: "#/components/requestBodies/updateRealmBody"
215+
/realm-defaults/replication:
216+
get:
217+
tags:
218+
- realm
219+
summary: Get default Realm replication settings
220+
description: >-
221+
Retrieves the default ScyllaDB replication settings configured for this Astarte instance.
222+
These are the settings that Astarte will automatically enforce when a new Realm is
223+
created without explicit replication parameters.
224+
operationId: getDefaultReplication
225+
security:
226+
- JWT: []
227+
responses:
228+
"200":
229+
description: Success
230+
content:
231+
application/json:
232+
schema:
233+
type: object
234+
properties:
235+
data:
236+
$ref: "#/components/schemas/DefaultReplication"
237+
"401":
238+
description: Authorization information is missing or invalid.
239+
content:
240+
application/json:
241+
schema:
242+
$ref: "#/components/schemas/GenericError"
243+
example:
244+
errors:
245+
detail: Unauthorized
246+
"403":
247+
description: Forbidden. The provided JWT token does not grant access to system configurations.
248+
content:
249+
application/json:
250+
schema:
251+
$ref: "#/components/schemas/GenericError"
252+
example:
253+
errors:
254+
detail: Forbidden
255+
"503":
256+
description: Service Unavailable. Astarte is unable to retrieve the replication settings.
257+
content:
258+
application/json:
259+
schema:
260+
$ref: "#/components/schemas/GenericError"
261+
example:
262+
errors:
263+
detail: "Service Unavailable: unable to fetch topology from ScyllaDB"
215264
components:
216265
securitySchemes:
217266
JWT:
@@ -345,6 +394,25 @@ components:
345394
f9jgaxW4oQV85enS/OJrrC9jU11agRc4bDv1h4s2t+ETWb4llTVk3HMIHbC3EvKJ
346395
VwIDAQAB
347396
-----END PUBLIC KEY-----
397+
DefaultReplication:
398+
type: object
399+
required:
400+
- replication_class
401+
properties:
402+
replication_class:
403+
type: string
404+
example: "NetworkTopologyStrategy"
405+
description: "The default Replication Class used for new realms (e.g., SimpleStrategy or NetworkTopologyStrategy)."
406+
replication_factor:
407+
type: integer
408+
example: 3
409+
description: 'The default replication factor. Populated only if replication_class is "SimpleStrategy".'
410+
datacenter_replication_factor:
411+
type: object
412+
example:
413+
datacenter_1: 3
414+
datacenter_2: 2
415+
description: 'The default datacenter replication map. Populated only if replication_class is "NetworkTopologyStrategy".'
348416
GenericError:
349417
type: object
350418
required:

0 commit comments

Comments
 (0)