Skip to content

Commit

Permalink
Merge pull request quarkusio#5096 from patriot1burke/remote-address-bug
Browse files Browse the repository at this point in the history
issue quarkusio#5095: Resteasy Standalone + Virtual HTTP (azure/aws) NPE
  • Loading branch information
stuartwdouglas authored Nov 1, 2019
2 parents 04ec03c + 086a4be commit 9be8665
Show file tree
Hide file tree
Showing 17 changed files with 749 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.amazon.lambda.http;

import java.io.ByteArrayOutputStream;
import java.net.InetSocketAddress;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
Expand Down Expand Up @@ -37,7 +38,14 @@ public class LambdaHttpHandler implements RequestHandler<AwsProxyRequest, AwsPro
}

public AwsProxyResponse handleRequest(AwsProxyRequest request, Context context) {
VirtualClientConnection connection = VirtualClientConnection.connect(VertxHttpRecorder.VIRTUAL_HTTP);
InetSocketAddress clientAddress = null;
if (request.getRequestContext() != null && request.getRequestContext().getIdentity() != null) {
if (request.getRequestContext().getIdentity().getSourceIp() != null) {
clientAddress = new InetSocketAddress(request.getRequestContext().getIdentity().getSourceIp(), 443);
}
}

VirtualClientConnection connection = VirtualClientConnection.connect(VertxHttpRecorder.VIRTUAL_HTTP, clientAddress);
try {
return nettyDispatch(connection, request);
} catch (Exception e) {
Expand All @@ -48,9 +56,7 @@ public AwsProxyResponse handleRequest(AwsProxyRequest request, Context context)

}

private AwsProxyResponse nettyDispatch(VirtualClientConnection connection,
AwsProxyRequest request)
throws Exception {
private AwsProxyResponse nettyDispatch(VirtualClientConnection connection, AwsProxyRequest request) throws Exception {
String path = request.getPath();
if (request.getMultiValueQueryStringParameters() != null && !request.getMultiValueQueryStringParameters().isEmpty()) {
StringBuilder sb = new StringBuilder(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void run() {

protected volatile State state;
protected volatile VirtualAddress localAddress;
protected volatile VirtualAddress remoteAddress;
protected volatile SocketAddress remoteAddress;
protected volatile ChannelPromise connectPromise;
protected volatile boolean readInProgress;
protected volatile boolean writeInProgress;
Expand Down Expand Up @@ -123,8 +123,8 @@ public VirtualAddress localAddress() {
}

@Override
public VirtualAddress remoteAddress() {
return (VirtualAddress) super.remoteAddress();
public SocketAddress remoteAddress() {
return remoteAddress;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.netty.runtime.virtual;

import java.net.SocketAddress;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

Expand All @@ -14,17 +15,17 @@
*
*/
public class VirtualClientConnection {
protected VirtualAddress address;
protected SocketAddress clientAddress;
protected BlockingQueue<Object> queue = new LinkedBlockingQueue<>();
protected boolean connected = true;
protected VirtualChannel peer;

VirtualClientConnection(VirtualAddress address) {
this.address = address;
VirtualClientConnection(SocketAddress clientAddress) {
this.clientAddress = clientAddress;
}

public VirtualAddress clientAddress() {
return address;
public SocketAddress clientAddress() {
return clientAddress;
}

/**
Expand Down Expand Up @@ -104,6 +105,21 @@ public void run() {
* @return
*/
public static VirtualClientConnection connect(final VirtualAddress remoteAddress) {
return connect(remoteAddress, remoteAddress);

}

/**
* Establish a virtual intra-JVM connection
*
* @param remoteAddress
* @param clientAddress
* @return
*/
public static VirtualClientConnection connect(VirtualAddress remoteAddress, SocketAddress clientAddress) {
if (clientAddress == null)
clientAddress = remoteAddress;

Channel boundChannel = VirtualChannelRegistry.get(remoteAddress);
if (boundChannel == null) {
throw new RuntimeException("No virtual channel available");
Expand All @@ -113,9 +129,8 @@ public static VirtualClientConnection connect(final VirtualAddress remoteAddress
}

VirtualServerChannel serverChannel = (VirtualServerChannel) boundChannel;
VirtualClientConnection conn = new VirtualClientConnection(remoteAddress);
VirtualClientConnection conn = new VirtualClientConnection(clientAddress);
conn.peer = serverChannel.serve(conn);
return conn;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.net.SocketAddress;
import io.vertx.ext.web.RoutingContext;

/**
Expand Down Expand Up @@ -95,8 +96,12 @@ private void dispatch(RoutingContext routingContext, InputStream is, VertxOutput
HttpServerResponse response = request.response();
VertxHttpResponse vertxResponse = new VertxHttpResponse(request, dispatcher.getProviderFactory(),
request.method(), allocator, output);
// client address may not be available with VirtualHttp
SocketAddress socketAddress = request.remoteAddress();
String host = socketAddress != null ? socketAddress.host() : null;

VertxHttpRequest vertxRequest = new VertxHttpRequest(ctx, headers, uriInfo, request.rawMethod(),
request.remoteAddress().host(), dispatcher.getDispatcher(), vertxResponse, false);
host, dispatcher.getDispatcher(), vertxResponse, false);
vertxRequest.setInputStream(is);
try {
ResteasyContext.pushContext(SecurityContext.class, new QuarkusResteasySecurityContext(request));
Expand Down
116 changes: 116 additions & 0 deletions integration-tests/amazon-lambda-http-resteasy/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-integration-tests-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-integration-test-amazon-lambda-http-resteasy</artifactId>
<name>Quarkus - Integration Tests - Amazon Lambda HTTP Resteasy</name>
<description>Test with Resteasy Standalone and Amazon Lambda HTTP</description>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-amazon-lambda-http</artifactId>
</dependency>

<!-- test dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-amazon-lambda</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<native.image.path>
${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<id>native-image</id>
<goals>
<goal>native-image</goal>
</goals>
<configuration>
<reportErrorsAtRuntime>false</reportErrorsAtRuntime>
<cleanupServer>true</cleanupServer>
<enableHttpUrlHandler>true</enableHttpUrlHandler>
<graalvmHome>${graalvmHome}</graalvmHome>
<enableJni>false</enableJni>
<debugBuildProcess>false</debugBuildProcess>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.quarkus.it.amazon.lambda;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}

@POST
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.TEXT_PLAIN)
public String hello(String name) {
return "hello " + name;
}

@POST
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
public byte[] hello(byte[] bytes) {
if (bytes[0] != 0 || bytes[1] != 1 || bytes[2] != 2 || bytes[3] != 3) {
throw new RuntimeException("bad input");
}
byte[] rtn = { 4, 5, 6 };
return rtn;
}

@POST
@Path("empty")
public void empty() {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
quarkus.lambda.enable-polling-jvm-mode=true
quarkus.http.virtual=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.quarkus.it.amazon.lambda;

import io.quarkus.test.junit.NativeImageTest;

@NativeImageTest
public class AmazonLambdaSimpleIT extends AmazonLambdaSimpleTestCase {
}
Loading

0 comments on commit 9be8665

Please sign in to comment.