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

Initial WebSocket Client Connector ("ws"/non-SSL support) #32

Merged
merged 17 commits into from
Mar 2, 2016

Conversation

dlaboss
Copy link
Member

@dlaboss dlaboss commented Feb 19, 2016

Do not merge. Pull request created for sharing the proposed API.
Compiles but no backing implementation.

@dlaboss dlaboss mentioned this pull request Feb 19, 2016
* @return sink
* @see JsonFunctions#asString()
*/
public <T> TSink<T> send(TStream<T> stream, Function<T,String> toPayload) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this method?

Why not just have the send<TStream<String>> and if anyone can use a upstream map to convert the tuple?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, could omit it. I was following the patterns present in other connectors (for better or worse).

Pulling on that thread, all that's really needed is a single send: send(TStream<byte[]>) and analogous single receive. There's a benefit to that & I'm OK with it. Start with just those? Presumably not too late to trim down other connectors too - with commensurate savings in footprint and # of test cases.

Note, if we later decide we want the convenience fn send(TStream<String>) we'll have to name it something else due to type erasure. Other connectors addressed that sort of thing by naming the, presumed less frequently used, byte payload variant sendBytes. Do likewise here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a connector should have methods to support the data types users logically send/receive from it. While it may all end up as byte[] under the covers the developer should be allowed to remain at their logical level, so if I naturally send strings then I don't want to be forced to do something like map(t -> t.getBytes(StandardCharsets.UTF8))

For websockets it probably depends on the use cases, but I would almost say JsonObject, String and byte[] and almost tempted to say bytes are the least likely and JSON the most likely.

@ddebrunner
Copy link
Contributor

I wonder if the client should be a separate module to the server.

I'm interested in feedback from @wmarshall484 about the use cases for web-sockets, is there even a use case for a server on an edge device? Maybe gateway devices?

@dlaboss
Copy link
Member Author

dlaboss commented Feb 19, 2016

Ditto on feedback. Yup, my thinking was that a server would be an important case for a quarks gateway device. I'll put the client & server in separate components.

@dlaboss dlaboss changed the title [WIP] Web Socket Connector - proposed API [WIP] Initial WebSocket Client Connector ("ws"/non-SSL support) Feb 24, 2016
@dlaboss
Copy link
Member Author

dlaboss commented Feb 24, 2016

@ddebrunner, looking for a +1 for merging this intermediate level of completion.

  • WebSocket Client connector API is fully spec'd / doc'd
  • files for proposed server connector were removed
  • full "ws" (non-SSL) support. Working on "wss"/SSL next.
  • a healthy collection of passing tests. None failing.

- client and server in separate components
- client support for JsonObject,String and byte[] streams.
- similar for server

