kestra-io / kestra-io/plugin-debezium

`@PluginProperty` on concrete fields has drifted from the interface getters (postgres, oracle, mongodb)

Open
#203 0 comments 0 reactions 0 assignees View on GitHub
area/plugin good first issue
Dominant language
Java
Stars
5
Forks
11
Avg merge
2d 5h
Merged PRs (30d)
9

Description

## Summary

Several concrete task classes redeclare properties that their connector interface already annotates, but with a different `@PluginProperty` value. Java field annotations do not inherit from interface getters, so the two declarations have drifted: properties land in the wrong UI group, and two MongoDB properties lose `dynamic = true` entirely — meaning Pebble expressions in them are not rendered.

Surfaced during the documentation review in #199, which deliberately left code changes out of scope.

## Actual Behaviour

**MongoDB — `dynamic = true` lost (functional impact).**

| Location | Annotation |
|---|---|
| `mongodb/Capture.java:104-108` | `@PluginProperty(group = "advanced")` |
| `MongodbInterface.java:26,34` | `@PluginProperty(dynamic = true, group = "advanced")` |

`includedCollections` and `excludedCollections` are declared on `Capture` without `dynamic = true`. Users writing `{{ inputs.collections }}` in those properties may not get the value rendered.

**PostgreSQL — group drift on the SSL properties.**

| Property | `postgres/Capture.java` | `PostgresInterface.java` |
|---|---|---|
| `sslMode` (line 77) | *no `@PluginProperty` at all* | `group = "connection"` (line 64) |
| `sslRootCert` (line 80) | `group = "advanced"` | `group = "connection"` (line 71) |
| `sslCert` (line 83) | `group = "advanced"` | `group = "connection"` (line 78) |
| `sslKey` (line 86) | `group = "connection"` | `group = "connection", secret = true` (line 85) ✓ |
| `sslKeyPassword` (line 89) | `group = "connection", secret = true` | `group = "connection", secret = true` (line 91) ✓ |

`sslMode` carries no `@PluginProperty` on the field, so it has no declared group at that level.

**Oracle — group drift on `snapshotMode`.**

| Location | Annotation |
|---|---|
| `oracle/Capture.java:82` | `@PluginProperty(group = "advanced")` |
| `OracleInterface.java` (getter) | `@PluginProperty(dynamic = false, group = "main")` |

`snapshotMode` is a primary-intent property; `"main"` is the correct group per the plugin standards, and the field says `"advanced"`.

**MySQL — `serverId`.** The same class of drift affects `mysql.Capture.serverId` (`group = "main"` on the field vs `group = "advanced"` on the interface). That property has additional problems and is tracked in its own issue; fixing it there is fine, but the group alignment should be consistent with whatever is decided here.

## Expected Behaviour

For every property redeclared on a concrete class, the `@PluginProperty` on the field matches the interface getter exactly — same `group`, same `dynamic`, same `secret`. Where they legitimately should differ, the interface is the one to change, so a single source of truth remains.

Concretely, per the plugin property-group standards:

- `snapshotMode` → `"main"` (required, primary intent)
- `sslMode`, `sslRootCert`, `sslCert`, `sslKey`, `sslKeyPassword` → `"connection"` (authentication/endpoint)
- `includedCollections` / `excludedCollections` → `"advanced"` **with** `dynamic = true`

## Reproducer

No runtime reproducer for the grouping drift — it is visible in the generated plugin documentation and in the UI's property form, where these properties appear under a different heading than the interface declares.

For the MongoDB `dynamic` loss:

```yaml
id: mongodb_dynamic_collections
namespace: company.team

inputs:
- id: collections
type: STRING
defaults: "inventory[.]*"

tasks:
- id: capture
type: io.kestra.plugin.debezium.mongodb.Capture
connectionString: "{{ secret('MONGODB_CONNECTION_STRING') }}"
snapshotMode: INITIAL
includedCollections: "{{ inputs.collections }}"
maxRecords: 100
```

Check whether `includedCollections` reaches the connector as the rendered value or as the literal `{{ inputs.collections }}` template.

## Logs / Stack Trace

No logs available — the failure mode is misplaced UI grouping and, for MongoDB, an unrendered expression rather than an error.

## Environment

- **Kestra version**: 1.3.16 (`kestraVersion` in `gradle.properties`)
- **Plugin version**: 1.4.7
- **Deployment**: n/a — source-level defect, reproducible on any deployment

## Acceptance Criteria

- [ ] `mongodb.Capture.includedCollections` / `excludedCollections` carry `dynamic = true`, matching `MongodbInterface`
- [ ] The MongoDB reproducer above confirms the expression is rendered
- [ ] `postgres.Capture` SSL properties are grouped `"connection"`, matching `PostgresInterface`; `sslMode` gets an explicit `@PluginProperty`
- [ ] `oracle.Capture.snapshotMode` is grouped `"main"`, matching `OracleInterface`
- [ ] A sweep confirms no other concrete field disagrees with its interface getter across the six modules
- [ ] Consider whether these redeclarations are needed at all — several exist only to attach `@Builder.Default`, and dropping the redundant `@PluginProperty` would remove the drift surface permanently

## Additional Context

Flagged in the review of #199 (documentation-only PR). The root cause is structural: Java does not inherit annotations from interface methods to implementing fields, so every redeclared property is a place where the two can silently diverge. A sweep plus a convention (annotate in one place only) is more durable than fixing the four current instances.

---
*[View as Artifact](https://claude.ai/code/artifact/055cde84-05a0-49aa-9084-81b39af50c23)*

Contributor guide

No contributing guide indexed for this repository

Research direction

Compare the annotations in mongodb/Capture.java and MongodbInterface.java, postgres/Capture.java and PostgresInterface.java, and oracle/Capture.java and OracleInterface.java, then inspect the corresponding concrete fields across the six modules. Run the MongoDB YAML reproducer to verify expression rendering and sweep each redeclared field for matching group, dynamic, and secret values. Done means the listed properties align and the sweep finds no remaining disagreement.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, mongodb, mysql, postgresql
Domain
databases
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.