diff --git a/conf/logback.xml b/conf/logback.xml
index 4a4eb58..3e04985 100644
--- a/conf/logback.xml
+++ b/conf/logback.xml
@@ -20,7 +20,7 @@
-
+
diff --git a/pom.xml b/pom.xml
index 7688b90..a6e6df6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -131,6 +131,11 @@
org.msgpack
jackson-dataformat-msgpack
0.8.12
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-xml
+ [2.8.8,)
com.fasterxml.jackson.module
@@ -236,5 +241,11 @@
graphql-java
2.3.0
+
+ io.github.lukehutch
+ fast-classpath-scanner
+ LATEST
+
+
\ No newline at end of file
diff --git a/src/main/java/com/wurrly/Application.java b/src/main/java/com/wurrly/Application.java
index b9abed9..0d9247f 100644
--- a/src/main/java/com/wurrly/Application.java
+++ b/src/main/java/com/wurrly/Application.java
@@ -28,6 +28,7 @@
import com.wurrly.server.endpoints.EndpointInfo;
import com.wurrly.server.handlers.HandlerGenerator;
import com.wurrly.server.handlers.benchmark.BenchmarkHandlers;
+import com.wurrly.services.AssetsService;
import com.wurrly.services.SwaggerService;
import io.undertow.Undertow;
@@ -93,7 +94,9 @@ public void start()
- Set services = registeredServices.stream().map( sc -> injector.getInstance(sc)).collect(Collectors.toSet());
+ Set services = registeredServices.stream()
+ .map( sc -> injector.getInstance(sc))
+ .collect(Collectors.toSet());
this.serviceManager = new ServiceManager(services);
@@ -214,6 +217,8 @@ public static void main(String[] args)
app.useService(SwaggerService.class);
+ app.useService(AssetsService.class);
+
app.useController(Users.class);
app.start();
diff --git a/src/main/java/com/wurrly/controllers/Users.java b/src/main/java/com/wurrly/controllers/Users.java
index beb862a..25967ee 100644
--- a/src/main/java/com/wurrly/controllers/Users.java
+++ b/src/main/java/com/wurrly/controllers/Users.java
@@ -10,6 +10,8 @@
import java.util.List;
import java.util.Optional;
import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -179,10 +181,11 @@ public ServerResponse createUser( final ServerRequest serverRequest, @QueryPara
@PUT
@Path("/username")
- @Consumes(("application/json"))
+ @Consumes("application/json,application/xml")
+ @Produces("application/json,application/xml")
// @ApiImplicitParams({ @ApiImplicitParam(dataType = "com.wurrly.models.User", name = "user", paramType = "body", required = false, allowMultiple = false) })
@ApiOperation(value = "Update a user's name", httpMethod = "PUT", response = User.class)
- public ServerResponse updateUsername(@ApiParam(hidden=true)final ServerRequest serverRequest, @QueryParam("context") Optional context, final User user )
+ public CompletableFuture updateUsername(@ApiParam(hidden=true)final ServerRequest serverRequest, @QueryParam("context") Optional context, final User user )
{
//
log.debug("esIndexName: " + esIndexName);
@@ -191,7 +194,7 @@ public ServerResponse updateUsername(@ApiParam(hidden=true)final ServerRequest s
log.debug("file: " + user);
- return response().entity(Any.wrap(user));
+ return CompletableFuture.completedFuture(response().entity(user));
}
diff --git a/src/main/java/com/wurrly/modules/RoutingModule.java b/src/main/java/com/wurrly/modules/RoutingModule.java
index 37f8ad4..4cc7b3c 100644
--- a/src/main/java/com/wurrly/modules/RoutingModule.java
+++ b/src/main/java/com/wurrly/modules/RoutingModule.java
@@ -11,6 +11,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
@@ -21,7 +22,7 @@
import io.undertow.predicate.TruePredicate;
import io.undertow.server.DefaultResponseListener;
-import io.undertow.server.HttpServerExchange;
+import io.undertow.server.HttpHandler;
import io.undertow.server.RoutingHandler;
import io.undertow.server.handlers.resource.FileResourceManager;
import io.undertow.server.handlers.resource.ResourceHandler;
@@ -57,24 +58,15 @@ protected void configure()
RoutingHandler router = new RoutingHandler()
.setFallbackHandler(BaseHandlers::notFoundHandler);
-
- final String assetsPath = config.getString("assets.path");
- final String assetsDirectoryName = config.getString("assets.dir") ;
- final Integer assetsCacheTime = config.getInt("assets.cache.time");
-
- final FileResourceManager fileResourceManager = new FileResourceManager(Paths.get(assetsDirectoryName).toFile());
-
+
+ this.bind(XmlMapper.class).toInstance(new XmlMapper());
- router.add(Methods.GET, assetsPath + "/*", io.undertow.Handlers.rewrite("regex['" + assetsPath + "/(.*)']", "/$1", getClass().getClassLoader(), new ResourceHandler(fileResourceManager)
- .setCachable(TruePredicate.instance())
- .setCacheTime(assetsCacheTime)
- ));
-
this.bind(RoutingHandler.class).toInstance(router);
this.bind(RoutingModule.class).toInstance(this);
+
try
{
String defaultResponseListenerClassName = config.getString("application.defaultResponseListener");
@@ -84,6 +76,8 @@ protected void configure()
{
log.error(e.getMessage(),e);
}
+
+
this.bind(new TypeLiteral>>() {}).annotatedWith(Names.named("registeredControllers")).toInstance(registeredControllers);
this.bind(new TypeLiteral>() {}).annotatedWith(Names.named("registeredEndpoints")).toInstance(registeredEndpoints);
diff --git a/src/main/java/com/wurrly/server/Extractors.java b/src/main/java/com/wurrly/server/Extractors.java
index 3df3990..5aae615 100644
--- a/src/main/java/com/wurrly/server/Extractors.java
+++ b/src/main/java/com/wurrly/server/Extractors.java
@@ -11,6 +11,7 @@
import java.nio.file.StandardOpenOption;
import java.time.ZonedDateTime;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.Deque;
import java.util.Objects;
@@ -19,13 +20,22 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.google.inject.Inject;
import com.jsoniter.JsonIterator;
import com.jsoniter.any.Any;
import com.jsoniter.spi.TypeLiteral;
+import com.wurrly.server.handlers.predicates.MaxRequestContentLengthPredicate;
+import io.undertow.attribute.ExchangeAttributes;
+import io.undertow.predicate.Predicate;
+import io.undertow.predicate.Predicates;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.form.FormData.FormValue;
import io.undertow.server.handlers.form.FormDataParser;
+import io.undertow.server.handlers.form.FormEncodedDataDefinition;
+import io.undertow.server.handlers.form.MultiPartParserDefinition;
+import io.undertow.util.Headers;
import io.undertow.util.HttpString;
import io.undertow.util.Methods;
@@ -36,15 +46,47 @@ public class Extractors
{
private static Logger log = LoggerFactory.getLogger(Extractors.class.getCanonicalName());
+
+
+ public static final Predicate JSON_PREDICATE = Predicates.contains(ExchangeAttributes.requestHeader(Headers.CONTENT_TYPE), MimeTypes.APPLICATION_JSON_TYPE);
+ public static final Predicate XML_PREDICATE = io.undertow.predicate.Predicates.contains(ExchangeAttributes.requestHeader(Headers.CONTENT_TYPE), MimeTypes.APPLICATION_XML_TYPE);
+
+ protected static final XmlMapper XML_MAPPER = new XmlMapper();
+
public static class Optional
{
public static java.util.Optional jsonIterator(final HttpServerExchange exchange)
{
- return java.util.Optional.ofNullable( JsonIterator.parse(exchange.getAttachment(ServerRequest.JSON_DATA).array()));
+ return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY)).map(ByteBuffer::array).map(JsonIterator::parse);
}
- public static java.util.Optional typed(final HttpServerExchange exchange, final TypeLiteral type )
+ public static java.util.Optional model(final HttpServerExchange exchange, final TypeLiteral type )
+ {
+ if( JSON_PREDICATE.resolve(exchange) )
+ {
+ return jsonModel(exchange,type);
+ }
+ else
+ {
+ return xmlModel(exchange,type);
+ }
+ }
+
+ public static java.util.Optional model(final HttpServerExchange exchange, final Class type )
+ {
+ if( JSON_PREDICATE.resolve(exchange) )
+ {
+ return jsonModel(exchange,type);
+ }
+ else
+ {
+ return xmlModel(exchange,type);
+ }
+ }
+
+
+ public static java.util.Optional jsonModel(final HttpServerExchange exchange, final TypeLiteral type )
{
return jsonIterator(exchange).map(i -> {
try
@@ -57,7 +99,7 @@ public static java.util.Optional typed(final HttpServerExchange exchange
});
}
- public static java.util.Optional typed(final HttpServerExchange exchange, final Class type )
+ public static java.util.Optional jsonModel(final HttpServerExchange exchange, final Class type )
{
return jsonIterator(exchange).map(i -> {
try
@@ -69,6 +111,35 @@ public static java.util.Optional typed(final HttpServerExchange exchange
}
});
}
+
+ public static java.util.Optional xmlModel(final HttpServerExchange exchange, final TypeLiteral type )
+ {
+ return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY)).map(ByteBuffer::array).map( b -> {
+ try
+ {
+ return XML_MAPPER.readValue(b,XML_MAPPER.getTypeFactory().constructType(type.getType()));
+ } catch (Exception e)
+ {
+ return null;
+ }
+ });
+ }
+
+ public static java.util.Optional xmlModel(final HttpServerExchange exchange, final Class type )
+ {
+ return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY)).map(ByteBuffer::array).map( b -> {
+ try
+ {
+ return XML_MAPPER.readValue(b,type);
+ } catch (Exception e)
+ {
+ return null;
+ }
+ });
+
+ }
+
+
public static java.util.Optional date(final HttpServerExchange exchange,final String name) {
@@ -79,7 +150,7 @@ public static java.util.Optional date(final HttpServerExchange exchange,fi
public static java.util.Optional any(final HttpServerExchange exchange )
{
- return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.JSON_DATA)).map(t -> JsonIterator.deserialize(t.array()));
+ return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY)).map(t -> JsonIterator.deserialize(t.array()));
}
public static java.util.Optional integerValue(final HttpServerExchange exchange, final String name)
@@ -108,10 +179,10 @@ public static java.util.Optional booleanValue(final HttpServerExchange
return string(exchange, name).map(Boolean::parseBoolean);
}
- public static > java.util.Optional enumValue(final HttpServerExchange exchange, final Class clazz, final String name)
- {
- return string(exchange, name).map(e -> Enum.valueOf(clazz, name));
- }
+// public static > java.util.Optional enumValue(final HttpServerExchange exchange, final Class clazz, final String name)
+// {
+// return string(exchange, name).map(e -> Enum.valueOf(clazz, name));
+// }
public static java.util.Optional string(final HttpServerExchange exchange, final String name)
{
@@ -150,7 +221,7 @@ public static Date date(final HttpServerExchange exchange,final String name) {
}
- public static T typed(final HttpServerExchange exchange, final TypeLiteral type ) throws Exception
+ public static T jsonModel(final HttpServerExchange exchange, final TypeLiteral type ) throws IllegalArgumentException
{
try
{
@@ -162,7 +233,7 @@ public static T typed(final HttpServerExchange exchange, final TypeLiteral<
}
}
- public static T typed(final HttpServerExchange exchange, final Class type ) throws Exception
+ public static T jsonModel(final HttpServerExchange exchange, final Class type ) throws IllegalArgumentException
{
try
{
@@ -174,12 +245,39 @@ public static T typed(final HttpServerExchange exchange, final Class typ
}
}
+
+
+ public static T xmlModel(final HttpServerExchange exchange, final Class type ) throws IllegalArgumentException
+ {
+ try
+ {
+ return XML_MAPPER.readValue(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY).array(), type);
+ }
+ catch( Exception e )
+ {
+ throw new IllegalArgumentException("Invalid XML");
+
+ }
+ }
+
+ public static T xmlModel(final HttpServerExchange exchange, final TypeLiteral type ) throws IllegalArgumentException
+ {
+ try
+ {
+ return XML_MAPPER.readValue(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY).array(), XML_MAPPER.getTypeFactory().constructType(type.getType()));
+ }
+ catch( Exception e )
+ {
+ throw new IllegalArgumentException("Invalid XML");
+
+ }
+ }
public static Any any(final HttpServerExchange exchange )
{
try
{
- return JsonIterator.parse( exchange.getAttachment(ServerRequest.JSON_DATA).array() ).readAny();
+ return JsonIterator.parse( exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY).array() ).readAny();
} catch (IOException e)
{
return Any.wrapNull();
@@ -188,7 +286,7 @@ public static Any any(final HttpServerExchange exchange )
public static JsonIterator jsonIterator(final HttpServerExchange exchange )
{
- return JsonIterator.parse(exchange.getAttachment(ServerRequest.JSON_DATA).array());
+ return JsonIterator.parse(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY).array());
}
public static Path filePath(final HttpServerExchange exchange, final String name)
@@ -242,13 +340,36 @@ public static Boolean booleanValue(final HttpServerExchange exchange, final Str
{
return Boolean.parseBoolean(string(exchange, name));
}
+
+ public static T model(final HttpServerExchange exchange, final TypeLiteral type ) throws IllegalArgumentException
+ {
+ if( JSON_PREDICATE.resolve(exchange) )
+ {
+ return jsonModel(exchange,type);
+ }
+ else
+ {
+ return xmlModel(exchange,type);
+ }
+ }
-
-
- public static > E enumValue(final HttpServerExchange exchange, Class clazz,final String name)
+ public static T model(final HttpServerExchange exchange, final Class type ) throws IllegalArgumentException
{
- return Enum.valueOf(clazz, string(exchange, name));
+ if( JSON_PREDICATE.resolve(exchange) )
+ {
+ return jsonModel(exchange,type);
+ }
+ else
+ {
+ return xmlModel(exchange,type);
+ }
}
+
+
+// public static > E enumValue(final HttpServerExchange exchange, Class clazz,final String name)
+// {
+// return Enum.valueOf(clazz, string(exchange, name));
+// }
diff --git a/src/main/java/com/wurrly/server/MimeTypes.java b/src/main/java/com/wurrly/server/MimeTypes.java
new file mode 100644
index 0000000..e7f70fd
--- /dev/null
+++ b/src/main/java/com/wurrly/server/MimeTypes.java
@@ -0,0 +1,19 @@
+/**
+ *
+ */
+package com.wurrly.server;
+
+/**
+ * @author jbauer
+ *
+ */
+public class MimeTypes
+{
+ public static final String OCTET_STREAM_TYPE = com.j256.simplemagic.ContentType.EMPTY.getMimeType();
+ public static final String APPLICATION_JSON_TYPE = com.j256.simplemagic.ContentType.JSON.getMimeType();
+ public static final String APPLICATION_XML_TYPE = com.j256.simplemagic.ContentType.XML.getMimeType();
+ public static final String TEXT_HTML_TYPE = com.j256.simplemagic.ContentType.HTML.getMimeType();
+ public static final String TEXT_PLAIN_TYPE = com.j256.simplemagic.ContentType.TEXT.getMimeType();
+
+
+}
diff --git a/src/main/java/com/wurrly/server/ServerPredicates.java b/src/main/java/com/wurrly/server/ServerPredicates.java
new file mode 100644
index 0000000..53b482d
--- /dev/null
+++ b/src/main/java/com/wurrly/server/ServerPredicates.java
@@ -0,0 +1,31 @@
+/**
+ *
+ */
+package com.wurrly.server;
+
+import java.util.Collections;
+
+import com.wurrly.server.handlers.predicates.MaxRequestContentLengthPredicate;
+
+import io.undertow.attribute.ExchangeAttributes;
+import io.undertow.predicate.Predicate;
+import io.undertow.predicate.Predicates;
+import io.undertow.server.handlers.form.FormEncodedDataDefinition;
+import io.undertow.server.handlers.form.MultiPartParserDefinition;
+import io.undertow.util.Headers;
+
+/**
+ * @author jbauer
+ *
+ */
+public class ServerPredicates
+{
+
+ public static final Predicate ACCEPT_JSON_PREDICATE = Predicates.contains(ExchangeAttributes.requestHeader(Headers.ACCEPT), MimeTypes.APPLICATION_JSON_TYPE);
+ public static final Predicate ACCEPT_XML_PREDICATE = io.undertow.predicate.Predicates.contains(ExchangeAttributes.requestHeader(Headers.ACCEPT), MimeTypes.APPLICATION_XML_TYPE);
+ public static final Predicate MAX_CONTENT_SIZE_PREDICATE = new MaxRequestContentLengthPredicate.Builder().build(Collections.singletonMap("value", 0L));
+ public static final Predicate STRING_BODY_PREDICATE = io.undertow.predicate.Predicates.and(io.undertow.predicate.Predicates.contains(ExchangeAttributes.requestHeader(Headers.CONTENT_TYPE), MimeTypes.APPLICATION_JSON_TYPE, MimeTypes.APPLICATION_XML_TYPE), MAX_CONTENT_SIZE_PREDICATE );
+ public static final Predicate MULTIPART_PREDICATE = Predicates.contains(ExchangeAttributes.requestHeader(Headers.CONTENT_TYPE), MimeTypes.OCTET_STREAM_TYPE, MultiPartParserDefinition.MULTIPART_FORM_DATA );
+ public static final Predicate URL_ENCODED_FORM_PREDICATE = io.undertow.predicate.Predicates.contains(ExchangeAttributes.requestHeader(Headers.CONTENT_TYPE), FormEncodedDataDefinition.APPLICATION_X_WWW_FORM_URLENCODED );
+
+}
diff --git a/src/main/java/com/wurrly/server/ServerRequest.java b/src/main/java/com/wurrly/server/ServerRequest.java
index e37fe57..0a461c7 100644
--- a/src/main/java/com/wurrly/server/ServerRequest.java
+++ b/src/main/java/com/wurrly/server/ServerRequest.java
@@ -5,24 +5,17 @@
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.nio.ByteBuffer;
import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
-import java.util.Scanner;
import java.util.concurrent.Executor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xnio.channels.StreamSourceChannel;
-import com.jsoniter.JsonIterator;
-
-import io.undertow.UndertowMessages;
import io.undertow.connector.PooledByteBuffer;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.form.FormData;
@@ -34,17 +27,13 @@
import io.undertow.util.Headers;
import io.undertow.util.MalformedMessageException;
-import java.util.stream.Collectors;
-
public class ServerRequest
{
private static Logger log = LoggerFactory.getLogger(ServerRequest.class.getCanonicalName());
-
- public static final AttachmentKey JSON_DATA = AttachmentKey.create(ByteBuffer.class);
-
-
- private static final String OCTET_STREAM_TYPE = org.apache.http.entity.ContentType.APPLICATION_OCTET_STREAM.getMimeType();
- private static final String APPLICATION_JSON = org.apache.http.entity.ContentType.APPLICATION_JSON.getMimeType();
+
+
+ public static final AttachmentKey BYTE_BUFFER_KEY = AttachmentKey.create(ByteBuffer.class);
+
private static final String CHARSET = "UTF-8";
public final HttpServerExchange exchange;
@@ -52,7 +41,8 @@ public class ServerRequest
private final String path;
private FormData form;
private final String contentType;
- private final String method;
+ private final String method;
+
private static final String TMP_DIR = System.getProperty("java.io.tmpdir");
@@ -62,7 +52,7 @@ public ServerRequest()
this.path = null;
this.exchange = null;
this.contentType = null;
-
+
}
public ServerRequest(HttpServerExchange exchange) throws IOException
@@ -70,23 +60,22 @@ public ServerRequest(HttpServerExchange exchange) throws IOException
this.method = exchange.getRequestMethod().toString();
this.path = URLDecoder.decode(exchange.getRequestPath(), CHARSET);
this.exchange = exchange;
- this.contentType = exchange.getRequestHeaders().getFirst("Content-Type");
-
-
+ this.contentType = exchange.getRequestHeaders().getFirst(Headers.CONTENT_TYPE);
+
if (this.contentType != null )
{
- if (this.contentType.contains(FormEncodedDataDefinition.APPLICATION_X_WWW_FORM_URLENCODED) )
+ if ( ServerPredicates.URL_ENCODED_FORM_PREDICATE.resolve(exchange) )
{
this.parseEncodedForm();
}
- else if (this.contentType.contains(MultiPartParserDefinition.MULTIPART_FORM_DATA) || this.contentType.contains(OCTET_STREAM_TYPE))
+ else if ( ServerPredicates.MULTIPART_PREDICATE.resolve(exchange) )
{
this.parseMultipartForm();
}
- else if (this.contentType.contains(APPLICATION_JSON) && this.exchange.getRequestContentLength() != -1)
- {
- this.parseJson();
- }
+ else if ( ServerPredicates.STRING_BODY_PREDICATE.resolve(exchange) )
+ {
+ this.extractBytes();
+ }
}
@@ -151,18 +140,11 @@ public Map> getPathParameters()
- private void parseJson() throws IOException
- {
-
- if(this.exchange.getRequestContentLength() != -1)
- {
+ private void extractBytes() throws IOException
+ {
+
this.exchange.startBlocking();
-
-// ByteBuffer buffer = ByteBuffer.allocate((int) this.exchange.getRequestContentLength());
-// this.exchange.getRequestChannel().read(buffer);
-// JsonIterator iterator = JsonIterator.parse(buffer.array());
-// this.exchange.putAttachment(JSON_DATA, iterator);
-
+
try (PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().getArrayBackedPool().allocate()){
ByteBuffer buf = pooled.getBuffer();
@@ -173,20 +155,17 @@ private void parseJson() throws IOException
buf.clear();
int c = channel.read(buf);
-
-
-
+
if (c == -1) {
-
-// JsonIterator iterator = JsonIterator.parse(buf.array());
-
+
int pos = buf.limit();
ByteBuffer buffer = ByteBuffer.allocate(pos);
System.arraycopy(buf.array(), 0, buffer.array(), 0, pos);
- exchange.putAttachment(JSON_DATA, buffer);
+ exchange.putAttachment(BYTE_BUFFER_KEY, buffer);
+
break;
} else if (c != 0) {
@@ -195,71 +174,34 @@ private void parseJson() throws IOException
}
} catch (MalformedMessageException e) {
throw new IOException(e);
- }
-// try(PooledByteBuffer resource = this.exchange.getConnection().getByteBufferPool().allocate())
-// {
-// final ByteBuffer buffer = resource.getBuffer();
-
-// final UTF8Output string = new UTF8Output();
+ }
+
+// else
+// {
+// this.exchange.startBlocking();
//
-// final StreamSourceChannel channel = this.exchange.getRequestChannel();
-//
-// try {
-// int r = 0;
-// do {
-// r = channel.read(buffer);
-// if (r == 0) {
-// //channel.getReadSetter().set(this);
-// channel.resumeReads();
-// } else if (r == -1) {
-// JsonIterator iterator = JsonIterator.parse(string.extract());
-// this.exchange.putAttachment(REQUEST_JSON_BODY, iterator);
-// IoUtils.safeClose(channel);
-// } else {
-// buffer.flip();
-// string.write(buffer);
-// }
-// } while (r > 0);
-
-
-
-
-// } catch (IOException e) {
-// throw e;
-// }
-// }
-// Logger.debug("iterator " + iterator);
-
- }
- else
- {
- this.exchange.startBlocking();
-
- InputStream is = exchange.getInputStream();
- if (is != null) {
-
- try
- {
- if (is.available() != -1) {
-
- try(Scanner scanner = new Scanner(is, "UTF-8"))
- {
- String s = scanner.useDelimiter("\\A").next();
- s = s.trim();
- // JsonIterator iterator = JsonIterator.parse(s);
- // log.debug("iterator " + iterator);
-
- this.exchange.putAttachment(JSON_DATA, ByteBuffer.wrap(s.getBytes()));
- }
-
- }
-
- } catch (IOException e) {
- log.error("IOException: ", e);
- }
-
- }
- }
+// InputStream is = exchange.getInputStream();
+// if (is != null) {
+//
+// try
+// {
+// if (is.available() != -1) {
+//
+// try(Scanner scanner = new Scanner(is, "UTF-8"))
+// {
+// String s = scanner.useDelimiter("\\A").next();
+// s = s.trim();
+// this.exchange.putAttachment(BYTE_BUFFER_KEY, ByteBuffer.wrap(s.getBytes()));
+// }
+//
+// }
+//
+// } catch (IOException e) {
+// log.error("IOException: ", e);
+// }
+//
+// }
+// }
}
@@ -272,28 +214,22 @@ private void parseMultipartForm() throws IOException
.setDefaultEncoding(CHARSET)
.create(this.exchange);
- log.debug(this.exchange+"\nmime: " + this.contentType);
-
- log.debug("boundary: " + Headers.extractQuotedValueFromHeader(this.contentType, "boundary"));
-
-
+
if(formDataParser != null)
{
- final FormData formData = formDataParser.parseBlocking();
-
- log.debug("formData: " + formData);
-
+ final FormData formData = formDataParser.parseBlocking();
this.exchange.putAttachment(FormDataParser.FORM_DATA, formData);
extractFormParameters(formData);
}
}
private void parseEncodedForm() throws IOException
- {
-
+ {
this.exchange.startBlocking();
- final FormData formData = new FormEncodedDataDefinition().setDefaultEncoding(this.exchange.getRequestCharset()).create(exchange).parseBlocking();
+ final FormData formData = new FormEncodedDataDefinition()
+ .setDefaultEncoding(this.exchange.getRequestCharset())
+ .create(exchange).parseBlocking();
this.exchange.putAttachment(FormDataParser.FORM_DATA, formData);
@@ -305,8 +241,11 @@ private void extractFormParameters(final FormData formData)
if (formData != null) {
for (String key : formData)
{
- Deque formValues = formData.get(key);
- Deque values = formValues.stream().filter(fv -> !fv.isFile()).map(FormData.FormValue::getValue).collect(java.util.stream.Collectors.toCollection(FastConcurrentDirectDeque::new));
+ final Deque formValues = formData.get(key);
+ final Deque values = formValues.stream()
+ .filter(fv -> !fv.isFile())
+ .map(FormData.FormValue::getValue)
+ .collect(java.util.stream.Collectors.toCollection(FastConcurrentDirectDeque::new));
exchange.getQueryParameters().put(key, values);
}
}
@@ -332,6 +271,7 @@ public String rawPath()
return exchange.getRequestURI();
}
+
public void startAsync(final Executor executor, final Runnable runnable)
{
exchange.dispatch(executor, runnable);
diff --git a/src/main/java/com/wurrly/server/ServerResponse.java b/src/main/java/com/wurrly/server/ServerResponse.java
index d9075aa..d8334ac 100644
--- a/src/main/java/com/wurrly/server/ServerResponse.java
+++ b/src/main/java/com/wurrly/server/ServerResponse.java
@@ -3,7 +3,6 @@
*/
package com.wurrly.server;
-import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
@@ -11,10 +10,14 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.jsoniter.any.Any;
import com.jsoniter.output.JsonStream;
+import io.undertow.attribute.ExchangeAttributes;
import io.undertow.io.IoCallback;
+import io.undertow.predicate.Predicate;
+import io.undertow.predicate.Predicates;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.Cookie;
@@ -29,14 +32,11 @@
*
*/
public class ServerResponse
-{
+{
private static Logger log = LoggerFactory.getLogger(ServerResponse.class.getCanonicalName());
-
- private static final String APPLICATION_JSON_CONTENT_TYPE = org.apache.http.entity.ContentType.APPLICATION_JSON.getMimeType();
- private static final String TEXT_PLAIN_CONTENT_TYPE = org.apache.http.entity.ContentType.TEXT_PLAIN.getMimeType();
- private static final String TEXT_XML_CONTENT_TYPE = org.apache.http.entity.ContentType.TEXT_XML.getMimeType();
- private static final String TEXT_HTML_CONTENT_TYPE = org.apache.http.entity.ContentType.TEXT_HTML.getMimeType();
-
+
+ protected static final XmlMapper XML_MAPPER = new XmlMapper();
+
protected ByteBuffer body;
protected int status = StatusCodes.OK;
@@ -48,7 +48,9 @@ public class ServerResponse
protected boolean hasCookies = false;
protected boolean hasHeaders = false;
protected boolean hasIoCallback = false;
-
+ protected boolean isXml = false;
+ protected boolean isJson = false;
+
public ServerResponse()
{
@@ -120,6 +122,15 @@ public void setStatus(int status)
public void setContentType(String contentType)
{
this.contentType = contentType;
+
+ if(this.contentType.equals(MimeTypes.APPLICATION_JSON_TYPE))
+ {
+ this.isJson = true;
+ }
+ else if(this.contentType.equals(MimeTypes.APPLICATION_XML_TYPE))
+ {
+ this.isXml = true;
+ }
}
public ServerResponse body(ByteBuffer body)
@@ -130,8 +141,7 @@ public ServerResponse body(ByteBuffer body)
public ServerResponse entity(Object entity)
{
- this.entity = entity;
- applicationJson();
+ this.entity = entity;
return this;
}
@@ -165,32 +175,35 @@ public ServerResponse cookie(String cookieName, Cookie cookie)
public ServerResponse contentType(String contentType)
{
- this.contentType = contentType;
+ this.setContentType(contentType);
return this;
}
public ServerResponse applicationJson()
{
- this.contentType = APPLICATION_JSON_CONTENT_TYPE;
+ this.contentType = MimeTypes.APPLICATION_JSON_TYPE;
+ this.isJson = true;
+
return this;
}
public ServerResponse textHtml()
{
- this.contentType = TEXT_HTML_CONTENT_TYPE;
+ this.contentType = MimeTypes.TEXT_HTML_TYPE;
return this;
}
- public ServerResponse textXml()
+ public ServerResponse applicationXml()
{
- this.contentType = TEXT_XML_CONTENT_TYPE;
+ this.contentType = MimeTypes.APPLICATION_XML_TYPE;
+ this.isXml = true;
return this;
}
public ServerResponse textPlain()
{
- this.contentType = TEXT_PLAIN_CONTENT_TYPE;
+ this.contentType = MimeTypes.TEXT_PLAIN_TYPE;
return this;
}
@@ -265,8 +278,9 @@ public ServerResponse exception(Throwable t)
return this.entity(Any.wrap(t));
}
- public void send( final HttpHandler handler, final HttpServerExchange exchange )
+ public void send( final HttpHandler handler, final HttpServerExchange exchange ) throws RuntimeException
{
+
if( this.hasHeaders )
{
long itr = this.headers.fastIterateNonEmpty();
@@ -292,8 +306,19 @@ public void send( final HttpHandler handler, final HttpServerExchange exchange )
{
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, this.contentType);
}
-
-
+ else if( !this.isJson && !this.isXml )
+ {
+ if( ServerPredicates.ACCEPT_JSON_PREDICATE.resolve(exchange) )
+ {
+ this.applicationJson();
+ exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, this.contentType);
+ }
+ else if( ServerPredicates.ACCEPT_XML_PREDICATE.resolve(exchange) )
+ {
+ this.applicationXml();
+ exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, this.contentType);
+ }
+ }
if( this.body != null)
{
@@ -303,41 +328,49 @@ public void send( final HttpHandler handler, final HttpServerExchange exchange )
}
else
{
- exchange.getResponseSender().send(this.body,this.ioCallback);
-
+ exchange.getResponseSender().send(this.body,this.ioCallback);
}
}
else if( this.entity != null)
{
- if(exchange.isInIoThread()) {
- exchange.dispatch(handler);
- return;
- }
-
-
- exchange.startBlocking();
-
- final int bufferSize = exchange.getConnection().getBufferSize();
-
- final JsonStream stream = new JsonStream(exchange.getOutputStream(), bufferSize);
-
- try
+ try
{
- stream.writeVal(this.entity);
- stream.close();
- } catch (IOException e)
+
+ if( this.isXml )
+ {
+ exchange.getResponseSender().send(ByteBuffer.wrap(XML_MAPPER.writeValueAsBytes(this.entity)));
+ }
+ else
+ {
+ if(exchange.isInIoThread()) {
+ exchange.dispatch(handler);
+ return;
+ }
+
+
+ exchange.startBlocking();
+
+ final int bufferSize = exchange.getConnection().getBufferSize();
+
+ try(final JsonStream stream = new JsonStream(exchange.getOutputStream(), bufferSize))
+ {
+ stream.writeVal(this.entity);
+ }
+
+ exchange.endExchange();
+
+ }
+
+ } catch (Exception e)
{
-
- log.error(e.getMessage(),e);
- exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
- exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
- exchange.getResponseSender().send(e.getMessage());
+ log.error(e.getMessage() + " for entity " + this.entity,e);
+
+ throw new IllegalArgumentException(e);
}
- exchange.endExchange();
- }
+ }
else
{
exchange.endExchange();
diff --git a/src/main/java/com/wurrly/server/endpoints/EndpointInfo.java b/src/main/java/com/wurrly/server/endpoints/EndpointInfo.java
index 26da81e..679812f 100644
--- a/src/main/java/com/wurrly/server/endpoints/EndpointInfo.java
+++ b/src/main/java/com/wurrly/server/endpoints/EndpointInfo.java
@@ -131,6 +131,10 @@ public String getControllerName()
public void setControllerName(String controllerName)
{
this.controllerName = controllerName;
+ if(this.controllerName == null)
+ {
+ this.controllerName = "";
+ }
}
@@ -162,7 +166,7 @@ public int compareTo(EndpointInfo other) {
@Override
public String toString()
{
- return String.format("%-8s %-30s %-26s %-26s %s", this.method, this.pathTemplate, "[" + this.consumes + "]", "[" + this.produces+ "]", "("+this.controllerMethod+ ")");
+ return String.format("%-8s %-30s %-26s %-26s %s", this.method, this.pathTemplate, "[" + this.consumes + "]", "[" + this.produces+ "]", "("+this.controllerName+"."+this.controllerMethod+ ")");
}
/**
diff --git a/src/main/java/com/wurrly/server/handlers/HandlerGenerator.java b/src/main/java/com/wurrly/server/handlers/HandlerGenerator.java
index 7c650ef..ab89bf8 100644
--- a/src/main/java/com/wurrly/server/handlers/HandlerGenerator.java
+++ b/src/main/java/com/wurrly/server/handlers/HandlerGenerator.java
@@ -11,9 +11,11 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.CompletionException;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.regex.Matcher;
@@ -45,7 +47,6 @@
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
-import com.wurrly.modules.RoutingModule;
import com.wurrly.server.Extractors;
import com.wurrly.server.ServerRequest;
import com.wurrly.server.ServerResponse;
@@ -66,7 +67,7 @@ public class HandlerGenerator
private static Logger log = LoggerFactory.getLogger(HandlerGenerator.class.getCanonicalName());
- private static final Pattern TYPE_NAME_PATTERN = Pattern.compile("(java\\.util\\.[A-Za-z]+)<([^>]+)", Pattern.DOTALL | Pattern.UNIX_LINES);
+ private static final Pattern TYPE_NAME_PATTERN = Pattern.compile("(java\\.util\\.(concurrent\\.)?[A-Za-z]+)<([^>]+)", Pattern.DOTALL | Pattern.UNIX_LINES);
public enum StatementParameterType
{
@@ -83,8 +84,9 @@ public enum TypeHandler
FilePathType("$T $L = $T.filePath(exchange,$S)", true, java.nio.file.Path.class, StatementParameterType.LITERAL,com.wurrly.server.Extractors.class, StatementParameterType.STRING),
AnyType("$T $L = $T.any(exchange)", true, com.jsoniter.any.Any.class, StatementParameterType.LITERAL,com.wurrly.server.Extractors.class),
JsonIteratorType("$T $L = $T.jsonIterator(exchange)", true, com.jsoniter.JsonIterator.class, StatementParameterType.LITERAL,com.wurrly.server.Extractors.class),
- ModelType("$T $L = com.wurrly.server.Extractors.typed(exchange,$L)", true, StatementParameterType.TYPE, StatementParameterType.LITERAL, StatementParameterType.LITERAL),
- EnumType("$T $L = $T.enumValue(exchange,$T.class,$S)", true, StatementParameterType.TYPE, StatementParameterType.LITERAL,com.wurrly.server.Extractors.class, StatementParameterType.TYPE, StatementParameterType.STRING),
+ ModelType("$T $L = com.wurrly.server.Extractors.model(exchange,$L)", true, StatementParameterType.TYPE, StatementParameterType.LITERAL, StatementParameterType.LITERAL),
+
+ //EnumType("$T $L = $T.enumValue(exchange,$T.class,$S)", true, StatementParameterType.TYPE, StatementParameterType.LITERAL,com.wurrly.server.Extractors.class, StatementParameterType.TYPE, StatementParameterType.STRING),
ByteBufferType("$T $L = $T.fileBytes(exchange,$S)", false, java.nio.ByteBuffer.class, StatementParameterType.LITERAL,com.wurrly.server.Extractors.class, StatementParameterType.STRING),
DateType("$T $L = $T.date(exchange,$S)", false, java.util.Date.class, StatementParameterType.LITERAL, com.wurrly.server.Extractors.class, StatementParameterType.STRING),
FloatType("Integer $L = $T.floatValue(exchange,$S)", false, StatementParameterType.LITERAL, com.wurrly.server.Extractors.class, StatementParameterType.STRING),
@@ -117,7 +119,7 @@ public enum TypeHandler
OptionalDateType("$T<$T> $L = $T.date(exchange,$S)", false, Optional.class, java.util.Date.class, StatementParameterType.LITERAL, com.wurrly.server.Extractors.Optional.class, StatementParameterType.STRING),
- OptionalModelType("java.util.Optional<$L> $L = $T.typed(exchange,$L)", true, StatementParameterType.LITERAL, StatementParameterType.LITERAL, com.wurrly.server.Extractors.Optional.class, StatementParameterType.LITERAL),
+ OptionalModelType("java.util.Optional<$L> $L = $T.model(exchange,$L)", true, StatementParameterType.LITERAL, StatementParameterType.LITERAL, com.wurrly.server.Extractors.Optional.class, StatementParameterType.LITERAL),
OptionalValueOfType("$T<$T> $L = $T.string(exchange,$S).map($T::valueOf)", false, Optional.class, StatementParameterType.RAW, StatementParameterType.LITERAL,com.wurrly.server.Extractors.Optional.class, StatementParameterType.STRING, StatementParameterType.RAW),
OptionalFromStringType("$T<$T> $L = $T.string(exchange,$S).map($T::fromString)", false, Optional.class, StatementParameterType.RAW, StatementParameterType.LITERAL, com.wurrly.server.Extractors.Optional.class, StatementParameterType.STRING, StatementParameterType.RAW),
@@ -230,6 +232,8 @@ public static void addStatement(MethodSpec.Builder builder, Parameter parameter)
public static TypeHandler forType(Type type)
{
+ log.debug("forType " + type);
+
boolean hasValueOf = false;
boolean hasFromString = false;
boolean isOptional = type.getTypeName().contains("java.util.Optional");
@@ -343,7 +347,7 @@ else if (type.getTypeName().contains("java.nio.file.Path"))
Class> erasedType = extractErasedType(type);
- //log.debug("erasedType: " + erasedType.getTypeName() + " valueOf: " + hasValueOfMethod(erasedType) + " fromString: " + hasFromStringMethod(erasedType));
+ log.debug("erasedType: " + erasedType + " for " + type);
if( hasValueOfMethod(erasedType) )
{
@@ -490,19 +494,21 @@ protected void generateRoutes()
}
}
- public void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> clazz)
+ public void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> clazz) throws Exception
{
ClassName httpHandlerClass = ClassName.get("io.undertow.server", "HttpHandler");
String controllerName = clazz.getSimpleName().toLowerCase();
+
+
MethodSpec.Builder initBuilder = MethodSpec.methodBuilder("get").addModifiers(Modifier.PUBLIC).returns(RoutingHandler.class).addStatement("final $T router = new $T()", io.undertow.server.RoutingHandler.class, io.undertow.server.RoutingHandler.class);
final Map typeLiteralsMap = Arrays.stream(clazz.getDeclaredMethods())
.flatMap(m -> Arrays.stream(m.getParameters()).map(Parameter::getParameterizedType)
- .filter(t -> t.getTypeName().contains("<")))
+ .filter(t -> t.getTypeName().contains("<") && !t.getTypeName().contains("concurrent")))
.distinct().filter(t -> {
- TypeHandler handler = TypeHandler.forType(t);
+ TypeHandler handler = TypeHandler.forType(t);
return (handler.equals(TypeHandler.ModelType) || handler.equals(TypeHandler.OptionalModelType));
}).collect(Collectors.toMap(java.util.function.Function.identity(), HandlerGenerator::typeLiteralNameForType));
@@ -511,12 +517,65 @@ public void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> clazz)
typeLiteralsMap.forEach((t, n) -> initBuilder.addStatement("final $T<$L> $LType = new $T<$L>(){}", TypeLiteral.class, t, n, TypeLiteral.class, t));
initBuilder.addCode("$L", "\n");
+
+
+ List consumesContentTypes = new ArrayList<>();
+ List producesContentTypes = new ArrayList<>();
for (Method m : clazz.getDeclaredMethods())
{
- EndpointInfo route = new EndpointInfo();
+ EndpointInfo endpointInfo = new EndpointInfo();
+
+ String producesContentType = "*/*";
- route.setControllerName(clazz.getSimpleName());
+ Optional producesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Produces.class));
+
+ if (!producesAnnotation.isPresent())
+ {
+ producesAnnotation = Optional.ofNullable(clazz.getAnnotation(javax.ws.rs.Produces.class));
+
+ if (producesAnnotation.isPresent())
+ {
+
+ producesContentTypes = Arrays.stream(producesAnnotation.get().value()).flatMap( v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
+
+ producesContentType = producesContentTypes.stream().collect(Collectors.joining(","));
+ }
+
+ }
+ else
+ {
+ producesContentTypes = Arrays.stream(producesAnnotation.get().value()).flatMap( v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
+
+ producesContentType = producesContentTypes.stream().collect(Collectors.joining(","));
+ }
+
+ endpointInfo.setProduces(producesContentType);
+
+ String consumesContentType = "*/*";
+
+ Optional consumesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Consumes.class));
+
+ if (!consumesAnnotation.isPresent())
+ {
+ consumesAnnotation = Optional.ofNullable(clazz.getAnnotation(javax.ws.rs.Consumes.class));
+
+ if (consumesAnnotation.isPresent())
+ {
+ consumesContentTypes = Arrays.stream(consumesAnnotation.get().value()).flatMap( v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
+
+ consumesContentType = consumesContentTypes.stream().collect(Collectors.joining(","));
+ }
+ }
+ else
+ {
+ consumesContentTypes = Arrays.stream(consumesAnnotation.get().value()).flatMap( v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
+
+ consumesContentType = consumesContentTypes.stream().collect(Collectors.joining(","));
+ }
+
+
+ endpointInfo.setControllerName(clazz.getSimpleName());
String methodPath = Extractors.pathTemplateFromMethod.apply(m).replaceAll("\\/\\/", "\\/");
@@ -525,11 +584,11 @@ public void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> clazz)
HttpString httpMethod = Extractors.httpMethodFromMethod.apply(m);
- route.setMethod(httpMethod);
+ endpointInfo.setMethod(httpMethod);
- route.setPathTemplate(methodPath);
+ endpointInfo.setPathTemplate(methodPath);
- route.setControllerMethod(clazz.getSimpleName() + "." + m.getName());
+ endpointInfo.setControllerMethod( m.getName());
String methodName = String.format("%c%s%sHandler", Character.toLowerCase(clazz.getSimpleName().charAt(0)), clazz.getSimpleName().substring(1, clazz.getSimpleName().length()), StringUtils.capitalize(m.getName()));
@@ -590,13 +649,10 @@ public void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> clazz)
{
if (p.isAnnotationPresent(HeaderParam.class))
{
-
- log.debug("header class: " + type);
TypeHandler handler = TypeHandler.forType(type);
-
- log.debug("header typehandler: " + handler);
+
if( handler.equals(TypeHandler.OptionalStringType) )
{
@@ -608,41 +664,31 @@ public void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> clazz)
else if( handler.equals(TypeHandler.OptionalValueOfType) )
{
handler = TypeHandler.OptionalHeaderValueOfType;
-
- log.debug("header typehandler: " + handler.statement);
-
+
TypeHandler.addStatement(methodBuilder, p,handler);
}
else if( handler.equals(TypeHandler.OptionalFromStringType) )
{
- handler = TypeHandler.OptionalHeaderFromStringType;
- log.debug("header typehandler: " + handler.statement);
-
+ handler = TypeHandler.OptionalHeaderFromStringType;
TypeHandler.addStatement(methodBuilder, p,handler);
}
else if( handler.equals(TypeHandler.StringType) )
{
- handler = TypeHandler.HeaderStringType;
- log.debug("header typehandler: " + handler.statement);
-
+ handler = TypeHandler.HeaderStringType;
TypeHandler.addStatement(methodBuilder, p,handler);
}
else if( handler.equals(TypeHandler.ValueOfType) )
{
- handler = TypeHandler.HeaderValueOfType;
- log.debug("header typehandler: " + handler.statement);
-
+ handler = TypeHandler.HeaderValueOfType;
TypeHandler.addStatement(methodBuilder, p,handler);
}
else if( handler.equals(TypeHandler.FromStringType) )
{
- handler = TypeHandler.HeaderFromStringType;
- log.debug("header typehandler: " + handler.statement);
-
+ handler = TypeHandler.HeaderFromStringType;
TypeHandler.addStatement(methodBuilder, p,handler);
}
@@ -671,7 +717,6 @@ else if( handler.equals(TypeHandler.FromStringType) )
}
else if (t.equals(TypeHandler.OptionalFromStringType) || t.equals(TypeHandler.OptionalValueOfType))
{
- Class> erasedType = extractErasedType(p.getParameterizedType());
TypeHandler.addStatement(methodBuilder,p);
}
@@ -697,54 +742,26 @@ else if (t.equals(TypeHandler.OptionalFromStringType) || t.equals(TypeHandler.Op
if (!m.getReturnType().equals(Void.class))
{
- // log.debug("return : " + m.getReturnType());
- functionBlockBuilder.add("$T $L = $L.$L($L);", m.getReturnType(), "response", controllerName, m.getName(), controllerMethodArgs);
+ if (m.getReturnType().getTypeName().contains("java.util.concurrent.CompletionStage") || m.getReturnType().getTypeName().contains("java.util.concurrent.CompletableFuture"))
+ {
+ Type futureType = m.getGenericReturnType();
+
+ functionBlockBuilder.add("$T $L = $L.$L($L);", futureType, "response", controllerName, m.getName(), controllerMethodArgs);
+ }
+ else
+ {
+ functionBlockBuilder.add("$T $L = $L.$L($L);", m.getReturnType(), "response", controllerName, m.getName(), controllerMethodArgs);
+ }
}
methodBuilder.addCode(functionBlockBuilder.build());
methodBuilder.addCode("$L", "\n");
- String producesContentType = "*/*";
-
- Optional producesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Produces.class));
-
- if (!producesAnnotation.isPresent())
- {
- producesAnnotation = Optional.ofNullable(clazz.getAnnotation(javax.ws.rs.Produces.class));
-
- if (producesAnnotation.isPresent())
- {
- producesContentType = producesAnnotation.get().value()[0];
- }
- }
- else
- {
- producesContentType = producesAnnotation.get().value()[0];
- }
-
- route.setProduces(producesContentType);
-
- String consumesContentType = "*/*";
-
- Optional consumesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Consumes.class));
-
- if (!consumesAnnotation.isPresent())
- {
- consumesAnnotation = Optional.ofNullable(clazz.getAnnotation(javax.ws.rs.Consumes.class));
-
- if (consumesAnnotation.isPresent())
- {
- consumesContentType = consumesAnnotation.get().value()[0];
- }
- }
- else
- {
- consumesContentType = consumesAnnotation.get().value()[0];
- }
+
- route.setConsumes(consumesContentType);
+ endpointInfo.setConsumes(consumesContentType);
methodBuilder.addCode("$L", "\n");
@@ -753,6 +770,11 @@ else if (t.equals(TypeHandler.OptionalFromStringType) || t.equals(TypeHandler.Op
methodBuilder.addStatement("$L.send(this,$L)","response","exchange");
}
+ else if( m.getReturnType().getTypeName().contains("java.util.concurrent.CompletionStage") || m.getReturnType().getTypeName().contains("java.util.concurrent.CompletableFuture") )
+ {
+
+ methodBuilder.addStatement("$L.thenAccept( r -> r.send(this,$L) ).exceptionally( ex -> { throw new java.util.concurrent.CompletionException(ex); } );","response","exchange");
+ }
else
{
@@ -782,7 +804,7 @@ else if (t.equals(TypeHandler.OptionalFromStringType) || t.equals(TypeHandler.Op
initBuilder.addCode("$L", "\n");
- registeredEndpoints.add(route);
+ registeredEndpoints.add(endpointInfo);
}
@@ -900,6 +922,30 @@ public static Class> extractErasedType(Type type) throws Exception
String clearDollarType = erasedType.replaceAll("\\$", ".");
+ log.debug("erasedType: " + erasedType);
+ log.debug("clearDollarType: " + clearDollarType);
+
+ try
+ {
+ return Class.forName(clearDollarType);
+
+ } catch (Exception e)
+ {
+ return Class.forName(erasedType);
+ }
+
+
+ }
+ else if (matches > 2)
+ {
+
+ String erasedType = matcher.group(3);
+
+ String clearDollarType = erasedType.replaceAll("\\$", ".");
+
+// log.debug("erasedType: " + erasedType);
+// log.debug("clearDollarType: " + clearDollarType);
+
try
{
return Class.forName(clearDollarType);
@@ -913,6 +959,10 @@ public static Class> extractErasedType(Type type) throws Exception
}
}
+ else
+ {
+ log.warn("No type found for " + typeName);
+ }
return null;
}
@@ -932,6 +982,9 @@ public static String typeLiteralNameForType(Type type)
{
String genericInterface = matcher.group(1);
String erasedType = matcher.group(2).replaceAll("\\$", ".");
+
+// log.debug("genericInterface: " + genericInterface);
+// log.debug("erasedType: " + erasedType);
String[] genericParts = genericInterface.split("\\.");
String[] erasedParts = erasedType.split("\\.");
@@ -972,6 +1025,7 @@ public static void generateParameterReference(MethodSpec.Builder builder, Class<
public static boolean hasValueOfMethod(Class> clazz)
{
+ log.debug("valueMethod: " + clazz);
return Arrays.stream(clazz.getMethods()).filter( m -> m.getName().equals("valueOf")).findFirst().isPresent();
}
diff --git a/src/main/java/com/wurrly/server/handlers/ServerDefaultResponseListener.java b/src/main/java/com/wurrly/server/handlers/ServerDefaultResponseListener.java
new file mode 100644
index 0000000..56e35a9
--- /dev/null
+++ b/src/main/java/com/wurrly/server/handlers/ServerDefaultResponseListener.java
@@ -0,0 +1,95 @@
+/**
+ *
+ */
+package com.wurrly.server.handlers;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.jsoniter.output.JsonStream;
+import com.wurrly.server.MimeTypes;
+import com.wurrly.server.ServerPredicates;
+
+import io.undertow.server.DefaultResponseListener;
+import io.undertow.server.HttpServerExchange;
+import io.undertow.util.Headers;
+
+/**
+ * @author jbauer
+ *
+ */
+@Singleton
+public class ServerDefaultResponseListener implements DefaultResponseListener
+{
+ private static Logger log = LoggerFactory.getLogger(ServerDefaultResponseListener.class.getCanonicalName());
+
+ @Inject
+ protected XmlMapper xmlMapper;
+
+ @Override
+ public boolean handleDefaultResponse(HttpServerExchange exchange)
+ {
+ if (!exchange.isResponseChannelAvailable()) {
+ return false;
+ }
+
+ if (exchange.getStatusCode() == 500) {
+
+ Throwable throwable = exchange.getAttachment(DefaultResponseListener.EXCEPTION);
+
+ if( throwable == null )
+ {
+ throwable = new Exception("An unknown error occured");
+ }
+
+ Map errorMap = new HashMap<>();
+
+ errorMap.put("message", throwable.getMessage());
+
+ if( throwable.getStackTrace() != null )
+ {
+ if( throwable.getStackTrace().length > 0 )
+ {
+ errorMap.put("exceptionClass", throwable.getStackTrace()[0].getClassName());
+ }
+ }
+
+ if( ServerPredicates.ACCEPT_XML_PREDICATE.resolve(exchange) )
+ {
+ try
+ {
+
+ final String xmlBody = xmlMapper.writeValueAsString(errorMap);
+ exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, xmlBody.length());
+ exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, MimeTypes.APPLICATION_XML_TYPE);
+ exchange.getResponseSender().send(xmlBody);
+
+ } catch (JsonProcessingException e)
+ {
+ log.warn("Unable to create XML from error...");
+ }
+
+ }
+ else
+ {
+ final String jsonBody = JsonStream.serialize(errorMap);
+
+ exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, MimeTypes.APPLICATION_JSON_TYPE);
+ exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, jsonBody.length());
+ exchange.getResponseSender().send(jsonBody);
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/com/wurrly/server/handlers/benchmark/BenchmarkHandlers.java b/src/main/java/com/wurrly/server/handlers/benchmark/BenchmarkHandlers.java
index 898dec6..fa37337 100644
--- a/src/main/java/com/wurrly/server/handlers/benchmark/BenchmarkHandlers.java
+++ b/src/main/java/com/wurrly/server/handlers/benchmark/BenchmarkHandlers.java
@@ -21,6 +21,8 @@
import com.jsoniter.output.JsonStream;
import com.wurrly.server.ServerResponse;
+import io.undertow.attribute.ExchangeAttributes;
+import io.undertow.predicate.Predicates;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.RoutingHandler;
@@ -52,7 +54,7 @@ public RoutingHandler get()
final RoutingHandler handler = new RoutingHandler();
- handler.add(Methods.GET, "/string".intern(), new HttpHandler(){
+ handler.add(Methods.GET, "/".intern(), new HttpHandler(){
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception
@@ -76,21 +78,7 @@ public void handleRequest(HttpServerExchange exchange) throws Exception
}
} );
- handler.add(Methods.GET, "/string3".intern(), new HttpHandler(){
-
- @Override
- public void handleRequest(HttpServerExchange exchange) throws Exception
- {
- // TODO Auto-generated method stub
-
- exchange.setStatusCode( 200 );
-
- //exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, PLAIN_TEXT);
-
- exchange.getResponseSender().send(msgBuffer);
-
- }
- } );
+
handler.add(Methods.GET, "/string4".intern(), new HttpHandler(){
@@ -293,6 +281,24 @@ public void handleRequest(HttpServerExchange exchange) throws Exception
}
} );
+
+
+
+ handler.add(Methods.GET, "/string3".intern(), new HttpHandler(){
+
+ @Override
+ public void handleRequest(HttpServerExchange exchange) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ exchange.setStatusCode( 200 );
+
+ //exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, PLAIN_TEXT);
+
+ exchange.getResponseSender().send(msgBuffer);
+
+ }
+ } );
diff --git a/src/main/java/com/wurrly/server/handlers/predicates/MaxRequestContentLengthPredicate.java b/src/main/java/com/wurrly/server/handlers/predicates/MaxRequestContentLengthPredicate.java
new file mode 100644
index 0000000..2234a60
--- /dev/null
+++ b/src/main/java/com/wurrly/server/handlers/predicates/MaxRequestContentLengthPredicate.java
@@ -0,0 +1,65 @@
+/**
+ *
+ */
+package com.wurrly.server.handlers.predicates;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import io.undertow.predicate.Predicate;
+import io.undertow.predicate.PredicateBuilder;
+import io.undertow.server.HttpServerExchange;
+import io.undertow.util.Headers;
+
+/**
+ * @author jbauer
+ *
+ */
+public class MaxRequestContentLengthPredicate implements Predicate
+{
+ private final long maxSize;
+
+ MaxRequestContentLengthPredicate(final long maxSize) {
+ this.maxSize = maxSize;
+ }
+
+ @Override
+ public boolean resolve(final HttpServerExchange value) {
+ final String length = value.getRequestHeaders().getFirst(Headers.CONTENT_LENGTH);
+ if (length == null) {
+ return false;
+ }
+ return Long.parseLong(length) > maxSize;
+ }
+
+ public static class Builder implements PredicateBuilder {
+
+ @Override
+ public String name() {
+ return "max-content-size";
+ }
+
+ @Override
+ public Map> parameters() {
+ return Collections.>singletonMap("value", Long.class);
+ }
+
+
+ @Override
+ public Set requiredParameters() {
+ return Collections.singleton("value");
+ }
+
+ @Override
+ public String defaultParameter() {
+ return "value";
+ }
+
+ @Override
+ public Predicate build(final Map config) {
+ Long max = (Long) config.get("value");
+ return new MaxRequestContentLengthPredicate(max);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/wurrly/server/listeners/ServerDefaultResponseListener.java b/src/main/java/com/wurrly/server/listeners/ServerDefaultResponseListener.java
deleted file mode 100644
index 4bf1f1d..0000000
--- a/src/main/java/com/wurrly/server/listeners/ServerDefaultResponseListener.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- *
- */
-package com.wurrly.server.listeners;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableMap;
-import com.jsoniter.output.JsonStream;
-
-import io.undertow.server.DefaultResponseListener;
-import io.undertow.server.HttpServerExchange;
-import io.undertow.util.Headers;
-
-/**
- * @author jbauer
- *
- */
-public class ServerDefaultResponseListener implements DefaultResponseListener
-{
-
-
- @Override
- public boolean handleDefaultResponse(HttpServerExchange exchange)
- {
- if (!exchange.isResponseChannelAvailable()) {
- return false;
- }
-
- if (exchange.getStatusCode() == 500) {
-
-
- Throwable throwable = exchange.getAttachment(DefaultResponseListener.EXCEPTION);
-
- if( throwable == null )
- {
- throwable = new Exception("An unknown error occured");
- }
-
- final String jsonBody = JsonStream.serialize(throwable);
-
- exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, org.apache.http.entity.ContentType.APPLICATION_JSON.getMimeType());
- exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, jsonBody.length());
- exchange.getResponseSender().send(jsonBody);
-
- return true;
- }
- return false;
- }
-
-}
diff --git a/src/main/java/com/wurrly/server/swagger/Reader.java b/src/main/java/com/wurrly/server/swagger/Reader.java
index f847139..6d08a4f 100644
--- a/src/main/java/com/wurrly/server/swagger/Reader.java
+++ b/src/main/java/com/wurrly/server/swagger/Reader.java
@@ -35,6 +35,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter;
+import com.fasterxml.jackson.databind.type.SimpleType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.wurrly.server.ServerRequest;
@@ -1062,9 +1063,13 @@ private List getParameters(Type type, List annotations, j
LOGGER.debug("getParameters for {}", type);
Set typesToSkip = new HashSet<>();
- // typesToSkip.add(ServerRequest.class);
+ typesToSkip.add(TypeFactory.defaultInstance().constructType(ServerRequest.class));
final SwaggerExtension extension = chain.next();
+ if (typesToSkip.contains(type)) {
+ return Collections.emptyList();
+ }
+
annotations = new ArrayList<>(annotations);
diff --git a/src/main/java/com/wurrly/server/swagger/ServerParameterExtension.java b/src/main/java/com/wurrly/server/swagger/ServerParameterExtension.java
index 5856806..10c1520 100644
--- a/src/main/java/com/wurrly/server/swagger/ServerParameterExtension.java
+++ b/src/main/java/com/wurrly/server/swagger/ServerParameterExtension.java
@@ -37,8 +37,7 @@ public ServerParameterExtension()
@Override
public List extractParameters(List annotations, Type type, Set typesToSkip, Iterator chain)
{
- log.debug("extractParameters: " + type);
-
+
if(type.getTypeName().contains("java.nio.ByteBuffer") || type.getTypeName().contains("java.nio.file.Path"))
{
type = java.io.File.class;
@@ -53,8 +52,8 @@ public List extractParameters(List annotations, Type type
@Override
protected boolean shouldIgnoreType(Type type, Set typesToSkip)
{
-
- if( type.getTypeName().contains("com.wurrly.server.ServerRequest"))
+
+ if( type.getTypeName().contains("ServerRequest"))
{
return true;
}
diff --git a/src/main/java/com/wurrly/services/AssetsService.java b/src/main/java/com/wurrly/services/AssetsService.java
new file mode 100644
index 0000000..4f84742
--- /dev/null
+++ b/src/main/java/com/wurrly/services/AssetsService.java
@@ -0,0 +1,75 @@
+/**
+ *
+ */
+package com.wurrly.services;
+
+import java.nio.file.Paths;
+import java.util.Set;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import com.typesafe.config.Config;
+import com.wurrly.server.endpoints.EndpointInfo;
+
+import io.undertow.predicate.TruePredicate;
+import io.undertow.server.RoutingHandler;
+import io.undertow.server.handlers.resource.FileResourceManager;
+import io.undertow.server.handlers.resource.ResourceHandler;
+import io.undertow.util.Methods;
+
+/**
+ * @author jbauer
+ *
+ */
+public class AssetsService extends BaseService
+{
+
+ @Inject
+ @Named("registeredEndpoints")
+ protected Set registeredEndpoints;
+
+ @Inject
+ protected RoutingHandler rootHandler;
+
+ @Inject
+ @Named("assets")
+ protected Config serviceConfig;
+ /**
+ *
+ */
+ public AssetsService()
+ {
+ // TODO Auto-generated constructor stub
+ }
+
+
+ @Override
+ protected void startUp() throws Exception
+ {
+ super.startUp();
+
+ final String assetsPath = serviceConfig.getString("path");
+ final String assetsDirectoryName = serviceConfig.getString("dir") ;
+ final Integer assetsCacheTime = serviceConfig.getInt("cache.time");
+
+ final FileResourceManager fileResourceManager = new FileResourceManager(Paths.get(assetsDirectoryName).toFile());
+
+
+ rootHandler.add(Methods.GET, assetsPath + "/*", io.undertow.Handlers.rewrite("regex['" + assetsPath + "/(.*)']", "/$1", getClass().getClassLoader(), new ResourceHandler(fileResourceManager)
+ .setCachable(TruePredicate.instance())
+ .setCacheTime(assetsCacheTime)
+ ));
+
+ this.registeredEndpoints.add(EndpointInfo.builder().withConsumes("*/*").withProduces("*/*").withPathTemplate(assetsPath).withControllerName("Assets").withMethod(Methods.GET).build());
+
+ }
+
+
+ @Override
+ protected void shutDown() throws Exception
+ {
+ super.shutDown();
+
+ }
+
+}
diff --git a/src/main/java/com/wurrly/services/BaseService.java b/src/main/java/com/wurrly/services/BaseService.java
new file mode 100644
index 0000000..192985f
--- /dev/null
+++ b/src/main/java/com/wurrly/services/BaseService.java
@@ -0,0 +1,56 @@
+/**
+ *
+ */
+package com.wurrly.services;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.AbstractIdleService;
+import com.google.inject.Inject;
+import com.typesafe.config.Config;
+import com.wurrly.modules.ConfigModule;
+
+/**
+ * @author jbauer
+ *
+ */
+public class BaseService extends AbstractIdleService
+{
+ private static Logger log = LoggerFactory.getLogger(BaseService.class.getCanonicalName());
+
+ /* (non-Javadoc)
+ * @see com.google.inject.AbstractModule#configure()
+ */
+
+ @Inject
+ protected Config config;
+
+
+ public BaseService()
+ {
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.google.common.util.concurrent.AbstractIdleService#startUp()
+ */
+ @Override
+ protected void startUp() throws Exception
+ {
+ log.info("Starting " + this.getClass().getSimpleName() );
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.google.common.util.concurrent.AbstractIdleService#shutDown()
+ */
+ @Override
+ protected void shutDown() throws Exception
+ {
+ log.info("Stopping " + this.getClass().getSimpleName() );
+ }
+
+
+}
diff --git a/src/main/java/com/wurrly/services/ConfigurableService.java b/src/main/java/com/wurrly/services/ConfigurableService.java
deleted file mode 100644
index cd1d906..0000000
--- a/src/main/java/com/wurrly/services/ConfigurableService.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- *
- */
-package com.wurrly.services;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.util.concurrent.AbstractIdleService;
-import com.google.inject.Inject;
-import com.wurrly.modules.ConfigModule;
-
-/**
- * @author jbauer
- *
- */
-public abstract class ConfigurableService extends AbstractIdleService
-{
- private static Logger log = LoggerFactory.getLogger(ConfigurableService.class.getCanonicalName());
-
- /* (non-Javadoc)
- * @see com.google.inject.AbstractModule#configure()
- */
-
- protected String configFile;
-
- @Inject
- protected ConfigModule configModule;
-
- public ConfigurableService()
- {
-
- }
-
-
- protected void configure()
- {
- log.debug("Configuring : " + this.getClass().getSimpleName());
-
- if( this.configFile != null )
- {
- configModule.bindFileConfig(this.configFile);
- }
-
- }
-
-
-
-}
diff --git a/src/main/java/com/wurrly/services/SwaggerService.java b/src/main/java/com/wurrly/services/SwaggerService.java
index ff90aac..dbef59b 100644
--- a/src/main/java/com/wurrly/services/SwaggerService.java
+++ b/src/main/java/com/wurrly/services/SwaggerService.java
@@ -1,10 +1,8 @@
package com.wurrly.services;
-import java.io.File;
import java.io.StringWriter;
import java.io.Writer;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -19,13 +17,11 @@
import com.google.inject.Inject;
import com.google.inject.name.Named;
-import com.j256.simplemagic.ContentType;
import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import com.typesafe.config.Config;
-import com.wurrly.modules.RoutingModule;
+import com.wurrly.server.MimeTypes;
import com.wurrly.server.endpoints.EndpointInfo;
-import com.wurrly.server.handlers.HandlerGenerator;
import com.wurrly.server.swagger.ServerParameterExtension;
import com.wurrly.utilities.JsonMapper;
@@ -37,17 +33,17 @@
import io.undertow.server.HttpServerExchange;
import io.undertow.server.RoutingHandler;
import io.undertow.server.handlers.resource.ClassPathResourceManager;
-import io.undertow.server.handlers.resource.Resource;
import io.undertow.server.handlers.resource.ResourceHandler;
import io.undertow.util.CanonicalPathUtils;
import io.undertow.util.Headers;
import io.undertow.util.Methods;
-import com.j256.simplemagic.ContentType;
-
-public class SwaggerService extends ConfigurableService implements Supplier
+public class SwaggerService extends BaseService implements Supplier
{
+
+
+
private static Logger log = LoggerFactory.getLogger(SwaggerService.class.getCanonicalName());
protected com.wurrly.server.swagger.Reader reader = null;
@@ -58,9 +54,9 @@ public class SwaggerService extends ConfigurableService implements Supplier> registeredControllers;
- public SwaggerService()
- {
- this.configFile = "swagger.conf";
- }
-
+ /**
+ * @param config
+ */
+ public SwaggerService( )
+ {
+
+ }
+
+
public void generateSwaggerSpec()
{
@@ -165,14 +165,7 @@ public void generateSwaggerSpec()
}
- @Override
- protected void configure()
- {
- // log.debug("Configuring : " + this.getClass().getSimpleName() + " swaggerBasePath: " + swaggerBasePath);
-
-
- super.configure();
- }
+
/**
* @return the swagger
@@ -242,7 +235,7 @@ public RoutingHandler get()
public void handleRequest(HttpServerExchange exchange) throws Exception
{
- exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, ContentType.JSON.getMimeType());
+ exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, MimeTypes.APPLICATION_JSON_TYPE);
exchange.getResponseSender().send(swaggerSpec);
@@ -252,7 +245,7 @@ public void handleRequest(HttpServerExchange exchange) throws Exception
});
- this.registeredEndpoints.add(EndpointInfo.builder().withConsumes("*/*").withPathTemplate(pathTemplate).withControllerName("Swagger").withMethod(Methods.GET).withProduces(ContentType.JSON.getMimeType()).build());
+ this.registeredEndpoints.add(EndpointInfo.builder().withConsumes("*/*").withPathTemplate(pathTemplate).withControllerName("Swagger").withMethod(Methods.GET).withProduces(MimeTypes.APPLICATION_JSON_TYPE).build());
pathTemplate = this.swaggerBasePath;
@@ -264,7 +257,7 @@ public void handleRequest(HttpServerExchange exchange) throws Exception
{
- exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, ContentType.HTML.getMimeType());
+ exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, MimeTypes.TEXT_HTML_TYPE);
exchange.getResponseSender().send(swaggerIndexHTML);
}
diff --git a/src/main/java/com/wurrly/tests/TestTypes.java b/src/main/java/com/wurrly/tests/TestTypes.java
new file mode 100644
index 0000000..f4e69e6
--- /dev/null
+++ b/src/main/java/com/wurrly/tests/TestTypes.java
@@ -0,0 +1,127 @@
+/**
+ *
+ */
+package com.wurrly.tests;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionStage;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import com.wurrly.server.ServerResponse;
+
+/**
+ * @author jbauer
+ *
+ */
+public class TestTypes
+{
+
+ interface ServiceCall
+ {
+ CompletableFuture invoke(T request);
+ }
+
+ public static interface FutureSupplier extends ServiceCall
+ {
+ default CompletableFuture invoke()
+ {
+ return completedFutureSupplier.get(); //CompletableFuture.completedFuture(new ServerResponse());
+ }
+
+ public CompletableFuture invoke( CompletableFuture response );
+ }
+
+
+
+ public static class RestCaller implements FutureSupplier
+ {
+
+ public RestCaller( UnaryOperator> initializer )
+ {
+ initializer.apply(this.invoke());
+ }
+
+ @Override
+ public CompletableFuture invoke(CompletableFuture response)
+ {
+ // TODO Auto-generated method stub
+ return response;
+ }
+
+ /* (non-Javadoc)
+ * @see com.wurrly.tests.TestTypes.ServiceCall#invoke(java.lang.Object)
+ */
+ @Override
+ public CompletableFuture invoke(ServerResponse request)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+
+ private static Supplier> completedFutureSupplier = () ->
+ {
+ return CompletableFuture.completedFuture(new ServerResponse());
+ };
+ /**
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ // TODO Auto-generated method stub
+ try
+ {
+
+
+ ServiceCall res = processRequest();
+
+
+
+
+ CompletableFuture response = (res.invoke(new ServerResponse()));
+
+ response.thenAccept( r ->
+ {
+
+ r.send(null, null);
+
+
+ }).exceptionally( ex -> { throw new CompletionException(ex); });
+
+
+ CompletableFuture future3 = CompletableFuture.supplyAsync(() -> "test");
+ future3.thenAccept(t -> {
+ throw new RuntimeException();
+ }).exceptionally(t -> {
+ t.printStackTrace();
+ throw new CompletionException(t);
+ });
+
+ //FutureSupplier supplier = processRequest2();
+
+
+
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static ServiceCall processRequest()
+ {
+ return (response) -> {
+
+ System.out.println(response);
+ return CompletableFuture.completedFuture(response);
+
+ };
+ }
+
+
+
+}