Skip to content

Commit

Permalink
[#4267] Add management command to migrate existing configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
Viicos committed Jul 23, 2024
1 parent 9280bb2 commit cdd2db5
Show file tree
Hide file tree
Showing 7 changed files with 732 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/openforms/contrib/zgw/clients/catalogi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Callable, Iterator
from typing import Any, Callable, Iterator
from uuid import UUID

from zgw_consumers.nlx import NLXClient

Expand Down Expand Up @@ -43,6 +44,11 @@ def get_all_informatieobjecttypen(self, *, catalogus: str = "") -> Iterator[dict
data = response.json()
yield from pagination_helper(self, data)

def get_informatieobjecttype(self, uuid: str | UUID) -> dict[str, Any]:
response = self.get(f"informatieobjecttypen/{uuid}")
response.raise_for_status()
return response.json()

def list_statustypen(self, zaaktype: str) -> list[dict]:
query = {"zaaktype": zaaktype}

Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from typing import Any

from django.core.management import BaseCommand

import requests

from openforms.forms.models import FormRegistrationBackend
from openforms.registrations.contrib.objects_api.models import ObjectsAPIGroupConfig

from ...client import get_catalogi_client
from ...plugin import PLUGIN_IDENTIFIER as OBJECTS_API_PLUGIN_IDENTIFIER

IOT_FIELDS = (
"informatieobjecttype_submission_report",
"informatieobjecttype_submission_csv",
"informatieobjecttype_attachment",
)


class SkipBackend(Exception):
"""The backend options were already migrated."""


class InvalidBackend(Exception):
"""The backend options are invalid and can't be migrated."""

def __init__(self, message: str, /) -> None:
self.message = message


def migrate_registration_backend(options: dict[str, Any]) -> None:
# idempotent check:
if "catalogus_domein" in options:
raise SkipBackend

try:
config = ObjectsAPIGroupConfig.objects.get(pk=options["objects_api_group"])
except ObjectsAPIGroupConfig.DoesNotExist:
raise InvalidBackend("The configured objects API group does not exist")

iot_omschrijving: dict[str, str] = {}

with get_catalogi_client(config) as catalogi_client:
catalogus_domein: str | None = None
catalogus_rsin: str | None = None

for field in IOT_FIELDS:
if url := options.get(field):
try:
uuid = url.rsplit("/", 1)[1]
except IndexError:
raise InvalidBackend(f"{field}: {url} is invalid")

try:
iot = catalogi_client.get_informatieobjecttype(uuid)
except requests.HTTPError as e:
if (status := e.response.status_code) == 404:
raise InvalidBackend(f"{field}: {url} does not exist")
else:
raise RuntimeError(
f"Encountered {status} error when fetching informatieobjecttype {uuid}"
)

catalogus_resp = catalogi_client.get(iot["catalogus"])
if not catalogus_resp.ok:
raise RuntimeError(
f"Encountered {catalogus_resp.status_code} error when fetching catalog {iot['catalogus']}"
)
catalogus = catalogus_resp.json()

if catalogus_domein is None and catalogus_rsin is None:
catalogus_domein = catalogus["domein"]
catalogus_rsin = catalogus["rsin"]
else:
if (
catalogus["domein"] != catalogus_domein
or catalogus["rsin"] != catalogus_rsin
):
raise InvalidBackend(
"Informatieobjecttypes don't share the same catalog"
)

iot_omschrijving[field] = iot["omschrijving"]

if catalogus_domein is not None and catalogus_rsin is not None:
options["catalogus_domein"] = catalogus_domein
options["catalogus_rsin"] = catalogus_rsin

for field in IOT_FIELDS:
if field in iot_omschrijving:
options[field] = iot_omschrijving[field]


class Command(BaseCommand):
help = (
"Migrate existing Objects API form registration backends "
"to switch from an informatieobjectype URL to a omschrijving and catalogus."
)

def handle(self, **options):
for registration_backend in FormRegistrationBackend.objects.filter(
backend=OBJECTS_API_PLUGIN_IDENTIFIER
):
backend_name = registration_backend.name

try:
migrate_registration_backend(registration_backend.options)
except SkipBackend:
self.stdout.write(f"{backend_name!r} was already migrated")
except InvalidBackend as e:
self.stderr.write(
f"{backend_name!r} configuration is invalid: {e.message!r}"
)
except RuntimeError as e:
self.stderr.write(
f"Encountered runtime error when trying to migrate {backend_name!r}: {e.args[0]!r}"
)
else:
registration_backend.save()
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Authorization:
- Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0X2NsaWVudF9pZCIsImlhdCI6MTcyMTM4MDMzMCwiY2xpZW50X2lkIjoidGVzdF9jbGllbnRfaWQiLCJ1c2VyX2lkIjoiIiwidXNlcl9yZXByZXNlbnRhdGlvbiI6IiJ9.hwTglJOQWFg8kKGO_-lZUg5FBp17bCkbqh8nCbpVgV0
Connection:
- keep-alive
User-Agent:
- python-requests/2.32.2
method: GET
uri: http://localhost:8003/catalogi/api/v1/informatieobjecttypen/d1cfb1d8-8593-4814-919d-72e38e80388f
response:
body:
string: '{"url":"http://localhost:8003/catalogi/api/v1/informatieobjecttypen/d1cfb1d8-8593-4814-919d-72e38e80388f","catalogus":"http://localhost:8003/catalogi/api/v1/catalogussen/630271f6-568a-485e-b1c4-4ed2d6ab3a58","omschrijving":"CSV
Informatieobjecttype other catalog","vertrouwelijkheidaanduiding":"openbaar","beginGeldigheid":"2024-07-19","eindeGeldigheid":null,"concept":false,"besluittypen":[],"informatieobjectcategorie":"Test
category","trefwoord":[],"omschrijvingGeneriek":{"informatieobjecttypeOmschrijvingGeneriek":"","definitieInformatieobjecttypeOmschrijvingGeneriek":"","herkomstInformatieobjecttypeOmschrijvingGeneriek":"","hierarchieInformatieobjecttypeOmschrijvingGeneriek":"","opmerkingInformatieobjecttypeOmschrijvingGeneriek":""},"zaaktypen":[],"beginObject":"2024-07-19","eindeObject":null}'
headers:
API-version:
- 1.3.1
Allow:
- GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Length:
- '804'
Content-Type:
- application/json
Cross-Origin-Opener-Policy:
- same-origin
ETag:
- '"c8e3c727b5a6eb192feeb5fdc3c12c67"'
Referrer-Policy:
- same-origin
Vary:
- Accept, origin
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Authorization:
- Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0X2NsaWVudF9pZCIsImlhdCI6MTcyMTM4MDMzMCwiY2xpZW50X2lkIjoidGVzdF9jbGllbnRfaWQiLCJ1c2VyX2lkIjoiIiwidXNlcl9yZXByZXNlbnRhdGlvbiI6IiJ9.hwTglJOQWFg8kKGO_-lZUg5FBp17bCkbqh8nCbpVgV0
Connection:
- keep-alive
User-Agent:
- python-requests/2.32.2
method: GET
uri: http://localhost:8003/catalogi/api/v1/catalogussen/630271f6-568a-485e-b1c4-4ed2d6ab3a58
response:
body:
string: '{"url":"http://localhost:8003/catalogi/api/v1/catalogussen/630271f6-568a-485e-b1c4-4ed2d6ab3a58","domein":"OTHER","rsin":"000000000","contactpersoonBeheerNaam":"Test
name","contactpersoonBeheerTelefoonnummer":"","contactpersoonBeheerEmailadres":"","zaaktypen":[],"besluittypen":[],"informatieobjecttypen":["http://localhost:8003/catalogi/api/v1/informatieobjecttypen/d1cfb1d8-8593-4814-919d-72e38e80388f"],"naam":"Test
catalog 2","versie":"","begindatumVersie":null}'
headers:
API-version:
- 1.3.1
Allow:
- GET, HEAD, OPTIONS
Content-Length:
- '466'
Content-Type:
- application/json
Cross-Origin-Opener-Policy:
- same-origin
ETag:
- '"7236b46ee9fd8c1eb24dd69c2e5cd51c"'
Referrer-Policy:
- same-origin
Vary:
- Accept, origin
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Authorization:
- Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0X2NsaWVudF9pZCIsImlhdCI6MTcyMTM4MDMzMCwiY2xpZW50X2lkIjoidGVzdF9jbGllbnRfaWQiLCJ1c2VyX2lkIjoiIiwidXNlcl9yZXByZXNlbnRhdGlvbiI6IiJ9.hwTglJOQWFg8kKGO_-lZUg5FBp17bCkbqh8nCbpVgV0
Connection:
- keep-alive
User-Agent:
- python-requests/2.32.2
method: GET
uri: http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7
response:
body:
string: '{"url":"http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7","catalogus":"http://localhost:8003/catalogi/api/v1/catalogussen/bd58635c-793e-446d-a7e0-460d7b04829d","omschrijving":"Attachment
Informatieobjecttype","vertrouwelijkheidaanduiding":"openbaar","beginGeldigheid":"2024-03-19","eindeGeldigheid":"2024-07-10","concept":false,"besluittypen":[],"informatieobjectcategorie":"Test
category","trefwoord":[],"omschrijvingGeneriek":{"informatieobjecttypeOmschrijvingGeneriek":"","definitieInformatieobjecttypeOmschrijvingGeneriek":"","herkomstInformatieobjecttypeOmschrijvingGeneriek":"","hierarchieInformatieobjecttypeOmschrijvingGeneriek":"","opmerkingInformatieobjecttypeOmschrijvingGeneriek":""},"zaaktypen":["http://localhost:8003/catalogi/api/v1/zaaktypen/1f41885e-23fc-4462-bbc8-80be4ae484dc"],"beginObject":"2024-03-19","eindeObject":"2024-07-10"}'
headers:
API-version:
- 1.3.1
Allow:
- GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Length:
- '899'
Content-Type:
- application/json
Cross-Origin-Opener-Policy:
- same-origin
ETag:
- '"cf350f1b55d7eb0ccd17cceb88c1c6c8"'
Referrer-Policy:
- same-origin
Vary:
- Accept, origin
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Authorization:
- Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0X2NsaWVudF9pZCIsImlhdCI6MTcyMTM4MDMzMCwiY2xpZW50X2lkIjoidGVzdF9jbGllbnRfaWQiLCJ1c2VyX2lkIjoiIiwidXNlcl9yZXByZXNlbnRhdGlvbiI6IiJ9.hwTglJOQWFg8kKGO_-lZUg5FBp17bCkbqh8nCbpVgV0
Connection:
- keep-alive
User-Agent:
- python-requests/2.32.2
method: GET
uri: http://localhost:8003/catalogi/api/v1/catalogussen/bd58635c-793e-446d-a7e0-460d7b04829d
response:
body:
string: '{"url":"http://localhost:8003/catalogi/api/v1/catalogussen/bd58635c-793e-446d-a7e0-460d7b04829d","domein":"TEST","rsin":"000000000","contactpersoonBeheerNaam":"Test
name","contactpersoonBeheerTelefoonnummer":"","contactpersoonBeheerEmailadres":"","zaaktypen":["http://localhost:8003/catalogi/api/v1/zaaktypen/1f41885e-23fc-4462-bbc8-80be4ae484dc"],"besluittypen":[],"informatieobjecttypen":["http://localhost:8003/catalogi/api/v1/informatieobjecttypen/7a474713-0833-402a-8441-e467c08ac55b","http://localhost:8003/catalogi/api/v1/informatieobjecttypen/b2d83b94-9b9b-4e80-a82f-73ff993c62f3","http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7","http://localhost:8003/catalogi/api/v1/informatieobjecttypen/29b63e5c-3835-4f68-8fad-f2aea9ae6b71"],"naam":"Test
catalog","versie":"","begindatumVersie":null}'
headers:
API-version:
- 1.3.1
Allow:
- GET, HEAD, OPTIONS
Content-Length:
- '846'
Content-Type:
- application/json
Cross-Origin-Opener-Policy:
- same-origin
ETag:
- '"3b954569daa5871216ebb13dbf11eb9e"'
Referrer-Policy:
- same-origin
Vary:
- Accept, origin
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Authorization:
- Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0X2NsaWVudF9pZCIsImlhdCI6MTcyMTM4MDMzMCwiY2xpZW50X2lkIjoidGVzdF9jbGllbnRfaWQiLCJ1c2VyX2lkIjoiIiwidXNlcl9yZXByZXNlbnRhdGlvbiI6IiJ9.hwTglJOQWFg8kKGO_-lZUg5FBp17bCkbqh8nCbpVgV0
Connection:
- keep-alive
User-Agent:
- python-requests/2.32.2
method: GET
uri: http://localhost:8003/catalogi/api/v1/informatieobjecttypen/996946c4-92e8-4bf2-a18f-3ef41dbb423f
response:
body:
string: '{"type":"http://localhost:8003/ref/fouten/NotFound/","code":"not_found","title":"Niet
gevonden.","status":404,"detail":"Niet gevonden.","instance":"urn:uuid:9878f790-825a-4eaa-9ff4-fd66d0442a00"}'
headers:
API-version:
- 1.3.1
Allow:
- GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Length:
- '195'
Content-Type:
- application/json
Cross-Origin-Opener-Policy:
- same-origin
Referrer-Policy:
- same-origin
Vary:
- Accept, origin
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
status:
code: 404
message: Not Found
version: 1
Loading

0 comments on commit cdd2db5

Please sign in to comment.