[OpenAjaxInterop] Howard's changes to Hub 1.1 proposal page

Howard Weingram weingram at tibco.com
Fri Dec 5 13:52:35 PST 2008

Thanks very much, Javier.

My comments are inserted below.


On 12/5/08 11:02 AM, "Javier H Pedemonte" <pedemont at us.ibm.com> wrote:

> Howard Weingram <weingram at tibco.com> wrote on 12/04/2008 05:35:15 PM:
>> 1. subscriberData
>>     There are several subscribe() functions.
>>     OpenAjax.hub.subscribe(): currently takes subscriberData, and I think
>>         that we agreed to continue this.
>>     OpenAjax.hub.Hub.subscribe() in OpenAjax.hub.Hub interface:
>>         It turns out that this is kind of useful. It allows
>>         "static" functions to receive subscription data.
>>     I guess I can take it out, but I am very tempted to leave it in.
>>     Otherwise programmers tend to be forced to create lots of callback
>>     functions, even when the app does not need this.
> Sounds fine to me.  Let's keep it in.
>> 3. getParameters()
>>     I added this to ManagedHub because I have information on the
>>     ManagedHub that containers are very likely to use.
>>         a. Containers should be able to use their Managedhub's
>>             onSecurityAlert callback to notify the Manager of
>>             security violations. There is no standard API to
>>             get this function, and rather than add a separate
>>             function to the MH API (getOnSecurityAlert) I
>>             think that being able to get the hub params and
>>             extract the onSecurityAlert callback via its well-
>>             known param name is a good thing. Note that Container
>>             is not allowed to access ManagedHub private interfaces,
>>             so in order to call MH's security alert callback, there
>>             must be a public way to get this callback.
>>         b. I have added a "scope" parameter to the params in the
>>             MH constructor. Containers should be able to use
>>             their ManagedHub's scope parameter for onConnect,
>>             onDisconnect, and the manager's onSecurityAlert
>>             callbacks. As above, there is no MH.getScope(), just
>>             getParams(), which returns the params object, from
>>             which you can get scope via "params.scope".
> OK, this sounds fine, but we'll definitely have to explain this somewhere,
> maybe in a "tips" or "best practices" page.

Yes. In fact, we need 2 separate Best Practices pages.

1. Best Practices for Developing Containers (for Container and
    HubClient developers). These points belong in this document.

2. Best Practices for Developing Applications (for developers of
    managers and client applications).

Also, the API spec needs to stipulate that after a constructor is called,
the params object belongs to the constructed object and MUST NOT be changed
or destroyed by the application.

>> 5. subscribe() disallowed in onSubscribe()
>>     First a tangent: there are several scenarios on the subscribe side.
>>     a. ManagedHub.subscribe() successful
>>         Returns SubscriptionHandle
>>     b. ManagedHub.subscribe() fails due to bad topic or ManagedHub is
>>         being cleaned up and permits no more subscribe operations.
>>         Throws an appropriate exception
> Then we should add something like "NotAllowed" to OpenAjax.hub.Error.

I have been reusing BadParameters for this one, but I agree. I should be
more explicit. 

