diff --git a/core/src/main/java/org/chodavarapu/datamill/http/ResponseBuilder.java b/core/src/main/java/org/chodavarapu/datamill/http/ResponseBuilder.java index b348125..f8fb89d 100644 --- a/core/src/main/java/org/chodavarapu/datamill/http/ResponseBuilder.java +++ b/core/src/main/java/org/chodavarapu/datamill/http/ResponseBuilder.java @@ -1,21 +1,19 @@ package org.chodavarapu.datamill.http; -import rx.Observable; - /** * @author Ravi Chodavarapu (rchodava@gmail.com) */ public interface ResponseBuilder { - Observable badRequest(); - Observable badRequest(String content); + Response badRequest(); + Response badRequest(String content); ResponseBuilder header(String name, T value); - Observable internalServerError(); - Observable internalServerError(String content); - Observable noContent(); - Observable notFound(); - Observable ok(); - Observable ok(String content); - Observable ok(byte[] content); - Observable unauthorized(); - Observable unauthorized(String content); + Response internalServerError(); + Response internalServerError(String content); + Response noContent(); + Response notFound(); + Response ok(); + Response ok(String content); + Response ok(byte[] content); + Response unauthorized(); + Response unauthorized(String content); } diff --git a/core/src/main/java/org/chodavarapu/datamill/http/ServerRequest.java b/core/src/main/java/org/chodavarapu/datamill/http/ServerRequest.java index e943cc1..8c3fb9c 100644 --- a/core/src/main/java/org/chodavarapu/datamill/http/ServerRequest.java +++ b/core/src/main/java/org/chodavarapu/datamill/http/ServerRequest.java @@ -2,6 +2,9 @@ import com.google.common.collect.Multimap; import org.chodavarapu.datamill.values.Value; +import rx.Observable; + +import java.util.function.Function; /** * @author Ravi Chodavarapu (rchodava@gmail.com) @@ -9,6 +12,6 @@ public interface ServerRequest extends Request { Value firstTrailingHeader(String header); Value firstTrailingHeader(RequestHeader header); - ResponseBuilder respond(); + Observable respond(Function responseBuilder); Multimap trailingHeaders(); } diff --git a/core/src/main/java/org/chodavarapu/datamill/http/impl/MatcherBasedRoute.java b/core/src/main/java/org/chodavarapu/datamill/http/impl/MatcherBasedRoute.java index de719d8..f0f32ae 100644 --- a/core/src/main/java/org/chodavarapu/datamill/http/impl/MatcherBasedRoute.java +++ b/core/src/main/java/org/chodavarapu/datamill/http/impl/MatcherBasedRoute.java @@ -33,11 +33,11 @@ public Observable apply(ServerRequest request) { } if (availableMethods.size() > 0) { - return request.respond() - .header("Allow", Joiner.on(',').join(availableMethods)) + return request.respond(b -> + b.header("Allow", Joiner.on(',').join(availableMethods)) .header("Access-Control-Allow-Headers", "Authorization") .header("Access-Control-Allow-Origin", "*") - .ok(); + .ok()); } } diff --git a/core/src/main/java/org/chodavarapu/datamill/http/impl/ResponseBuilderImpl.java b/core/src/main/java/org/chodavarapu/datamill/http/impl/ResponseBuilderImpl.java index a294fde..9e2150c 100644 --- a/core/src/main/java/org/chodavarapu/datamill/http/impl/ResponseBuilderImpl.java +++ b/core/src/main/java/org/chodavarapu/datamill/http/impl/ResponseBuilderImpl.java @@ -6,7 +6,6 @@ import org.chodavarapu.datamill.http.ResponseBuilder; import org.chodavarapu.datamill.http.Status; import org.chodavarapu.datamill.values.StringValue; -import rx.Observable; /** * @author Ravi Chodavarapu (rchodava@gmail.com) @@ -15,13 +14,13 @@ public class ResponseBuilderImpl implements ResponseBuilder { private final Multimap headers = LinkedListMultimap.create(); @Override - public Observable badRequest() { - return Observable.just(new ResponseImpl(Status.BAD_REQUEST, headers)); + public Response badRequest() { + return new ResponseImpl(Status.BAD_REQUEST, headers); } @Override - public Observable badRequest(String content) { - return Observable.just(new ResponseImpl(Status.BAD_REQUEST, headers, new ValueEntity(new StringValue(content)))); + public Response badRequest(String content) { + return new ResponseImpl(Status.BAD_REQUEST, headers, new ValueEntity(new StringValue(content))); } @Override @@ -31,47 +30,47 @@ public ResponseBuilder header(String name, T value) { } @Override - public Observable internalServerError() { - return Observable.just(new ResponseImpl(Status.INTERNAL_SERVER_ERROR, headers)); + public Response internalServerError() { + return new ResponseImpl(Status.INTERNAL_SERVER_ERROR, headers); } @Override - public Observable internalServerError(String content) { - return Observable.just(new ResponseImpl(Status.INTERNAL_SERVER_ERROR, headers, new ValueEntity(new StringValue(content)))); + public Response internalServerError(String content) { + return new ResponseImpl(Status.INTERNAL_SERVER_ERROR, headers, new ValueEntity(new StringValue(content))); } @Override - public Observable noContent() { - return Observable.just(new ResponseImpl(Status.NO_CONTENT, headers)); + public Response noContent() { + return new ResponseImpl(Status.NO_CONTENT, headers); } @Override - public Observable notFound() { - return Observable.just(new ResponseImpl(Status.NOT_FOUND, headers)); + public Response notFound() { + return new ResponseImpl(Status.NOT_FOUND, headers); } @Override - public Observable ok() { - return Observable.just(new ResponseImpl(Status.OK, headers)); + public Response ok() { + return new ResponseImpl(Status.OK, headers); } @Override - public Observable ok(String content) { - return Observable.just(new ResponseImpl(Status.OK, headers, new ValueEntity(new StringValue(content)))); + public Response ok(String content) { + return new ResponseImpl(Status.OK, headers, new ValueEntity(new StringValue(content))); } @Override - public Observable ok(byte[] content) { - return Observable.just(new ResponseImpl(Status.OK, headers, new BytesEntity(content))); + public Response ok(byte[] content) { + return new ResponseImpl(Status.OK, headers, new BytesEntity(content)); } @Override - public Observable unauthorized() { - return Observable.just(new ResponseImpl(Status.UNAUTHORIZED, headers)); + public Response unauthorized() { + return new ResponseImpl(Status.UNAUTHORIZED, headers); } @Override - public Observable unauthorized(String content) { - return Observable.just(new ResponseImpl(Status.UNAUTHORIZED, headers, new ValueEntity(new StringValue(content)))); + public Response unauthorized(String content) { + return new ResponseImpl(Status.UNAUTHORIZED, headers, new ValueEntity(new StringValue(content))); } } diff --git a/core/src/main/java/org/chodavarapu/datamill/http/impl/ServerRequestImpl.java b/core/src/main/java/org/chodavarapu/datamill/http/impl/ServerRequestImpl.java index 5c18966..1767fe7 100644 --- a/core/src/main/java/org/chodavarapu/datamill/http/impl/ServerRequestImpl.java +++ b/core/src/main/java/org/chodavarapu/datamill/http/impl/ServerRequestImpl.java @@ -5,9 +5,12 @@ import io.netty.handler.codec.http.QueryStringDecoder; import org.chodavarapu.datamill.http.*; import org.chodavarapu.datamill.values.Value; +import rx.*; +import rx.Observable; import java.nio.charset.Charset; import java.util.*; +import java.util.function.Function; /** * @author Ravi Chodavarapu (rchodava@gmail.com) @@ -73,8 +76,8 @@ public Map options() { } @Override - public ResponseBuilder respond() { - return new ResponseBuilderImpl(); + public rx.Observable respond(Function responseBuilder) { + return Observable.just(responseBuilder.apply(new ResponseBuilderImpl())); } public void setTrailingHeaders(Multimap trailingHeaders) { diff --git a/core/src/test/java/org/chodavarapu/datamill/http/impl/BeanMethodMatcherTest.java b/core/src/test/java/org/chodavarapu/datamill/http/impl/BeanMethodMatcherTest.java index c5cb24b..7178e7a 100644 --- a/core/src/test/java/org/chodavarapu/datamill/http/impl/BeanMethodMatcherTest.java +++ b/core/src/test/java/org/chodavarapu/datamill/http/impl/BeanMethodMatcherTest.java @@ -22,37 +22,37 @@ public class BeanMethodMatcherTest { private static class TestBean { @DELETE public Observable delete() { - return new ResponseBuilderImpl().ok("DELETE"); + return Observable.just(new ResponseBuilderImpl().ok("DELETE")); } @GET public Observable get() { - return new ResponseBuilderImpl().ok("GET"); + return Observable.just(new ResponseBuilderImpl().ok("GET")); } @HEAD public Observable head() { - return new ResponseBuilderImpl().ok("HEAD"); + return Observable.just(new ResponseBuilderImpl().ok("HEAD")); } @OPTIONS public Observable options() { - return new ResponseBuilderImpl().ok("OPTIONS"); + return Observable.just(new ResponseBuilderImpl().ok("OPTIONS")); } @PATCH public Observable patch() { - return new ResponseBuilderImpl().ok("PATCH"); + return Observable.just(new ResponseBuilderImpl().ok("PATCH")); } @POST public Observable post() { - return new ResponseBuilderImpl().ok("POST"); + return Observable.just(new ResponseBuilderImpl().ok("POST")); } @PUT public Observable put() { - return new ResponseBuilderImpl().ok("PUT"); + return Observable.just(new ResponseBuilderImpl().ok("PUT")); } } @@ -61,37 +61,37 @@ private static class TestBeanWithPaths { @Path("delete") @DELETE public Observable delete() { - return new ResponseBuilderImpl().ok("DELETE"); + return Observable.just(new ResponseBuilderImpl().ok("DELETE")); } @Path("get/") @GET public Observable get() { - return new ResponseBuilderImpl().ok("GET"); + return Observable.just(new ResponseBuilderImpl().ok("GET")); } @Path("/head/") @HEAD public Observable head() { - return new ResponseBuilderImpl().ok("HEAD"); + return Observable.just(new ResponseBuilderImpl().ok("HEAD")); } @Path("/options") @OPTIONS public Observable options() { - return new ResponseBuilderImpl().ok("OPTIONS"); + return Observable.just(new ResponseBuilderImpl().ok("OPTIONS")); } @Path("") @PATCH public Observable patch() { - return new ResponseBuilderImpl().ok("PATCH"); + return Observable.just(new ResponseBuilderImpl().ok("PATCH")); } @Path("/") @POST public Observable post() { - return new ResponseBuilderImpl().ok("POST"); + return Observable.just(new ResponseBuilderImpl().ok("POST")); } } @@ -99,7 +99,7 @@ private static class TestBeanWithOnlyMethodPaths { @POST @Path("/post") public Observable post() { - return new ResponseBuilderImpl().ok("POST"); + return Observable.just(new ResponseBuilderImpl().ok("POST")); } } @@ -107,12 +107,12 @@ public Observable post() { private static class TestBeanWithOnlyBeanPath { @POST public Observable post() { - return new ResponseBuilderImpl().ok("POST"); + return Observable.just(new ResponseBuilderImpl().ok("POST")); } @GET public Observable get() { - return new ResponseBuilderImpl().ok("GET"); + return Observable.just(new ResponseBuilderImpl().ok("GET")); } } diff --git a/core/src/test/java/org/chodavarapu/datamill/http/impl/ClientToServerChannelHandlerTest.java b/core/src/test/java/org/chodavarapu/datamill/http/impl/ClientToServerChannelHandlerTest.java index fd41bbf..b68d9ed 100644 --- a/core/src/test/java/org/chodavarapu/datamill/http/impl/ClientToServerChannelHandlerTest.java +++ b/core/src/test/java/org/chodavarapu/datamill/http/impl/ClientToServerChannelHandlerTest.java @@ -11,6 +11,7 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import rx.Observable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -82,7 +83,7 @@ public void readEntitySentWithFullRequest() throws Exception { DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "localhost"); request.content().writeBytes("Test Content".getBytes()); - when(route.apply(any())).thenReturn(new ResponseBuilderImpl().ok()); + when(route.apply(any())).thenReturn(Observable.just(new ResponseBuilderImpl().ok())); handler.channelRead(context, request); @@ -96,7 +97,7 @@ public void readEntitySentWithFullRequest() throws Exception { @Test public void readEntitySentWithMultipleChunks() throws Exception { - when(route.apply(any())).thenReturn(new ResponseBuilderImpl().ok()); + when(route.apply(any())).thenReturn(Observable.just(new ResponseBuilderImpl().ok())); ExecutorService service = Executors.newSingleThreadExecutor(); @@ -129,7 +130,7 @@ public void singleChunkResponseSent() throws Exception { DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "localhost"); - when(route.apply(any())).thenReturn(new ResponseBuilderImpl().ok()); + when(route.apply(any())).thenReturn(Observable.just(new ResponseBuilderImpl().ok())); handler.channelRead(context, request); @@ -147,7 +148,7 @@ public void multipeResponseChunksSent() throws Exception { DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "localhost"); - when(route.apply(any())).thenReturn(new ResponseBuilderImpl().ok("Test Content")); + when(route.apply(any())).thenReturn(Observable.just(new ResponseBuilderImpl().ok("Test Content"))); handler.channelRead(context, request); diff --git a/core/src/test/java/org/chodavarapu/datamill/http/impl/ResponseBuilderTest.java b/core/src/test/java/org/chodavarapu/datamill/http/impl/ResponseBuilderTest.java index 657698f..2c50949 100644 --- a/core/src/test/java/org/chodavarapu/datamill/http/impl/ResponseBuilderTest.java +++ b/core/src/test/java/org/chodavarapu/datamill/http/impl/ResponseBuilderTest.java @@ -13,19 +13,19 @@ public class ResponseBuilderTest { @Test public void responseCodes() { ResponseBuilder builder = new ResponseBuilderImpl(); - assertEquals(Status.BAD_REQUEST, builder.badRequest().toBlocking().last().status()); - assertEquals(Status.BAD_REQUEST, builder.badRequest("Content").toBlocking().last().status()); - assertEquals("Content", builder.badRequest("Content").toBlocking().last().entity().asString().toBlocking().last()); - assertEquals(Status.INTERNAL_SERVER_ERROR, builder.internalServerError().toBlocking().last().status()); - assertEquals(Status.INTERNAL_SERVER_ERROR, builder.internalServerError("Content").toBlocking().last().status()); - assertEquals("Content", builder.internalServerError("Content").toBlocking().last().entity().asString().toBlocking().last()); - assertEquals(Status.NOT_FOUND, builder.notFound().toBlocking().last().status()); - assertEquals(Status.OK, builder.ok().toBlocking().last().status()); - assertEquals(Status.OK, builder.ok("Content").toBlocking().last().status()); - assertEquals("Content", builder.ok("Content").toBlocking().last().entity().asString().toBlocking().last()); - assertEquals(Status.UNAUTHORIZED, builder.unauthorized().toBlocking().last().status()); - assertEquals(Status.UNAUTHORIZED, builder.unauthorized("Content").toBlocking().last().status()); - assertEquals("Content", builder.unauthorized("Content").toBlocking().last().entity().asString().toBlocking().last()); - assertEquals(Status.NO_CONTENT, builder.noContent().toBlocking().last().status()); + assertEquals(Status.BAD_REQUEST, builder.badRequest().status()); + assertEquals(Status.BAD_REQUEST, builder.badRequest("Content").status()); + assertEquals("Content", builder.badRequest("Content").entity().asString().toBlocking().last()); + assertEquals(Status.INTERNAL_SERVER_ERROR, builder.internalServerError().status()); + assertEquals(Status.INTERNAL_SERVER_ERROR, builder.internalServerError("Content").status()); + assertEquals("Content", builder.internalServerError("Content").entity().asString().toBlocking().last()); + assertEquals(Status.NOT_FOUND, builder.notFound().status()); + assertEquals(Status.OK, builder.ok().status()); + assertEquals(Status.OK, builder.ok("Content").status()); + assertEquals("Content", builder.ok("Content").entity().asString().toBlocking().last()); + assertEquals(Status.UNAUTHORIZED, builder.unauthorized().status()); + assertEquals(Status.UNAUTHORIZED, builder.unauthorized("Content").status()); + assertEquals("Content", builder.unauthorized("Content").entity().asString().toBlocking().last()); + assertEquals(Status.NO_CONTENT, builder.noContent().status()); } }