eclipse / microprofile-lra

microprofile-lra
Apache License 2.0
101 stars 30 forks source link

Provide an annotation to supply opaque data during participant registration #15

Open mmusgrov opened 6 years ago

mmusgrov commented 6 years ago

The client API for participants to join an LRA includes a method parameter that the caller may optionally use to supply [https://github.com/eclipse/microprofile-lra/blob/master/api/src/main/java/org/eclipse/microprofile/lra/client/LRAClient.java#L301](opaque data) that will be provided back to the participant when its compensation/completion method is subsequently triggered. There is no corresponding facility in the Java annotations used for registering participants.

The proposal is to include an annotation that annotation based participants can use to register the equivalent data.

Please refer to the section of the spec that describes [https://github.com/eclipse/microprofile-lra/blob/master/spec/src/main/asciidoc/microprofile-lra-spec.adoc#322-compensating-activities](participant registration) and the javadoc for the annotation - for example [https://github.com/eclipse/microprofile-lra/blob/master/api/src/main/java/org/eclipse/microprofile/lra/annotation/Compensate.java#L42](the @Compensate annotation).

Note that reliable participants may wish to manage there own data by durably recording which LRAs the are participating in. However this git issue makes it easier to write reliable participants.

mmusgrov commented 6 years ago

@tomjenkinson There is a problem with providing an annotation for spec implementations to call to get the extra data via an annotation which makes this issue invalid for the following reason:

if a JAX-RS method has an @LRA annotation then the implementation must register the participant before invoking the method. But the participant may only know which data he wants to associate with the join request during the method call which is too late.

I propose that we reject this issue and add a spec note to say that the feature is only available in the LRAClient API..

tomjenkinson commented 6 years ago

I think that the specification could be expressed in a manner to cover that case by saying the @LRAData method is called during the @LRA method and that it is expected that business logic is called exactly once by the implementation. You are expected to prepare the compensation data during @LRAData.

tomjenkinson commented 6 years ago

It would need to return a String to match the LRA Client API

tomjenkinson commented 6 years ago

The @LRAData method needs at least access to the LRA ID in order that @ApplicationScoped JAX-RS resource can refer to it from a map

tomjenkinson commented 6 years ago

The business logic should not be making changes that require @Compensate or @Confirm to be called.

tomjenkinson commented 6 years ago

@ParticipantData not @LRAData

mmusgrov commented 5 years ago

Can we move this issue back to milestone 1. We have had two queries about it from the community so I think it is a big issue for them to have to manage their own durability requirements. - we used to have an implementation of it so it will be simple to add back in.

rdebusscher commented 5 years ago

@mmusgrov We have left it out due to the fact that we have postponed the LRAClient API.

Can we have opaque user data with annotations only?

xstefank commented 5 years ago

@rdebusscher there is a proposal in above discussion discussing adding annotation @ParticipantData

rdebusscher commented 5 years ago

Enum can only take constants. And within MicroProfile we do not have access to EL expressions to have some Participant Data which are dependent on the request.

Or is it the idea to annotate a method parameter with @ParticipantData which becomes then the Opaque Data?

xstefank commented 5 years ago

IIRC it would be a separate method annotated with @ParticipantData which only returns the opaque data and will be invoked once when the LRA is starting (when someone invokes some other method which is annotated by @LRA)

rdebusscher commented 5 years ago

And how is the link of this additional method annotated with @ParticipantData with the JAX-RS called method (like the request parameters, headers, ...)

Can you give a small example?

xstefank commented 5 years ago

I am guessing, but when you are starting LRA in our case it's a container request filter, so we can scan the rest of the method in the resource class and check dynamically for @ParticipantData annotation and invoke it from the filter.

However, I don't think this is the only solution to this problem. Personally I can also see an option similar to Fallback annotation from Fault Tolerance, when you can specify method name or class name (of class implementing spec interface) in the LRA annotation itself which gets invoked when LRA is starting. This would allow implementations to avoid scanning all resource methods and checking for data annotation.

EDIT: sorry, after second read, I see that is not what you were asking. Passing parameters from @LRA method to data method can be done in the filter as it has access to the requestContext which can be basically passed to the data method if needed I think.

The only issue I can see now is on which instance of the resource class should the data method be invoked. Can we mandate that JAX-RS resource method is always a CDI bean so the instance can be retrieved programmatically?