Hi, Kedar.
I agree with some of what you've said, with some differences of
opinion. See below.
Kedar Mhaswade wrote:
> Tim, others,
>
> I like this proposal, but it is not evident to me that this is going
> to provide
> desired returns. And I think this requires arch discussion.
>
> Let me describe it in the meanwhile.
>
> Description of the problems:
> 1- Client (asadmin) should be generic. It should not treat one command
> differently from other. The major stumbling block here is that of
> "file
> upload". Other kind of data transfer is mostly resolved.
> 2- Server should be able to ask client about missing option values
> implementing
> some kind of suspend-resume semantics.
I think we all agree that problem 1 must be solved. The asadmin client
currently depends on certain hard-coded command options and we really
need to fix that.
The callback mechanism I've outlined earlier can handle both problem 2
and the file upload task without requiring the change to local-only file
access you described.
In this model, the admin client must be prepared to handle certain types
of callback. (Ideally which callbacks it could handle would be
extensible but that's a separate question.) Some of these callback types
require interaction with a human user (or a clever enough script) such
as displaying a prompt and accepting an answer for transmission back to
the suspended command. But for other types of callback an admin client
can deal with them all on its own. Suppose for a moment that the admin
client knows how to handle two callbacks: promptForAnswer and fileUpload.
In the "deploy --upload=true" case, for example, we do not want the
admin CLI to somehow recognize the upload option and the path and
deploymentplan options that are part of that command. Here is what
would happen:
0.1 The DeployCommand author knows that the command will need to do
callbacks to the admin client for file uploading, so he or she writes
DeployCommand so it implements the Suspendable interface which defines a
continue method.
0.2 The admin client author knows that the contract between it and the
server requires it to honor certain types of callback - including file
uploading, so he or she writes the client to detect those and respond to
them.
At runtime:
1. The admin client sends the command and its options in the http
request with no payload (because it should know nothing about that
command and the fact that the user said --upload=true and
--deploymentplan=myPlan.jar and that the path is myApp.ear).
2. The DeployCommand code on the server sees the upload option in the
request and invokes the "suspend" method on the AdminCommand superclass
passing one or two FileUpload objects - one if the user specified only
the archive being deployed and two if the user also specified a
deployment plan. Each FileUpload object contains the path - supplied by
the user in the original command - of the file to be uploaded.
3. The suspend method composes an action report that includes any
callback information - the fileUpload ones in this example - and
generates a unique ID for this suspended command. It stores this
Suspendable instance in a map keyed by the ID, then sends the http
response containing the callback-laden action report.
4. The admin client detects that the action report contains callbacks,
not a final result of the command. It cycles through each of the
callbacks, acting on each individually and gradually composing the
payload, one part per callback. If the callback is a promptForAnswer
then the client displays the prompt and gathers input to store in the
payload part. If the callback is a fileUpload then the client uses the
file path information in the callback to locate that file in the local
file system and attach it to the payload. Note that the client still
knows nothing about the details of the command, just that it is acting
on behalf of some command in executing the callbacks.
5. When the admin client has processed all callbacks - and therefore
populated the payload with the callback answers whatever they might be -
it invokes the "continue" command passing the unique suspended command
ID as an option. Or, as another option, the client could set a
"continue" header field containing the suspended command ID in the http
request.
6. The AdminAdapter either executes the ContinueCommand or,
alternatively, detects the "continue" header. Either way, some logic
looks up the Suspendable from the map using the ID, removes that entry
from the map, and invokes the Suspendable's continue method passing the
callback answers. Because this Suspendable instance is the
DeployCommand (or some class closely affiliated with it) it knows
exactly what to do with the callback answers - extract files from the
payload into temp files - and continue with the rest of the deployment
command logic.
The admin client needs to know only about the types of callbacks it
might be asked to perform; it needs to know nothing about the specific
commands.
- Tim
- Tim