Skip to content

Commit

Permalink
Merge remote-tracking branch 'MSTR/master' into 2.x
Browse files Browse the repository at this point in the history
Signed-off-by: jansupol <jan.supol@oracle.com>
  • Loading branch information
jansupol committed Aug 27, 2021
2 parents 9526b16 + 0bab5e3 commit 16aa29d
Show file tree
Hide file tree
Showing 16 changed files with 369 additions and 55 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ language: java

jdk:
- oraclejdk8
- oraclejdk13
- oraclejdk11
- openjdk17

cache:
directories:
Expand Down
87 changes: 87 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
[//]: # " Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. "
[//]: # " "
[//]: # " This program and the accompanying materials are made available under the "
[//]: # " terms of the Eclipse Public License v. 2.0, which is available at "
[//]: # " http://www.eclipse.org/legal/epl-2.0. "
[//]: # " "
[//]: # " This Source Code may also be made available under the following Secondary "
[//]: # " Licenses when the conditions for such availability set forth in the "
[//]: # " Eclipse Public License v. 2.0 are satisfied: GNU General Public License, "
[//]: # " version 2 with the GNU Classpath Exception, which is available at "
[//]: # " https://www.gnu.org/software/classpath/license.html. "
[//]: # " "
[//]: # " SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 "

# Contributing to Eclipse Tyrus

Thanks for your interest in this project.

## Project description

Eclipse Tyrus is the open source
<a href="https://projects.eclipse.org/projects/ee4j.websocket">JSR 356 - Java API for WebSocket</a>
reference implementation for easy development of WebSocket applications. Eclipse Tyrus is also
a Jakarta WebSocket 2.0 compatible implementation.

WebSocket protocol defined by IETF
provides bi-directional communication between the server and the remote host. The
pros are mainly the ability to communicate both ways, low latency and small
communication overhead. Therefore Tyrus and WebSocket in general are suitable for web
applications that require sending a huge volume of relatively small messages like
online games or market ticker broadcasting.

Goals of Eclipse Tyrus project can be summarized in the following points:
* Track the Eclipse WebSocket API and provide regular releases of production quality implementations that ships with GlassFish;

* Provide APIs to extend Tyrus & Build a community of users and developers; and finally

* Make it easy to build websocket based web services utilising Java and the Java Virtual Machine.

## Developer resources

Information regarding source code management, builds, coding standards, and
more.

* https://projects.eclipse.org/projects/ee4j.tyrus/developer

The project maintains the following source code repositories

* https://github.com/eclipse-ee4j/tyrus
* https://github.com/eclipse-ee4j/tyrus-project.github.io

## Eclipse Development Process

This Eclipse Foundation open project is governed by the Eclipse Foundation
Development Process and operates under the terms of the Eclipse IP Policy.

## Specifications

This specification project operates under the terms of the Eclipse Foundation
Specification process.

* https://eclipse.org/projects/dev_process
* https://www.eclipse.org/org/documents/Eclipse_IP_Policy.pdf
* https://www.eclipse.org/projects/efsp/
* https://www.eclipse.org/legal/efsp_non_assert.php

## Eclipse Contributor Agreement

Before your contribution can be accepted by the project team contributors must
electronically sign the Eclipse Contributor Agreement (ECA).

* http://www.eclipse.org/legal/ECA.php

Commits that are provided by non-committers must have a Signed-off-by field in
the footer indicating that the author is aware of the terms by which the
contribution has been provided to the project. The non-committer must
additionally have an Eclipse Foundation account and must have a signed Eclipse
Contributor Agreement (ECA) on file.

For more information, please see the Eclipse Committer Handbook:
https://www.eclipse.org/projects/handbook/#resources-commit

## Contact

Contact the project developers via the project's "dev" list.

* https://dev.eclipse.org/mailman/listinfo/tyrus-dev
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
[![Build Status](https://travis-ci.org/eclipse-ee4j/tyrus.svg?branch=master)](https://travis-ci.org/eclipse-ee4j/tyrus)

# Tyrus
# Eclipse Tyrus

Tyrus is the open source
Eclipse Tyrus is the open source
<a href="https://projects.eclipse.org/projects/ee4j.websocket">JSR 356 - Java API for WebSocket</a>
reference implementation
for easy development of WebSocket applications. WebSocket protocol defined by IETF
for easy development of WebSocket applications.Eclipse Tyrus is also
a Jakarta WebSocket 2.0 compatible implementation.

WebSocket protocol defined by IETF
provides bi-directional communication between the server and the remote host. The
pros are mainly the ability to communicate both ways, low latency and small
communication overhead. Therefore Tyrus and WebSocket in general are suitable for web
applications that require sending a huge volume of relatively small messages like
online games or market ticker broadcasting.

## Building Eclipse Tyrus

Building Tyrus can be done using `mvn clean install`, but sometimes (such as for building 2.x from a tag)
`mvn clean install -Pstaging` would be required.

## Licensing

- [Eclipse Public License 2.0](https://projects.eclipse.org/license/epl-2.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ public void close(CloseReason reason) {
@Override
public void processConnectionClosed() {
LOGGER.log(Level.FINE, "Connection has been closed by the server");
if (connectCompletionHandler != null) {
connectCompletionHandler.failed(new IOException("Connection closed by server"));
}

if (wsConnection == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,34 +83,9 @@ public void onStartup(Set<Class<?>> classes, final ServletContext ctx) throws Se
DebugContext.TracingThreshold.TRACE);

final ApplicationEventListener applicationEventListener = createApplicationEventListener(ctx);
final TyrusServerContainer serverContainer = new TyrusServerContainer(classes) {

private final WebSocketEngine engine =
TyrusWebSocketEngine.builder(this)
.applicationEventListener(applicationEventListener)
.incomingBufferSize(incomingBufferSize)
.maxSessionsPerApp(maxSessionsPerApp)
.maxSessionsPerRemoteAddr(maxSessionsPerRemoteAddr)
.parallelBroadcastEnabled(parallelBroadcastEnabled)
.tracingType(tracingType)
.tracingThreshold(tracingThreshold)
.build();

@Override
public void register(Class<?> endpointClass) throws DeploymentException {
engine.register(endpointClass, ctx.getContextPath());
}

@Override
public void register(ServerEndpointConfig serverEndpointConfig) throws DeploymentException {
engine.register(serverEndpointConfig, ctx.getContextPath());
}

@Override
public WebSocketEngine getWebSocketEngine() {
return engine;
}
};
final TyrusServerContainer serverContainer = new TyrusServerContainerImpl(classes, applicationEventListener,
incomingBufferSize, maxSessionsPerApp, maxSessionsPerRemoteAddr, parallelBroadcastEnabled, tracingType,
tracingThreshold, ctx.getContextPath());
ctx.setAttribute(ServerContainer.class.getName(), serverContainer);
Boolean wsadlEnabled = getBooleanContextParam(ctx, TyrusWebSocketEngine.WSADL_SUPPORT);
if (wsadlEnabled == null) {
Expand Down Expand Up @@ -224,4 +199,55 @@ private ApplicationEventListener createApplicationEventListener(final ServletCon
}
return null;
}

private static class TyrusServerContainerImpl extends TyrusServerContainer {
private final ApplicationEventListener applicationEventListener;
private final Integer incomingBufferSize;
private final Integer maxSessionsPerApp;
private final Integer maxSessionsPerRemoteAddr;
private final Boolean parallelBroadcastEnabled;
private final DebugContext.TracingType tracingType;
private final DebugContext.TracingThreshold tracingThreshold;
private final String contextPath;
private final WebSocketEngine engine;

public TyrusServerContainerImpl(Set<Class<?>> set, ApplicationEventListener applicationEventListener,
Integer incomingBufferSize, Integer maxSessionsPerApp, Integer maxSessionsPerRemoteAddr,
Boolean parallelBroadcastEnabled, DebugContext.TracingType tracingType,
DebugContext.TracingThreshold tracingThreshold, String contextPath) {
super(set);
this.applicationEventListener = applicationEventListener;
this.incomingBufferSize = incomingBufferSize;
this.maxSessionsPerApp = maxSessionsPerApp;
this.maxSessionsPerRemoteAddr = maxSessionsPerRemoteAddr;
this.parallelBroadcastEnabled = parallelBroadcastEnabled;
this.tracingType = tracingType;
this.tracingThreshold = tracingThreshold;
this.contextPath = contextPath;
this.engine = TyrusWebSocketEngine.builder(this)
.applicationEventListener(applicationEventListener)
.incomingBufferSize(incomingBufferSize)
.maxSessionsPerApp(maxSessionsPerApp)
.maxSessionsPerRemoteAddr(maxSessionsPerRemoteAddr)
.parallelBroadcastEnabled(parallelBroadcastEnabled)
.tracingType(tracingType)
.tracingThreshold(tracingThreshold)
.build();
}

@Override
public void register(Class<?> endpointClass) throws DeploymentException {
engine.register(endpointClass, contextPath);
}

@Override
public void register(ServerEndpointConfig serverEndpointConfig) throws DeploymentException {
engine.register(serverEndpointConfig, contextPath);
}

@Override
public WebSocketEngine getWebSocketEngine() {
return engine;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
class TyrusServletFilter implements Filter, HttpSessionListener {

private static final Logger LOGGER = Logger.getLogger(TyrusServletFilter.class.getName());
private final TyrusWebSocketEngine engine;
private TyrusWebSocketEngine engine;
private final boolean wsadlEnabled;

// I don't like this map, but it seems like it is necessary. I am forced to handle subscriptions
Expand Down Expand Up @@ -303,5 +303,7 @@ private synchronized JAXBContext getWsadlJaxbContext() throws JAXBException {
public void destroy() {
serverContainer.stop();
engine.getApplicationEventListener().onApplicationDestroyed();
serverContainer = null;
engine = null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -301,21 +301,25 @@ public void removeMessageHandler(MessageHandler handler) {
}
}

Map<Class<?>, MessageHandler> getRegisteredHandlers() {
return new HashMap<>(registeredHandlers);
}

/**
* Get all successfully registered {@link MessageHandler}s.
*
* @return unmodifiable {@link Set} of registered {@link MessageHandler}s.
*/
public Set<MessageHandler> getMessageHandlers() {
if (messageHandlerCache == null) {
messageHandlerCache = Collections.unmodifiableSet(new HashSet<MessageHandler>(registeredHandlers.values()));
messageHandlerCache = Collections.unmodifiableSet(new HashSet<>(registeredHandlers.values()));
}

return messageHandlerCache;
}

public List<Map.Entry<Class<?>, MessageHandler>> getOrderedWholeMessageHandlers() {
List<Map.Entry<Class<?>, MessageHandler>> result = new ArrayList<Map.Entry<Class<?>, MessageHandler>>();
List<Map.Entry<Class<?>, MessageHandler>> result = new ArrayList<>();
for (final Map.Entry<Class<?>, MessageHandler> entry : registeredHandlers.entrySet()) {
if (entry.getValue() instanceof MessageHandler.Whole) {
result.add(entry);
Expand All @@ -325,7 +329,7 @@ public List<Map.Entry<Class<?>, MessageHandler>> getOrderedWholeMessageHandlers(
return result;
}

static Class<?> getHandlerType(MessageHandler handler) {
private static Class<?> getHandlerType(MessageHandler handler) {
Class<?> root;
if (handler instanceof AsyncMessageHandler) {
return ((AsyncMessageHandler) handler).getType();
Expand Down
16 changes: 8 additions & 8 deletions core/src/main/java/org/glassfish/tyrus/core/TyrusSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
Expand Down Expand Up @@ -61,7 +62,7 @@
* @author Martin Matula (martin.matula at oracle.com)
* @author Pavel Bucek (pavel.bucek at oracle.com)
*/
public class TyrusSession implements Session, DistributedSession {
public class TyrusSession implements DistributedSession {

private static final Logger LOGGER = Logger.getLogger(TyrusSession.class.getName());

Expand Down Expand Up @@ -587,9 +588,10 @@ <T> MessageHandler.Whole<T> getMessageHandler(Class<T> c) {
void notifyMessageHandlers(Object message, boolean last) {
boolean handled = false;

for (MessageHandler handler : getMessageHandlers()) {
for (Entry<Class<?>, MessageHandler> e : this.handlerManager.getRegisteredHandlers().entrySet()) {
MessageHandler handler = e.getValue();
if ((handler instanceof MessageHandler.Partial)
&& MessageHandlerManager.getHandlerType(handler).isAssignableFrom(message.getClass())) {
&& e.getKey().isAssignableFrom(message.getClass())) {

if (handler instanceof AsyncMessageHandler) {
checkMessageSize(message, ((AsyncMessageHandler) handler).getMaxMessageSize());
Expand All @@ -615,11 +617,9 @@ void notifyMessageHandlers(Object message, boolean last) {
}

void notifyPongHandler(PongMessage pongMessage) {
final Set<MessageHandler> messageHandlers = getMessageHandlers();
for (MessageHandler handler : messageHandlers) {
if (MessageHandlerManager.getHandlerType(handler).equals(PongMessage.class)) {
((MessageHandler.Whole<PongMessage>) handler).onMessage(pongMessage);
}
final MessageHandler.Whole<PongMessage> handler = getMessageHandler(PongMessage.class);
if (handler != null) {
handler.onMessage(pongMessage);
}
}

Expand Down
41 changes: 38 additions & 3 deletions core/src/test/java/org/glassfish/tyrus/core/TyrusSessionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@ public void onMessage(InputStream message, boolean last) {
public void multiplePongHandlersAsync() {
Session session = createSession(endpointWrapper);


session.addMessageHandler(new MessageHandler.Partial<PongMessage>() {
@Override
public void onMessage(PongMessage message, boolean last) {
Expand All @@ -312,7 +311,6 @@ public void onMessage(PongMessage message, boolean last) {
public void multipleBasicDecodableAsync() {
Session session = createSession(endpointWrapper);


session.addMessageHandler(new MessageHandler.Partial<TyrusSessionTest>() {
@Override
public void onMessage(TyrusSessionTest message, boolean last) {
Expand Down Expand Up @@ -359,7 +357,6 @@ public void onMessage(PongMessage message) {
public void removeHandlers() {
Session session = createSession(endpointWrapper);


final MessageHandler.Partial<String> handler1 = new MessageHandler.Partial<String>() {
@Override
public void onMessage(String message, boolean last) {
Expand Down Expand Up @@ -408,6 +405,44 @@ public void idTest() {
assertFalse(session2.getId().equals(session3.getId()));
}

@Test
public void getLambdaHandlers() {
Session session = createSession(endpointWrapper);

final MessageHandler.Partial<String> handler1 = this::stringPartialHandler;
final MessageHandler.Whole<ByteBuffer> handler2 = this::bytesHandler;
final MessageHandler.Whole<PongMessage> handler3 = this::pongHandler;

session.addMessageHandler(String.class, handler1);
session.addMessageHandler(ByteBuffer.class, handler2);
session.addMessageHandler(PongMessage.class, handler3);

assertTrue(session.getMessageHandlers().contains(handler1));
assertTrue(session.getMessageHandlers().contains(handler2));
assertTrue(session.getMessageHandlers().contains(handler3));

session.removeMessageHandler(handler3);

assertTrue(session.getMessageHandlers().contains(handler1));
assertTrue(session.getMessageHandlers().contains(handler2));
assertFalse(session.getMessageHandlers().contains(handler3));

session.removeMessageHandler(handler2);

assertTrue(session.getMessageHandlers().contains(handler1));
assertFalse(session.getMessageHandlers().contains(handler2));
assertFalse(session.getMessageHandlers().contains(handler3));
}

private void stringPartialHandler(String message, boolean last) {
}

private void bytesHandler(ByteBuffer message) {
}

private void pongHandler(PongMessage message) {
}


@ServerEndpoint(value = "/echo")
private static class EchoEndpoint extends Endpoint {
Expand Down
Loading

0 comments on commit 16aa29d

Please sign in to comment.