diff --git a/core/pom.xml b/core/pom.xml
index bd9a513..d345c70 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -62,7 +62,7 @@
maven-surefire-plugin
- 2.20.1
+ org.apache.maven.plugins
diff --git a/core/src/main/java/io/sinistral/proteus/ProteusApplication.java b/core/src/main/java/io/sinistral/proteus/ProteusApplication.java
index d50afbe..ed1595a 100644
--- a/core/src/main/java/io/sinistral/proteus/ProteusApplication.java
+++ b/core/src/main/java/io/sinistral/proteus/ProteusApplication.java
@@ -14,6 +14,9 @@
import com.google.inject.name.Named;
import com.typesafe.config.Config;
import io.sinistral.proteus.modules.ConfigModule;
+import io.sinistral.proteus.modules.JacksonModule;
+import io.sinistral.proteus.server.Extractors;
+import io.sinistral.proteus.server.ServerResponse;
import io.sinistral.proteus.server.endpoints.EndpointInfo;
import io.sinistral.proteus.server.handlers.HandlerGenerator;
import io.sinistral.proteus.server.handlers.ServerDefaultHttpHandler;
@@ -226,6 +229,8 @@ public boolean isRunning()
public void buildServer()
{
+
+
for (Class> controllerClass : registeredControllers) {
HandlerGenerator generator = new HandlerGenerator("io.sinistral.proteus.controllers.handlers", controllerClass);
diff --git a/core/src/main/java/io/sinistral/proteus/modules/ApplicationModule.java b/core/src/main/java/io/sinistral/proteus/modules/ApplicationModule.java
index 16b57ec..b6a13ef 100644
--- a/core/src/main/java/io/sinistral/proteus/modules/ApplicationModule.java
+++ b/core/src/main/java/io/sinistral/proteus/modules/ApplicationModule.java
@@ -59,21 +59,32 @@ public void bindMappers()
this.bind(XmlMapper.class).toInstance(xmlMapper);
- ObjectMapper objectMapper = new ObjectMapper();
-
- objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
- objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
- objectMapper.configure(DeserializationFeature.EAGER_DESERIALIZER_FETCH, true);
- objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
- objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
- objectMapper.registerModule(new AfterburnerModule());
- objectMapper.registerModule(new Jdk8Module());
-
- this.bind(ObjectMapper.class).toInstance(objectMapper);
+ try {
+
+ String className = config.getString("application.jacksonModule");
+
+ log.info("Installing JacksonModule " + className);
+
+ Class extends AbstractModule> clazz = (Class extends AbstractModule>) Class.forName(className);
+
+ AbstractModule module = clazz.newInstance();
+
+ install(module);
+
+ } catch (Exception e) {
+
+ this.binder().addError(e);
+
+ log.error(e.getMessage(), e);
+
+ install(new JacksonModule());
+
+ }
+
this.requestStaticInjection(Extractors.class);
this.requestStaticInjection(ServerResponse.class);
- }
+
+ }
@SuppressWarnings("unchecked")
@Override
diff --git a/core/src/main/java/io/sinistral/proteus/modules/ConfigModule.java b/core/src/main/java/io/sinistral/proteus/modules/ConfigModule.java
index 09a5a26..0d1fd73 100644
--- a/core/src/main/java/io/sinistral/proteus/modules/ConfigModule.java
+++ b/core/src/main/java/io/sinistral/proteus/modules/ConfigModule.java
@@ -46,6 +46,8 @@ public ConfigModule()
}
}
+
+
public ConfigModule(String configFile)
{
this.configFile = configFile;
@@ -56,6 +58,16 @@ public ConfigModule(URL configURL)
this.configURL = configURL;
}
+ public Config getConfig()
+ {
+ return config;
+ }
+
+ public void setConfig(Config config)
+ {
+ this.config = config;
+ }
+
@SuppressWarnings("unchecked")
private void bindConfig(final Config config)
{
diff --git a/core/src/main/java/io/sinistral/proteus/modules/JacksonModule.java b/core/src/main/java/io/sinistral/proteus/modules/JacksonModule.java
new file mode 100644
index 0000000..b66e00e
--- /dev/null
+++ b/core/src/main/java/io/sinistral/proteus/modules/JacksonModule.java
@@ -0,0 +1,27 @@
+package io.sinistral.proteus.modules;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
+import com.google.inject.AbstractModule;
+
+public class JacksonModule extends AbstractModule
+{
+ @Override
+ protected void configure()
+ {
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
+ objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
+ objectMapper.configure(DeserializationFeature.EAGER_DESERIALIZER_FETCH, true);
+ objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
+ objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
+ objectMapper.registerModule(new AfterburnerModule());
+ objectMapper.registerModule(new Jdk8Module());
+
+ this.bind(ObjectMapper.class).toInstance(objectMapper);
+ }
+}
diff --git a/core/src/main/java/io/sinistral/proteus/server/MediaType.java b/core/src/main/java/io/sinistral/proteus/server/MediaType.java
index cf8a13c..928b2ac 100644
--- a/core/src/main/java/io/sinistral/proteus/server/MediaType.java
+++ b/core/src/main/java/io/sinistral/proteus/server/MediaType.java
@@ -9,9 +9,14 @@
*/
+import java.lang.reflect.Field;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
import java.util.stream.Collectors;
public class MediaType
@@ -1210,6 +1215,11 @@ public static synchronized MediaType getByFileName(String filename)
}
}
+ public static synchronized MediaType getByMimeType(String type)
+ {
+ return Optional.ofNullable(getTypeMap().get(type)).orElse(MediaType.DEFAULT);
+ }
+
public String withCharset(String charset)
{
return charset != null ? String.format("%s; charset=%s", this.contentType, charset.toUpperCase()) : this.contentType;
@@ -1262,6 +1272,30 @@ public String toString()
return this.contentType;
}
+ private static final Map TYPE_MAP = new HashMap<>();
+
+ public static Map getTypeMap()
+ {
+ if(TYPE_MAP.size() == 0) {
+ Class> clazz = MediaType.class;
+
+ Field[] fields = clazz.getDeclaredFields();
+
+ Arrays.stream(fields).filter(f -> f.getType().equals(MediaType.class)).forEach( f -> {
+
+ try
+ {
+ MediaType mt = (MediaType)f.get(MediaType.class);
+ TYPE_MAP.put(mt.contentType,mt);
+ } catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ return TYPE_MAP;
+ }
@Override
public int hashCode()
@@ -1307,5 +1341,4 @@ public String info()
return toString();
}
-
}
diff --git a/core/src/main/java/io/sinistral/proteus/server/exceptions/ServerException.java b/core/src/main/java/io/sinistral/proteus/server/exceptions/ServerException.java
index f98a5d0..ef5e8a5 100644
--- a/core/src/main/java/io/sinistral/proteus/server/exceptions/ServerException.java
+++ b/core/src/main/java/io/sinistral/proteus/server/exceptions/ServerException.java
@@ -9,7 +9,7 @@
* @author jbauer
*
*/
-public class ServerException extends Exception
+public class ServerException extends RuntimeException
{
/**
*
diff --git a/core/src/main/resources/reference.conf b/core/src/main/resources/reference.conf
index 3afcb62..610134f 100644
--- a/core/src/main/resources/reference.conf
+++ b/core/src/main/resources/reference.conf
@@ -22,6 +22,8 @@ application {
defaultResponseListener = "io.sinistral.proteus.server.handlers.ServerDefaultResponseListener"
+ jacksonModule = "io.sinistral.proteus.modules.JacksonModule"
+
tmpdir = ${java.io.tmpdir}/${application.name}
# path to default favicon file
@@ -61,7 +63,6 @@ assets {
openapi {
-
basePath= ${application.path}"/openapi"
redocPath= "redoc"
@@ -93,6 +94,10 @@ openapi {
description="Default Server"
}
]
+
+ converterClasses = [
+
+ ]
}
diff --git a/core/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java b/core/src/test/java/io/sinistral/proteus/test/controllers/Tests.java
similarity index 98%
rename from core/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java
rename to core/src/test/java/io/sinistral/proteus/test/controllers/Tests.java
index 3a2f3ed..aa852b6 100644
--- a/core/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java
+++ b/core/src/test/java/io/sinistral/proteus/test/controllers/Tests.java
@@ -1,7 +1,7 @@
/**
*
*/
-package io.sinistral.proteus.swagger.test.controllers;
+package io.sinistral.proteus.test.controllers;
import static io.sinistral.proteus.server.ServerResponse.response;
@@ -37,10 +37,9 @@
import com.google.inject.Singleton;
import io.sinistral.proteus.annotations.Blocking;
-import io.sinistral.proteus.annotations.Debug;
import io.sinistral.proteus.server.ServerRequest;
import io.sinistral.proteus.server.ServerResponse;
-import io.sinistral.proteus.swagger.test.models.User;
+import io.sinistral.proteus.test.models.User;
import io.undertow.server.HttpServerExchange;
diff --git a/core/src/test/java/io/sinistral/proteus/swagger/test/models/User.java b/core/src/test/java/io/sinistral/proteus/test/models/User.java
similarity index 94%
rename from core/src/test/java/io/sinistral/proteus/swagger/test/models/User.java
rename to core/src/test/java/io/sinistral/proteus/test/models/User.java
index 32d81c2..04e405e 100644
--- a/core/src/test/java/io/sinistral/proteus/swagger/test/models/User.java
+++ b/core/src/test/java/io/sinistral/proteus/test/models/User.java
@@ -1,7 +1,7 @@
/**
*
*/
-package io.sinistral.proteus.swagger.test.models;
+package io.sinistral.proteus.test.models;
/**
diff --git a/core/src/test/java/io/sinistral/proteus/swagger/test/server/DefaultServer.java b/core/src/test/java/io/sinistral/proteus/test/server/DefaultServer.java
similarity index 95%
rename from core/src/test/java/io/sinistral/proteus/swagger/test/server/DefaultServer.java
rename to core/src/test/java/io/sinistral/proteus/test/server/DefaultServer.java
index a65fab2..4f651d7 100644
--- a/core/src/test/java/io/sinistral/proteus/swagger/test/server/DefaultServer.java
+++ b/core/src/test/java/io/sinistral/proteus/test/server/DefaultServer.java
@@ -1,11 +1,11 @@
/**
*
*/
-package io.sinistral.proteus.swagger.test.server;
+package io.sinistral.proteus.test.server;
import java.util.List;
-import io.sinistral.proteus.swagger.test.controllers.Tests;
+import io.sinistral.proteus.test.controllers.Tests;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.RunListener;
diff --git a/core/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java b/core/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java
similarity index 98%
rename from core/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java
rename to core/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java
index ae48ec1..64aaf53 100644
--- a/core/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java
+++ b/core/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java
@@ -1,7 +1,7 @@
/**
*
*/
-package io.sinistral.proteus.swagger.test.server;
+package io.sinistral.proteus.test.server;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.containsString;
@@ -36,8 +36,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.restassured.http.ContentType;
-import io.sinistral.proteus.swagger.test.models.User;
-import io.sinistral.proteus.swagger.test.models.User.UserType;
+import io.sinistral.proteus.test.models.User;
+import io.sinistral.proteus.test.models.User.UserType;
/*
* import static io.restassured.RestAssured.*; import static io.restassured.matcher.RestAssuredMatchers.*; import static org.hamcrest.Matchers.*;
diff --git a/core/src/test/resources/application.conf b/core/src/test/resources/application.conf
index 9c55400..ddd47d4 100644
--- a/core/src/test/resources/application.conf
+++ b/core/src/test/resources/application.conf
@@ -22,6 +22,8 @@ application {
defaultResponseListener = "io.sinistral.proteus.server.handlers.ServerDefaultResponseListener"
+ jacksonModule = "io.sinistral.proteus.modules.JacksonModule"
+
tmpdir = ${java.io.tmpdir}/${application.name}
# path to default favicon file
diff --git a/core/src/test/resources/logback-test.xml b/core/src/test/resources/logback-test.xml
index 8763c33..44a9e83 100644
--- a/core/src/test/resources/logback-test.xml
+++ b/core/src/test/resources/logback-test.xml
@@ -16,12 +16,8 @@
-
-
-
+
-
-
diff --git a/openapi/pom.xml b/openapi/pom.xml
index 7badaa1..7cfa6a0 100644
--- a/openapi/pom.xml
+++ b/openapi/pom.xml
@@ -29,7 +29,7 @@
src/test/resources
- src/test/java
+ src/test/java/sinistral/proteus/openapi
**/*.java
@@ -59,7 +59,7 @@
maven-surefire-plugin
- 2.20.1
+ org.apache.maven.plugins
@@ -109,6 +109,14 @@
swagger-integration
${openapi.version}
+
+
+ org.zalando
+ jackson-datatype-money
+ 1.1.1
+ test
+
+
${project.groupId}
proteus-core
diff --git a/openapi/src/main/java/io/sinistral/proteus/openapi/jaxrs2/ServerModelResolver.java b/openapi/src/main/java/io/sinistral/proteus/openapi/jaxrs2/ServerModelResolver.java
index 0944968..b5981c2 100644
--- a/openapi/src/main/java/io/sinistral/proteus/openapi/jaxrs2/ServerModelResolver.java
+++ b/openapi/src/main/java/io/sinistral/proteus/openapi/jaxrs2/ServerModelResolver.java
@@ -58,7 +58,6 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
if ((rawClass != null) &&!resolvedType.isPrimitive())
{
- // log.debug("resolvedType in " + resolvedType);
if (rawClass.isAssignableFrom(ServerResponse.class))
{
resolvedType = classType.containedType(0);
@@ -69,14 +68,12 @@ else if (rawClass.isAssignableFrom(CompletableFuture.class))
if (futureCls.isAssignableFrom(ServerResponse.class))
{
- // log.debug("class is assignable from ServerResponse");
final JavaType futureType = TypeFactory.defaultInstance().constructType(classType.containedType(0));
resolvedType = futureType.containedType(0);
}
else
{
- // log.debug("class is NOT assignable from ServerResponse");
resolvedType = classType.containedType(0);
}
}
@@ -114,13 +111,11 @@ else if (resolvedType.getTypeName().contains("Optional"))
annotatedType.setType(resolvedType);
- // log.debug("resolvedType out " + resolvedType);
}
}
try {
- // log.info("Processing " + annotatedType + " " + classType + " " + annotatedType.getName());
return super.resolve(annotatedType, context, next);
} catch (Exception e) {
diff --git a/openapi/src/main/java/io/sinistral/proteus/openapi/jaxrs2/ServerParameterExtension.java b/openapi/src/main/java/io/sinistral/proteus/openapi/jaxrs2/ServerParameterExtension.java
index 5d6c85b..2ba39a5 100644
--- a/openapi/src/main/java/io/sinistral/proteus/openapi/jaxrs2/ServerParameterExtension.java
+++ b/openapi/src/main/java/io/sinistral/proteus/openapi/jaxrs2/ServerParameterExtension.java
@@ -22,10 +22,19 @@
import io.swagger.v3.oas.models.parameters.Parameter;
import org.apache.commons.lang3.StringUtils;
-import javax.ws.rs.*;
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.CookieParam;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.MatrixParam;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
/**
* @author jbauer
@@ -38,7 +47,8 @@ public class ServerParameterExtension extends AbstractOpenAPIExtension
private static String COOKIE_PARAM = "cookie";
private static String PATH_PARAM = "path";
private static String FORM_PARAM = "form";
- final ObjectMapper mapper = Json.mapper();
+
+ final static ObjectMapper mapper = Json.mapper();
@Override
public ResolvedParameter extractParameters(List annotations, Type type, Set typesToSkip, Components components, javax.ws.rs.Consumes classConsumes,
diff --git a/openapi/src/main/java/io/sinistral/proteus/openapi/services/OpenAPIService.java b/openapi/src/main/java/io/sinistral/proteus/openapi/services/OpenAPIService.java
index 09a2ca0..6fa5c5a 100644
--- a/openapi/src/main/java/io/sinistral/proteus/openapi/services/OpenAPIService.java
+++ b/openapi/src/main/java/io/sinistral/proteus/openapi/services/OpenAPIService.java
@@ -1,52 +1,18 @@
package io.sinistral.proteus.openapi.services;
-import java.io.File;
-import java.io.InputStream;
-
-import java.net.URL;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.Supplier;
-import java.util.jar.JarFile;
-import java.util.stream.Collectors;
-
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.core.MediaType;
-
-import io.sinistral.proteus.openapi.jaxrs2.Reader;
-import io.sinistral.proteus.openapi.jaxrs2.ServerModelResolver;
-import io.sinistral.proteus.openapi.jaxrs2.ServerParameterExtension;
-import io.sinistral.proteus.services.DefaultService;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
-
import com.typesafe.config.Config;
-
+import io.sinistral.proteus.openapi.jaxrs2.Reader;
+import io.sinistral.proteus.openapi.jaxrs2.ServerModelResolver;
+import io.sinistral.proteus.openapi.jaxrs2.ServerParameterExtension;
import io.sinistral.proteus.server.endpoints.EndpointInfo;
-
+import io.sinistral.proteus.services.DefaultService;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.core.util.Yaml;
import io.swagger.v3.jaxrs2.ext.OpenAPIExtensions;
@@ -59,7 +25,6 @@
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
-
import io.undertow.server.HandlerWrapper;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.RoutingHandler;
@@ -69,6 +34,31 @@
import io.undertow.util.CanonicalPathUtils;
import io.undertow.util.Headers;
import io.undertow.util.Methods;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
/**
* A service for generating and serving an OpenAPI v3 spec and ui.
@@ -265,7 +255,15 @@ protected void generateSpec() throws Exception
SwaggerConfiguration config = new SwaggerConfiguration().resourceClasses(classes.stream().map(Class::getName).collect(Collectors.toSet())).openAPI(openApi);
- config.setModelConverterClassess(Collections.singleton(ServerModelResolver.class.getName()));
+ Set modelConverterClasses = new HashSet<>();
+
+ modelConverterClasses.add(ServerModelResolver.class.getName());
+
+ List additionalConverterClasses = openAPIConfig.getStringList("converterClasses");
+
+ modelConverterClasses.addAll(additionalConverterClasses);
+
+ config.setModelConverterClassess(modelConverterClasses);
OpenApiContext ctx = new GenericOpenApiContext().openApiConfiguration(config)
.openApiReader(new Reader(config))
diff --git a/openapi/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java b/openapi/src/test/java/io/sinistral/proteus/openapi/test/controllers/OpenAPITests.java
similarity index 88%
rename from openapi/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java
rename to openapi/src/test/java/io/sinistral/proteus/openapi/test/controllers/OpenAPITests.java
index 71bf8dd..4796233 100644
--- a/openapi/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java
+++ b/openapi/src/test/java/io/sinistral/proteus/openapi/test/controllers/OpenAPITests.java
@@ -1,7 +1,7 @@
/**
*
*/
-package io.sinistral.proteus.swagger.test.controllers;
+package io.sinistral.proteus.openapi.test.controllers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
@@ -9,6 +9,7 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import io.sinistral.proteus.annotations.Blocking;
+import io.sinistral.proteus.openapi.test.models.Pojo;
import io.sinistral.proteus.server.ServerRequest;
import io.sinistral.proteus.server.ServerResponse;
import io.swagger.v3.oas.annotations.Operation;
@@ -16,14 +17,26 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.tags.Tags;
import io.undertow.server.HttpServerExchange;
+import org.javamoney.moneta.Money;
-import javax.ws.rs.*;
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.nio.ByteBuffer;
import java.sql.Timestamp;
import java.time.Instant;
-import java.util.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import static io.sinistral.proteus.server.ServerResponse.response;
@@ -38,7 +51,7 @@
@Produces((MediaType.APPLICATION_JSON))
@Consumes((MediaType.MEDIA_TYPE_WILDCARD))
@Singleton
-public class Tests
+public class OpenAPITests
{
private static final ByteBuffer buffer;
static {
@@ -127,8 +140,27 @@ public ServerResponse> genericSet( ServerRequest request, @QueryParam
{
return response( ids ).applicationJson();
}
-
-
+
+
+ @GET
+ @Path("types/money")
+ @Produces((MediaType.APPLICATION_JSON))
+ @Operation(description = "Money type endpoint" )
+ public ServerResponse getMoney(ServerRequest request ) throws Exception
+ {
+ return response( Money.of(123.23,"USD") ).applicationJson();
+ }
+
+
+ @GET
+ @Path("types/pojo")
+ @Produces((MediaType.APPLICATION_JSON))
+ @Operation(description = "Pojo type endpoint" )
+ public ServerResponse getPojo(ServerRequest request ) throws Exception
+ {
+ return response( new Pojo(100L,"John Doe") ).applicationJson();
+ }
+
@POST
@Path("generic/set/bean")
@Produces((MediaType.APPLICATION_JSON))
diff --git a/openapi/src/test/java/io/sinistral/proteus/openapi/test/converters/MoneyModelConverter.java b/openapi/src/test/java/io/sinistral/proteus/openapi/test/converters/MoneyModelConverter.java
new file mode 100644
index 0000000..b4c25fe
--- /dev/null
+++ b/openapi/src/test/java/io/sinistral/proteus/openapi/test/converters/MoneyModelConverter.java
@@ -0,0 +1,151 @@
+package io.sinistral.proteus.openapi.test.converters;
+
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.google.common.collect.ImmutableMap;
+import io.swagger.v3.core.converter.AnnotatedType;
+import io.swagger.v3.core.converter.ModelConverter;
+import io.swagger.v3.core.converter.ModelConverterContext;
+import io.swagger.v3.core.util.Json;
+import io.swagger.v3.oas.models.media.NumberSchema;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.oas.models.media.StringSchema;
+import org.javamoney.moneta.Money;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class MoneyModelConverter implements ModelConverter
+{
+
+ private final Schema schema = new MoneySchema();
+
+ @Override
+ public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator chain) {
+
+ JavaType _type = Json.mapper().constructType(type.getType());
+
+ if(_type != null && (_type.getRawClass().equals(Money.class)))
+ {
+ context.defineModel("Money",schema, type, null);
+
+ return schema;
+ }
+
+ if (type.getType() instanceof Class>) {
+
+ Class> cls = (Class>) type.getType();
+
+ if(cls.isAssignableFrom(Money.class))
+ {
+ context.defineModel("Money",schema, type, null);
+
+ return schema;
+ }
+ }
+ else if(type.getType().getTypeName().equals("[simple type, class org.javamoney.moneta.Money]"))
+ {
+ context.defineModel("Money",schema, type, null);
+
+ return schema;
+ }
+ else if (type.isSchemaProperty()) {
+
+ _type = Json.mapper().constructType(type.getType());
+
+ if (_type != null) {
+ Class> cls = _type.getRawClass();
+ if (Money.class.isAssignableFrom(cls)) {
+
+ context.defineModel("Money",schema, type, null);
+
+ return schema;
+ }
+ }
+ }
+
+ if (chain.hasNext()) {
+ return chain.next().resolve(type, context, chain);
+ }
+
+ return null;
+
+ }
+
+
+ public static class MoneySchema extends Schema
+ {
+ private String _type = "object";
+
+ private String _$ref = null;
+
+ private String _description = "A monetary amount";
+
+ private Map _properties = ImmutableMap.of("amount",new NumberSchema(),"currency",new StringSchema());
+
+ private List _required = Arrays.asList("amount","currency");
+
+ public MoneySchema()
+ {
+ super();
+ super.setName("Money");
+ super.setType("object");
+ super.set$ref(_$ref);
+ super.description(_description);
+ super.properties(_properties);
+ super.required(_required);
+ }
+
+ @Override
+ protected Money cast(Object value)
+ {
+ if (value != null) {
+ try {
+ if (value instanceof Money) {
+ return (Money) value;
+ }
+ } catch (Exception e) {
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean equals(java.lang.Object o)
+ {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ MoneySchema MoneySchema = (MoneySchema) o;
+ return Objects.equals(this._type, MoneySchema._type) &&
+ Objects.equals(this._properties, MoneySchema._properties) &&
+ Objects.equals(this._description, MoneySchema._description) &&
+ super.equals(o);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(_type, _properties, super.hashCode());
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(java.lang.Object o)
+ {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+ }
+}
diff --git a/openapi/src/test/java/io/sinistral/proteus/openapi/test/models/Pojo.java b/openapi/src/test/java/io/sinistral/proteus/openapi/test/models/Pojo.java
new file mode 100644
index 0000000..5d9e8af
--- /dev/null
+++ b/openapi/src/test/java/io/sinistral/proteus/openapi/test/models/Pojo.java
@@ -0,0 +1,40 @@
+package io.sinistral.proteus.openapi.test.models;
+
+public class Pojo
+{
+
+ public Long id;
+
+ public String name;
+
+
+ public Pojo(Long id, String name)
+ {
+ this.id = id;
+ this.name = name;
+ }
+
+ public Pojo()
+ {
+ }
+
+ public Long getId()
+ {
+ return id;
+ }
+
+ public void setId(Long id)
+ {
+ this.id = id;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+}
diff --git a/openapi/src/test/java/io/sinistral/proteus/openapi/test/modules/JacksonModule.java b/openapi/src/test/java/io/sinistral/proteus/openapi/test/modules/JacksonModule.java
new file mode 100644
index 0000000..4bf0036
--- /dev/null
+++ b/openapi/src/test/java/io/sinistral/proteus/openapi/test/modules/JacksonModule.java
@@ -0,0 +1,35 @@
+package io.sinistral.proteus.openapi.test.modules;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
+import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+import org.zalando.jackson.datatype.money.MoneyModule;
+
+@Singleton
+public class JacksonModule extends AbstractModule
+{
+
+ @Override
+ protected void configure()
+ {
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
+ objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
+ objectMapper.configure(DeserializationFeature.EAGER_DESERIALIZER_FETCH,true);
+ objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
+ objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
+
+ objectMapper.registerModule(new MoneyModule())
+ .registerModule(new AfterburnerModule())
+ .registerModule(new Jdk8Module());
+
+ this.bind(ObjectMapper.class).toInstance(objectMapper);
+
+ }
+}
\ No newline at end of file
diff --git a/openapi/src/test/java/io/sinistral/proteus/swagger/test/server/DefaultServer.java b/openapi/src/test/java/io/sinistral/proteus/openapi/test/server/OpenAPIDefaultServer.java
similarity index 84%
rename from openapi/src/test/java/io/sinistral/proteus/swagger/test/server/DefaultServer.java
rename to openapi/src/test/java/io/sinistral/proteus/openapi/test/server/OpenAPIDefaultServer.java
index 5d1ea93..fbb6e1d 100644
--- a/openapi/src/test/java/io/sinistral/proteus/swagger/test/server/DefaultServer.java
+++ b/openapi/src/test/java/io/sinistral/proteus/openapi/test/server/OpenAPIDefaultServer.java
@@ -1,13 +1,13 @@
/**
*
*/
-package io.sinistral.proteus.swagger.test.server;
+package io.sinistral.proteus.openapi.test.server;
import io.restassured.RestAssured;
import io.sinistral.proteus.ProteusApplication;
import io.sinistral.proteus.openapi.services.OpenAPIService;
+import io.sinistral.proteus.openapi.test.controllers.OpenAPITests;
import io.sinistral.proteus.services.AssetsService;
-import io.sinistral.proteus.swagger.test.controllers.Tests;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.RunListener;
@@ -22,9 +22,9 @@
/**
* @author jbauer
*/
-public class DefaultServer extends BlockJUnit4ClassRunner
+public class OpenAPIDefaultServer extends BlockJUnit4ClassRunner
{
- private static Logger log = LoggerFactory.getLogger(DefaultServer.class.getCanonicalName());
+ private static Logger log = LoggerFactory.getLogger(OpenAPIDefaultServer.class.getCanonicalName());
private static boolean first = true;
@@ -32,7 +32,7 @@ public class DefaultServer extends BlockJUnit4ClassRunner
* @param clazz
* @throws InitializationError
*/
- public DefaultServer(Class> clazz) throws InitializationError
+ public OpenAPIDefaultServer(Class> clazz) throws InitializationError
{
super(clazz);
}
@@ -73,9 +73,10 @@ private static void runInternal(final RunNotifier notifier)
final ProteusApplication app = new ProteusApplication();
app.addService(OpenAPIService.class);
+
app.addService(AssetsService.class);
- app.addController(Tests.class);
+ app.addController(OpenAPITests.class);
app.start();
diff --git a/openapi/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java b/openapi/src/test/java/io/sinistral/proteus/openapi/test/server/TestOpenAPIControllerEndpoints.java
similarity index 71%
rename from openapi/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java
rename to openapi/src/test/java/io/sinistral/proteus/openapi/test/server/TestOpenAPIControllerEndpoints.java
index c91cb8d..9961e44 100644
--- a/openapi/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java
+++ b/openapi/src/test/java/io/sinistral/proteus/openapi/test/server/TestOpenAPIControllerEndpoints.java
@@ -1,12 +1,12 @@
/**
*
*/
-package io.sinistral.proteus.swagger.test.server;
+package io.sinistral.proteus.openapi.test.server;
-import static io.restassured.RestAssured.given;
-import static io.restassured.RestAssured.when;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
import java.io.File;
import java.nio.file.Files;
@@ -15,19 +15,14 @@
import java.util.Set;
import java.util.stream.LongStream;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static io.restassured.RestAssured.when;
+import static org.hamcrest.CoreMatchers.equalTo;
-/*
- * import static io.restassured.RestAssured.*; import static io.restassured.matcher.RestAssuredMatchers.*; import static org.hamcrest.Matchers.*;
- */
/**
* @author jbauer
*/
-@RunWith(DefaultServer.class)
-public class TestControllerEndpoints
+@RunWith(OpenAPIDefaultServer.class)
+public class TestOpenAPIControllerEndpoints
{
private File file = null;
@@ -66,6 +61,18 @@ public void testOpenAPIDocs()
when().get("openapi.yaml").then().statusCode(200);
}
+ @Test
+ public void testPojoType()
+ {
+ when().get("tests/types/pojo").then().statusCode(200).body("id", equalTo(100),"name", equalTo("John Doe"));
+ }
+
+ @Test
+ public void testMoneyType()
+ {
+ when().get("tests/types/money").then().statusCode(200).body("amount", equalTo(123.23f),"currency", equalTo("USD"));
+ }
+
@Test
public void testSecurityRequirementEndpoint()
diff --git a/openapi/src/test/resources/application.conf b/openapi/src/test/resources/application.conf
new file mode 100644
index 0000000..098b42b
--- /dev/null
+++ b/openapi/src/test/resources/application.conf
@@ -0,0 +1,89 @@
+
+application {
+
+ env = dev
+
+ version = "1.0"
+
+ name="proteus"
+
+ path = "/v1"
+
+ host = "localhost"
+
+ ports {
+ http = 0
+ # https = 8443
+ }
+
+ charset = UTF-8
+
+ fallbackHandler = "io.sinistral.proteus.server.handlers.ServerFallbackHandler"
+
+ defaultResponseListener = "io.sinistral.proteus.server.handlers.ServerDefaultResponseListener"
+
+ jacksonModule = "io.sinistral.proteus.openapi.test.modules.JacksonModule"
+
+ tmpdir = ${java.io.tmpdir}/${application.name}
+
+ # path to default favicon file
+ favicon = "/io/sinistral/proteus/favicon.ico"
+
+}
+
+api.version="v1"
+
+openapi.converterClasses = ["io.sinistral.proteus.openapi.test.converters.MoneyModelConverter"]
+
+globalHeaders
+{
+# Access-Control-Allow-Origin: "*"
+# Access-Control-Allow-Methods: "*"
+# Access-Control-Allow-Headers: "*"
+ Server = ${application.name}
+}
+
+assets {
+ # the base path assets will be server from
+ path = "/public"
+ # the directory to load the assets from
+ dir = "./assets"
+ cache {
+ # cache timeout for the assets
+ time = 500
+ }
+}
+
+undertow
+{
+ server {
+ enableHttp2 = false
+ alwaysSetDate = true
+ alwaysSetKeepAlive = false
+ recordRequestStartTime = false
+ maxEntitySize = 100M
+ bufferPipelinedData = false
+ }
+
+ socket {
+ backlog = 10000
+ }
+
+
+ ssl {
+ enabled=false
+ keystorePath="development.jks"
+ truststorePath="development.ts"
+ keystorePassword="password"
+ truststorePassword="password"
+ }
+
+ enableHttp2=false
+ # x AvailableProcessors
+ ioThreadsMultiplier = 2
+ workerThreadMultiplier = 8
+ bufferSize = 16K
+ directBuffers = true
+}
+
+
\ No newline at end of file
diff --git a/openapi/src/test/resources/development.jks b/openapi/src/test/resources/development.jks
new file mode 100644
index 0000000..96d0454
Binary files /dev/null and b/openapi/src/test/resources/development.jks differ
diff --git a/openapi/src/test/resources/development.ts b/openapi/src/test/resources/development.ts
new file mode 100644
index 0000000..3dfea06
Binary files /dev/null and b/openapi/src/test/resources/development.ts differ
diff --git a/openapi/src/test/resources/logback-test.xml b/openapi/src/test/resources/logback-test.xml
index aba346f..733e338 100644
--- a/openapi/src/test/resources/logback-test.xml
+++ b/openapi/src/test/resources/logback-test.xml
@@ -16,12 +16,11 @@
-
-
-
+
+ "
diff --git a/pom.xml b/pom.xml
index 0d93f2b..5780273 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,7 +60,7 @@
org.apache.maven.plugins
maven-source-plugin
- 2.2.1
+ 3.0.1
attach-sources
@@ -70,10 +70,14 @@
+
org.apache.maven.plugins
maven-javadoc-plugin
- 2.9.1
+
+
+
+ 3.1.0
attach-javadocs
@@ -81,10 +85,11 @@
jar
- -Xdoclint:none
+ none
+
@@ -130,22 +135,41 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.5.1
+ 3.8.1
1.8
-parameters
+
-
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ enforce-versions
+
+ enforce
+
+
+
+
+ 1.8
+
+
+
+
+
+
maven-surefire-plugin
- 2.20.1
+ 3.0.0-M3
org.apache.maven.surefire
surefire-junit47
- 2.20.1
+ 3.0.0-M3
diff --git a/swagger/pom.xml b/swagger/pom.xml
index ff0a0fa..4406a84 100644
--- a/swagger/pom.xml
+++ b/swagger/pom.xml
@@ -58,7 +58,7 @@
maven-surefire-plugin
- 2.20.1
+ org.apache.maven.plugins
diff --git a/swagger/src/main/java/io/sinistral/proteus/swagger/services/SwaggerService.java b/swagger/src/main/java/io/sinistral/proteus/swagger/services/SwaggerService.java
index 3bf5a2a..c88e217 100644
--- a/swagger/src/main/java/io/sinistral/proteus/swagger/services/SwaggerService.java
+++ b/swagger/src/main/java/io/sinistral/proteus/swagger/services/SwaggerService.java
@@ -187,7 +187,7 @@ public void generateSwaggerSpec() throws Exception
// String name = apiKeyConfig.getString("name");
// String value = apiKeyConfig.getString("value");
//
-// io.swagger.models.auth.In keyLocation = io.swagger.models.auth.In.valueOf(apiKeyConfig.getString("in"));
+// io.swagger.converters.auth.In keyLocation = io.swagger.converters.auth.In.valueOf(apiKeyConfig.getString("in"));
//
// final Predicate predicate;
//
diff --git a/swagger/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java b/swagger/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java
index c83bfff..fd4c29c 100644
--- a/swagger/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java
+++ b/swagger/src/test/java/io/sinistral/proteus/swagger/test/controllers/Tests.java
@@ -15,13 +15,23 @@
import io.swagger.annotations.ApiOperation;
import io.undertow.server.HttpServerExchange;
-import javax.ws.rs.*;
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.nio.ByteBuffer;
import java.sql.Timestamp;
import java.time.Instant;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import static io.sinistral.proteus.server.ServerResponse.response;
diff --git a/swagger/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java b/swagger/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java
index 131200b..178fdc2 100644
--- a/swagger/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java
+++ b/swagger/src/test/java/io/sinistral/proteus/swagger/test/server/TestControllerEndpoints.java
@@ -3,31 +3,26 @@
*/
package io.sinistral.proteus.swagger.test.server;
-import static io.restassured.RestAssured.given;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
+import io.restassured.http.ContentType;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
import java.io.File;
-import java.io.InputStream;
import java.nio.file.Files;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.stream.LongStream;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import io.restassured.http.ContentType;
-import org.slf4j.LoggerFactory;
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.is;
/*
* import static io.restassured.RestAssured.*; import static io.restassured.matcher.RestAssuredMatchers.*; import static org.hamcrest.Matchers.*;
*/
+
/**
* @author jbauer
*/
diff --git a/swagger/src/test/resources/logback-test.xml b/swagger/src/test/resources/logback-test.xml
index aba346f..91e240d 100644
--- a/swagger/src/test/resources/logback-test.xml
+++ b/swagger/src/test/resources/logback-test.xml
@@ -16,11 +16,8 @@
-
-
-