From 8deb05660e8124986727470f2d8bb62519360816 Mon Sep 17 00:00:00 2001 From: lostlevels Date: Thu, 2 Apr 2026 01:33:41 -0700 Subject: [PATCH 1/3] Add user_attribute to keycloak debezium source table filter. --- charts/tidepool/Chart.yaml | 2 +- .../kafka/templates/2-users-source-kafka-connector.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/tidepool/Chart.yaml b/charts/tidepool/Chart.yaml index 0769b39f8..cea07650d 100644 --- a/charts/tidepool/Chart.yaml +++ b/charts/tidepool/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 description: A Helm chart for Tidepool name: tidepool -version: 0.24.2 +version: 0.24.4 maintainers: - name: Todd Kazakov email: todd@tidepool.org diff --git a/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml b/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml index 54b944485..a31dee287 100644 --- a/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml +++ b/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml @@ -27,11 +27,11 @@ spec: value.converter: 'org.apache.kafka.connect.json.JsonConverter' value.converter.schemas.enable: false snapshot.mode: {{ .Values.keycloak.snapshotMode }} - table.include.list: 'public.user_entity,public.user_role_mapping,public.keycloak_role' + table.include.list: 'public.user_entity,public.user_role_mapping,public.keycloak_role,public.user_attribute' transforms: 'filter' transforms.filter.type: 'io.debezium.transforms.Filter' transforms.filter.language: 'jsr223.groovy' - transforms.filter.topic.regex: '.+\.public.(user_entity|keycloak_role)' - transforms.filter.condition: "value.op && (((value.op == 'r' || value.op == 'c' || value.op == 'u') && (value.after && value.after.realm_id && value.after.realm_id == '{{ $realm }}')) || (value.op == 'd'))" + transforms.filter.topic.regex: '.+\.public.(user_entity|keycloak_role|user_attribute)' + transforms.filter.condition: "value.op && (((value.op == 'r' || value.op == 'c' || value.op == 'u') && (value.after && (value.after?.realm_id == '{{ $realm }}' || value.after?.name == 'terms_and_conditions')) || (value.op == 'd'))" tasksMax: 1 {{- end }} From 15cf83e9003148c19876a24c2abea2f4c9c13674 Mon Sep 17 00:00:00 2001 From: lostlevels Date: Thu, 2 Apr 2026 04:22:44 -0700 Subject: [PATCH 2/3] Exclude user_attribute deleted from events. --- .../charts/kafka/templates/2-users-source-kafka-connector.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml b/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml index a31dee287..7c00daab4 100644 --- a/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml +++ b/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml @@ -32,6 +32,6 @@ spec: transforms.filter.type: 'io.debezium.transforms.Filter' transforms.filter.language: 'jsr223.groovy' transforms.filter.topic.regex: '.+\.public.(user_entity|keycloak_role|user_attribute)' - transforms.filter.condition: "value.op && (((value.op == 'r' || value.op == 'c' || value.op == 'u') && (value.after && (value.after?.realm_id == '{{ $realm }}' || value.after?.name == 'terms_and_conditions')) || (value.op == 'd'))" + transforms.filter.condition: "value.op && ((((value.op == 'r' || value.op == 'c' || value.op == 'u') && value?.after?.realm_id == '{{ $realm }}') || value.op == 'd') || ((value.op == 'r' || value.op == 'c' || value.op == 'u') && value?.after?.name == 'terms_and_conditions'))" tasksMax: 1 {{- end }} From 7d8c009872b6eb0952bae8be872d3d3012fb9cc2 Mon Sep 17 00:00:00 2001 From: lostlevels Date: Thu, 23 Apr 2026 13:53:23 -0700 Subject: [PATCH 3/3] Handle difference b/t table schemas. Handle difference b/t user_entity and keycloak_role having field realm_id and table user_attribute not having it. --- .../templates/2-users-source-kafka-connector.yaml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml b/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml index 7c00daab4..85717257c 100644 --- a/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml +++ b/charts/tidepool/charts/kafka/templates/2-users-source-kafka-connector.yaml @@ -28,10 +28,14 @@ spec: value.converter.schemas.enable: false snapshot.mode: {{ .Values.keycloak.snapshotMode }} table.include.list: 'public.user_entity,public.user_role_mapping,public.keycloak_role,public.user_attribute' - transforms: 'filter' + transforms: 'filter,filter_user_attr' transforms.filter.type: 'io.debezium.transforms.Filter' transforms.filter.language: 'jsr223.groovy' - transforms.filter.topic.regex: '.+\.public.(user_entity|keycloak_role|user_attribute)' - transforms.filter.condition: "value.op && ((((value.op == 'r' || value.op == 'c' || value.op == 'u') && value?.after?.realm_id == '{{ $realm }}') || value.op == 'd') || ((value.op == 'r' || value.op == 'c' || value.op == 'u') && value?.after?.name == 'terms_and_conditions'))" + transforms.filter.topic.regex: '.+\.public.(user_entity|keycloak_role)' + transforms.filter.condition: "value.op && (((value.op == 'r' || value.op == 'c' || value.op == 'u') && (value.after && value.after.realm_id && value.after.realm_id == '{{ $realm }}')) || (value.op == 'd'))" + transforms.filter_user_attr.type: 'io.debezium.transforms.Filter' + transforms.filter_user_attr.language: 'jsr223.groovy' + transforms.filter_user_attr.topic.regex: '.+\.public.(user_attribute)' + transforms.filter_user_attr.condition: "value.op && ((value.op == 'r' || value.op == 'c' || value.op == 'u') && value?.after?.name != null && value.after.name == 'terms_and_conditions')" tasksMax: 1 {{- end }}