Skip to content

Commit f2ff412

Browse files
committed
global route mapper fix #367
1 parent 04940d2 commit f2ff412

File tree

7 files changed

+147
-47
lines changed

7 files changed

+147
-47
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.jooby.issues;
2+
3+
import org.jooby.reactor.Reactor;
4+
import org.jooby.rx.Rx;
5+
import org.jooby.test.ServerFeature;
6+
import org.junit.Test;
7+
8+
import reactor.core.publisher.Flux;
9+
import rx.Observable;
10+
11+
public class Issue367 extends ServerFeature {
12+
13+
{
14+
mapper(Rx.rx());
15+
16+
mapper(Reactor.reactor());
17+
18+
get("/rx", () -> Observable.just("reactive"));
19+
20+
get("/flux", () -> Flux.just("reactive"));
21+
22+
get("/normal", () -> "no-reactive");
23+
}
24+
25+
@Test
26+
public void globalMapShouldWork() throws Exception {
27+
request()
28+
.get("/rx")
29+
.expect("reactive");
30+
31+
request()
32+
.get("/flux")
33+
.expect("reactive");
34+
35+
request()
36+
.get("/normal")
37+
.expect("no-reactive");
38+
}
39+
40+
}

jooby/src/main/java/org/jooby/Jooby.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,10 @@ public EnvDep(final Predicate<String> predicate, final Consumer<Config> callback
585585
/** stop callback . */
586586
private List<CheckedConsumer<Registry>> onStop = new ArrayList<>();
587587

588+
/** Mappers .*/
589+
@SuppressWarnings("rawtypes")
590+
private Mapper mapper;
591+
588592
public Jooby() {
589593
this(null);
590594
}
@@ -3401,23 +3405,31 @@ public void start(final String[] args) throws Throwable {
34013405
public void start(final String[] args, final Consumer<List<Route.Definition>> routes)
34023406
throws Throwable {
34033407
long start = System.currentTimeMillis();
3408+
34043409
// shutdown hook
34053410
Runtime.getRuntime().addShutdownHook(new Thread(() -> stop()));
34063411

34073412
this.injector = bootstrap(args(args), routes);
34083413

34093414
started.set(true);
34103415

3411-
Config config = injector.getInstance(Config.class);
3416+
Config conf = injector.getInstance(Config.class);
34123417

34133418
Logger log = LoggerFactory.getLogger(getClass());
3414-
log.debug("config tree:\n{}", configTree(config.origin().description()));
3419+
log.debug("config tree:\n{}", configTree(conf.origin().description()));
34153420

34163421
// start services
34173422
for (CheckedConsumer<Registry> onStart : this.onStart) {
34183423
onStart.accept(this);
34193424
}
34203425

3426+
// route mapper
3427+
Set<Route.Definition> routeDefs = injector.getInstance(Route.KEY);
3428+
Set<WebSocket.Definition> sockets = injector.getInstance(WebSocket.KEY);
3429+
if (mapper != null) {
3430+
routeDefs.forEach(it -> it.map(mapper));
3431+
}
3432+
34213433
// Start server
34223434
Server server = injector.getInstance(Server.class);
34233435
String serverName = server.getClass().getSimpleName().replace("Server", "").toLowerCase();
@@ -3426,17 +3438,26 @@ public void start(final String[] args, final Consumer<List<Route.Definition>> ro
34263438
long end = System.currentTimeMillis();
34273439

34283440
log.info("[{}@{}]: Server started in {}ms\n\n{}\n",
3429-
config.getString("application.env"),
3441+
conf.getString("application.env"),
34303442
serverName,
34313443
end - start,
3432-
injector.getInstance(AppPrinter.class));
3444+
new AppPrinter(routeDefs, sockets, conf));
34333445

3434-
boolean join = config.hasPath("server.join") ? config.getBoolean("server.join") : true;
3446+
boolean join = conf.hasPath("server.join") ? conf.getBoolean("server.join") : true;
34353447
if (join) {
34363448
server.join();
34373449
}
34383450
}
34393451

3452+
@Override
3453+
@SuppressWarnings({"rawtypes", "unchecked" })
3454+
public Jooby mapper(final Mapper mapper) {
3455+
this.mapper = Optional.ofNullable(this.mapper)
3456+
.map(it -> Route.Mapper.compose(it, mapper))
3457+
.orElse(mapper);
3458+
return this;
3459+
}
3460+
34403461
/**
34413462
* Run app in javascript.
34423463
*

jooby/src/main/java/org/jooby/Route.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,14 @@ public interface Route {
273273
*/
274274
interface Mapper<T> {
275275

276+
@SuppressWarnings({"rawtypes", "unchecked" })
277+
static Mapper<Object> compose(final Mapper it, final Mapper next) {
278+
return v -> {
279+
Object m = it.map(v);
280+
return m == v ? next.map(v) : m;
281+
};
282+
}
283+
276284
/**
277285
* Map the type to something else.
278286
*
@@ -1944,7 +1952,7 @@ default void next(final Request req, final Response rsp) throws Throwable {
19441952
}
19451953
}
19461954

1947-
/** Renderer key. */
1955+
/** Route key. */
19481956
Key<Set<Route.Definition>> KEY = Key.get(new TypeLiteral<Set<Route.Definition>>() {
19491957
});
19501958

jooby/src/main/java/org/jooby/Routes.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.util.Optional;
2222

23+
import org.jooby.Route.Mapper;
2324
import org.jooby.handlers.AssetHandler;
2425

2526
/**
@@ -2449,4 +2450,24 @@ default Route.Definition complete(final String pattern, final Route.Complete han
24492450
*/
24502451
Route.Collection with(Runnable callback);
24512452

2453+
/**
2454+
* Apply the mapper to all the functional routes.
2455+
*
2456+
* <pre>{@code
2457+
* {
2458+
* mapper(Rx.rx());
2459+
*
2460+
* mapper(Reactor.reactor());
2461+
*
2462+
* get("/rx", () -> Observable.just("reactive"));
2463+
*
2464+
* get("/flux", () -> Flux.just("reactive"));
2465+
*
2466+
* }
2467+
* }</pre>
2468+
*
2469+
* @param mapper
2470+
* @return This instance.
2471+
*/
2472+
Routes mapper(final Mapper<?> mapper);
24522473
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.io.Closeable;
2424
import java.util.Map;
2525
import java.util.Optional;
26+
import java.util.Set;
2627

2728
import org.jooby.internal.RouteMatcher;
2829
import org.jooby.internal.RoutePattern;
@@ -83,6 +84,10 @@
8384
*/
8485
public interface WebSocket extends Closeable {
8586

87+
/** Websocket key. */
88+
Key<Set<WebSocket.Definition>> KEY = Key.get(new TypeLiteral<Set<WebSocket.Definition>>() {
89+
});
90+
8691
/**
8792
* A web socket connect handler. Executed every time a new client connect to the socket.
8893
*

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
import java.util.Set;
2727
import java.util.function.Function;
2828

29-
import javax.inject.Inject;
30-
3129
import org.jooby.Route;
3230
import org.jooby.WebSocket;
3331

@@ -41,7 +39,6 @@ public class AppPrinter {
4139

4240
private String[] urls;
4341

44-
@Inject
4542
public AppPrinter(final Set<Route.Definition> routes,
4643
final Set<WebSocket.Definition> sockets,
4744
final Config conf) {

0 commit comments

Comments
 (0)