Difference: ApplicationsMessagingHighLevelProtocol (1 vs. 7)

Revision 72012-06-26 - root

 
META TOPICPARENT name="ApplicationsMessaging"

High Level Protocol

This document describes the application messaging protocol in terms of the operations a Hub and a client application should support. It does not describe lower level details such as the wire protocol and parameter types. This document is still under discussion and will change.

In the following, I've used [] to denote multiple values, rather than necessarily an array.

The operations/methods a Hub should support

Registration

1 private-id = register*(hub-secret)

2 declareAppMetaData(private-id, metadata[])

3 declareMessages(private-id, mtypes[])

Once an application has located a hub (by means as yet undecided), its first step is to register with it - this needs only be done once per session per application. The application provides the hub with a secret key that is only easily knowable by applications running under the user's uid. This is to make it harder for unauthorized applications to register by (for example) port scanning.

The hub provides the application with a session-unique private-id that is used to authenticate subsequent communications, and is kept secret from other applications to avoid application-spoofing. Each application will also be assigned a public-id that is used to identify it to other applications (see below).

Note that asterisk in the register operation. This denotes that there could be several different register operations, one for each "wire protocol". An application would choose the register operation appropriate to the way it wanted to communicate.

Operation 2) is for the application to tell the hub about itself: a human-readable name, and maybe an icon, description etc.... I see this as being more contentious: we could instead simply use messages between applications to achieve the same thing. The advantage of having it as an operation in the protocol is for those environments that can send messages but can't easily receive them. For instance, I could send a message from the python commandline to Topcat, and all Topcat would have to identify me would be the hub-generated unique id, which isn't very friendly. If I'd also declared some metadata to the hub, then Topcat could interrogate the hub to find out just who senderId=app://1234567-891 is.

Operation 3) is for the application to tell the hub which message types it wishes to receive. The hub won't send it messages it can't understand, and applications can interrogate the hub (using operation 10) to determine the appropriate messages to send. We might need a mechanism to say "send me messages of any type", or "send me messages matching this pattern."

4 unregister(private-id)

When an application closes, it should inform the hub.

Messaging

5 msgId = send(sender-private-id, recipient-public-Id, message)

6 msgId = broadcast(sender-private-id, message)

5) sends a message from sender to recipient using the hub-supplied ids for addressing. The sender's private-id is obtained on registration, while the recipient's public-id is obtained by interrogating the hub (see below). 6) sends the message to everyone (if they've elected to receive that message's mtype). The hub returns a session-unique msgId that can be used in further comms, such as to tie reply messages up with request messages.

we need to elaborate on this msgId idea a bit

These messages are asynchronous in the sense that they return as soon as the hub has received the message. Hubs will disregard messages with unknown or invalid private-ids.

The contents of message are specified on ApplicationsMessagingMsgContent.

Application and hub metadata

7 hub-public-id = getHubId() We can treat the hub itself as just another application that can be messaged. However, you do need to know which application it is, and this operation does the job.

8 public-ids[] = getApplicationIds()

Tell me the hub-assigned public ids of all the registered applications.

9 public-ids[] = getApplicationsUnderstanding(mtype)

Tell me the hub-assigned public ids of the all the registered applications that understand messages with this mtype.

10 mtypes[] = getUnderstoodMessagesForApplication(public-id)

Tell me the mtypes of the messages this application wants to receive.

11 metadata[] = getAppMetaData(public-id)

Return the metadata for that application.

12 public-id = getPublicId(private-id)

An application will use its private-id for all communication with the hub, but it might occasionally need to know its public-id.

The operations a client application should support

13 receive(recipient-publid-id, sender-public-id, msgId, message)

Receive a message from this sender.

Application metadata

In PLASTIC, the hub stores the human-readable name of each application, in addition to its generated id. Additionally other metadata, such as a logo and description is available by using some standard messages. I propose to move all of this to the hub so it is accessible by environments that cannot receive response messages, and tidy it up.

I suggest that the metadata is a struct mapping keys to values that has certain reserved keys:

ivoa.name

ivoa.description

ivoa.ivorn

ivoa.logoURL

The prefix ivoa. would be reserved, but application authors are free to add new data to this struct. This would allow users such as Mike to define (e.g.) iraf.worker=1

to filter the connected applications.


-- JohnTaylor - 10 Apr 2007

Revision 62007-04-24 - JohnTaylor

 
META TOPICPARENT name="ApplicationsMessaging"

High Level Protocol

This document describes the application messaging protocol in terms of the operations a Hub and a client application should support. It does not describe lower level details such as the wire protocol and parameter types. This document is still under discussion and will change.

