Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 1 addition & 22 deletions docker/setup_configuration/data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ sites_config:
zgw_consumers_config_enable: true
zgw_consumers:
services:
- identifier: objecttypes-api
label: Objecttypes API
api_root: http://objecttypes-web:8000/api/v2/
api_connection_check_path: objecttypes
api_type: orc
auth_type: api_key
header_key: Authorization
header_value: Token b9f100590925b529664ed9d370f5f8da124b2c20

- identifier: notifications-api
label: Notificaties API
api_root: http://notificaties.local/api/v1/
Expand All @@ -35,18 +26,6 @@ notifications_config:
notification_delivery_retry_backoff_max: 3


objecttypes_config_enable: true
objecttypes:
items:
- uuid: b427ef84-189d-43aa-9efd-7bb2c459e281
name: Object Type 1
service_identifier: objecttypes-api

- uuid: b0e8553f-8b1a-4d55-ab90-6d02f1bcf2c2
name: Object Type 2
service_identifier: objecttypes-api


tokenauth_config_enable: true
tokenauth:
items:
Expand Down Expand Up @@ -119,4 +98,4 @@ oidc_db_config_admin_auth:
default_groups: []
make_users_staff: true
superuser_group_names:
- Registreerders
- Registreerders
8 changes: 1 addition & 7 deletions docs/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Database
* ``DB_HOST``: hostname of the PostgreSQL database. Defaults to ``db`` for the docker environment, otherwise defaults to ``localhost``.
* ``DB_PORT``: port number of the database. Defaults to: ``5432``.
* ``DB_CONN_MAX_AGE``: The lifetime of a database connection, as an integer of seconds. Use 0 to close database connections at the end of each request — Django’s historical behavior. This setting is ignored if connection pooling is used. Defaults to: ``60``.
* ``DB_POOL_ENABLED``: **Experimental:** Whether to use connection pooling. This feature is not yet recommended for production use. See the documentation for details: https://open-api-framework.readthedocs.io/en/latest/connection_pooling.html. Defaults to: ``False``.
* ``DB_POOL_ENABLED``: Whether to use connection pooling. Defaults to: ``False``.
* ``DB_POOL_MIN_SIZE``: The minimum number of connection the pool will hold. The pool will actively try to create new connections if some are lost (closed, broken) and will try to never go below min_size. Defaults to: ``4``.
* ``DB_POOL_MAX_SIZE``: The maximum number of connections the pool will hold. If None, or equal to min_size, the pool will not grow or shrink. If larger than min_size, the pool can grow if more than min_size connections are requested at the same time and will shrink back after the extra connections have been unused for more than max_idle seconds. Defaults to: ``None``.
* ``DB_POOL_TIMEOUT``: The default maximum time in seconds that a client can wait to receive a connection from the pool (using connection() or getconn()). Note that these methods allow to override the timeout default. Defaults to: ``30``.
Expand Down Expand Up @@ -98,12 +98,6 @@ Content Security Policy
* ``CSP_REPORT_PERCENTAGE``: Fraction (between 0 and 1) of requests to include report-uri directive. Defaults to: ``0.0``.


Cache
-----

* ``OBJECTTYPE_VERSION_CACHE_TIMEOUT``: Timeout in seconds for cache when retrieving objecttype versions. Defaults to: ``300``.


Optional
--------

Expand Down
1 change: 0 additions & 1 deletion performance_test/create_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from objects.token.tests.factories import PermissionFactory, TokenAuthFactory

object_type = ObjectTypeFactory.create(
service__api_root="http://localhost:8001/api/v2/",
uuid="f1220670-8ab7-44f1-a318-bd0782e97662",
)

Expand Down
2 changes: 2 additions & 0 deletions requirements/base.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ furl
# Django libraries
django-capture-tag

django-jsonsuit

# Common ground libraries
django-setup-configuration>=0.5.0
notifications-api-common[setup-configuration]
Expand Down
3 changes: 3 additions & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ django==5.2.8
# django-filter
# django-formtools
# django-jsonform
# django-jsonsuit
# django-log-outgoing-requests
# django-markup
# django-otp
Expand Down Expand Up @@ -138,6 +139,8 @@ django-jsonform==2.22.0
# via
# mozilla-django-oidc-db
# open-api-framework
django-jsonsuit==0.5.0
# via -r requirements/base.in
django-log-outgoing-requests==0.6.1
# via open-api-framework
django-markup==1.8.1
Expand Down
5 changes: 5 additions & 0 deletions requirements/ci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ django==5.2.8
# django-filter
# django-formtools
# django-jsonform
# django-jsonsuit
# django-log-outgoing-requests
# django-markup
# django-otp
Expand Down Expand Up @@ -222,6 +223,10 @@ django-jsonform==2.22.0
# -r requirements/base.txt
# mozilla-django-oidc-db
# open-api-framework
django-jsonsuit==0.5.0
# via
# -c requirements/base.txt
# -r requirements/base.txt
django-log-outgoing-requests==0.6.1
# via
# -c requirements/base.txt
Expand Down
5 changes: 5 additions & 0 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ django==5.2.8
# django-filter
# django-formtools
# django-jsonform
# django-jsonsuit
# django-log-outgoing-requests
# django-markup
# django-otp
Expand Down Expand Up @@ -266,6 +267,10 @@ django-jsonform==2.22.0
# -r requirements/ci.txt
# mozilla-django-oidc-db
# open-api-framework
django-jsonsuit==0.5.0
# via
# -c requirements/ci.txt
# -r requirements/ci.txt
django-log-outgoing-requests==0.6.1
# via
# -c requirements/ci.txt
Expand Down
5 changes: 5 additions & 0 deletions src/objects/accounts/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ class Params:
)


