Convert grizzly groovy to java (#12248)
This commit is contained in:
parent
ee30a26796
commit
171e9d170a
|
@ -1,243 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey
|
||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
|
||||
import io.opentelemetry.semconv.HttpAttributes
|
||||
import org.glassfish.grizzly.filterchain.BaseFilter
|
||||
import org.glassfish.grizzly.filterchain.FilterChain
|
||||
import org.glassfish.grizzly.filterchain.FilterChainBuilder
|
||||
import org.glassfish.grizzly.filterchain.FilterChainContext
|
||||
import org.glassfish.grizzly.filterchain.NextAction
|
||||
import org.glassfish.grizzly.filterchain.TransportFilter
|
||||
import org.glassfish.grizzly.http.HttpContent
|
||||
import org.glassfish.grizzly.http.HttpHeader
|
||||
import org.glassfish.grizzly.http.HttpRequestPacket
|
||||
import org.glassfish.grizzly.http.HttpResponsePacket
|
||||
import org.glassfish.grizzly.http.HttpServerFilter
|
||||
import org.glassfish.grizzly.http.server.HttpServer
|
||||
import org.glassfish.grizzly.http.util.Parameters
|
||||
import org.glassfish.grizzly.nio.transport.TCPNIOServerConnection
|
||||
import org.glassfish.grizzly.nio.transport.TCPNIOTransport
|
||||
import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder
|
||||
import org.glassfish.grizzly.utils.DelayedExecutor
|
||||
import org.glassfish.grizzly.utils.IdleTimeoutFilter
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.AUTH_REQUIRED
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.NOT_FOUND
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.PATH_PARAM
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS
|
||||
import static java.lang.String.valueOf
|
||||
import static java.nio.charset.Charset.defaultCharset
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS
|
||||
import static org.glassfish.grizzly.memory.Buffers.wrap
|
||||
|
||||
class GrizzlyFilterchainServerTest extends HttpServerTest<HttpServer> implements AgentTestTrait {
|
||||
|
||||
private TCPNIOTransport transport
|
||||
private TCPNIOServerConnection serverConnection
|
||||
|
||||
@Override
|
||||
HttpServer startServer(int port) {
|
||||
FilterChain filterChain = setUpFilterChain()
|
||||
setUpTransport(filterChain)
|
||||
|
||||
serverConnection = transport.bind("127.0.0.1", port)
|
||||
transport.start()
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
void stopServer(HttpServer httpServer) {
|
||||
transport.shutdownNow()
|
||||
}
|
||||
|
||||
@Override
|
||||
Set<AttributeKey<?>> httpAttributes(ServerEndpoint endpoint) {
|
||||
def attributes = super.httpAttributes(endpoint)
|
||||
attributes.remove(HttpAttributes.HTTP_ROUTE)
|
||||
attributes
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean testException() {
|
||||
// justification: grizzly async closes the channel which
|
||||
// looks like a ConnectException to the client when this happens
|
||||
false
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean testCapturedHttpHeaders() {
|
||||
false
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean verifyServerSpanEndTime() {
|
||||
// server spans are ended inside of the controller spans
|
||||
return false
|
||||
}
|
||||
|
||||
void setUpTransport(FilterChain filterChain) {
|
||||
TCPNIOTransportBuilder transportBuilder = TCPNIOTransportBuilder.newInstance()
|
||||
.setOptimizedForMultiplexing(true)
|
||||
|
||||
transportBuilder.setTcpNoDelay(true)
|
||||
transportBuilder.setKeepAlive(false)
|
||||
transportBuilder.setReuseAddress(true)
|
||||
transportBuilder.setServerConnectionBackLog(50)
|
||||
transportBuilder.setServerSocketSoTimeout(80000)
|
||||
|
||||
transport = transportBuilder.build()
|
||||
transport.setProcessor(filterChain)
|
||||
}
|
||||
|
||||
FilterChain setUpFilterChain() {
|
||||
return FilterChainBuilder.stateless()
|
||||
.add(createTransportFilter())
|
||||
.add(createIdleTimeoutFilter())
|
||||
.add(new HttpServerFilter())
|
||||
.add(new LastFilter())
|
||||
.build()
|
||||
}
|
||||
|
||||
TransportFilter createTransportFilter() {
|
||||
return new TransportFilter()
|
||||
}
|
||||
|
||||
IdleTimeoutFilter createIdleTimeoutFilter() {
|
||||
return new IdleTimeoutFilter(new DelayedExecutor(Executors.newCachedThreadPool()), 80000, MILLISECONDS)
|
||||
}
|
||||
|
||||
static class LastFilter extends BaseFilter {
|
||||
|
||||
@Override
|
||||
NextAction handleRead(final FilterChainContext ctx) throws IOException {
|
||||
if (ctx.getMessage() instanceof HttpContent) {
|
||||
HttpContent httpContent = ctx.getMessage()
|
||||
HttpHeader httpHeader = httpContent.getHttpHeader()
|
||||
if (httpHeader instanceof HttpRequestPacket) {
|
||||
HttpRequestPacket request = (HttpRequestPacket) httpContent.getHttpHeader()
|
||||
ResponseParameters responseParameters = buildResponse(request)
|
||||
HttpResponsePacket.Builder builder = HttpResponsePacket.builder(request)
|
||||
.status(responseParameters.getStatus())
|
||||
.header("Content-Length", valueOf(responseParameters.getResponseBody().length))
|
||||
responseParameters.fillHeaders(builder)
|
||||
HttpResponsePacket responsePacket = builder.build()
|
||||
controller(responseParameters.getEndpoint()) {
|
||||
responseParameters.execute()
|
||||
ctx.write(HttpContent.builder(responsePacket)
|
||||
.content(wrap(ctx.getMemoryManager(), responseParameters.getResponseBody()))
|
||||
.build())
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctx.getStopAction()
|
||||
}
|
||||
|
||||
ResponseParameters buildResponse(HttpRequestPacket request) {
|
||||
String uri = request.getRequestURI()
|
||||
Map<String, String> headers = new HashMap<>()
|
||||
|
||||
ServerEndpoint endpoint
|
||||
Closure closure
|
||||
switch (uri) {
|
||||
case "/success":
|
||||
endpoint = SUCCESS
|
||||
break
|
||||
case "/redirect":
|
||||
endpoint = REDIRECT
|
||||
headers.put("location", REDIRECT.body)
|
||||
break
|
||||
case "/error-status":
|
||||
endpoint = ERROR
|
||||
break
|
||||
case "/exception":
|
||||
throw new Exception(EXCEPTION.body)
|
||||
case "/query":
|
||||
endpoint = QUERY_PARAM
|
||||
break
|
||||
case "/path/123/param":
|
||||
endpoint = PATH_PARAM
|
||||
break
|
||||
case "/authRequired":
|
||||
endpoint = AUTH_REQUIRED
|
||||
break
|
||||
case "/child":
|
||||
endpoint = INDEXED_CHILD
|
||||
Parameters parameters = new Parameters()
|
||||
parameters.setQuery(request.getQueryStringDC())
|
||||
parameters.setQueryStringEncoding(StandardCharsets.UTF_8)
|
||||
parameters.handleQueryParameters()
|
||||
closure = {
|
||||
INDEXED_CHILD.collectSpanAttributes { name -> parameters.getParameter(name) }
|
||||
}
|
||||
break
|
||||
default:
|
||||
endpoint = NOT_FOUND
|
||||
break
|
||||
}
|
||||
|
||||
int status = endpoint.status
|
||||
String responseBody = endpoint == REDIRECT ? "" : endpoint.body
|
||||
|
||||
byte[] responseBodyBytes = responseBody.getBytes(defaultCharset())
|
||||
return new ResponseParameters(endpoint, status, responseBodyBytes, headers, closure)
|
||||
}
|
||||
|
||||
static class ResponseParameters {
|
||||
Map<String, String> headers
|
||||
ServerEndpoint endpoint
|
||||
int status
|
||||
byte[] responseBody
|
||||
Closure closure
|
||||
|
||||
ResponseParameters(ServerEndpoint endpoint,
|
||||
int status,
|
||||
byte[] responseBody,
|
||||
Map<String, String> headers,
|
||||
Closure closure) {
|
||||
this.endpoint = endpoint
|
||||
this.status = status
|
||||
this.responseBody = responseBody
|
||||
this.headers = headers
|
||||
this.closure = closure
|
||||
}
|
||||
|
||||
int getStatus() {
|
||||
return status
|
||||
}
|
||||
|
||||
byte[] getResponseBody() {
|
||||
return responseBody
|
||||
}
|
||||
|
||||
ServerEndpoint getEndpoint() {
|
||||
return endpoint
|
||||
}
|
||||
|
||||
void fillHeaders(HttpResponsePacket.Builder builder) {
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
builder.header(header.getKey(), header.getValue())
|
||||
}
|
||||
}
|
||||
|
||||
void execute() {
|
||||
if (closure != null) {
|
||||
closure.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import org.glassfish.grizzly.IOStrategy
|
||||
import org.glassfish.grizzly.http.server.NetworkListener
|
||||
import org.glassfish.grizzly.strategies.LeaderFollowerNIOStrategy
|
||||
import org.glassfish.grizzly.strategies.SameThreadIOStrategy
|
||||
import org.glassfish.grizzly.strategies.SimpleDynamicNIOStrategy
|
||||
|
||||
abstract class GrizzlyIOStrategyTest extends GrizzlyTest {
|
||||
|
||||
@Override
|
||||
void configureListener(NetworkListener listener) {
|
||||
// Default in NIOTransportBuilder is WorkerThreadIOStrategy, so don't need to retest that.
|
||||
listener.getTransport().setIOStrategy(strategy())
|
||||
}
|
||||
|
||||
abstract IOStrategy strategy()
|
||||
}
|
||||
|
||||
class LeaderFollowerTest extends GrizzlyIOStrategyTest {
|
||||
|
||||
@Override
|
||||
IOStrategy strategy() {
|
||||
return LeaderFollowerNIOStrategy.instance
|
||||
}
|
||||
}
|
||||
|
||||
class SameThreadTest extends GrizzlyIOStrategyTest {
|
||||
|
||||
@Override
|
||||
IOStrategy strategy() {
|
||||
return SameThreadIOStrategy.instance
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleDynamicTest extends GrizzlyIOStrategyTest {
|
||||
|
||||
@Override
|
||||
IOStrategy strategy() {
|
||||
return SimpleDynamicNIOStrategy.instance
|
||||
}
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey
|
||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
|
||||
import io.opentelemetry.semconv.HttpAttributes
|
||||
import org.glassfish.grizzly.http.server.HttpHandler
|
||||
import org.glassfish.grizzly.http.server.HttpServer
|
||||
import org.glassfish.grizzly.http.server.NetworkListener
|
||||
import org.glassfish.grizzly.http.server.Request
|
||||
import org.glassfish.grizzly.http.server.Response
|
||||
import org.glassfish.grizzly.http.server.ServerConfiguration
|
||||
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.NOT_FOUND
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS
|
||||
|
||||
class GrizzlyTest extends HttpServerTest<HttpServer> implements AgentTestTrait {
|
||||
|
||||
@Override
|
||||
HttpServer startServer(int port) {
|
||||
HttpServer server = new HttpServer()
|
||||
NetworkListener listener = new NetworkListener("grizzly", "localhost", port)
|
||||
configureListener(listener)
|
||||
server.addListener(listener)
|
||||
ServerConfiguration config = server.getServerConfiguration()
|
||||
config.addHttpHandler(new HttpHandler() {
|
||||
@Override
|
||||
void service(Request request, Response response) throws Exception {
|
||||
def endpoint = ServerEndpoint.forPath(request.getDecodedRequestURI())
|
||||
controller(endpoint) {
|
||||
switch (endpoint) {
|
||||
case SUCCESS:
|
||||
response.status = endpoint.status
|
||||
response.writer.write(endpoint.body)
|
||||
break
|
||||
case INDEXED_CHILD:
|
||||
response.status = endpoint.status
|
||||
endpoint.collectSpanAttributes { request.getParameter(it) }
|
||||
break
|
||||
case QUERY_PARAM:
|
||||
response.status = endpoint.status
|
||||
response.writer.write(request.queryString)
|
||||
break
|
||||
case REDIRECT:
|
||||
response.sendRedirect(endpoint.body)
|
||||
break
|
||||
case ERROR:
|
||||
response.sendError(endpoint.status, endpoint.body)
|
||||
break
|
||||
case NOT_FOUND:
|
||||
response.status = endpoint.status
|
||||
break
|
||||
case EXCEPTION:
|
||||
throw new Exception(EXCEPTION.body)
|
||||
default:
|
||||
throw new IllegalStateException("unexpected endpoint " + endpoint)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "/")
|
||||
|
||||
server.start()
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
void configureListener(NetworkListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
Set<AttributeKey<?>> httpAttributes(ServerEndpoint endpoint) {
|
||||
def attributes = super.httpAttributes(endpoint)
|
||||
attributes.remove(HttpAttributes.HTTP_ROUTE)
|
||||
attributes
|
||||
}
|
||||
|
||||
@Override
|
||||
void stopServer(HttpServer server) {
|
||||
server.stop()
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasResponseCustomizer(ServerEndpoint endpoint) {
|
||||
true
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean testCapturedHttpHeaders() {
|
||||
false
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean verifyServerSpanEndTime() {
|
||||
// fails for redirect test
|
||||
false
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean testErrorBody() {
|
||||
false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.grizzly;
|
||||
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION;
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD;
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT;
|
||||
import static java.nio.charset.Charset.defaultCharset;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.glassfish.grizzly.memory.Buffers.wrap;
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint;
|
||||
import io.opentelemetry.semconv.HttpAttributes;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import org.glassfish.grizzly.Transport;
|
||||
import org.glassfish.grizzly.filterchain.BaseFilter;
|
||||
import org.glassfish.grizzly.filterchain.FilterChain;
|
||||
import org.glassfish.grizzly.filterchain.FilterChainBuilder;
|
||||
import org.glassfish.grizzly.filterchain.FilterChainContext;
|
||||
import org.glassfish.grizzly.filterchain.NextAction;
|
||||
import org.glassfish.grizzly.filterchain.TransportFilter;
|
||||
import org.glassfish.grizzly.http.HttpContent;
|
||||
import org.glassfish.grizzly.http.HttpHeader;
|
||||
import org.glassfish.grizzly.http.HttpRequestPacket;
|
||||
import org.glassfish.grizzly.http.HttpResponsePacket;
|
||||
import org.glassfish.grizzly.http.HttpServerFilter;
|
||||
import org.glassfish.grizzly.http.util.Parameters;
|
||||
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
|
||||
import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder;
|
||||
import org.glassfish.grizzly.utils.DelayedExecutor;
|
||||
import org.glassfish.grizzly.utils.IdleTimeoutFilter;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
class GrizzlyFilterchainServerTest extends AbstractHttpServerTest<Transport> {
|
||||
|
||||
@RegisterExtension
|
||||
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent();
|
||||
|
||||
private TCPNIOTransport transport;
|
||||
|
||||
@Override
|
||||
protected Transport setupServer() throws Exception {
|
||||
FilterChain filterChain = setUpFilterChain();
|
||||
setUpTransport(filterChain);
|
||||
|
||||
transport.bind("127.0.0.1", port);
|
||||
transport.start();
|
||||
return transport;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopServer(Transport transport) throws IOException {
|
||||
transport.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpServerTestOptions options) {
|
||||
options.setHttpAttributes(
|
||||
serverEndpoint -> {
|
||||
Set<AttributeKey<?>> attributes =
|
||||
new HashSet<>(HttpServerTestOptions.DEFAULT_HTTP_ATTRIBUTES);
|
||||
attributes.remove(HttpAttributes.HTTP_ROUTE);
|
||||
return attributes;
|
||||
});
|
||||
|
||||
// justification: grizzly async closes the channel which
|
||||
// looks like a ConnectException to the client when this happens
|
||||
options.setTestException(false);
|
||||
|
||||
options.setTestCaptureHttpHeaders(false);
|
||||
|
||||
// server spans are ended inside of the controller spans
|
||||
options.setVerifyServerSpanEndTime(false);
|
||||
options.setTestErrorBody(false);
|
||||
}
|
||||
|
||||
private void setUpTransport(FilterChain filterChain) {
|
||||
TCPNIOTransportBuilder transportBuilder =
|
||||
TCPNIOTransportBuilder.newInstance().setOptimizedForMultiplexing(true);
|
||||
|
||||
transportBuilder.setTcpNoDelay(true);
|
||||
transportBuilder.setKeepAlive(false);
|
||||
transportBuilder.setReuseAddress(true);
|
||||
transportBuilder.setServerConnectionBackLog(50);
|
||||
transportBuilder.setServerSocketSoTimeout(80000);
|
||||
|
||||
transport = transportBuilder.build();
|
||||
transport.setProcessor(filterChain);
|
||||
}
|
||||
|
||||
@SuppressWarnings(
|
||||
"deprecation") // Constructor has been deprecated in favor of builder pattern promised to be
|
||||
// released in a next major release version, but it is not yet available.
|
||||
private static FilterChain setUpFilterChain() {
|
||||
return FilterChainBuilder.stateless()
|
||||
.add(createTransportFilter())
|
||||
.add(createIdleTimeoutFilter())
|
||||
.add(new HttpServerFilter())
|
||||
.add(new LastFilter())
|
||||
.build();
|
||||
}
|
||||
|
||||
private static TransportFilter createTransportFilter() {
|
||||
return new TransportFilter();
|
||||
}
|
||||
|
||||
private static IdleTimeoutFilter createIdleTimeoutFilter() {
|
||||
return new IdleTimeoutFilter(
|
||||
new DelayedExecutor(Executors.newCachedThreadPool()), 80000, MILLISECONDS);
|
||||
}
|
||||
|
||||
private static class LastFilter extends BaseFilter {
|
||||
@Override
|
||||
public NextAction handleRead(FilterChainContext ctx) throws IOException {
|
||||
if (ctx.getMessage() instanceof HttpContent) {
|
||||
HttpContent httpContent = ctx.getMessage();
|
||||
HttpHeader httpHeader = httpContent.getHttpHeader();
|
||||
if (httpHeader instanceof HttpRequestPacket) {
|
||||
HttpRequestPacket request = (HttpRequestPacket) httpContent.getHttpHeader();
|
||||
ResponseParameters responseParameters = buildResponse(request);
|
||||
HttpResponsePacket.Builder builder =
|
||||
HttpResponsePacket.builder(request)
|
||||
.status(responseParameters.getStatus())
|
||||
.header(
|
||||
"Content-Length",
|
||||
String.valueOf(responseParameters.getResponseBody().length));
|
||||
responseParameters.fillHeaders(builder);
|
||||
HttpResponsePacket responsePacket = builder.build();
|
||||
controller(
|
||||
responseParameters.getEndpoint(),
|
||||
() -> {
|
||||
responseParameters.execute();
|
||||
ctx.write(
|
||||
HttpContent.builder(responsePacket)
|
||||
.content(wrap(ctx.getMemoryManager(), responseParameters.getResponseBody()))
|
||||
.build());
|
||||
return responsePacket;
|
||||
});
|
||||
}
|
||||
}
|
||||
return ctx.getStopAction();
|
||||
}
|
||||
|
||||
private static ResponseParameters buildResponse(HttpRequestPacket request) {
|
||||
String uri = request.getRequestURI();
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
|
||||
ServerEndpoint endpoint = ServerEndpoint.forPath(uri);
|
||||
Runnable closure = null;
|
||||
if (endpoint == REDIRECT) {
|
||||
headers.put("location", REDIRECT.getBody());
|
||||
}
|
||||
if (endpoint == EXCEPTION) {
|
||||
throw new IllegalArgumentException(EXCEPTION.getBody());
|
||||
}
|
||||
if (endpoint == INDEXED_CHILD) {
|
||||
Parameters parameters = new Parameters();
|
||||
parameters.setQuery(request.getQueryStringDC());
|
||||
parameters.setQueryStringEncoding(StandardCharsets.UTF_8);
|
||||
parameters.handleQueryParameters();
|
||||
closure =
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
INDEXED_CHILD.collectSpanAttributes(parameters::getParameter);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int status = endpoint.getStatus();
|
||||
String responseBody = endpoint == REDIRECT ? "" : endpoint.getBody();
|
||||
|
||||
byte[] responseBodyBytes = responseBody.getBytes(defaultCharset());
|
||||
return new ResponseParameters(endpoint, status, responseBodyBytes, headers, closure);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResponseParameters {
|
||||
private final Map<String, String> headers;
|
||||
private final ServerEndpoint endpoint;
|
||||
private final int status;
|
||||
private final byte[] responseBody;
|
||||
private final Runnable closure;
|
||||
|
||||
ResponseParameters(
|
||||
ServerEndpoint endpoint,
|
||||
int status,
|
||||
byte[] responseBody,
|
||||
Map<String, String> headers,
|
||||
Runnable closure) {
|
||||
this.endpoint = endpoint;
|
||||
this.status = status;
|
||||
this.responseBody = responseBody;
|
||||
this.headers = headers;
|
||||
this.closure = closure;
|
||||
}
|
||||
|
||||
int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
byte[] getResponseBody() {
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
ServerEndpoint getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
void fillHeaders(HttpResponsePacket.Builder builder) {
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
builder.header(header.getKey(), header.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
void execute() {
|
||||
if (closure != null) {
|
||||
closure.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.grizzly;
|
||||
|
||||
import org.glassfish.grizzly.IOStrategy;
|
||||
import org.glassfish.grizzly.http.server.NetworkListener;
|
||||
|
||||
abstract class GrizzlyIoStrategyTest extends GrizzlyTest {
|
||||
|
||||
@Override
|
||||
public void configureListener(NetworkListener listener) {
|
||||
// Default in NIOTransportBuilder is WorkerThreadIOStrategy, so don't need to retest that.
|
||||
listener.getTransport().setIOStrategy(strategy());
|
||||
}
|
||||
|
||||
abstract IOStrategy strategy();
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.grizzly;
|
||||
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR;
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION;
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD;
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.NOT_FOUND;
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM;
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT;
|
||||
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS;
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint;
|
||||
import io.opentelemetry.semconv.HttpAttributes;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.glassfish.grizzly.http.server.HttpHandler;
|
||||
import org.glassfish.grizzly.http.server.HttpServer;
|
||||
import org.glassfish.grizzly.http.server.NetworkListener;
|
||||
import org.glassfish.grizzly.http.server.Request;
|
||||
import org.glassfish.grizzly.http.server.Response;
|
||||
import org.glassfish.grizzly.http.server.ServerConfiguration;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
abstract class GrizzlyTest extends AbstractHttpServerTest<HttpServer> {
|
||||
|
||||
@RegisterExtension
|
||||
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent();
|
||||
|
||||
@Override
|
||||
protected HttpServer setupServer() throws Exception {
|
||||
HttpServer server = new HttpServer();
|
||||
NetworkListener listener = new NetworkListener("grizzly", "localhost", port);
|
||||
configureListener(listener);
|
||||
server.addListener(listener);
|
||||
ServerConfiguration config = server.getServerConfiguration();
|
||||
config.addHttpHandler(
|
||||
new HttpHandler() {
|
||||
@Override
|
||||
public void service(Request request, Response response) throws Exception {
|
||||
ServerEndpoint endpoint = ServerEndpoint.forPath(request.getDecodedRequestURI());
|
||||
controller(
|
||||
endpoint,
|
||||
() -> {
|
||||
if (endpoint.equals(SUCCESS)) {
|
||||
try {
|
||||
response.getWriter().write(endpoint.getBody());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (endpoint.equals(INDEXED_CHILD)) {
|
||||
response.setStatus(endpoint.getStatus());
|
||||
endpoint.collectSpanAttributes(request::getParameter);
|
||||
} else if (endpoint.equals(QUERY_PARAM)) {
|
||||
response.setStatus(endpoint.getStatus());
|
||||
try {
|
||||
response.getWriter().write(request.getQueryString());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (endpoint.equals(REDIRECT)) {
|
||||
try {
|
||||
response.sendRedirect(endpoint.getBody());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (endpoint.equals(ERROR)) {
|
||||
try {
|
||||
response.sendError(endpoint.getStatus(), endpoint.getBody());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (endpoint.equals(NOT_FOUND)) {
|
||||
response.setStatus(endpoint.getStatus());
|
||||
} else if (endpoint.equals(EXCEPTION)) {
|
||||
throw new IllegalArgumentException(EXCEPTION.getBody());
|
||||
} else {
|
||||
throw new IllegalStateException("unexpected endpoint " + endpoint);
|
||||
}
|
||||
return response;
|
||||
});
|
||||
}
|
||||
},
|
||||
"/");
|
||||
|
||||
server.start();
|
||||
return server;
|
||||
}
|
||||
|
||||
protected abstract void configureListener(NetworkListener listener);
|
||||
|
||||
@Override
|
||||
protected void stopServer(HttpServer server) {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpServerTestOptions options) {
|
||||
options.setHttpAttributes(
|
||||
serverEndpoint -> {
|
||||
Set<AttributeKey<?>> attributes =
|
||||
new HashSet<>(HttpServerTestOptions.DEFAULT_HTTP_ATTRIBUTES);
|
||||
attributes.remove(HttpAttributes.HTTP_ROUTE);
|
||||
return attributes;
|
||||
});
|
||||
options.setTestCaptureHttpHeaders(false);
|
||||
options.setHasResponseCustomizer(serverEndpoint -> true);
|
||||
options.setVerifyServerSpanEndTime(false); // fails for redirect test
|
||||
options.setTestErrorBody(false);
|
||||
options.setExpectedException(new IllegalArgumentException(EXCEPTION.getBody()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.grizzly;
|
||||
|
||||
import org.glassfish.grizzly.IOStrategy;
|
||||
import org.glassfish.grizzly.strategies.LeaderFollowerNIOStrategy;
|
||||
|
||||
class LeaderFollowerTest extends GrizzlyIoStrategyTest {
|
||||
|
||||
@Override
|
||||
IOStrategy strategy() {
|
||||
return LeaderFollowerNIOStrategy.getInstance();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.grizzly;
|
||||
|
||||
import org.glassfish.grizzly.IOStrategy;
|
||||
import org.glassfish.grizzly.strategies.SameThreadIOStrategy;
|
||||
|
||||
class SameThreadTest extends GrizzlyIoStrategyTest {
|
||||
|
||||
@Override
|
||||
IOStrategy strategy() {
|
||||
return SameThreadIOStrategy.getInstance();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.grizzly;
|
||||
|
||||
import org.glassfish.grizzly.IOStrategy;
|
||||
import org.glassfish.grizzly.strategies.SimpleDynamicNIOStrategy;
|
||||
|
||||
class SimpleDynamicTest extends GrizzlyIoStrategyTest {
|
||||
|
||||
@Override
|
||||
IOStrategy strategy() {
|
||||
return SimpleDynamicNIOStrategy.getInstance();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue