diff --git a/README.md b/README.md index 08ff0cd..cea79e1 100644 --- a/README.md +++ b/README.md @@ -444,9 +444,9 @@ By default, the configuration is loaded into a `com.typesafe.config.Config` from Proteus applications generally have a main method that creates an instance of `io.sinistral.proteus.ProteusApplication`. Prior to calling `start` on the `ProteusApplication` instance: -* Register `Service` classes via `addService` -* Register `Module` classes via `addModule` -* Register classes annotated with `javax.ws.rs.Path` via `addController` +* Register `Service` classes via `registerService` +* Register `Module` classes via `registerModule` +* Register classes annotated with `javax.ws.rs.Path` via `registerController` Out of the box you get a [Swagger UI](https://github.com/swagger-api/swagger-ui) at `/openapi`. diff --git a/pom.xml b/pom.xml index 86a77c5..44892cc 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ Joshua Lee Bauer - josh@sinistral.io + bauer@sinistral.io @@ -35,7 +35,7 @@ UTF-8 3.0.0 2.0.15.Final - 2.9.6 + 2.9.8 2.0.6 1.5.21 @@ -404,23 +404,49 @@ ${openapi.version} - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/io/sinistral/proteus/modules/ApplicationModule.java b/src/main/java/io/sinistral/proteus/modules/ApplicationModule.java index d14fb39..fa0f25c 100644 --- a/src/main/java/io/sinistral/proteus/modules/ApplicationModule.java +++ b/src/main/java/io/sinistral/proteus/modules/ApplicationModule.java @@ -1,7 +1,4 @@ -/** - * - */ package io.sinistral.proteus.modules; import java.util.HashMap; @@ -93,6 +90,7 @@ public void bindMappers() protected void configure() { this.binder().requestInjection(this); + this.bindMappers(); RoutingHandler router = new RoutingHandler(); diff --git a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java index 4e314db..0365dec 100644 --- a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java +++ b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java @@ -3,53 +3,10 @@ */ package io.sinistral.proteus.server.handlers; -import java.io.File; -import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import javax.lang.model.element.Modifier; -import javax.ws.rs.BeanParam; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.Path; -import javax.ws.rs.core.MediaType; - -import org.apache.commons.lang3.StringUtils; -import org.reflections.Reflections; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.fasterxml.jackson.core.type.TypeReference; import com.google.inject.Inject; import com.google.inject.name.Named; -import com.squareup.javapoet.AnnotationSpec; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.FieldSpec; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterSpec; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; -import com.squareup.javapoet.TypeSpec; - +import com.squareup.javapoet.*; import io.sinistral.proteus.annotations.Blocking; import io.sinistral.proteus.annotations.Debug; import io.sinistral.proteus.server.Extractors; @@ -57,7 +14,6 @@ import io.sinistral.proteus.server.ServerResponse; import io.sinistral.proteus.server.endpoints.EndpointInfo; import io.swagger.v3.oas.annotations.security.SecurityRequirement; -import io.swagger.v3.oas.annotations.tags.Tags; import io.undertow.server.HandlerWrapper; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; @@ -67,6 +23,30 @@ import io.undertow.util.Headers; import io.undertow.util.HttpString; import net.openhft.compiler.CompilerUtils; +import org.apache.commons.lang3.StringUtils; +import org.reflections.Reflections; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.lang.model.element.Modifier; +import javax.ws.rs.BeanParam; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; +import java.io.File; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.net.URI; +import java.net.URL; +import java.util.*; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Generates code and compiles a Supplier class @@ -105,9 +85,9 @@ public enum StatementParameterType { @Named("registeredHandlerWrappers") protected Map registeredHandlerWrappers; - protected Map, String> typeLevelHandlerWrapperMap = new LinkedHashMap, String>(); + protected Map, String> typeLevelHandlerWrapperMap = new LinkedHashMap<>(); - protected Map, String> handlerWrapperMap = new LinkedHashMap, String>(); + protected Map, String> handlerWrapperMap = new LinkedHashMap<>(); /** * Create a new {@code HandlerGenerator} instance used to generate a @@ -241,7 +221,7 @@ protected void generateRoutes() { } } - protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class clazz) throws Exception { + protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class clazz) { ClassName httpHandlerClass = ClassName.get("io.undertow.server", "HttpHandler"); String controllerName = clazz.getSimpleName().toLowerCase() + "Controller"; @@ -307,7 +287,7 @@ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class cla t = optionalType; } - } catch (Exception e) { + } catch (Exception ignored) { } @@ -328,9 +308,7 @@ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class cla if (pClazz.isPrimitive()) { return false; } - if (pClazz.isEnum()) { - return false; - } + return !pClazz.isEnum(); } @@ -351,11 +329,9 @@ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class cla if (typeLevelWrapAnnotation.isPresent()) { io.sinistral.proteus.annotations.Chain w = typeLevelWrapAnnotation.get(); - Class wrapperClasses[] = w.value(); - - for (int i = 0; i < wrapperClasses.length; i++) { - Class wrapperClass = wrapperClasses[i]; + Class[] wrapperClasses = w.value(); + for (Class wrapperClass : wrapperClasses) { String wrapperName = generateFieldName(wrapperClass.getCanonicalName()); initBuilder.addStatement("final $T $L = new $T()", wrapperClass, wrapperName, wrapperClass); @@ -368,8 +344,8 @@ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class cla initBuilder.addCode("$L", "\n"); - List consumesContentTypes = new ArrayList<>(); - List producesContentTypes = new ArrayList<>(); + List consumesContentTypes; + List producesContentTypes; /* * Controller Level Authorization @@ -428,7 +404,7 @@ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class cla producesContentTypes = Arrays.stream(producesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList()); - producesContentType = producesContentTypes.stream().collect(Collectors.joining(",")); + producesContentType = String.join(",", producesContentTypes); } } else { @@ -447,17 +423,17 @@ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class cla if (consumesAnnotation.isPresent()) { consumesContentTypes = Arrays.stream(consumesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList()); - consumesContentType = consumesContentTypes.stream().collect(Collectors.joining(",")); + consumesContentType = String.join(",", consumesContentTypes); } } else { consumesContentTypes = Arrays.stream(consumesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList()); - consumesContentType = consumesContentTypes.stream().collect(Collectors.joining(",")); + consumesContentType = String.join(",", consumesContentTypes); } endpointInfo.setControllerName(clazz.getSimpleName()); - String methodPath = null; + String methodPath; try { methodPath = Extractors.pathTemplateFromMethod.apply(m).replaceAll("\\/\\/", "\\/"); @@ -491,7 +467,7 @@ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class cla TypeSpec.Builder handlerClassBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(httpHandlerClass); - /** + /** * @TODO * Rewrite with lambdas or method references. * @@ -908,7 +884,7 @@ protected static ArrayList getClassNamesFromPackage(String packageName) return names; } - protected static Set> getApiClasses(String basePath, Predicate pathPredicate) throws Exception { + protected static Set> getApiClasses(String basePath, Predicate pathPredicate) { Reflections ref = new Reflections(basePath); Stream> stream = ref.getTypesAnnotatedWith(Path.class).stream(); @@ -944,14 +920,12 @@ protected static Type extractErasedType(Type type) { String clearDollarType = erasedType.replaceAll("\\$", "."); try { - Class clazz = Class.forName(clearDollarType); - return clazz; + return Class.forName(clearDollarType); } catch (Exception e1) { try { - Class clazz = Class.forName(erasedType); - return clazz; + return Class.forName(erasedType); } catch (Exception e2) { return type; @@ -1008,7 +982,7 @@ protected static String typeReferenceNameForParameterizedType(Type type) { erasedTypeName = erasedParts[0]; } - typeName = String.format("%s%s%s", Character.toLowerCase(erasedTypeName.charAt(0)), erasedTypeName.substring(1, erasedTypeName.length()), genericTypeName); + typeName = String.format("%s%s%s", Character.toLowerCase(erasedTypeName.charAt(0)), erasedTypeName.substring(1), genericTypeName); return typeName; } @@ -1037,7 +1011,7 @@ protected static String typeReferenceNameForParameterizedType(Type type) { erasedTypeName = erasedParts[0]; } - typeName = String.format("%s%s%s", Character.toLowerCase(erasedTypeName.charAt(0)), erasedTypeName.substring(1, erasedTypeName.length()), genericTypeName); + typeName = String.format("%s%s%s", Character.toLowerCase(erasedTypeName.charAt(0)), erasedTypeName.substring(1), genericTypeName); return typeName; } @@ -1073,9 +1047,9 @@ protected static String generateFieldName(String name) { String part = parts[i]; if (i == 0) { - sb.append(String.format("%s%s", Character.toLowerCase(part.charAt(0)), part.substring(1, part.length()))); + sb.append(String.format("%s%s", Character.toLowerCase(part.charAt(0)), part.substring(1))); } else { - sb.append(String.format("%s%s", Character.toUpperCase(part.charAt(0)), part.substring(1, part.length()))); + sb.append(String.format("%s%s", Character.toUpperCase(part.charAt(0)), part.substring(1))); } } diff --git a/src/main/java/io/sinistral/proteus/server/tools/openapi/Reader.java b/src/main/java/io/sinistral/proteus/server/tools/openapi/Reader.java index bfbf6a8..02ed263 100644 --- a/src/main/java/io/sinistral/proteus/server/tools/openapi/Reader.java +++ b/src/main/java/io/sinistral/proteus/server/tools/openapi/Reader.java @@ -230,12 +230,24 @@ else if (class2.isAssignableFrom(class1)) return openAPI; } + public static OpenAPIConfiguration deepCopy(OpenAPIConfiguration config) { + if (config == null) { + return null; + } + try { + return Json.mapper().readValue(Json.pretty(config), SwaggerConfiguration.class); + } catch (Exception e) { + LOGGER.error("Exception cloning config: " + e.getMessage(), e); + return config; + } + } + @Override public void setConfiguration(OpenAPIConfiguration openApiConfiguration) { if (openApiConfiguration != null) { - this.config = ContextUtils.deepCopy(openApiConfiguration); + this.config = deepCopy(openApiConfiguration); if (openApiConfiguration.getOpenAPI() != null) { this.openAPI = this.config.getOpenAPI(); diff --git a/src/main/java/io/sinistral/proteus/services/BaseService.java b/src/main/java/io/sinistral/proteus/services/BaseService.java index 6fbd4de..6481e94 100644 --- a/src/main/java/io/sinistral/proteus/services/BaseService.java +++ b/src/main/java/io/sinistral/proteus/services/BaseService.java @@ -32,15 +32,17 @@ public BaseService() } /* + * (non-Javadoc) * @see com.google.inject.Module#configure(com.google.inject.Binder) */ - public void configure(Binder binder) - { + @Override + public void configure(Binder binder) { + } /* - * @see com.google.common.util.concurrent.AbstractIdleService#shutDown() - */ + //* @see com.google.common.util.concurrent.AbstractIdleService#shutDown() + */ @Override protected void shutDown() throws Exception { diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf index 2ae43f3..9837ec6 100644 --- a/src/main/resources/reference.conf +++ b/src/main/resources/reference.conf @@ -184,7 +184,7 @@ undertow } # x AvailableProcessors - ioThreadsMultiplier = 2 + ioThreadsMultiplier = 1 workerThreadMultiplier = 8 bufferSize = 16k directBuffers = true