In the following, I've used [] to denote multiple values, rather than necessarily an array.

The operations/methods a Hub should support

Registration

1 private-id = register*(hub-secret)

2 declareAppMetaData(private-id, metadata[])

3 declareMessages(private-id, mtypes[])

Once an application has located a hub (by means as yet undecided), its first step is to register with it - this needs only be done once per session per application. The application provides the hub with a secret key that is only easily knowable by applications running under the user's uid. This is to make it harder for unauthorized applications to register by (for example) port scanning.

The hub provides the application with a session-unique private-id that is used to authenticate subsequent communications, and is kept secret from other applications to avoid application-spoofing. Each application will also be assigned a public-id that is used to identify it to other applications (see below).

Note that asterisk in the register operation. This denotes that there could be several different register operations, one for each "wire protocol". An application would choose the register operation appropriate to the way it wanted to communicate.

Operation 2) is for the application to tell the hub about itself: a human-readable name, and maybe an icon, description etc.... I see this as being more contentious: we could instead simply use messages between applications to achieve the same thing. The advantage of having it as an operation in the protocol is for those environments that can send messages but can't easily receive them. For instance, I could send a message from the python commandline to Topcat, and all Topcat would have to identify me would be the hub-generated unique id, which isn't very friendly. If I'd also declared some metadata to the hub, then Topcat could interrogate the hub to find out just who senderId=app://1234567-891 is.

Operation 3) is for the application to tell the hub which message types it wishes to receive. The hub won't send it messages it can't understand, and applications can interrogate the hub (using operation 10) to determine the appropriate messages to send. We might need a mechanism to say "send me messages of any type", or "send me messages matching this pattern."

4 unregister(private-id)

When an application closes, it should inform the hub.

Messaging

5 msgId = send(sender-private-id, recipient-public-Id, message)

6 msgId = broadcast(sender-private-id, message)

5) sends a message from sender to recipient using the hub-supplied ids for addressing. The sender's private-id is obtained on registration, while the recipient's public-id is obtained by interrogating the hub (see below). 6) sends the message to everyone (if they've elected to receive that message's mtype). The hub returns a session-unique msgId that can be used in further comms, such as to tie reply messages up with request messages.

we need to elaborate on this msgId idea a bit

These messages are asynchronous in the sense that they return as soon as the hub has received the message. Hubs will disregard messages with unknown or invalid private-ids.

The contents of message are specified on ApplicationsMessagingMsgContent.

Application and hub metadata

7 hub-public-id = getHubId() We can treat the hub itself as just another application that can be messaged. However, you do need to know which application it is, and this operation does the job.

8 public-ids[] = getApplicationIds()

Tell me the hub-assigned public ids of all the registered applications.

9 public-ids[] = getApplicationsUnderstanding(mtype)

Tell me the hub-assigned public ids of the all the registered applications that understand messages with this mtype.

10 mtypes[] = getUnderstoodMessagesForApplication(public-id)

Tell me the mtypes of the messages this application wants to receive.

11 metadata[] = getAppMetaData(public-id)

Return the metadata for that application.

12 public-id = getPublicId(private-id)

An application will use its private-id for all communication with the hub, but it might occasionally need to know its public-id.

The operations a client application should support

Changed:
<
<
13 receive(sender-public-id, msgId, message)
>
>
13 receive(recipient-publid-id, sender-public-id, msgId, message)
  Receive a message from this sender.

Application metadata

In PLASTIC, the hub stores the human-readable name of each application, in addition to its generated id. Additionally other metadata, such as a logo and description is available by using some standard messages. I propose to move all of this to the hub so it is accessible by environments that cannot receive response messages, and tidy it up.

I suggest that the metadata is a struct mapping keys to values that has certain reserved keys:

ivoa.name

ivoa.description

ivoa.ivorn

ivoa.logoURL

The prefix ivoa. would be reserved, but application authors are free to add new data to this struct. This would allow users such as Mike to define (e.g.) iraf.worker=1

to filter the connected applications.


<--  
-->
-- JohnTaylor - 10 Apr 2007

Revision 52007-04-14 - JohnTaylor

 
META TOPICPARENT name="ApplicationsMessaging"

High Level Protocol

This document describes the application messaging protocol in terms of the operations a Hub and a client application should support. It does not describe lower level details such as the wire protocol and parameter types. This document is still under discussion and will change.

In the following, I've used [] to denote multiple values, rather than necessarily an array.

The operations/methods a Hub should support

Registration

