Skip to content

Commit 2bcdd52

Browse files
committed
WebSocket attributes (session, e.t.c) fix jooby-project#977
1 parent 3ddab24 commit 2bcdd52

File tree

4 files changed

+492
-360
lines changed

4 files changed

+492
-360
lines changed

jooby/src/main/java/org/jooby/WebSocket.java

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -203,23 +203,21 @@
203203
*/
204204
package org.jooby;
205205

206+
import com.google.common.base.Preconditions;
207+
import com.google.inject.Key;
208+
import com.google.inject.TypeLiteral;
206209
import static java.util.Objects.requireNonNull;
207-
208-
import java.io.Closeable;
209-
import java.util.Map;
210-
import java.util.Optional;
211-
import java.util.Set;
212-
213210
import org.jooby.internal.RouteMatcher;
214211
import org.jooby.internal.RoutePattern;
215212
import org.jooby.internal.WebSocketImpl;
216213
import org.slf4j.LoggerFactory;
217214

218-
import com.google.common.base.Preconditions;
219-
import com.google.inject.Key;
220-
import com.google.inject.TypeLiteral;
221-
222215
import javax.annotation.Nonnull;
216+
import javax.annotation.Nullable;
217+
import java.io.Closeable;
218+
import java.util.Map;
219+
import java.util.Optional;
220+
import java.util.Set;
223221

224222
/**
225223
* <h1>WebSockets</h1>
@@ -975,4 +973,54 @@ default void broadcast(final Object data, final OnError err) throws Exception {
975973
* @throws Exception If something goes wrong.
976974
*/
977975
void broadcast(Object data, SuccessCallback success, OnError err) throws Exception;
976+
977+
/**
978+
* Set a web socket attribute.
979+
*
980+
* @param name Attribute name.
981+
* @param value Attribute value.
982+
* @return This socket.
983+
*/
984+
@Nullable
985+
WebSocket set(String name, Object value);
986+
987+
/**
988+
* Get a web socket attribute.
989+
*
990+
* @param name Attribute name.
991+
* @return Attribute value.
992+
*/
993+
<T> T get(String name);
994+
995+
/**
996+
* Get a web socket attribute or empty value.
997+
*
998+
* @param name Attribute name.
999+
* @param <T> Attribute type.
1000+
* @return Attribute value or empty value.
1001+
*/
1002+
<T> Optional<T> ifGet(String name);
1003+
1004+
/**
1005+
* Clear/remove a web socket attribute.
1006+
*
1007+
* @param name Attribute name.
1008+
* @param <T> Attribute type.
1009+
* @return Attribute value (if any).
1010+
*/
1011+
<T> Optional<T> unset(String name);
1012+
1013+
/**
1014+
* Clear/reset all the web socket attributes.
1015+
*
1016+
* @return This socket.
1017+
*/
1018+
WebSocket unset();
1019+
1020+
/**
1021+
* Web socket attributes.
1022+
*
1023+
* @return Web socket attributes.
1024+
*/
1025+
Map<String, Object> attributes();
9781026
}

jooby/src/main/java/org/jooby/internal/WebSocketImpl.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@
220220
import org.slf4j.Logger;
221221
import org.slf4j.LoggerFactory;
222222

223+
import javax.annotation.Nullable;
223224
import java.nio.channels.ClosedChannelException;
224225
import java.nio.charset.StandardCharsets;
225226
import java.util.Collections;
@@ -280,6 +281,8 @@ public class WebSocketImpl implements WebSocket {
280281

281282
private volatile boolean open;
282283

284+
private ConcurrentMap<String, Object> attributes = new ConcurrentHashMap<>();
285+
283286
public WebSocketImpl(final OnOpen handler, final String path,
284287
final String pattern, final Map<Object, String> vars,
285288
final MediaType consumes, final MediaType produces) {
@@ -471,6 +474,32 @@ public void onClose(final WebSocket.OnClose callback) throws Exception {
471474
this.closeCallback = requireNonNull(callback, "A callback is required.");
472475
}
473476

477+
@Override public <T> T get(String name) {
478+
return (T) ifGet(name).orElseThrow(() -> new NullPointerException(name));
479+
}
480+
481+
@Override public <T> Optional<T> ifGet(String name) {
482+
return Optional.ofNullable((T) attributes.get(name));
483+
}
484+
485+
@Nullable @Override public WebSocket set(String name, Object value) {
486+
attributes.put(name, value);
487+
return this;
488+
}
489+
490+
@Override public <T> Optional<T> unset(String name) {
491+
return Optional.ofNullable((T) attributes.remove(name));
492+
}
493+
494+
@Override public WebSocket unset() {
495+
attributes.clear();
496+
return this;
497+
}
498+
499+
@Override public Map<String, Object> attributes() {
500+
return Collections.unmodifiableMap(attributes);
501+
}
502+
474503
private void handleErr(final Throwable cause) {
475504
Try.run(() -> {
476505
boolean silent = ConnectionResetByPeer.test(cause) || cause instanceof ClosedChannelException;

jooby/src/test/java/org/jooby/WebSocketTest.java

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
package org.jooby;
22

3+
import com.google.inject.Key;
4+
import com.google.inject.TypeLiteral;
35
import static org.easymock.EasyMock.expect;
4-
import static org.junit.Assert.assertEquals;
5-
import static org.junit.Assert.assertTrue;
6-
7-
import java.util.LinkedList;
8-
import java.util.Map;
9-
106
import org.jooby.WebSocket.CloseStatus;
117
import org.jooby.test.MockUnit;
8+
import static org.junit.Assert.assertEquals;
9+
import static org.junit.Assert.assertTrue;
1210
import org.junit.Test;
1311
import org.junit.runner.RunWith;
1412
import org.powermock.core.classloader.annotations.PrepareForTest;
1513
import org.powermock.modules.junit4.PowerMockRunner;
1614
import org.slf4j.Logger;
1715
import org.slf4j.LoggerFactory;
1816

19-
import com.google.inject.Key;
20-
import com.google.inject.TypeLiteral;
17+
import javax.annotation.Nullable;
18+
import java.util.LinkedList;
19+
import java.util.Map;
20+
import java.util.Optional;
2121

2222
@RunWith(PowerMockRunner.class)
2323
@PrepareForTest({WebSocket.class, LoggerFactory.class })
@@ -112,6 +112,29 @@ public void onClose(final OnClose callback) throws Exception {
112112
throw new UnsupportedOperationException();
113113
}
114114

115+
@Override public <T> T get(String name) {
116+
throw new UnsupportedOperationException();
117+
}
118+
119+
@Override public <T> Optional<T> ifGet(String name) {
120+
throw new UnsupportedOperationException();
121+
}
122+
123+
@Nullable @Override public WebSocket set(String name, Object value) {
124+
throw new UnsupportedOperationException();
125+
}
126+
127+
@Override public WebSocket unset() {
128+
throw new UnsupportedOperationException();
129+
}
130+
131+
@Override public <T> Optional<T> unset(String name) {
132+
throw new UnsupportedOperationException();
133+
}
134+
135+
@Override public Map<String, Object> attributes() {
136+
throw new UnsupportedOperationException();
137+
}
115138
}
116139

117140
@Test

0 commit comments

Comments
 (0)