Giving priority to the client.
- "wss" support is next on the list
- removed iotf/ext/{javax.servlet,ibm.json4j} from component .classpath.
They're unnecessary (issue#43) and javax.servlet caused binding problems
with the websocket code when running from Eclipse.
- note, the various test.ext/jetty jars are needed for the test
websocket server. They're not included in the connector's jar.
- remove proposed wsserver artifacts
- misc cleanup
@Override
public void accept(Consumer<T> eventHandler) {
this.eventHandler = eventHandler;
connector.setReceiver(this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could connector.setReceiver(this) be called once in the constructor, instead of on every accept()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This accept is the setup callback from Topology.events() and it's only called once for the lifetime of the job to initialize the "source". If setReceiver() was called prior to receiving the eventHandler, there might be cases where the receiver would be given a message so it would have to check every time to ensure it had an eventHandler to give it to.

@ddebrunner
Copy link
Contributor

Does it make sense to have a interface for a web-socket client that is separate from the implementation?

That would then allow different implementations of the same interface. Jetty may provide the best libraries for web-sockets but I wonder if smaller footprint client libraries might exist.

That's what I'm going to do for serial ports ( #27 ), just have a connector that specifies an interface.

@dlaboss
Copy link
Member Author

dlaboss commented Feb 25, 2016

re the "interface" idea, we could do that, but I wonder if it's necessary as there's already a level of indirection in this WebSocketClient connector impl. The impl uses the std jsr-356 javax.websocket API - there's no direct references to any jetty code. Might that be sufficient? Are you concerned that jsr-356 itself will be too heavweight?

[ as an aside, if we're going to start creating interfaces for connectors should there also be a common factory patten to get an impl? ]

Details on the current impl...
Under the covers, javax.websocket.ContainerProvider.getWebSocketContainer() binds to an actual impl (via the java.util.ServiceLoader mechanism). We're getting the generic javax.websocket API & provider from one jetty supplied jar. There are other jetty jars that provide an actual implementation.
Currently they're all on the wsclient connector jar's manifest classpath (needs tweaking). But at least in theory all the pieces are there to allow alternative javax.websocket based implementations to be used by just tweaking the classpath/manifest.

@ddebrunner
Copy link
Contributor

I didn't know there was a standard api for web-sockets, so we don't need to provide an additional separation.

@ddebrunner
Copy link
Contributor

-1 on license issue

Please include the notice file from the Eclipse Jetty distribution.

@ddebrunner
Copy link
Contributor

I'm still not seeing the notice file from Eclipse Jetty distribution in the ext, only the licence file.

@dlaboss
Copy link
Member Author

dlaboss commented Feb 26, 2016

ah. thx for the clarification.

@dlaboss
Copy link
Member Author

dlaboss commented Feb 26, 2016

BTW, I'm having second thoughts about not doing a wsclient interface. It seems like one "bare bones" websocket implementation, Java-WebSocket, doesn't have any javax.websocket support.

@ddebrunner
Copy link
Contributor

That almost seems like a dead project, maybe take the yagni approach.

- TODO extract a WebSocketClient connector API interface
- wsclient is a jsr356 javax.websocket API client (and includes a
generic javax.websocket API impl jar from jetty)
- user of the connector needs to also include a javax.websocket client
implementation, such as the supplied javax.websocket-client.jar

- add javax.websocket-client to capture a jetty based client impl
- add javax.websocket-server to capture a jetty based server impl (used
today by the WebSocketServerEcho test util for the wsclient API tests)
- don't require javax.websocket based client/server impls
- ws based impl is now Jsr356WebSocketClient in package
...wsclient.javax.websocket  ugh?
@dlaboss
Copy link
Member Author

dlaboss commented Feb 27, 2016

To summarize where things are now:

  • WebSocket Client connector is fully spec'd / doc'd
    • wsclient.WebSocketClient connector API (don't preclude non-jsr356 based impls)
    • wsclient.javax.websocket.Jsr356WebSocketClient connector API impl - bound only to generic jsr356 API
    • separate jetty-supplied impls of jsr356 javax.websocket client and server
    • hence user of Jsr356WebSocketClient has to include its jar and the (or some other) jsr356 javax.websocket client impl jar
  • files for proposed server connector were removed for now
  • full "ws" (non-SSL) support. Working on "wss"/SSL next.
  • a healthy collection of passing tests. None failing.

@ddebrunner
Copy link
Contributor

So is the pull request still a wip ?

@dlaboss dlaboss changed the title [WIP] Initial WebSocket Client Connector ("ws"/non-SSL support) Initial WebSocket Client Connector ("ws"/non-SSL support) Feb 29, 2016
@dlaboss
Copy link
Member Author

dlaboss commented Feb 29, 2016

Re: Java-WebSockets, fwiw it's what streamsx.inet.wsserver uses.
Removing WIP.

@dlaboss
Copy link
Member Author

dlaboss commented Feb 29, 2016

@ddebrunner, why is this appropriate: interface IotDevice extends TopologyElement
Will it still be appropriate if TopologyElement extends Taggable (not sure if issue #39 implied that or not)
Following that lead I blindly did the same for WebSocketClient and want to be sure it's appropriate or to clean it up.

@ddebrunner
Copy link
Contributor

It is an element of the topology. I could image such items being of interest in a graph visualization, though additional elements would need to be added to the JSON representation.

@dlaboss
Copy link
Member Author

dlaboss commented Feb 29, 2016

thx for clarification. +1 on a merge now?

@ddebrunner
Copy link
Contributor

-1 lifted as ext directories now contain licence and notice files.

dlaboss added a commit that referenced this pull request Mar 2, 2016
Initial WebSocket Client Connector ("ws"/non-SSL support)
@dlaboss dlaboss merged commit a13f71c into quarks-edge:master Mar 2, 2016
@dlaboss dlaboss deleted the websockets branch March 4, 2016 17:45
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

Successfully merging this pull request may close these issues.

3 participants