1 private-id = register*(hub-secret)

2 declareAppMetaData(private-id, metadata[])

3 declareMessages(private-id, mtypes[])

Once an application has located a hub (by means as yet undecided), its first step is to register with it - this needs only be done once per session per application. The application provides the hub with a secret key that is only easily knowable by applications running under the user's uid. This is to make it harder for unauthorized applications to register by (for example) port scanning.

The hub provides the application with a session-unique private-id that is used to authenticate subsequent communications, and is kept secret from other applications to avoid application-spoofing. Each application will also be assigned a public-id that is used to identify it to other applications (see below).

Note that asterisk in the register operation. This denotes that there could be several different register operations, one for each "wire protocol". An application would choose the register operation appropriate to the way it wanted to communicate.

Operation 2) is for the application to tell the hub about itself: a human-readable name, and maybe an icon, description etc.... I see this as being more contentious: we could instead simply use messages between applications to achieve the same thing. The advantage of having it as an operation in the protocol is for those environments that can send messages but can't easily receive them. For instance, I could send a message from the python commandline to Topcat, and all Topcat would have to identify me would be the hub-generated unique id, which isn't very friendly. If I'd also declared some metadata to the hub, then Topcat could interrogate the hub to find out just who senderId=app://1234567-891 is.

Operation 3) is for the application to tell the hub which message types it wishes to receive. The hub won't send it messages it can't understand, and applications can interrogate the hub (using operation 10) to determine the appropriate messages to send. We might need a mechanism to say "send me messages of any type", or "send me messages matching this pattern."

4 unregister(private-id)

When an application closes, it should inform the hub.

Messaging

5 msgId = send(sender-private-id, recipient-public-Id, message)

6 msgId = broadcast(sender-private-id, message)

5) sends a message from sender to recipient using the hub-supplied ids for addressing. The sender's private-id is obtained on registration, while the recipient's public-id is obtained by interrogating the hub (see below). 6) sends the message to everyone (if they've elected to receive that message's mtype). The hub returns a session-unique msgId that can be used in further comms, such as to tie reply messages up with request messages.

we need to elaborate on this msgId idea a bit

These messages are asynchronous in the sense that they return as soon as the hub has received the message. Hubs will disregard messages with unknown or invalid private-ids.

Changed:
<
<
The contents of message are specified on ApplicationsMessagingMessageContent.
>
>
The contents of message are specified on ApplicationsMessagingMsgContent.
 

Application and hub metadata

7 hub-public-id = getHubId() We can treat the hub itself as just another application that can be messaged. However, you do need to know which application it is, and this operation does the job.

8 public-ids[] = getApplicationIds()

Tell me the hub-assigned public ids of all the registered applications.

9 public-ids[] = getApplicationsUnderstanding(mtype)

Tell me the hub-assigned public ids of the all the registered applications that understand messages with this mtype.

10 mtypes[] = getUnderstoodMessagesForApplication(public-id)

Tell me the mtypes of the messages this application wants to receive.

11 metadata[] = getAppMetaData(public-id)

Return the metadata for that application.

12 public-id = getPublicId(private-id)

An application will use its private-id for all communication with the hub, but it might occasionally need to know its public-id.

The operations a client application should support

13 receive(sender-public-id, msgId, message)

Receive a message from this sender.

Application metadata

In PLASTIC, the hub stores the human-readable name of each application, in addition to its generated id. Additionally other metadata, such as a logo and description is available by using some standard messages. I propose to move all of this to the hub so it is accessible by environments that cannot receive response messages, and tidy it up.

I suggest that the metadata is a struct mapping keys to values that has certain reserved keys:

ivoa.name

ivoa.description

ivoa.ivorn

ivoa.logoURL

The prefix ivoa. would be reserved, but application authors are free to add new data to this struct. This would allow users such as Mike to define (e.g.) iraf.worker=1

to filter the connected applications.


<--  
-->
-- JohnTaylor - 10 Apr 2007

Revision 42007-04-10 - JohnTaylor

 
META TOPICPARENT name="ApplicationsMessaging"

High Level Protocol

This document describes the application messaging protocol in terms of the operations a Hub and a client application should support. It does not describe lower level details such as the wire protocol and parameter types. This document is still under discussion and will change.

In the following, I've used [] to denote multiple values, rather than necessarily an array.

The operations/methods a Hub should support

Registration

Changed:
<
<
  1. (private-id, public-id) = register*(hub-secret)
>
>
1 private-id = register*(hub-secret)
Deleted:
<
<
  1. declareAppMetaData(private-id, metadata[])
  2. declareMessages(private-id, mtypes[])
 
