Skip to content

Commit

Permalink
[relates #3087] Migrate netty-http module into netty http tests
Browse files Browse the repository at this point in the history
  • Loading branch information
avano authored and ppalaga committed Jul 13, 2023
1 parent 9f6b5cb commit ff464b2
Show file tree
Hide file tree
Showing 25 changed files with 411 additions and 802 deletions.
12 changes: 12 additions & 0 deletions integration-tests/http/netty-http/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-direct</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-rest</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-jaxb</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,29 @@

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import io.netty.handler.codec.http.FullHttpResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.camel.Exchange;
import org.apache.camel.component.netty.http.NettyHttpMessage;
import org.apache.camel.quarkus.component.http.common.AbstractHttpResource;
import org.apache.camel.util.IOHelper;

Expand Down Expand Up @@ -119,4 +128,107 @@ public String nettyHttpSerializedException(@QueryParam("test-port") int port) {
.send();
return exchange.getException().getClass().getName();
}

@GET
@Path("/getRequest/{method}/{hName}/{hValue}/{body}")
public String getRequest(@PathParam("method") String method, @PathParam("hName") String headerName,
@PathParam("hValue") String headerValue,
@PathParam("body") String body,
@QueryParam("test-port") int port) {
return producerTemplate.toF("netty-http:http://localhost:%d/request", port)
.withHeaders(Map.of(Exchange.HTTP_METHOD, method, headerName, headerValue))
.withBody(body)
.request(String.class);
}

@GET
@Path("/getResponse/{message}")
public String getResponse(@PathParam("message") String message, @QueryParam("test-port") int port) {
Exchange exchange = producerTemplate.toF("netty-http:http://localhost:%d/response", port)
.withBody(message)
.send();
FullHttpResponse response = exchange.getIn().getBody(NettyHttpMessage.class).getHttpResponse();
String received = exchange.getIn().getBody(String.class);
return received + ": " + response.status().reasonPhrase() + " " + response.status().code();
}

@GET
@Path("/wildcard/{path}")
public String wildcard(@PathParam("path") String path, @QueryParam("test-port") int port) {
return producerTemplate.toF("netty-http:http://localhost:%d/%s", port, path)
.withHeader(Exchange.HTTP_METHOD, "GET")
.request(String.class);
}

@GET
@Path("/consumer-proxy")
public String proxy(@QueryParam("test-port") int port, @QueryParam("proxy-port") int proxyPort) {
final Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", proxyPort));
final String url = "http://localhost:" + port + "/proxy";

try {
final HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
return new String(connection.getInputStream().readAllBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@GET
@Path("/auth/{path}/{user}/{password}")
public Response auth(@QueryParam("test-port") int port, @PathParam("path") String path, @PathParam("user") String user,
@PathParam("password") String password) {
final Exchange exchange = producerTemplate.toF("netty-http:http://localhost:%d/%s", port, path)
.withHeaders(getAuthHeaders(user, password))
.send();

return Response.status(exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class)).build();
}

@GET
@Path("/rest/{method}")
public String rest(@QueryParam("rest-port") int port, @PathParam("method") String method) {
return producerTemplate.toF("netty-http:http://localhost:%d/rest", port)
.withHeader(Exchange.HTTP_METHOD, method)
.request(String.class);
}

@GET
@Path("/rest/pojo/{type}")
public String restPojo(@QueryParam("rest-port") int port, @PathParam("type") String type) {
final String body;
final String contentType;
if ("json".equals(type)) {
body = "{\"firstName\":\"John\", \"lastName\":\"Doe\"}";
contentType = "application/json";
} else {
body = "<user firstName=\"John\" lastName=\"Doe\"/>";
contentType = "text/xml";
}
return producerTemplate.toF("netty-http:http://localhost:%d/rest/%s", port, type)
.withBody(body)
.withHeaders(Map.of(Exchange.HTTP_METHOD, "POST", "Content-Type", contentType))
.request(String.class);
}

@GET
@Path("/jaas/{user}/{password}")
public Response auth(@QueryParam("test-port") int port, @PathParam("user") String user,
@PathParam("password") String password) {
final Exchange exchange = producerTemplate
.toF("netty-http:http://localhost:%d/jaas", port)
.withHeaders(getAuthHeaders(user, password))
.send();

return Response.status(exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class)).build();
}

private Map<String, Object> getAuthHeaders(String user, String password) {
Map<String, Object> headers = new HashMap<>();
headers.put(Exchange.HTTP_METHOD, "GET");
if (!"null".equals(user)) {
headers.put("Authorization", "Basic " + Base64.getEncoder().encodeToString((user + ":" + password).getBytes()));
}
return headers;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,95 @@
*/
package org.apache.camel.quarkus.component.http.netty;

import java.nio.charset.Charset;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import io.netty.handler.codec.http.FullHttpRequest;
import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.inject.Named;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.netty.http.JAASSecurityAuthenticator;
import org.apache.camel.component.netty.http.NettyHttpComponent;
import org.apache.camel.component.netty.http.NettyHttpConfiguration;
import org.apache.camel.component.netty.http.NettyHttpMessage;
import org.apache.camel.component.netty.http.NettyHttpSecurityConfiguration;
import org.apache.camel.component.netty.http.SecurityConstraintMapping;
import org.apache.camel.component.rest.RestConstants;
import org.apache.camel.model.rest.RestBindingMode;
import org.apache.camel.quarkus.component.http.netty.auth.TestAuthenticator;
import org.apache.camel.quarkus.component.http.netty.pojo.UserPojo;
import org.eclipse.microprofile.config.ConfigProvider;

@RegisterForReflection(targets = IllegalStateException.class, serialization = true)
public class NettyHttpRoutes extends RouteBuilder {
@Named("jaasConfig")
NettyHttpSecurityConfiguration jaasConfig() {
final NettyHttpSecurityConfiguration config = new NettyHttpSecurityConfiguration();
config.setRealm("Quarkus");
JAASSecurityAuthenticator jaas = new JAASSecurityAuthenticator();
jaas.setName("Quarkus");
config.setSecurityAuthenticator(jaas);
return config;
}

@Named("securityConfig")
NettyHttpSecurityConfiguration securityConfiguration() {
final NettyHttpSecurityConfiguration config = new NettyHttpSecurityConfiguration();
config.setRealm("Quarkus");
config.setSecurityAuthenticator(new TestAuthenticator());
return config;
}

// Each ACL configuration is using a separate route/endpoint, so all of them are using /* mapping
@Named("acladmin")
NettyHttpSecurityConfiguration aclAdmin() {
final NettyHttpSecurityConfiguration config = securityConfiguration();
SecurityConstraintMapping securityConstraintMapping = new SecurityConstraintMapping();
securityConstraintMapping.addInclusion("/*", "admin");
config.setSecurityConstraint(securityConstraintMapping);
return config;
}

@Named("aclguest")
NettyHttpSecurityConfiguration aclGuest() {
final NettyHttpSecurityConfiguration config = securityConfiguration();
SecurityConstraintMapping securityConstraintMapping = new SecurityConstraintMapping();
securityConstraintMapping.addInclusion("/*", "admin,guest");
config.setSecurityConstraint(securityConstraintMapping);
return config;
}

@Named("aclpublic")
NettyHttpSecurityConfiguration aclPublic() {
final NettyHttpSecurityConfiguration config = securityConfiguration();
SecurityConstraintMapping securityConstraintMapping = new SecurityConstraintMapping();
securityConstraintMapping.addExclusion("/*");
config.setSecurityConstraint(securityConstraintMapping);
return config;
}

@Named("aclwildcard")
NettyHttpSecurityConfiguration aclWildcard() {
final NettyHttpSecurityConfiguration config = securityConfiguration();
SecurityConstraintMapping securityConstraintMapping = new SecurityConstraintMapping();
securityConstraintMapping.addInclusion("/*", "*");
config.setSecurityConstraint(securityConstraintMapping);
return config;
}

@Named("netty-http")
NettyHttpComponent component() {
NettyHttpComponent component = new NettyHttpComponent();
NettyHttpConfiguration config = new NettyHttpConfiguration();
// This helps to stabilize the tests when running on windows, as occasionally when invoking the same route from a parameterized test,
// the next request got the same channel as the previous request that was not fully done yet and it caused the next test to fail.
config.setReuseChannel(true);
component.setConfiguration(config);
return component;
}

@Override
public void configure() throws Exception {
from("direct:https")
Expand All @@ -31,5 +115,53 @@ public void configure() throws Exception {
.throwException(new IllegalStateException("Forced exception"));
from("netty-http:http://0.0.0.0:{{camel.netty-http.compression-test-port}}/compressed?compression=true")
.transform().constant("Netty Hello World Compressed");

restConfiguration().component("netty-http")
.host("localhost").port(ConfigProvider.getConfig().getValue("camel.netty-http.restPort", Integer.class));

from("netty-http:http://localhost:{{camel.netty-http.port}}/request")
.process(ex -> {
final FullHttpRequest req = ex.getIn(NettyHttpMessage.class).getHttpRequest();
ex.getIn().setBody(
String.join(",", req.method().name(), req.content().toString(Charset.defaultCharset()),
StreamSupport.stream(req.headers().spliterator(), false)
.map(h -> h.getKey() + ":" + h.getValue()).collect(Collectors.joining(","))));
});

from("netty-http:http://localhost:{{camel.netty-http.port}}/response").transform().simple("Received message ${body}");

from("netty-http:http://localhost:{{camel.netty-http.port}}/auth?securityConfiguration=#securityConfig").log("success");

from("netty-http:http://localhost:{{camel.netty-http.port}}/jaas?securityConfiguration=#jaasConfig").log("success");

from("netty-http:http://localhost:{{camel.netty-http.port}}/acls/admin?securityConfiguration=#acladmin").log("success");
from("netty-http:http://localhost:{{camel.netty-http.port}}/acls/guest?securityConfiguration=#aclguest").log("success");
from("netty-http:http://localhost:{{camel.netty-http.port}}/acls/wildcard?securityConfiguration=#aclwildcard")
.log("success");
from("netty-http:http://localhost:{{camel.netty-http.port}}/acls/public?securityConfiguration=#aclpublic")
.log("success");

from("netty-http:http://localhost:{{camel.netty-http.port}}/wildcard?matchOnUriPrefix=true").setBody()
.constant("wildcard matched");

from("netty-http:proxy://localhost:{{camel.netty-http.proxyPort}}?reuseChannel=false")
.toD("netty-http:http://${headers." + Exchange.HTTP_HOST + "}:${headers." + Exchange.HTTP_PORT + "}/${headers."
+ Exchange.HTTP_PATH + "}");
from("netty-http:http://localhost:{{camel.netty-http.port}}/proxy").setBody().constant("proxy");

rest("/rest")
.get("/").to("direct:printMethod")
.post("/").to("direct:printMethod")
.put("/").to("direct:printMethod")
.post("/json").bindingMode(RestBindingMode.json).consumes("application/json").type(UserPojo.class)
.to("direct:printBody")
.post("/xml").bindingMode(RestBindingMode.xml).consumes("application/xml").type(UserPojo.class)
.to("direct:printBody");

from("direct:printMethod").setBody().header(RestConstants.HTTP_METHOD);
from("direct:printBody").process(e -> {
e.getIn().setHeader(Exchange.CONTENT_TYPE, "text/plain");
e.getIn().setBody(e.getIn().getBody(UserPojo.class).toString());
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.quarkus.component.netty.http.auth;
package org.apache.camel.quarkus.component.http.netty.auth;

import java.util.Map;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.quarkus.component.netty.http.auth;
package org.apache.camel.quarkus.component.http.netty.auth;

import java.security.Principal;
import java.util.Arrays;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.quarkus.component.netty.http.auth;
package org.apache.camel.quarkus.component.http.netty.auth;

import java.security.Principal;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.quarkus.component.netty.http.pojo;
package org.apache.camel.quarkus.component.http.netty.pojo;

import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.xml.bind.annotation.XmlAccessType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.quarkus.component.netty.http;
package org.apache.camel.quarkus.component.http.netty.it;

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import org.eclipse.microprofile.config.ConfigProvider;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

Expand All @@ -32,8 +33,10 @@ public class NettyHttpJaasTest {
})
public void testJaas(String user, String password, int responseCode) {
RestAssured
.given()
.queryParam("test-port", ConfigProvider.getConfig().getValue("camel.netty-http.port", Integer.class))
.when()
.get("/netty/http/jaas/{user}/{password}", user, password)
.get("/test/client/netty-http/jaas/{user}/{password}", user, password)
.then()
.statusCode(responseCode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.quarkus.component.netty.http;
package org.apache.camel.quarkus.component.http.netty.it;

import java.io.IOException;
import java.io.InputStream;
Expand Down
Loading

0 comments on commit ff464b2

Please sign in to comment.