class SuperUserFactory(UserFactory):
is_staff = True
is_superuser = True


class StaffUserFactory(UserFactory):
is_staff = True

Expand Down
55 changes: 0 additions & 55 deletions src/objects/api/fields.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.utils.encoding import smart_str
from django.utils.translation import gettext_lazy as _

from rest_framework import serializers
from vng_api_common.serializers import CachedHyperlinkedIdentityField
from vng_api_common.utils import get_uuid_from_path
from zgw_consumers.models import Service

from objects.core.models import ObjectRecord

Expand All @@ -15,7 +9,6 @@ def get_queryset(self):
queryset = ObjectRecord.objects.select_related(
"object",
"object__object_type",
"object__object_type__service",
"correct",
"corrected",
).order_by("-pk")
Expand All @@ -27,54 +20,6 @@ def get_queryset(self):
return queryset.filter(object=record_instance.object)


class ObjectTypeField(serializers.RelatedField):
default_error_messages = {
"max_length": _("The value has too many characters"),
"min_length": _("The value has too few characters"),
"does_not_exist": _("ObjectType with url={value} is not configured."),
"invalid": _("Invalid value."),
}

def __init__(self, **kwargs):
self.max_length = kwargs.pop("max_length", None)
self.min_length = kwargs.pop("min_length", None)

super().__init__(**kwargs)

def to_internal_value(self, data):
if self.max_length and len(data) > self.max_length:
self.fail("max_length")

if self.min_length and len(data) < self.min_length:
self.fail("min_length")

try:
return self.get_queryset().get_by_url(data)
except ObjectDoesNotExist:
# if service is configured, but object_type is missing
# let's try to create an ObjectType
service = Service.get_service(data)
if not service:
self.fail("does_not_exist", value=smart_str(data))

uuid = get_uuid_from_path(data)
object_type = self.get_queryset().model(service=service, uuid=uuid)

try:
object_type.clean()
except ValidationError:
self.fail("does_not_exist", value=smart_str(data))

object_type.save()
return object_type

except (TypeError, ValueError):
self.fail("invalid")

def to_representation(self, obj):
return obj.url


class ObjectUrlField(serializers.HyperlinkedIdentityField):
lookup_field = "uuid"

Expand Down
6 changes: 5 additions & 1 deletion src/objects/api/kanalen.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from rest_framework.request import Request

from objects.core.models import ObjectRecord
from objects.tests.v2.utils import reverse


class ObjectKanaal(Kanaal):
Expand All @@ -32,7 +33,10 @@ def get_kenmerken(
data = data or {}
return {
kenmerk: (
data.get("type") or obj._object_type.url
data.get("type")
or request.build_absolute_url(
reverse("objecttype-detail", args=[data.object_type.uuid])
)
if kenmerk == "object_type"
else data.get(kenmerk, getattr(obj, kenmerk))
)
Expand Down
26 changes: 22 additions & 4 deletions src/objects/api/metrics.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
from opentelemetry import metrics

meter = metrics.get_meter("objects.api")
object_meter = metrics.get_meter("objects.api")

objects_create_counter = meter.create_counter(
objects_create_counter = object_meter.create_counter(
"objects.object.creates",
description="Amount of objects created (via the API).",
unit="1",
)
objects_update_counter = meter.create_counter(
objects_update_counter = object_meter.create_counter(
"objects.object.updates",
description="Amount of objects updated (via the API).",
unit="1",
)
objects_delete_counter = meter.create_counter(
objects_delete_counter = object_meter.create_counter(
"objects.object.deletes",
description="Amount of objects deleted (via the API).",
unit="1",
)

objecttype_meter = metrics.get_meter("objecttypes.api.v2")

objecttype_create_counter = objecttype_meter.create_counter(
"objecttypes.objecttype.creates",
description="Amount of objecttypes created (via the API).",
unit="1",
)
objecttype_update_counter = objecttype_meter.create_counter(
"objecttypes.objecttype.updates",
description="Amount of objecttypes updated (via the API).",
unit="1",
)
objecttype_delete_counter = objecttype_meter.create_counter(
"objecttypes.objecttype.deletes",
description="Amount of objecttypes deleted (via the API).",
unit="1",
)
17 changes: 17 additions & 0 deletions src/objects/api/mixins.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.http import Http404

from notifications_api_common.viewsets import (
NotificationCreateMixin,
Expand All @@ -8,6 +10,7 @@
)
from rest_framework.exceptions import NotAcceptable
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework_nested.viewsets import NestedViewSetMixin as _NestedViewSetMixin
from vng_api_common.exceptions import PreconditionFailed
from vng_api_common.geo import (
DEFAULT_CRS,
Expand All @@ -18,6 +21,20 @@
)


class NestedViewSetMixin(_NestedViewSetMixin):
def get_queryset(self):
"""
catch validation errors if parent_lookup_kwargs have incorrect format
and return 404
"""
try:
queryset = super().get_queryset()
except ValidationError:
raise Http404

return queryset


class GeoMixin(_GeoMixin):
def perform_crs_negotation(self, request):
# don't cripple the browsable API...
Expand Down
Loading
Loading