Added:
>
>
2 declareAppMetaData(private-id, metadata[])

3 declareMessages(private-id, mtypes[])

 Once an application has located a hub (by means as yet undecided), its first step is to register with it - this needs only be done once per session per application. The application provides the hub with a secret key that is only easily knowable by applications running under the user's uid. This is to make it harder for unauthorized applications to register by (for example) port scanning.
Changed:
<
<
The hub provides the application with a session-unique private-id that is used to authenticate subsequent communications, but is kept secret from other applications to avoid application-spoofing. Each application will also be provided with a public-id that is used to identify it to other applications (see below).
>
>
The hub provides the application with a session-unique private-id that is used to authenticate subsequent communications, and is kept secret from other applications to avoid application-spoofing. Each application will also be assigned a public-id that is used to identify it to other applications (see below).
  Note that asterisk in the register operation. This denotes that there could be several different register operations, one for each "wire protocol". An application would choose the register operation appropriate to the way it wanted to communicate.

Operation 2) is for the application to tell the hub about itself: a human-readable name, and maybe an icon, description etc.... I see this as being more contentious: we could instead simply use messages between applications to achieve the same thing. The advantage of having it as an operation in the protocol is for those environments that can send messages but can't easily receive them. For instance, I could send a message from the python commandline to Topcat, and all Topcat would have to identify me would be the hub-generated unique id, which isn't very friendly. If I'd also declared some metadata to the hub, then Topcat could interrogate the hub to find out just who senderId=app://1234567-891 is.

Changed:
<
<
Operation 3) is for the application to tell the hub which message types it wishes to receive. The hub won't send it messages it can't understand, and applications can interrogate the hub (using operation 12) to determine the appropriate messages to send. We might need a mechanism to say "send me messages of any type", or "send me messages matching this pattern."
>
>
Operation 3) is for the application to tell the hub which message types it wishes to receive. The hub won't send it messages it can't understand, and applications can interrogate the hub (using operation 10) to determine the appropriate messages to send. We might need a mechanism to say "send me messages of any type", or "send me messages matching this pattern."
 
Changed:
<
<
  1. unregister(private-id)
>
>
4 unregister(private-id)
  When an application closes, it should inform the hub.

Messaging

Changed:
<
<
  1. msgId = send(sender-private-id, recipient-public-Id, message)
>
>
5 msgId = send(sender-private-id, recipient-public-Id, message)
Deleted:
<
<
  1. msgId = broadcast(sender-private-id, message)
 
Added:
>
>
6 msgId = broadcast(sender-private-id, message)
 5) sends a message from sender to recipient using the hub-supplied ids for addressing. The sender's private-id is obtained on registration, while the recipient's public-id is obtained by interrogating the hub (see below). 6) sends the message to everyone (if they've elected to receive that message's mtype). The hub returns a session-unique msgId that can be used in further comms, such as to tie reply messages up with request messages.
Changed:
<
<
These messages are asynchronous in the sense that they return as soon as the hub has received the message. The contents of message are specified on ApplicationsMessagingMessageContent.
>
>
we need to elaborate on this msgId idea a bit
 
Added:
>
>
These messages are asynchronous in the sense that they return as soon as the hub has received the message. Hubs will disregard messages with unknown or invalid private-ids.
 
Added:
>
>
The contents of message are specified on ApplicationsMessagingMessageContent.
 

Application and hub metadata

Changed:
<
<
  1. hub-public-id = getHubId()
>
>
7 hub-public-id = getHubId()
 We can treat the hub itself as just another application that can be messaged. However, you do need to know which application it is, and this operation does the job.
Changed:
<
<
  1. public-ids[] = getApplicationIds()
>
>
8 public-ids[] = getApplicationIds()
  Tell me the hub-assigned public ids of all the registered applications.
Changed:
<
<
  1. public-ids[] = getApplicationsUnderstanding(mtype)
>
>
9 public-ids[] = getApplicationsUnderstanding(mtype)
  Tell me the hub-assigned public ids of the all the registered applications that understand messages with this mtype.
Changed:
<
<
  1. mtypes[] = getUnderstoodMessagesForApplication(public-id)
>
>
10 mtypes[] = getUnderstoodMessagesForApplication(public-id)
 

Tell me the mtypes of the messages this application wants to receive.

Changed:
<
<
  1. metadata[] = getAppMetaData(public-id)
>
>
11 metadata[] = getAppMetaData(public-id)
  Return the metadata for that application.
Added:
>
>
12 public-id = getPublicId(private-id)
 
