Skip to content

Commit 0fc9d44

Browse files
committed
Ensure we use the right context.
1 parent 4f7f47b commit 0fc9d44

File tree

5 files changed

+157
-16
lines changed

5 files changed

+157
-16
lines changed

core/wisdom-vertx-engine/src/main/java/org/wisdom/framework/vertx/ContextFromVertx.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class ContextFromVertx implements Context {
7575
* @param accessor a structure containing the used services.
7676
* @param req the incoming HTTP Request.
7777
*/
78-
public ContextFromVertx(Vertx vertx, ServiceAccessor accessor, HttpServerRequest req) {
78+
public ContextFromVertx(Vertx vertx, io.vertx.core.Context vertxContext, ServiceAccessor accessor, HttpServerRequest req) {
7979
id = ids.getAndIncrement();
8080
services = accessor;
8181
request = new RequestFromVertx(req);
@@ -84,6 +84,12 @@ public ContextFromVertx(Vertx vertx, ServiceAccessor accessor, HttpServerRequest
8484
session = new SessionCookieImpl(accessor.getCrypto(), accessor.getConfiguration());
8585
flash.init(this);
8686
session.init(this);
87+
88+
if (vertxContext == null) {
89+
throw new IllegalArgumentException("Creating a context from vert.x outside of an event loop");
90+
} else {
91+
this.vertxContext = vertxContext;
92+
}
8793
}
8894

8995

core/wisdom-vertx-engine/src/main/java/org/wisdom/framework/vertx/HttpHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public HttpHandler(Vertx vertx, ServiceAccessor accessor, Server server) {
8989
@Override
9090
public void handle(final HttpServerRequest request) {
9191
LOGGER.debug("A request has arrived on the server : {} {}", request.method(), request.path());
92-
final ContextFromVertx context = new ContextFromVertx(vertx, accessor, request);
92+
final ContextFromVertx context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor, request);
9393

9494
if (!server.accept(request.path())) {
9595
LOGGER.warn("Request on {} denied by {}", request.path(), server.name());

core/wisdom-vertx-engine/src/test/java/org/wisdom/framework/vertx/ContextFromVertxTest.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.vertx.core.Vertx;
2727
import org.junit.After;
2828
import org.junit.Before;
29+
import org.junit.Rule;
2930
import org.junit.Test;
3031
import org.wisdom.api.Controller;
3132
import org.wisdom.api.DefaultController;
@@ -45,6 +46,8 @@ public class ContextFromVertxTest {
4546
private ServiceAccessor accessor;
4647
private ApplicationConfiguration configuration;
4748

49+
@Rule
50+
public RunOnVertxContext runOnVertxContext = new RunOnVertxContext();
4851

4952
@Before
5053
public void setUp() {
@@ -65,49 +68,52 @@ public void tearDown() {
6568
@Test
6669
public void testId() throws Exception {
6770
HttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
68-
ContextFromVertx context = new ContextFromVertx(vertx, accessor,
71+
ContextFromVertx context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor,
6972
RequestFromVertXTest.create(req));
7073
assertThat(context.id()).isNotNegative();
7174
long id1 = context.id();
72-
context = new ContextFromVertx(vertx, accessor,
75+
context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor,
7376
RequestFromVertXTest.create(req));
7477
assertThat(id1).isLessThan(context.id());
7578
}
7679

7780
@Test
7881
public void testRequest() throws Exception {
7982
HttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
80-
ContextFromVertx context = new ContextFromVertx(vertx, accessor,
83+
ContextFromVertx context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor,
8184
RequestFromVertXTest.create(req));
8285
assertThat(context.request()).isNotNull();
8386
}
8487

8588
@Test
8689
public void testPath() throws Exception {
8790
HttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
88-
ContextFromVertx context = new ContextFromVertx(vertx, accessor,
91+
ContextFromVertx context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor,
8992
RequestFromVertXTest.create(req));
9093
assertThat(context.path()).isEqualTo("/");
9194

9295
req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/foo");
9396

94-
context = new ContextFromVertx(vertx, accessor,
97+
context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor,
9598
RequestFromVertXTest.create(req));
9699
assertThat(context.path()).isEqualTo("/foo");
97100

98101
req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/foo?k=v");
99-
context = new ContextFromVertx(vertx, accessor,
102+
context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor,
100103
RequestFromVertXTest.create(req));
101104
assertThat(context.path()).isEqualTo("/foo");
102105
}
103106

104107
@Test
105108
public void testCookie() throws Exception {
109+
110+
System.out.println(Thread.currentThread().getName() + " " + vertx.getOrCreateContext() + " " + Vertx.currentContext());
111+
106112
String c = "mediaWiki.user.id=0kn3VaEP7XG7mbxRPNgBOe5DNfOAGaHL; centralnotice_bucket=0-4.2; " +
107113
"uls-previous-languages=%5B%22en%22%5D; mediaWiki.user.sessionId=Mu2OplNdlL98mRoHEwKGlxYsOXbyP1f0; GeoIP=::::v6";
108114
HttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
109115
req.headers().set(HeaderNames.COOKIE, c);
110-
ContextFromVertx context = new ContextFromVertx(vertx, accessor, RequestFromVertXTest.create(req));
116+
ContextFromVertx context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor, RequestFromVertXTest.create(req));
111117
assertThat(context.cookies().get("mediaWiki.user.id").value()).isEqualTo("0kn3VaEP7XG7mbxRPNgBOe5DNfOAGaHL");
112118
assertThat(context.cookies().get("GeoIP").value()).isEqualTo("::::v6");
113119

@@ -117,7 +123,7 @@ public void testCookie() throws Exception {
117123
assertThat(context.cookieValue("GeoIP")).isEqualTo("::::v6");
118124

119125
req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
120-
context = new ContextFromVertx(vertx, accessor, RequestFromVertXTest.create(req));
126+
context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor, RequestFromVertXTest.create(req));
121127

122128
assertThat(context.cookies().get("GeoIP")).isNull();
123129
assertThat(context.cookie("GeoIP")).isNull();
@@ -127,7 +133,7 @@ public void testCookie() throws Exception {
127133
@Test
128134
public void testParameterFromQuery() throws Exception {
129135
HttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/foo?k=v&i=5&b=true");
130-
ContextFromVertx context = new ContextFromVertx(vertx, accessor, RequestFromVertXTest.create(req));
136+
ContextFromVertx context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor, RequestFromVertXTest.create(req));
131137

132138
assertThat(context.parameter("k")).isEqualTo("v");
133139
assertThat(context.parameter("k", "v2")).isEqualTo("v");
@@ -145,7 +151,7 @@ public void testParameterFromQuery() throws Exception {
145151
assertThat(context.parameterAsBoolean("b2", true)).isTrue();
146152

147153
req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/foo?k=v&i=5&b=true&i=6");
148-
context = new ContextFromVertx(vertx, accessor, RequestFromVertXTest.create(req));
154+
context = new ContextFromVertx(vertx,vertx.getOrCreateContext(), accessor, RequestFromVertXTest.create(req));
149155
assertThat(context.parameterMultipleValues("i")).containsExactly("5", "6");
150156
}
151157

@@ -156,7 +162,7 @@ public void testHeader() throws Exception {
156162
req.headers().add(HeaderNames.ACCEPT_LANGUAGE, "en-US");
157163
req.headers().add(HeaderNames.ACCEPT_CHARSET, "utf-8");
158164
req.headers().add("test", "a").add("test", "b");
159-
ContextFromVertx context = new ContextFromVertx(vertx, accessor, RequestFromVertXTest.create(req));
165+
ContextFromVertx context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor, RequestFromVertXTest.create(req));
160166

161167
assertThat(context.headers().containsKey(HeaderNames.ACCEPT_LANGUAGE)).isTrue();
162168
assertThat(context.header(HeaderNames.ACCEPT_LANGUAGE)).isEqualTo("en-US");
@@ -170,13 +176,13 @@ public void testHeader() throws Exception {
170176
public void testThatColonAreEncodedCorrectly() throws NoSuchMethodException {
171177
HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
172178
"/foo?key=value:value");
173-
ContextFromVertx context = new ContextFromVertx(vertx, accessor,
179+
ContextFromVertx context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor,
174180
RequestFromVertXTest.create(request));
175181
assertThat(context.path()).isEqualToIgnoringCase("/foo");
176182

177183
request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
178184
"/foo/bar:baz/x");
179-
context = new ContextFromVertx(vertx, accessor, RequestFromVertXTest.create(request));
185+
context = new ContextFromVertx(vertx, vertx.getOrCreateContext(), accessor, RequestFromVertXTest.create(request));
180186
Controller controller = new MyController();
181187
context.route(new Route(org.wisdom.api.http.HttpMethod.GET, "/foo/{p}/x",
182188
controller, MyController.class.getMethod("action")));

core/wisdom-vertx-engine/src/test/java/org/wisdom/framework/vertx/FileUploadTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@ public Result call() throws Exception {
329329
if (!doneSignal.await(60, TimeUnit.SECONDS)) { // wait for all to finish
330330
Assert.fail("testFileUploadOfSmallFilesWithAsyncDownload - Client not served in time");
331331
}
332-
333332
assertThat(failure).isEmpty();
334333
assertThat(success).hasSize(NUMBER_OF_CLIENTS);
335334
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* #%L
3+
* Wisdom-Framework
4+
* %%
5+
* Copyright (C) 2013 - 2016 Wisdom Framework
6+
* %%
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* #L%
19+
*/
20+
package org.wisdom.framework.vertx;
21+
22+
import io.vertx.core.Vertx;
23+
import io.vertx.core.VertxOptions;
24+
import org.junit.rules.TestRule;
25+
import org.junit.runner.Description;
26+
import org.junit.runners.model.Statement;
27+
28+
import java.util.concurrent.CountDownLatch;
29+
import java.util.concurrent.TimeUnit;
30+
import java.util.concurrent.atomic.AtomicReference;
31+
import java.util.function.BiConsumer;
32+
import java.util.function.Consumer;
33+
import java.util.function.Supplier;
34+
35+
/**
36+
* @author <a href="http://escoffier.me">Clement Escoffier</a>
37+
*/
38+
public class RunOnVertxContext implements TestRule {
39+
40+
private volatile Vertx vertx;
41+
private final Supplier<Vertx> createVertx;
42+
private final BiConsumer<Vertx, CountDownLatch> closeVertx;
43+
44+
/**
45+
* Create a new rule managing a Vertx instance created with default options. The Vert.x instance
46+
* is created and closed for each test.
47+
*/
48+
public RunOnVertxContext() {
49+
this(new VertxOptions());
50+
}
51+
52+
/**
53+
* Create a new rule managing a Vertx instance created with specified options. The Vert.x instance
54+
* is created and closed for each test.
55+
*
56+
* @param options the vertx options
57+
*/
58+
public RunOnVertxContext(VertxOptions options) {
59+
this(() -> Vertx.vertx(options));
60+
}
61+
62+
/**
63+
* Create a new rule with supplier/consumer for creating/closing a Vert.x instance. The lambda are invoked for each
64+
* test. The {@code closeVertx} lambda should invoke the consumer with null when the {@code vertx} instance is closed.
65+
*
66+
* @param createVertx the create Vert.x supplier
67+
* @param closeVertx the close Vert.x consumer
68+
*/
69+
public RunOnVertxContext(Supplier<Vertx> createVertx, BiConsumer<Vertx, Consumer<Void>> closeVertx) {
70+
this.createVertx = createVertx;
71+
this.closeVertx = (vertx, latch) -> closeVertx.accept(vertx, v -> latch.countDown());
72+
}
73+
74+
/**
75+
* Create a new rule with supplier for creating a Vert.x instance. The lambda are invoked for each
76+
* test.
77+
*
78+
* @param createVertx the create Vert.x supplier
79+
*/
80+
public RunOnVertxContext(Supplier<Vertx> createVertx) {
81+
this(createVertx, (vertx, latch) -> vertx.close(ar -> latch.accept(null)));
82+
}
83+
84+
/**
85+
* Retrieves the current Vert.x instance, this value varies according to the test life cycle.
86+
*
87+
* @return the vertx object
88+
*/
89+
public Vertx vertx() {
90+
return vertx;
91+
}
92+
93+
@Override
94+
public Statement apply(Statement base, Description description) {
95+
return new Statement() {
96+
@Override
97+
public void evaluate() throws Throwable {
98+
vertx = createVertx.get();
99+
CountDownLatch lock = new CountDownLatch(1);
100+
AtomicReference<Throwable> error = new AtomicReference<>();
101+
vertx.runOnContext((v) -> {
102+
try {
103+
base.evaluate();
104+
} catch (Throwable throwable) {
105+
error.set(throwable);
106+
} finally {
107+
lock.countDown();
108+
}
109+
}
110+
111+
);
112+
113+
lock.await();
114+
CountDownLatch latch = new CountDownLatch(1);
115+
closeVertx.accept(vertx, latch);
116+
try {
117+
if (!latch.await(30 * 1000, TimeUnit.MILLISECONDS)) {
118+
System.err.println("Could not close Vert.x in tme");
119+
}
120+
} catch (InterruptedException e) {
121+
Thread.currentThread().interrupt();
122+
}
123+
124+
if (error.get() != null) {
125+
throw error.get();
126+
}
127+
}
128+
};
129+
}
130+
}

0 commit comments

Comments
 (0)