>>     c. HubClient.subscribe() successful
>>         Returns SubscriptionHandle
>>     d. INLINE HubClient.subscribe() causes Manager to call onSubscribe,
>>         which returns false, causing request to be denied.
>>         Before subscribe returns, onDone is synchronously invoked
>>         to report the error. Then subscribe() automatically destroys
>>         the dead SubscriptionHandle and returns null.
>>     e. FIM/POSTMSG HubClient.subscribe() causes Manager to call
>>         onSubscribe, which returns false, causing request to be denied.
>>         Subscribe returns a SubscriptionHandle, because we cannot
>>         tell yet whether the operation succeeded or failed.
>>         Some time after subscribe returns, the subscription's
>>         onDone is invoked to report the error, after which the
>>         SubscriptionHandle is automatically destroyed.
> Sounds good. 
>> 5a. Now the comment about Publish:
>>     I did not include this in my first revision, but in one
>>     implementation I have an optional parameter that can be included
>>     in the params for any ManagedHub or HubClient contructor. This
>>     parameter is a callback for handling asynchronous warnings.
>>     params = {
>>         onPublish: ...,
>>         onSubscribe: ...,
>>         onSecurityAlert: ...,
>>         onScope: ...,
>>         onWarning: ...
>>     }
>>     This callback is used when something that is not a serious
>>     security error occurs asynchronously.
>>     Or, we could simply turn onSecurityAlert into onError, and
>>     have it called in these cases too; the code would then need
>>     to check the error code to see if the problem were serious.
> Yes, I am all for having a single onError function that handles errors and
> security alerts.  And I like sending an error if publish fails, but not sure
> if we should do so if publish is denied.  The way I see it, the clients are
> blind as to what the manager is doing.  If the manager chooses to disallow a
> pub/sub, is there any reason to tell the client?

5a. Regarding one or two onError functions:

Currently, I have been using 2 different functions:

 * onSecurityAlertError
 * onWarning

The onWarning function handles asynchronous errors that do not appear to be
dangerous, while the onSecurityAlertError reports suspected attacks. My
thinking is that we need an easy way to distinguish suspected attacks from
less urgent issues. I avoided forcing the triage mechanism to depend on
exhaustive enumeration of specific errors, because different
Container/HubClient implementations may have specialized errors/warnings.
Generic application code may not recognize every type of error/warning
generated by every type of Container. Treating every warning as a suspected
attack would probably be overkill. Treating a suspected attack as a warning
could be a big mistake. I could have had some kind of severity flag, I
suppose, but I figured that a manager's behavior when an attack is suspected
(we probably destroy the container immediately) is much more extreme than
the behavior when a "warning" is received. Thus, I separated the two
handlers. Since many applications might not care about warnings at all, 2
functions seemed easiest and most efficient. However, a severity flag is
another possible option.

5b. Tangent: viewing permission-denied as warning vs. as attack

Right now I am treating authorization failures (onPublish returns false) as
warnings rather than as attempted attacks. I don't know whether everyone
else agrees with this approach.

5c. Regarding why we should tell the client when publish fails (good

When a client tries to publish and fails, this generally means that client
and manager applications have made mismatched assumptions about the security
policy of the mash-up. I certainly believe that the "fail-fast" principle
should apply to the mash-up as a whole (manager app + hub + client app).

Of course, one can argue that applying the fail-fast principle to the
complete system does not automatically require that it apply to the client
application in particular. For example, one might argue that the manager
application should be responsible for notifying the user of the mismatch,
given that the manager alone can tell the user how to modify the manager's
security policies in order to allow the client to publish.

However, there are a number of actions that a client can take if it sees
that the manager is rejecting publishes on a given topic.

* The client could disable further publication on the topic.

* If the ability to publish is required for the client to execute,
    may gracefully clean up scarce resources (e.g. comet connections)
    and may even disconnect from the hub.

* The client could display a warning message of its own, in the context
    of the client application UI.

If we do require that the client application be permitted to request
notification when publish fails, the following implications exist:

* Spec must indicate that every Container MUST try to notify its
    HubClient when onPublish returns false.

* publishForClient and subscribeForClient MUST throw an exception if
    onPublish or onSubscribe returns false, and the container
    implementation MUST catch and handle the exception.

Thanks for your patience with this long email. I am trying to provide
explanations, rationales and examples that will help us when we are writing
the specs and documents.
Your thoughts welcome.

Best Regards,
Howard Weingram

Howard Weingram      650.846.1000
Principal Architect  TIBCO Software Inc.

TIBCO PageBus(TM) delivers ultra-lightweight
publish-subscribe messaging for mash-ups.
Learn more at http://www.pagebus.org

More information about the interop mailing list