Added:
>
>
An application will use its private-id for all communication with the hub, but it might occasionally need to know its public-id.
 

The operations a client application should support

Changed:
<
<
  1. receive(sender-public-id, msgId, message)
>
>
13 receive(sender-public-id, msgId, message)
  Receive a message from this sender.
Added:
>
>

Application metadata

In PLASTIC, the hub stores the human-readable name of each application, in addition to its generated id. Additionally other metadata, such as a logo and description is available by using some standard messages. I propose to move all of this to the hub so it is accessible by environments that cannot receive response messages, and tidy it up.

I suggest that the metadata is a struct mapping keys to values that has certain reserved keys:

ivoa.name

ivoa.description

ivoa.ivorn

ivoa.logoURL

The prefix ivoa. would be reserved, but application authors are free to add new data to this struct. This would allow users such as Mike to define (e.g.) iraf.worker=1

to filter the connected applications.

 


<--  
-->
-- JohnTaylor - 10 Apr 2007

Revision 32007-04-10 - JohnTaylor

 
META TOPICPARENT name="ApplicationsMessaging"

High Level Protocol

This document describes the application messaging protocol in terms of the operations a Hub and a client application should support. It does not describe lower level details such as the wire protocol and parameter types. This document is still under discussion and will change.

In the following, I've used [] to denote multiple values, rather than necessarily an array.

Deleted:
<
<

The operations a client application should support

  1. receive()
 

The operations/methods a Hub should support

Deleted:
<
<
 

Registration

Changed:
<
<
  1. id= register*()
  2. declareAppMetaData(id, metadata[])
  3. declareMessages(id, mtypes[])
>
>
  1. (private-id, public-id) = register*(hub-secret)
  2. declareAppMetaData(private-id, metadata[])
  3. declareMessages(private-id, mtypes[])
 
Changed:
<
<
Once an application has located a hub (by means as yet undecided), its first step is to register with it - this needs only be done once per session per application. The hub provides a session-unique id that is used in subsequent communications. This differs slightly from Mike's model where the application's human-readable-name is used for addressing. Early on we canvassed opinion amongst our users as to whether they'd ever want to run two instances of the same program simultaneously, they said yes, so I prefer the unique-id mechanism, even though it's less user-friendly. Note that asterisk in the register operation. This denotes that there could be several different register operations, one for each "wire protocol". An application would choose the register operation appropriate to the way it wanted to communicate.
>
>
Once an application has located a hub (by means as yet undecided), its first step is to register with it - this needs only be done once per session per application. The application provides the hub with a secret key that is only easily knowable by applications running under the user's uid. This is to make it harder for unauthorized applications to register by (for example) port scanning.
 
Changed:
<
<
Operation 2) is for the application to tell the hub about itself: a human-readable name, and maybe an icon, description etc.... I see this as being more contentious: we could instead simply use messages between applications to achieve the same thing. The advantage of having it as an operation in the protocol is for those environments that can send messages but can't easily receive them. For instance, I could send a message from the python commandline to Topcat, and all Topcat would have to identify me would be the hub-generated unique id, which isn't very friendly. If I'd also declared some metadata to the hub, then Topcat could interrogate the hub to find out just who senderId=vom://1234567-891 is. (with operation 2b)
>
>
The hub provides the application with a session-unique private-id that is used to authenticate subsequent communications, but is kept secret from other applications to avoid application-spoofing. Each application will also be provided with a public-id that is used to identify it to other applications (see below).
 
Changed:
<
<
Operation 3) is for the application to tell the hub which message types it wishes to receive. The hub won't send it messages it can't understand, and applications can interrogate the hub (using operation 12) to determine the appropriate messages to send. We might need a mechanism to say "send me messages of any type" [if we do, I hope we make a better job of it than we did in PLASTIC...which was a mess.]
>
>
Note that asterisk in the register operation. This denotes that there could be several different register operations, one for each "wire protocol". An application would choose the register operation appropriate to the way it wanted to communicate.
 
Changed:
<
<
In PLASTIC, these 3 operations are rolled into 1, but I feel it's better to separate them.
>
>
Operation 2) is for the application to tell the hub about itself: a human-readable name, and maybe an icon, description etc.... I see this as being more contentious: we could instead simply use messages between applications to achieve the same thing. The advantage of having it as an operation in the protocol is for those environments that can send messages but can't easily receive them. For instance, I could send a message from the python commandline to Topcat, and all Topcat would have to identify me would be the hub-generated unique id, which isn't very friendly. If I'd also declared some metadata to the hub, then Topcat could interrogate the hub to find out just who senderId=app://1234567-891 is.
 
