Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interoperability: Clients running on different MP platforms need to know how to start and end and LRA #62

Open
mmusgrov opened this issue Dec 10, 2018 · 9 comments
Milestone

Comments

@mmusgrov
Copy link
Contributor

In MP environments running different MP implementations a client running on one platform must be able to start and end an LRA implemented by another vendor.

This requirement was briefly discussed in issue #17 .

The specification should:

  • define using MP Configuration how the client can locate a REST endpoint where LRAs can be started and ended.
  • define the REST payload and verbs (PUT, POST etc) for the requests to start and end LRAs
@xstefank
Copy link
Member

xstefank commented Dec 18, 2018

As it was discussed on the hangout this week, here are starting proposed REST definitions:

start:
POST /start

parameters:

  • ClientID: query, optional, String
    • a unique identity of a client starting LRA
  • TimeLimit: query, optional, int64
    • Specifies the maximum time in milliseconds that the LRA will exist for
  • ParentLRA: query, optional, String
    • The enclosing LRA if this new LRA is nested
  • CompensateTimeLimit: query, optional, int64
    • The time limit (in seconds) that the Compensator can guarantee that it can compensate
  • CompleteTimeLimit: query, optional, int64
    • The time limit (in seconds) that the Compensator can guarantee that it can complete
  • Link: header, optional, String
    • The resource paths that will be used to complete, compensate, etc.. The link rel names are complete, compensate, status, forget, leave.
  • payload: optional, JSON (Accept application/json)
    • opaque data that will be passed back to the participant when the LRA is closed or cancelled

responses:
200: The request was successful and the response body contains the id of the new LRA and optionally recoveryURL if join was requested
500: A new LRA could not be started, response body may optionally specify reason

Produces text/plain

join
PUT {lraId}/join

parameters:

  • lraId: path, required, String
  • CompensateTimeLimit: query, optional, int64
    • The time limit (in seconds) that the Compensator can guarantee that it can compensate
  • CompleteTimeLimit: query, optional, int64
    • The time limit (in seconds) that the Compensator can guarantee that it can complete
  • Link: header, optional, String
    • The resource paths that will be used to complete, compensate, etc.. The link rel names are complete, compensate, status, forget, leave.
  • payload: optional, JSON (Accept application/json)
    • opaque data that will be passed back to the participant when the LRA is closed or cancelled

responses:
200: The participant was successfully registered with the LRA and the response body contains a unique resource reference for that participant
404: The coordinator has no knowledge of this LRA
412: The LRA is not longer active (ie in the complete or compensate messages have been sent)

close:
PUT {lraId}/close

paramerters:

  • lraId: path, required, String
    • The unique identifier of the LRA

responses:
200: The complete message was sent to all participants
404: This LRA presumably does not exit

cancel:
PUT {lraId}/cancel

paramerters:

  • lraId: path, required, String
    • The unique identifier of the LRA

responses:
200: The compensate message was sent to all participants
404: This LRA presumably does not exit

@mmusgrov
Copy link
Contributor Author

We need to follow REST HATEOS principles, ie the POST request should return the newly created resource in the Location header and a link header containing three URLs that can be used to close, cancel and join the LRA (with relation types close , cancel and join respectively).

@mmusgrov
Copy link
Contributor Author

After thinking further on your proposal and on what I said in my last comment, I have two questions/observations:

  1. With a RESTful API POST creates new resources and the payload optionally specifies it's initial state (the list of participants is part of the state of an LRA so passing along an initial participant makes good sense).
    Question: But is it good REST design to ask the server to infer the initial state via query params and link headers or should we require that JSON should be used?

  2. The response to the POST should return a link to the new resource (in the Location header). But in the case of an LRA resource the cancel/close/join are really part of the state of the LRA (they are not resources like I implied). So I would suggest that to cancel an LRA the client should issue a PUT request to the LRA resource and the payload should set the state of the LRA to cancelled. The server would then attempt to transition the LRA to the cancelled state. Similarly for close.

@mmusgrov
Copy link
Contributor Author

Also note that from my point of view this work should cover starting, closing and cancelling LRAs but should also include how to join an LRA: @rdebusscher may we move this issue back to #17 since starting, joining and ending are all tied to each other, ie starting an LRA should return something that participants can use to join with the new LRA?

@xstefank
Copy link
Member

@mmusgrov I've added the join to the initial proposal. I also included completeTimelimit for both start and join as now it is also configurable.

I definitely agree that we should move configuration options to JSON passed as payload. This would allow us to be more flexible if need be to change it in later releases / add new things easily while staying backward compatible.

I also agree with your second point.

Just to clarify that I understood your intention:
If the client wants to start LRA it will use its default way of doing it. If this is not possible to complete, that it should fallback to interop API endpoint where this discussed API will be exposed right?

@ochaloup
Copy link
Contributor

I like the Mike's point about the JSON as configuration options. In addition what was already said as benefits it seems to me kind of "cleaner" design as I think JSON is more suitable for POST request data.

one think I don't understand now is the second point of Mike's comment

2. The response to the POST should return a link to the new resource (in the Location header). But in the case of an LRA resource the cancel/close/join are really part of the state of the LRA (they are not resources like I implied). So I would suggest that to cancel an LRA the client should issue a PUT request to the LRA resource and the payload should set the state of the LRA to `cancelled`. The server would then attempt to transition the LRA to the `cancelled` state. Similarly for close.

Does the commend proposes there will be only one URL from the start call and the cancel would not be called to the PUT {lraId}/cancel but to PUT {lraId} with body cancelled? Or this is thought differently?

@mmusgrov
Copy link
Contributor Author

mmusgrov commented Dec 20, 2018

@ochaloup you are right. Starting an LRA will create a new LRA resource {lraId}. To close or cancel the LRA you would send a PUT request to {lraId} and the body of the request would contain some JSON that contains the desired resource representation that corresponds to the closed state:

{
 ...
  "state": "closed"
  ...
}

@xstefank Does that clarify my proposal: I am saying that we do not have separate REST resources for {lraId}/close and {lraId}/cancel. There is a single resource that corresponds to the LRA. The resource representation contains things like its status, its list of participants, its time to live etc. If the client wants to close the LRA he issues a resource update (using PUT) with the desired new state (sending a partial representation in a PUT request conforms to REST principles).

Also I would prefer not to allow the timelimit for compensate and complete to be different in release 1.0.

When POSTing to the "start URL" (to request the creation of a new LRA resource), the payload should contain an initial JSON representation of the LRA which identifies the ClientID, TimeLimit, ParentLRA, TimeLimit, participant and the opaque data (ie my proposal was to not use query params and the link header).

Also we need to support 202 Accepted responses when closing or cancelling LRAs.

@rdebusscher
Copy link
Contributor

@mmusgrov Yes, we can merge this with #17. I don't know anymore why I thought issue #17 was about the integration of different coordinators.

@mmusgrov
Copy link
Contributor Author

mmusgrov commented Feb 6, 2019

The decision made at the last hangout was to defer this topic to milestone 1.1

@mmusgrov mmusgrov added this to the 1.x milestone Feb 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants