[Fix #1690] Add metadata() method to WorkflowInstance - #1692
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Restore constant compatibility and expose metadata through the persistence-facing contract.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds metadata access APIs to workflow instances for persistence integrations.
Changes:
- Introduces
MetadataOperationsfor metadata retrieval and mutation. - Exposes metadata operations through
WorkflowInstanceand implements them inWorkflowMutableInstance. - Narrows
CLOUD_EVENT_IDSvisibility.
File summaries
| File | Summary |
|---|---|
impl/persistence/api/src/main/java/io/serverlessworkflow/impl/persistence/AbstractPersistenceInstanceWriter.java |
Changes cloud-event constant visibility. |
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowMutableInstance.java |
Implements metadata access and typed removal. |
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstance.java |
Extends the metadata operations API. |
impl/core/src/main/java/io/serverlessworkflow/impl/MetadataOperations.java |
Defines metadata operations. |
Review details
Suppressed comments (1)
impl/core/src/main/java/io/serverlessworkflow/impl/MetadataOperations.java:29
metadata()is only declared onMetadataOperations, which is inherited byWorkflowInstance, but persistence callbacks receiveWorkflowContextDatawhoseinstanceData()type isWorkflowInstanceData. Consequently a persistence implementation cannot call this new method through the public contract (unlikefindMetadata), so the stated persistence use case still requires an implementation-specific cast. Expose the map fromWorkflowInstanceDataor change the persistence context contract so writers can access it directly.
Map<String, Object> metadata();
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
Critical API compatibility issues and a destructive typed-removal bug remain unresolved.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (1)
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowMutableInstance.java:459
- The entry is removed before its type is checked, so
removeMetadata("key", WrongClass.class)returnsOptional.empty()but still deletes the metadata. This makes a failed typed removal destructive and differs fromfindMetadata's type-filtering behavior; check the type before removing (using an atomic conditional removal) so mismatched calls leave the entry intact.
Object value = additionalObjects.remove(key);
return clazz.isInstance(value) ? Optional.of(clazz.cast(value)) : Optional.empty();
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Lite
71523b8 to
9e3a0a8
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
Review details
Suppressed comments (3)
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstance.java:72
- This new abstract method likewise breaks external
WorkflowInstanceimplementations. The existingfindMetadataandremoveMetadata(String)methods are sufficient for a compatibility-preserving default implementation, so this should be defaulted rather than requiring every consumer to update immediately.
* Remove metatadata key if present and return a non empty key if the object being deleted match
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstanceData.java:37
- Because
WorkflowInstanceDatais a public extension point consumed by persistence modules, making this new method abstract breaks every existing implementation (and makes existingWorkflowInstanceimplementations fail to compile) even though those implementations previously had no metadata to expose. Make this a default method returning an empty map for compatibility;WorkflowMutableInstancecan continue to override it with the actual metadata.
Map<String, Object> metadata();
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowMutableInstance.java:459
- This removes the entry before checking its type, so a call such as
removeMetadata("key", String.class)silently deletes an existingIntegervalue and returns empty. That is destructive on a type mismatch and inconsistent withfindMetadata, which leaves mismatched values intact; check the value first and conditionally remove the same key/value.
public <T> Optional<T> removeMetadata(String key, Class<T> clazz) {
Object value = additionalObjects.remove(key);
return clazz.isInstance(value) ? Optional.of(clazz.cast(value)) : Optional.empty();
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstance.java:75
- This new abstract overload likewise breaks existing implementations of the public
WorkflowInstanceinterface, although its behavior can be composed from the existingfindMetadataandremoveMetadatamethods. Make it a default method to preserve compatibility for existing implementations.
<T> Optional<T> removeMetadata(String key, Class<T> clazz);
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstanceData.java:37
- Because
WorkflowInstanceDatais a public interface consumed by persistence adapters, adding this abstract method makes existing external implementations fail to compile (and can causeAbstractMethodErrorin already compiled implementations). Preserve compatibility with a default empty map, or explicitly treat this as a breaking API release.
Map<String, Object> metadata();
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
Review details
Suppressed comments (3)
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstance.java:73
- The new Javadoc has a subject–verb agreement error: the object "match" should be "matches" the specified class type.
* match the specified class type
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstance.java:75
- This unrelated overload is also a new abstract method on the public
WorkflowInstanceinterface, so existing custom implementations will no longer compile (and old binaries can fail when the method is invoked). Make it a default implemented via the existingfindMetadata/removeMetadatamethods, or omit it from this change.
default <T> Optional<T> removeMetadata(String key, Class<T> clazz) {
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstanceData.java:37
WorkflowInstanceDatais a public interface, so adding this abstract member breaks source (and can causeAbstractMethodErrorfor binary) compatibility for every external implementation that does not override it. Make the new accessor a default returning an empty map, whileWorkflowMutableInstancecontinues to provide the real metadata, or otherwise introduce this as a compatibility-preserving API change.
Map<String, Object> metadata();
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (1)
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowMutableInstance.java:464
- The new public metadata accessor has no test coverage. Add a focused test that adds metadata through
addMetadataIfAbsent, verifies it is returned bymetadata(), and confirms the exposed map cannot be mutated; this protects the persistence-facing contract.
public Map<String, Object> metadata() {
return Collections.unmodifiableMap(additionalObjects);
- Files reviewed: 3/3 changed files
- Comments generated: 3
- Review effort level: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
Review details
Suppressed comments (1)
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstanceData.java:37
WorkflowInstanceDatais a public interface consumed by persistence implementations, so adding this abstract method is a source-compatibility break for every downstream implementation and can produceAbstractMethodErrorfor already-compiled implementations. Since this is an additive accessor, preserve compatibility with a default empty map (while allowing implementations such asWorkflowMutableInstanceto override it), or make this change only as part of an intentional major-version break.
Map<String, Object> metadata();
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
…lowInstance Signed-off-by: Francisco Javier Tirado Sarti <ftirados@ibm.com>
There was a problem hiding this comment.
🟡 Changes recommended
The default removal implementation must avoid a lookup/removal race that can delete a replacement value.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (1)
impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstanceData.java:40
- The new persistence-facing contract silently returns an empty map for any existing/custom
WorkflowInstanceDataimplementation that does not overridemetadata()(including implementations that already expose metadata throughfindMetadata), so persistence can lose metadata without a compile-time signal. Make this method abstract so every implementation must provide the complete metadata view, as intended for this API.
default Map<String, Object> metadata() {
return Map.of();
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
Fix #1690
All metadata operations are now optional (since metadata is not really on the spec and should not be mandatory)