Added:
>
>
Operation 3) is for the application to tell the hub which message types it wishes to receive. The hub won't send it messages it can't understand, and applications can interrogate the hub (using operation 12) to determine the appropriate messages to send. We might need a mechanism to say "send me messages of any type", or "send me messages matching this pattern."
 
Added:
>
>
  1. unregister(private-id)
 
Changed:
<
<
  1. unregister(id)
>
>
When an application closes, it should inform the hub.
 

Messaging

Changed:
<
<
  1. msgId = send(senderId, recipientId, message)
  2. msgId = broadcast(senderId, message)
>
>
  1. msgId = send(sender-private-id, recipient-public-Id, message)
  2. msgId = broadcast(sender-private-id, message)
 
Added:
>
>
5) sends a message from sender to recipient using the hub-supplied ids for addressing. The sender's private-id is obtained on registration, while the recipient's public-id is obtained by interrogating the hub (see below). 6) sends the message to everyone (if they've elected to receive that message's mtype). The hub returns a session-unique msgId that can be used in further comms, such as to tie reply messages up with request messages.
 These messages are asynchronous in the sense that they return as soon as the hub has received the message. The contents of message are specified on ApplicationsMessagingMessageContent.
Deleted:
<
<

Application metadata

 
Changed:
<
<
  1. hubId = getHubId()
>
>

Application and hub metadata

Deleted:
<
<
  1. ids[] = getApplicationIds()
  2. ids[] = getApplicationsUnderstanding(mtype)
  3. mtypes[] = getUnderstoodMessagesForApplication(id)
  4. metadata[] = getAppMetaData(id)
 
Changed:
<
<
>
>
  1. hub-public-id = getHubId()
Deleted:
<
<
=============================================== 1) id= register*() 2) declareAppMetaData(id, metadata) 3) declareMessages(id, mtypes[])

4) unregister(id) When an application closes, it should inform the hub.

5) msgId = sendAsynch(senderId, recipientId, mtype, args[]) 6) msgId = broadcastAsynch(senderId, mtype, args[])

OK, this is where the fun happens. 5) sends a message from sender to recipient using the hub-supplied ids for addressing. 6) sends the message to everyone (if they've elected to receive that mtype). The hub returns a session-unique msgId that can be used in further comms, such as to tie reply messages up with request messages (in Mike's parlance). In these operations the message argument list args[] is intended to be quite general. I'm explicitly writing out the parameters here...if you prefer you can write it: 5) msgId = sendAsynch(message) where message wraps the whole lot. At some point we need to decide which parameters are part of the message, and which are not. My initial feeling is that mtype and args[] are part of the message, while the addressing info are not. [We could also add the msgId (if one already exists for that "conversation") as one of the input params, or we could put it inside args[] - I'm not sure which is best.]

Plastic devs will note another difference with Plastic - the above operations reflect the two most common modes of use that we've encountered in 18 months of experience: one-to-one, and one-to-all. Plastic has a one-to-subsetOfAll mode, which is rarely used to send to more than one application and is extremely annoying.

7) msgId, response = send(senderId, recipientId, mtype, args[]) 8) msgId, responses[] = broadcast(senderId, mtype, args[])

These are like 5 and 6, but block and then return a response value. This value can be quite general ( e.g. some kind of datastructure)

These are going to be contentious. Plastic allows a request-response style messaging pattern. This is not exactly radical: SOAP does it, and MPI has blocking send modes (though they're not quite the same as this). It is very useful in making the programmer's life easier when dealing with very quick informational messages such as "tell me what your application's icon is". Yes, I know you could do this asynchronously and sit around waiting for a message to come back with the answer, but I feel that we should be prepared to sacrifice some purity of style to make the application programmer's life easier. Furthermore, my putative python-command-line hacker cannot receive data back from applications any other way (or at least, not easily). However, I'd be interested to know what the community thinks. Could including a request-response style seriously restrict our choices when it comes to picking wire protocols?

9) hubId = getHubId()

 We can treat the hub itself as just another application that can be messaged. However, you do need to know which application it is, and this operation does the job.
Changed:
<
<
10) ids[] = getApplicationIds()
>
>
  1. public-ids[] = getApplicationIds()
 
Changed:
<
<
Tell me the hub-assigned ids of all the registered applications.
>
>
Tell me the hub-assigned public ids of all the registered applications.
 
Changed:
<
<
11) ids[] = getApplicationsUnderstanding(mtype)
>
>
  1. public-ids[] = getApplicationsUnderstanding(mtype)
 
