kestra-io / kestra-io/plugin-debezium
`@PluginProperty` on concrete fields has drifted from the interface getters (postgres, oracle, mongodb)
- 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