From 594cf0af5687c51b1ad39e3f6cc1c690697c545a Mon Sep 17 00:00:00 2001 From: "Edward M. Kagan" Date: Tue, 2 Nov 2021 18:49:18 +0300 Subject: [PATCH] Initial JAX-RS test facilities --- .gitignore | 5 ++ modules/rawnetty/pom.xml | 51 +++++++++++++++++ .../java/twopm/tech/bench/jaxrs/Bench.java | 45 +++++++++++++++ .../tech/bench/jaxrs/HelloWorldHandler.java | 55 +++++++++++++++++++ pom.xml | 19 +++++++ workspace.code-workspace | 21 +++++++ 6 files changed, 196 insertions(+) create mode 100644 .gitignore create mode 100644 modules/rawnetty/pom.xml create mode 100644 modules/rawnetty/src/main/java/twopm/tech/bench/jaxrs/Bench.java create mode 100644 modules/rawnetty/src/main/java/twopm/tech/bench/jaxrs/HelloWorldHandler.java create mode 100644 pom.xml create mode 100644 workspace.code-workspace diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..320e75b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.project +dependency-reduced-pom.xml +.classpath +.settings +target \ No newline at end of file diff --git a/modules/rawnetty/pom.xml b/modules/rawnetty/pom.xml new file mode 100644 index 0000000..6b8a836 --- /dev/null +++ b/modules/rawnetty/pom.xml @@ -0,0 +1,51 @@ + + + + twopm.tech + jax-rs-bench + 1.0-SNAPSHOT + ../../pom.xml + + 4.0.0 + rawnetty + + com.colobu.rest.nativenetty.Main + + + + io.netty + netty-all + ${netty.version} + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + + ${app.main.class} + ${maven.compile.source} + ${maven.compile.target} + + + + + + + + + + \ No newline at end of file diff --git a/modules/rawnetty/src/main/java/twopm/tech/bench/jaxrs/Bench.java b/modules/rawnetty/src/main/java/twopm/tech/bench/jaxrs/Bench.java new file mode 100644 index 0000000..0076ba7 --- /dev/null +++ b/modules/rawnetty/src/main/java/twopm/tech/bench/jaxrs/Bench.java @@ -0,0 +1,45 @@ +package twopm.tech.bench.jaxrs; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpServerCodec; + +public class Bench { + public static void main(String[] args) throws Exception { + String host = "0.0.0.0"; + int port = 8080; + if (args.length > 0) { + host = args[0]; + } + if (args.length > 1) { + port = Integer.parseInt(args[1]); + } + + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.option(ChannelOption.SO_BACKLOG, 1024); + b.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .childHandler(new ChannelInitializer(){ + + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + p.addLast(new HttpServerCodec()); + p.addLast(new HelloWorldHandler()); + } + }); + + Channel ch = b.bind(host,port).sync().channel(); + ch.closeFuture().sync(); + } finally { + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + } +} diff --git a/modules/rawnetty/src/main/java/twopm/tech/bench/jaxrs/HelloWorldHandler.java b/modules/rawnetty/src/main/java/twopm/tech/bench/jaxrs/HelloWorldHandler.java new file mode 100644 index 0000000..063cb70 --- /dev/null +++ b/modules/rawnetty/src/main/java/twopm/tech/bench/jaxrs/HelloWorldHandler.java @@ -0,0 +1,55 @@ +package twopm.tech.bench.jaxrs; + +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.codec.http.*; +import io.netty.util.AsciiString; +import static io.netty.handler.codec.http.HttpResponseStatus.*; +import static io.netty.handler.codec.http.HttpVersion.*; + + +public class HelloWorldHandler extends ChannelInboundHandlerAdapter { + private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' }; + + private static final AsciiString CONTENT_TYPE = new AsciiString("Content-Type"); + private static final AsciiString CONTENT_LENGTH = new AsciiString("Content-Length"); + private static final AsciiString CONNECTION = new AsciiString("Connection"); + private static final AsciiString KEEP_ALIVE = new AsciiString("keep-alive"); + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) { + ctx.flush(); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + if (msg instanceof HttpRequest) { + HttpRequest req = (HttpRequest) msg; + + if (HttpUtil.is100ContinueExpected(req)) { + ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); + } + boolean keepAlive = HttpUtil.isKeepAlive(req); + FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT)); + if (req.method() == HttpMethod.GET) { + response.headers().set(CONTENT_TYPE, "text/plain"); + response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes()); + } + + if (!keepAlive) { + ctx.write(response).addListener(ChannelFutureListener.CLOSE); + } else { + response.headers().set(CONNECTION, KEEP_ALIVE); + ctx.write(response); + } + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + ctx.close(); + } +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..10a6a24 --- /dev/null +++ b/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + twopm.tech + jax-rs-bench + pom + 1.0-SNAPSHOT + + 4.1.69.Final + + 11 + 11 + 11 + UTF-8 + + + modules/rawnetty + + diff --git a/workspace.code-workspace b/workspace.code-workspace new file mode 100644 index 0000000..6afd800 --- /dev/null +++ b/workspace.code-workspace @@ -0,0 +1,21 @@ +{ + "folders": [ + { + "name": "modules", + "path": "modules" + }, + { + "name": "jax-rs-bench", + "path": ".", + "files.exclude": ["", ""] + } + ], + "settings": { + "java.configuration.updateBuildConfiguration": "automatic", + "java.dependency.packagePresentation": "hierarchical", + "java.dependency.syncWithFolderExplorer": true, + "files.exclude": { + "modules": true + } + } +}