Changed:
<
<
Tell me the hub-assigned ids of the all the registered applications that understand messages with this mtype.
>
>
Tell me the hub-assigned public ids of the all the registered applications that understand messages with this mtype.
 
Changed:
<
<
12) mtypes[] = getUnderstoodMessagesForApplication(id)
>
>
  1. mtypes[] = getUnderstoodMessagesForApplication(public-id)
 
Deleted:
<
<
Tell me what mtypes this particular application claims to support.
 
Changed:
<
<
Security
>
>
Tell me the mtypes of the messages this application wants to receive.
Deleted:
<
<

The question of applications spoofing one another has come up a few times. While I don't really believe it's a serious risk (those astronomers - they're such jokers!), I set out below a simple modification to the above protocol that would make it more secure. This is based on proposals by Mark Taylor in discussions we had a year ago - if they don't make any sense then blame my faulty memory rather than Mark.
 
Deleted:
<
<
The register operation could be changed as follows: (id, application-secret) = register*(hub-secret)
 
Changed:
<
<
The hub-secret is a secret that can only be easily known by applications running under the user's uid and is intended to defeat other users on the same machine who might try ( e.g.) port scanning. For instance, it could be a random string written into the .ivoamsg file. The application-secret is a per-application secret that apps must keep track of and use along with their id to identify themselves. Thus, operations 2-8 would all include this as an extra parameter (though it wouldn't be transmitted to any receiving application by the hub.) This prevents Topcat pretending to be Aladin and vice versa (you guys!).
>
>
  1. metadata[] = getAppMetaData(public-id)
 
Changed:
<
<
Well, I hope that you have time in between munching Easter Eggs to give me your thoughts on this. I'll try to get this up on the wiki so that we can keep track of modifications and suggestions.
>
>
Return the metadata for that application.
 
Added:
>
>

The operations a client application should support

  1. receive(sender-public-id, msgId, message)
 
Changed:
<
<
>
>
Receive a message from this sender.
 


<--  
-->
-- JohnTaylor - 10 Apr 2007

Revision 22007-04-10 - JohnTaylor

 
META TOPICPARENT name="ApplicationsMessaging"

High Level Protocol

This document describes the application messaging protocol in terms of the operations a Hub and a client application should support. It does not describe lower level details such as the wire protocol and parameter types. This document is still under discussion and will change.
Added:
>
>
In the following, I've used [] to denote multiple values, rather than necessarily an array.
 
Added:
>
>

The operations a client application should support

  1. receive()

The operations/methods a Hub should support

 
Added:
>
>

Registration

  1. id= register*()
  2. declareAppMetaData(id, metadata[])
  3. declareMessages(id, mtypes[])

Once an application has located a hub (by means as yet undecided), its first step is to register with it - this needs only be done once per session per application. The hub provides a session-unique id that is used in subsequent communications. This differs slightly from Mike's model where the application's human-readable-name is used for addressing. Early on we canvassed opinion amongst our users as to whether they'd ever want to run two instances of the same program simultaneously, they said yes, so I prefer the unique-id mechanism, even though it's less user-friendly. Note that asterisk in the register operation. This denotes that there could be several different register operations, one for each "wire protocol". An application would choose the register operation appropriate to the way it wanted to communicate.

Operation 2) is for the application to tell the hub about itself: a human-readable name, and maybe an icon, description etc.... I see this as being more contentious: we could instead simply use messages between applications to achieve the same thing. The advantage of having it as an operation in the protocol is for those environments that can send messages but can't easily receive them. For instance, I could send a message from the python commandline to Topcat, and all Topcat would have to identify me would be the hub-generated unique id, which isn't very friendly. If I'd also declared some metadata to the hub, then Topcat could interrogate the hub to find out just who senderId=vom://1234567-891 is. (with operation 2b)

Operation 3) is for the application to tell the hub which message types it wishes to receive. The hub won't send it messages it can't understand, and applications can interrogate the hub (using operation 12) to determine the appropriate messages to send. We might need a mechanism to say "send me messages of any type" [if we do, I hope we make a better job of it than we did in PLASTIC...which was a mess.]

In PLASTIC, these 3 operations are rolled into 1, but I feel it's better to separate them.

  1. unregister(id)

Messaging

  1. msgId = send(senderId, recipientId, message)
  2. msgId = broadcast(senderId, message)

These messages are asynchronous in the sense that they return as soon as the hub has received the message. The contents of message are specified on ApplicationsMessagingMessageContent.

