Use the new Server Side Event support in ipaas-rest to automatically reload updated entity lists. #186
Conversation
4339a7d
to
e8e807f
Compare
retest this please |
Does EventSource support authorization headers? Our REST API currently only authenticates via validation of JWT contained in authorization header... |
@jimmidyson Looks we have to pass it via cookies.. is that a deal breaker for SSE? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chirino That'd be a no-go for IE support out of the box (this is pretty useful for determining what you can use), but check out this polyfill. Honestly, I say we get rid of the WS (WSS preferably), use SSE from the REST API and a really nice service in the UI to update the model on an as-needed basis via regular HTTP requests.
Basically, I think we only really need one or the other, not both. And if I had to choose, I'd normally go with Websockets, but in this case SSEs may make more sense. It's not without its caveats though. On the Java side, SSE allows you to override the header, but JS side you can't. A way around that is to use query parameters. Not my best idea, but, hey.
SSE does use regular HTTP, so the polyfill may be worth looking into. If we went with Websockets we'd really not be taking advantage of client > server communication because we don't need to (unless we of course decide to add a chat or something of that nature). As much as I like working with Websockets and its quirky complexities I don't see the benefit of dealing with it in this case. We'd mostly be looking for responses from the server, not bi-directional communication in realtime.
An example of what we need is that the client be notified when we delete a connection or integration, which could take a while for a 'delete completed' response from the server. Again, I'd usually opt for Websockets for specific events like this, not something like arbitrarily updating the server on any model change. And with the polyfill we just don't need it.
For most client > server model updates (e.g. creating a connection) we can just send manual HTTP requests, not leaving connections open as with Websockets, constantly checking for connection/disconnection. This will also be a pain when it comes to checking user inactivity later on. SSEs offer a ton of relevant things that WebSockets don't by design, like automatic reconnection, event IDs, and the ability to send arbitrary events.
Keep in mind that I'm more comfortable using Websockets, but I mean, it should be more about the right tool for the job I think? WDYT @chirino @jimmidyson ?
|
||
get resource() { return this._current.asObservable(); } | ||
get resource() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this was you or ts-lint.json
, but either way, ty.
If something doesn't make sense in my comment, just know I'm running on 3 hours of sleep, which may or may not be relevant. ;D |
Even better, a Node.js implementation that can be used to override headers from the "JS side", polyfill included: eventsource |
@kahboom, @jimmidyson I think SSE security should be sorted now without needing to do the cookie thing. Basically I first do a POST to request a event stream ID, at that point the user is associated with the stream, and then then we setup the SSE connection against that registered stream id (a random UUID) which does not get re-used. I kind like the SSE first then fallback to WS scenario, since if we ever move to HTTP2, then we are using the preferred strategy to begin with. also take a peek at: Notice we would be using SSE on most browsers except IE and Edge, and both have good WebSocket support. |
Yeah Websockets have the advantage of wider browser support. I'm not opposed to falling back on WS, or at least don't feel strongly about it. @jimmidyson I'd like to hear your thoughts on this. @chirino once tests are resolved I'll approve it, then merge based on what Jimmi prefers. |
add to whitelist |
// , fallback to using a WebSocket | ||
let wsurl = config.getSettings().apiEndpoint; | ||
// I know hacky! need to figure out how to put the wsevents resource under the apiEndpoint | ||
wsurl = wsurl.replace( /^https?/, 'ws' ).replace( /\/api\/v\d+$/, '/wsevents' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would always fall back to insecure ws rather than wss if https is used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, we'd absolutely need WSS considering we'd be opening connections quite frequently if it's to update models on any change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will fix in a bit.
Providing Websocket support as a fallback means we would need to maintain it along with the SSE implementation as the application scales, otherwise it'd be for naught. Just something to consider, but again, not opposed to it at all. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, minor issues need updating. Will probably need tweaking once we start using it properly.
@@ -0,0 +1,90 @@ | |||
import {Injectable} from '@angular/core'; | |||
import {Subject} from 'rxjs/Subject'; | |||
import {UUID} from 'angular2-uuid'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to be used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep.. don't need the uuid anymore. hangover from previous iteration.
Can't remember if the server side even supports websockets right now - @chirino? |
@jimmidyson - Now it does I believe, see syndesisio/syndesis-rest#115. More specifically. |
Also of relevance #114 . |
a000eb5
to
cb88c6d
Compare
Squashed and rebased off master. |
@kahboom, @jimmidyson: yep ipaas-reset supports both SSE and WebSockets. |
// , fallback to using a WebSocket | ||
let wsurl = config.getSettings().apiEndpoint; | ||
// I know hacky! need to figure out how to put the wsevents resource under the apiEndpoint | ||
wsurl = wsurl.replace( /^http/, 'ws' ).replace( /\/api\/v\d+$/, '/wsevents' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm this is a bit pants and means we need to set up another subpath route in openshift. what's the problem putting it under the API endpoint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep that's what I initially tried but the websocket handler would not trigger if not at a top level path. Not sure why yet. Perhaps if I use a different WS handling strategy it might work better (I'm currently using the SB abstractions).
…matically reload updated entity lists. (cherry picked from commit a000eb5)
@kahboom Are you happy with this? LGTM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for fixing the tests. 👍
Works in conjunction with the following PR:
syndesisio/syndesis-rest#115