Skip to content

Commit

Permalink
Merge development. Bump version.
Browse files Browse the repository at this point in the history
Missed version in pom.xml.

Remove iml.
  • Loading branch information
noboomu committed Sep 13, 2018
1 parent f70c107 commit 6e4b13e
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 102 deletions.
80 changes: 42 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@

![Alt logo](https://cdn.rawgit.com/noboomu/proteus/master/src/main/resources/io/sinistral/proteus/proteus-logo.svg)

* An extremely lightweight, flexible, and fast [Swagger](http://swagger.io/) first MVC REST framework atop [Undertow](http://undertow.io).
* Inspired by: [Play](http://playframework.com), [Jooby](http://jooby.org), and [light-4j](https://github.com/networknt/light-4j).
* Verifiably [FAST AF](https://www.techempower.com/benchmarks/).
* [Latest benchmarks](https://www.techempower.com/benchmarks/) show Proteus at least 6x faster than Spring and Play across the board.
An extremely lightweight, flexible, and high performance [Undertow](http://undertow.io) based Java framework for developing and running microservices.

## Motivation
JAX-RS compliant.

Verifiably [FAST](https://www.techempower.com/benchmarks/): [The latest benchmarks](https://www.techempower.com/benchmarks/) show Proteus ranks faster than 99% of other Java frameworks.

Inspired by [Play](http://playframework.com), [Jooby](http://jooby.org), and [light-4j](https://github.com/networknt/light-4j).



## Getting Started
COMING SOON

* Several years of working with the [Play](http://playframework.com) framework convinced us there had to be a better way.
* We faced a Goldilocks Crisis with the existing alternatives: [Jooby](http://jooby.org) did too much, [light-4j](https://github.com/networknt/light-4j) didn't do quite enough.
* We needed a framework that enabled us to write clean MVC REST controllers that created Swagger docs we could plug directly into the existing [codegen](https://github.com/swagger-api/swagger-codegen) solutions.
* We needed a framework with minimal overhead and performance at or near that of raw [Undertow](http://undertow.io).

## Under the Hood

Proteus takes your MVC controller classes and methods decorated with Swagger / JAX-RS annotations and generates native Undertow handler classes at runtime.

You can review the generated code by setting the ```io.sinistral.proteus.server``` log level to `DEBUG`.

## Setup

By default, the configuration is loaded into a `com.typesafe.config.Config` from a file at `conf/application.conf`.

Expand All @@ -38,7 +37,7 @@ Out of the box you get a [Swagger UI](https://github.com/swagger-api/swagger-ui)
> A `Module` implements `com.google.inject.Module`.
##### Example Application Class
#### Example Application Class

```java
public class ExampleApplication extends ProteusApplication
Expand All @@ -53,7 +52,7 @@ public class ExampleApplication extends ProteusApplication
}
}
```
##### Example Controller Class
#### Example Controller Class
```java
import java.nio.ByteBuffer;
import javax.ws.rs.*;
Expand Down Expand Up @@ -104,8 +103,8 @@ public class Examples

# Controllers

### Controller Class Annotations
---
### Supported Controller Annotations

Controller classes respect standard Swagger / JAX-RS annotations:
```java
@Api(tags="benchmarks")
Expand All @@ -114,9 +113,9 @@ Controller classes respect standard Swagger / JAX-RS annotations:
@Consumes((MediaType.MEDIA_TYPE_WILDCARD))
```

### Controller Method Annotations
---
Controller class methods also respect standard Swagger / JAX-RS annotations:
### Supported Method Annotations

Controller class methods respect standard Swagger / JAX-RS annotations:
```java
@GET
@Path("/plaintext")
Expand All @@ -129,17 +128,16 @@ public void plaintext(HttpServerExchange exchange)
```
In addition, the `io.sinistral.proteus.annotations.Blocking` annotation can be used to explicitly mark a method for blocked request handling.

### Return Types
---
##### HttpServerExchange = Total Control
## Return Types

##### Performance
For total control and maximum performance the raw `HttpServerExchange` can be passed to the controller method.

Methods that take an `HttpServerExchange` as an argument should __not__ return a value.

In this case the method takes on __full responsibility__ for completing the exchange.

##### ServerResponse = Convenience
##### Convenience
The static method ```io.sinistral.proteus.server.ServerResponse.response``` helps create ```ServerResponse<T>``` instances that are the preferred return type for controller methods.

If the response object's `contentType` is not explicitly set, the `@Produces` annotation is used in combination with the `Accept` headers to determine the `Content-Type`.
Expand Down Expand Up @@ -201,15 +199,15 @@ public void handleRequest(final io.undertow.server.HttpServerExchange exchange)
}
```

### Arguments
---
A ```io.sinistral.proteus.server.ServerRequest``` can be added as an endpoint argument if the user wishes to access request properties that are not included in the argument list.
## Controller Parameters

A ```io.sinistral.proteus.server.ServerRequest``` can be added as an endpoint parameter if the user wishes to access request properties that are not included in the parameter list.

Proteus is capable of parsing most types of endpoint arguments automatically so long as the type has a ```fromString```, ```valueOf```, or can be deserialized from JSON.
Proteus is capable of parsing most types of endpoint parameters automatically so long as the type has a ```fromString```, ```valueOf```, or can be deserialized from JSON.

Multipart/Form file uploads can be passed to the endpoint methods as a ```java.io.File```, a ```java.nio.Files.Path```, or a ```java.nio.ByteBuffer```.

Optional arguments are also supported, here is a more complex endpoint demonstrating several argument types:
Optional parameters are also supported, here is a more complex endpoint demonstrating several parameter types:
```java
@GET
@Path("/response/parameters/complex/{pathLong}")
Expand Down Expand Up @@ -248,11 +246,11 @@ public ServerResponse<Map<String,Object>> complexParameters(
return response(responseMap).applicationJson();
}
```
### Services
---
# Services

Proteus comes with two standard services that extend the ```io.sinistral.proteus.services.BaseService``` class.
#### AssetsService
---
## AssetsService

The AssetsService mounts an asset directory at a given path and is configured in your ```application.conf``` file.

The default configuration:
Expand All @@ -268,8 +266,8 @@ assets {
}
}
```
#### SwaggerService
---
## SwaggerService

The SwaggerService generates a swagger-spec file from your endpoints and serves a swagger-ui and spec.

The service is configured in your ```application.conf``` file.
Expand Down Expand Up @@ -302,17 +300,23 @@ swagger {
schemes = ["http"]
}
```
---
## Getting Started
COMING SOON


---

## Examples
COMING SOON

---


## Motivation

* Several years of working with the [Play](http://playframework.com) framework convinced us there had to be a better way.
* We faced a Goldilocks Crisis with the existing alternatives: [Jooby](http://jooby.org) did too much, [light-4j](https://github.com/networknt/light-4j) didn't do quite enough.
* We needed a framework that enabled us to write clean MVC REST controllers that created Swagger docs we could plug directly into the existing [codegen](https://github.com/swagger-api/swagger-codegen) solutions.
* We needed a framework with minimal overhead and performance at or near that of raw [Undertow](http://undertow.io).


### Dependencies

* [JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.sinistral</groupId>
<artifactId>proteus-core</artifactId>
<version>0.3.1-SNAPSHOT</version>
<version>0.3.2</version>
<name>proteus core</name>
<description>Proteus is an extremely light, fast, and flexible Java REST API framework built atop Undertow.</description>
<url>http://github.com/noboomu/proteus</url>
Expand Down Expand Up @@ -34,7 +34,7 @@
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.maven-shade-plugin>3.0.0</version.maven-shade-plugin>
<version.undertow>1.4.13.Final</version.undertow>
<version.undertow>2.0.13.Final</version.undertow>
<version.jackson>2.9.6</version.jackson>
</properties>

Expand Down
19 changes: 0 additions & 19 deletions proteus.iml

This file was deleted.

23 changes: 4 additions & 19 deletions src/main/java/io/sinistral/proteus/ProteusApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,21 +129,6 @@ public void start()
log.info("Configuring modules: " + registeredModules);

Set<Module> modules = registeredModules.stream().map(mc -> injector.getInstance(mc)).collect(Collectors.toSet());

//boolean needsMappingModule = true;

// for(Module m : modules)
// {
// if(m.getClass().getSuperclass().equals(MappingModule.class))
// {
// needsMappingModule = false;
// }
// }
//
// if(needsMappingModule)
// {
// modules.add(injector.getInstance(MappingModule.class));
// }

injector = injector.createChildInjector(modules);

Expand Down Expand Up @@ -286,11 +271,11 @@ public void buildServer()
Undertow.Builder undertowBuilder = Undertow.builder().addHttpListener(httpPort, config.getString("application.host"))
.setBufferSize(16 * 1024)
.setIoThreads(Runtime.getRuntime().availableProcessors() * 2)
.setServerOption(UndertowOptions.ENABLE_HTTP2, config.getBoolean("undertow.enableHttp2"))
.setServerOption(UndertowOptions.ALWAYS_SET_DATE, true)
.setServerOption(UndertowOptions.ENABLE_HTTP2, config.getBoolean("undertow.server.enableHttp2"))
.setServerOption(UndertowOptions.ALWAYS_SET_DATE, config.getBoolean("undertow.server.alwaysSetDate"))
.setSocketOption(org.xnio.Options.BACKLOG, config.getInt("undertow.socket.backlog"))
.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, false)
.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, false)
.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, config.getBoolean("undertow.server.alwaysSetKeepAlive"))
.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, config.getBoolean("undertow.server.recordRequestStartTime"))
.setServerOption(UndertowOptions.MAX_ENTITY_SIZE, config.getBytes("undertow.server.maxEntitySize"))
.setWorkerThreads(config.getInt("undertow.workerThreads"))
.setHandler(handler);
Expand Down
30 changes: 19 additions & 11 deletions src/main/java/io/sinistral/proteus/modules/ConfigModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,24 @@ public ConfigModule(URL configURL)

@Override
protected void configure()
{
if(configFile == null && configURL == null)
{
this.bindConfig(ConfigFactory.defaultApplication());
}
else if(configURL != null)
{
this.bindConfig( ConfigFactory.load(ConfigFactory.parseURL(configURL)));
{
Config config = ConfigFactory.defaultApplication();

Config referenceConfig = ConfigFactory.load(ConfigFactory.defaultReference());

config = ConfigFactory.load(config).withFallback(referenceConfig);

if(configURL != null)
{
config = ConfigFactory.load(ConfigFactory.parseURL(configURL)).withFallback(config);
}
else if(configFile != null)
{
this.bindConfig(fileConfig(configFile));
{

config = fileConfig(configFile).withFallback(config);
}

this.bindConfig(config);

install(new ApplicationModule(this.config));
}
Expand All @@ -84,6 +89,7 @@ else if(configFile != null)
@SuppressWarnings("unchecked")
private void bindConfig(final Config config)
{

traverse(this.binder(), "", config.root());

for (Entry<String, ConfigValue> entry : config.entrySet())
Expand All @@ -102,6 +108,7 @@ private void bindConfig(final Config config)

Key<Object> key = (Key<Object>) Key.get(listType, Names.named(name));


this.binder().bind(key).toInstance(values);
}
else
Expand All @@ -126,14 +133,15 @@ private static void traverse(final Binder binder, final String nextPath, final C
{
rootConfig.forEach((key, value) ->
{

if (value instanceof ConfigObject)
{
ConfigObject child = (ConfigObject) value;

String path = nextPath + key;

Named named = Names.named(path);

binder.bind(Config.class).annotatedWith(named).toInstance(child.toConfig());

traverse(binder, path + ".", child);
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/io/sinistral/proteus/server/Extractors.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class Extractors
@Inject
public static ObjectMapper OBJECT_MAPPER;

public static Function<byte[],JsonNode> parseJson = (bytes) -> {
public static JsonNode parseJson(byte[] bytes) {
try
{
return OBJECT_MAPPER.readTree(bytes);
Expand All @@ -66,7 +66,7 @@ public static <T> java.util.Optional<T> extractWithFunction(final HttpServerExch

public static java.util.Optional<JsonNode> jsonNode(final HttpServerExchange exchange)
{
return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY)).map(ByteBuffer::array).map(parseJson);
return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY)).map(ByteBuffer::array).map( o -> parseJson(o));
}

public static <T> java.util.Optional<T> model(final HttpServerExchange exchange, final TypeReference<T> type )
Expand Down Expand Up @@ -175,7 +175,7 @@ public static java.util.Optional<ZonedDateTime> zonedDateTime(final HttpServerEx

public static java.util.Optional<JsonNode> any(final HttpServerExchange exchange )
{
return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY)).map( b -> parseJson.apply(b.array()));
return java.util.Optional.ofNullable(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY)).map( b -> parseJson(b.array()));
}

public static java.util.Optional<Integer> integerValue(final HttpServerExchange exchange, final String name)
Expand Down Expand Up @@ -346,7 +346,7 @@ public static JsonNode any(final HttpServerExchange exchange )
{
try
{
return parseJson.apply( exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY).array() );
return parseJson( exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY).array() );
} catch (Exception e)
{
log.warn(e.getMessage(),e);
Expand All @@ -356,7 +356,7 @@ public static JsonNode any(final HttpServerExchange exchange )

public static JsonNode jsonNode(final HttpServerExchange exchange )
{
return parseJson.apply(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY).array());
return parseJson(exchange.getAttachment(ServerRequest.BYTE_BUFFER_KEY).array());
}

public static Path filePath(final HttpServerExchange exchange, final String name) throws java.lang.IllegalArgumentException
Expand Down
Loading

0 comments on commit 6e4b13e

Please sign in to comment.