Application metadata

  1. hubId = getHubId()
  2. ids[] = getApplicationIds()
  3. ids[] = getApplicationsUnderstanding(mtype)
  4. mtypes[] = getUnderstoodMessagesForApplication(id)
  5. metadata[] = getAppMetaData(id)

=============================================== 1) id= register*() 2) declareAppMetaData(id, metadata) 3) declareMessages(id, mtypes[])

4) unregister(id) When an application closes, it should inform the hub.

5) msgId = sendAsynch(senderId, recipientId, mtype, args[]) 6) msgId = broadcastAsynch(senderId, mtype, args[])

OK, this is where the fun happens. 5) sends a message from sender to recipient using the hub-supplied ids for addressing. 6) sends the message to everyone (if they've elected to receive that mtype). The hub returns a session-unique msgId that can be used in further comms, such as to tie reply messages up with request messages (in Mike's parlance). In these operations the message argument list args[] is intended to be quite general. I'm explicitly writing out the parameters here...if you prefer you can write it: 5) msgId = sendAsynch(message) where message wraps the whole lot. At some point we need to decide which parameters are part of the message, and which are not. My initial feeling is that mtype and args[] are part of the message, while the addressing info are not. [We could also add the msgId (if one already exists for that "conversation") as one of the input params, or we could put it inside args[] - I'm not sure which is best.]

Plastic devs will note another difference with Plastic - the above operations reflect the two most common modes of use that we've encountered in 18 months of experience: one-to-one, and one-to-all. Plastic has a one-to-subsetOfAll mode, which is rarely used to send to more than one application and is extremely annoying.

7) msgId, response = send(senderId, recipientId, mtype, args[]) 8) msgId, responses[] = broadcast(senderId, mtype, args[])

These are like 5 and 6, but block and then return a response value. This value can be quite general ( e.g. some kind of datastructure)

These are going to be contentious. Plastic allows a request-response style messaging pattern. This is not exactly radical: SOAP does it, and MPI has blocking send modes (though they're not quite the same as this). It is very useful in making the programmer's life easier when dealing with very quick informational messages such as "tell me what your application's icon is". Yes, I know you could do this asynchronously and sit around waiting for a message to come back with the answer, but I feel that we should be prepared to sacrifice some purity of style to make the application programmer's life easier. Furthermore, my putative python-command-line hacker cannot receive data back from applications any other way (or at least, not easily). However, I'd be interested to know what the community thinks. Could including a request-response style seriously restrict our choices when it comes to picking wire protocols?

9) hubId = getHubId()

We can treat the hub itself as just another application that can be messaged. However, you do need to know which application it is, and this operation does the job.

10) ids[] = getApplicationIds()

Tell me the hub-assigned ids of all the registered applications.

11) ids[] = getApplicationsUnderstanding(mtype)

Tell me the hub-assigned ids of the all the registered applications that understand messages with this mtype.

12) mtypes[] = getUnderstoodMessagesForApplication(id)

Tell me what mtypes this particular application claims to support.

Security


The question of applications spoofing one another has come up a few times. While I don't really believe it's a serious risk (those astronomers - they're such jokers!), I set out below a simple modification to the above protocol that would make it more secure. This is based on proposals by Mark Taylor in discussions we had a year ago - if they don't make any sense then blame my faulty memory rather than Mark.

The register operation could be changed as follows: (id, application-secret) = register*(hub-secret)

The hub-secret is a secret that can only be easily known by applications running under the user's uid and is intended to defeat other users on the same machine who might try ( e.g.) port scanning. For instance, it could be a random string written into the .ivoamsg file. The application-secret is a per-application secret that apps must keep track of and use along with their id to identify themselves. Thus, operations 2-8 would all include this as an extra parameter (though it wouldn't be transmitted to any receiving application by the hub.) This prevents Topcat pretending to be Aladin and vice versa (you guys!).

Well, I hope that you have time in between munching Easter Eggs to give me your thoughts on this. I'll try to get this up on the wiki so that we can keep track of modifications and suggestions.

 


<--  
-->
-- JohnTaylor - 10 Apr 2007

Revision 12007-04-10 - JohnTaylor

 
META TOPICPARENT name="ApplicationsMessaging"

High Level Protocol

This document describes the application messaging protocol in terms of the operations a Hub and a client application should support. It does not describe lower level details such as the wire protocol and parameter types. This document is still under discussion and will change.


<--  
-->
-- JohnTaylor - 10 Apr 2007
 
This site is powered by the TWiki collaboration platform Powered by Perl This site is powered by the TWiki collaboration platformCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback