Convert restlet-2.0 tests to java (#12348)

This commit is contained in:
Lauri Tulmin 2024-09-30 03:06:55 +03:00 committed by GitHub
parent 0f0477a35b
commit f0115c6bdc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 689 additions and 572 deletions

View File

@ -27,7 +27,8 @@ import org.restlet.resource.Resource;
import org.restlet.resource.StringRepresentation;
import org.restlet.resource.Variant;
public class RestletAppTestBase {
class RestletAppTestBase {
abstract static class BaseResource extends Resource {
@Override

View File

@ -1,31 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.restlet.v2_0
import io.opentelemetry.instrumentation.restlet.v2_0.AbstractRestletServerTest
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.NOT_FOUND
class RestletServerTest extends AbstractRestletServerTest implements AgentTestTrait {
@Override
String expectedHttpRoute(ServerEndpoint endpoint, String method) {
switch (endpoint) {
case NOT_FOUND:
return getContextPath() + "/"
default:
return super.expectedHttpRoute(endpoint, method)
}
}
@Override
boolean hasResponseCustomizer(ServerEndpoint endpoint) {
return true
}
}

View File

@ -1,23 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.restlet.v2_0.spring
import io.opentelemetry.instrumentation.restlet.v2_0.spring.AbstractSpringServerTest
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
class SpringBeanRouterTest extends AbstractSpringServerTest implements AgentTestTrait {
@Override
String getConfigurationName() {
return "springBeanRouterConf.xml"
}
@Override
boolean hasResponseCustomizer(ServerEndpoint endpoint) {
return true
}
}

View File

@ -1,23 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.restlet.v2_0.spring
import io.opentelemetry.instrumentation.restlet.v2_0.spring.AbstractSpringServerTest
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
class SpringRouterTest extends AbstractSpringServerTest implements AgentTestTrait {
@Override
String getConfigurationName() {
return "springRouterConf.xml"
}
@Override
boolean hasResponseCustomizer(ServerEndpoint endpoint) {
return true
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.restlet.v2_0;
import io.opentelemetry.instrumentation.restlet.v2_0.AbstractRestletServerTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
import org.junit.jupiter.api.extension.RegisterExtension;
class RestletServerTest extends AbstractRestletServerTest {
@RegisterExtension
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent();
@Override
protected void configure(HttpServerTestOptions options) {
super.configure(options);
options.setHasResponseCustomizer((endpoint) -> true);
}
@Override
protected String notFoundRoute() {
return "/";
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.restlet.v2_0.spring;
import io.opentelemetry.instrumentation.restlet.v2_0.spring.AbstractSpringServerTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
import org.junit.jupiter.api.extension.RegisterExtension;
class SpringBeanRouterTest extends AbstractSpringServerTest {
@RegisterExtension
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent();
@Override
protected void configure(HttpServerTestOptions options) {
super.configure(options);
options.setHasResponseCustomizer((endpoint) -> true);
}
@Override
protected String getConfigurationName() {
return "springBeanRouterConf.xml";
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.restlet.v2_0.spring;
import io.opentelemetry.instrumentation.restlet.v2_0.spring.AbstractSpringServerTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
import org.junit.jupiter.api.extension.RegisterExtension;
class SpringRouterTest extends AbstractSpringServerTest {
@RegisterExtension
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent();
@Override
protected void configure(HttpServerTestOptions options) {
super.configure(options);
options.setHasResponseCustomizer((endpoint) -> true);
}
@Override
protected String getConfigurationName() {
return "springRouterConf.xml";
}
}

View File

@ -9,12 +9,12 @@ repositories {
}
dependencies {
library("org.restlet.jse:org.restlet:2.0.2")
testImplementation(project(":instrumentation:restlet:restlet-2.0:testing"))
testLibrary("org.restlet.jse:org.restlet.ext.jetty:2.0.2")
}
// restlet registers the first engine that is present on classpath, so we need to enforce the appropriate version
if (findProperty("testLatestDeps") as Boolean) {
configurations.configureEach {

View File

@ -1,32 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0
import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import org.restlet.Restlet
import org.restlet.engine.application.StatusFilter
import org.restlet.service.StatusService
class RestletServerTest extends AbstractRestletServerTest implements LibraryTestTrait {
@Override
Restlet wrapRestlet(Restlet restlet, String path) {
RestletTelemetry telemetry = RestletTelemetry.builder(openTelemetry)
.setCapturedRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build()
def tracingFilter = telemetry.newFilter(path)
def statusFilter = new StatusFilter(component.getContext(), new StatusService())
tracingFilter.setNext(statusFilter)
statusFilter.setNext(restlet)
return tracingFilter
}
}

View File

@ -1,71 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0.spring
import io.opentelemetry.instrumentation.restlet.v2_0.RestletTelemetry
import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import org.restlet.Request
import org.restlet.Response
import org.restlet.Restlet
import org.restlet.data.Status
import org.restlet.engine.application.StatusFilter
import org.restlet.routing.Route
import org.restlet.routing.Template
import org.restlet.routing.TemplateRoute
import org.restlet.service.StatusService
import org.restlet.util.RouteList
import java.lang.reflect.Modifier
abstract class AbstractSpringServerLibraryTest extends AbstractSpringServerTest implements LibraryTestTrait {
@Override
Restlet wrapRestlet(Restlet restlet, String path) {
RestletTelemetry telemetry = RestletTelemetry.builder(openTelemetry)
.setCapturedRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build()
def tracingFilter = telemetry.newFilter(path)
def statusFilter = new StatusFilter(component.getContext(), new StatusService())
tracingFilter.setNext(statusFilter)
statusFilter.setNext(restlet)
return tracingFilter
}
@Override
void setupRouting() {
//for latestDepTest
def routeClass = Modifier.isAbstract(Route.getModifiers()) ? TemplateRoute : Route
List<Route> routes = []
for (Route route : router.getRoutes()) {
def pattern = route.getTemplate().getPattern()
routes.add((Route) routeClass.newInstance(router, pattern, wrapRestlet(route.getNext(), pattern)))
}
def notFoundRestlet = new Restlet(router.getContext()) {
@Override
void handle(Request request, Response response) {
super.handle(request, response)
response.setStatus(Status.CLIENT_ERROR_NOT_FOUND)
}
}
notFoundRestlet = wrapRestlet(notFoundRestlet, "/*")
def route = (Route) routeClass.newInstance(router, "/", notFoundRestlet)
route.setMatchingMode(Template.MODE_STARTS_WITH)
routes.add(route)
router.setRoutes(new RouteList(routes))
host.attach(router)
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0;
import static java.util.Collections.singletonList;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.restlet.Restlet;
import org.restlet.engine.application.StatusFilter;
import org.restlet.routing.Filter;
import org.restlet.service.StatusService;
class RestletServerTest extends AbstractRestletServerTest {
@RegisterExtension
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forLibrary();
@Override
protected Restlet wrapRestlet(Restlet restlet, String path) {
RestletTelemetry telemetry =
RestletTelemetry.builder(testing.getOpenTelemetry())
.setCapturedRequestHeaders(singletonList(AbstractHttpServerTest.TEST_REQUEST_HEADER))
.setCapturedResponseHeaders(singletonList(AbstractHttpServerTest.TEST_RESPONSE_HEADER))
.build();
Filter tracingFilter = telemetry.newFilter(path);
Filter statusFilter = new StatusFilter(component.getContext(), new StatusService());
tracingFilter.setNext(statusFilter);
statusFilter.setNext(restlet);
return tracingFilter;
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0.spring;
import static java.util.Collections.singletonList;
import io.opentelemetry.instrumentation.restlet.v2_0.RestletTelemetry;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.data.Status;
import org.restlet.engine.application.StatusFilter;
import org.restlet.routing.Filter;
import org.restlet.routing.Router;
import org.restlet.routing.Template;
import org.restlet.routing.TemplateRoute;
import org.restlet.service.StatusService;
import org.restlet.util.RouteList;
abstract class AbstractSpringServerLibraryTest extends AbstractSpringServerTest {
// org.restlet.routing.Route is deprecated in 2.0 but not deprecated in later versions
@SuppressWarnings("deprecation")
private static final Class<?> ROUTE_CLASS = org.restlet.routing.Route.class;
@RegisterExtension
static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forLibrary();
@Override
protected Restlet wrapRestlet(Restlet restlet, String path) {
RestletTelemetry telemetry =
RestletTelemetry.builder(testing.getOpenTelemetry())
.setCapturedRequestHeaders(singletonList(AbstractHttpServerTest.TEST_REQUEST_HEADER))
.setCapturedResponseHeaders(singletonList(AbstractHttpServerTest.TEST_RESPONSE_HEADER))
.build();
Filter tracingFilter = telemetry.newFilter(path);
Filter statusFilter = new StatusFilter(component.getContext(), new StatusService());
tracingFilter.setNext(statusFilter);
statusFilter.setNext(restlet);
return tracingFilter;
}
// org.restlet.routing.Route is deprecated in 2.0 but not deprecated in later versions
@SuppressWarnings("deprecation")
@Override
protected void setupRouting() {
try {
// for latestDepTest
Class<?> routeClass =
Modifier.isAbstract(ROUTE_CLASS.getModifiers()) ? TemplateRoute.class : ROUTE_CLASS;
Constructor<?> routeConstructor =
routeClass.getConstructor(Router.class, String.class, Restlet.class);
Method getTemplate = routeClass.getMethod("getTemplate");
List<org.restlet.routing.Route> routes = new ArrayList<>();
for (org.restlet.routing.Route route : router.getRoutes()) {
String pattern = ((Template) getTemplate.invoke(route)).getPattern();
routes.add(
(org.restlet.routing.Route)
routeConstructor.newInstance(
router, pattern, wrapRestlet(route.getNext(), pattern)));
}
Restlet notFoundRestlet =
new Restlet(router.getContext()) {
@Override
public void handle(Request request, Response response) {
super.handle(request, response);
response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
}
};
notFoundRestlet = wrapRestlet(notFoundRestlet, "/*");
org.restlet.routing.Route route =
(org.restlet.routing.Route) routeConstructor.newInstance(router, "/", notFoundRestlet);
((Template) getTemplate.invoke(route)).setMatchingMode(Template.MODE_STARTS_WITH);
routes.add(route);
router.setRoutes(new RouteList(routes));
host.attach(router);
} catch (Exception exception) {
throw new IllegalStateException(exception);
}
}
}

View File

@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0.spring
package io.opentelemetry.instrumentation.restlet.v2_0.spring;
class SpringBeanRouterTest extends AbstractSpringServerLibraryTest {
@Override
String getConfigurationName() {
return "springBeanRouterConf.xml"
}
@Override
protected String getConfigurationName() {
return "springBeanRouterConf.xml";
}
}

View File

@ -3,13 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0.spring
package io.opentelemetry.instrumentation.restlet.v2_0.spring;
class SpringRouterTest extends AbstractSpringServerLibraryTest {
@Override
String getConfigurationName() {
return "springRouterConf.xml"
protected String getConfigurationName() {
return "springRouterConf.xml";
}
}

View File

@ -1,196 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0
import io.opentelemetry.instrumentation.api.internal.HttpConstants
import io.opentelemetry.instrumentation.test.base.HttpServerTest
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
import org.restlet.Component
import org.restlet.Context
import org.restlet.Request
import org.restlet.Response
import org.restlet.Restlet
import org.restlet.Server
import org.restlet.data.Form
import org.restlet.data.MediaType
import org.restlet.data.Protocol
import org.restlet.data.Status
import org.restlet.routing.Redirector
import org.restlet.routing.Router
import org.restlet.routing.Template
import org.restlet.routing.VirtualHost
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS
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
abstract class AbstractRestletServerTest extends HttpServerTest<Server> {
Component component
VirtualHost host
@Override
Server startServer(int port) {
component = new Component()
host = component.getDefaultHost()
def server = setupServer(component)
setupRouting()
component.start()
return server
}
@Override
void stopServer(Server server) {
component.stop()
}
def attachAndWrap(path, restlet) {
host.attach(path, wrapRestlet(restlet, path))
}
Server setupServer(Component component) {
return component.getServers().add(Protocol.HTTP, port)
}
void setupRouting() {
def defaultRouter = wrapRestlet(new Router(host.getContext()), "/*")
host.attach("/", defaultRouter).setMatchingMode(Template.MODE_STARTS_WITH)
attachAndWrap(SUCCESS.path, new Restlet() {
@Override
void handle(Request request, Response response) {
controller(SUCCESS) {
response.setEntity(SUCCESS.body, MediaType.TEXT_PLAIN)
response.setStatus(Status.valueOf(SUCCESS.status), SUCCESS.body)
}
}
})
attachAndWrap(REDIRECT.path, new Redirector(Context.getCurrent(), REDIRECT.body, Redirector.MODE_CLIENT_FOUND) {
@Override
void handle(Request request, Response response) {
super.handle(request, response)
controller(REDIRECT) {
}
}
})
attachAndWrap(ERROR.path, new Restlet() {
@Override
void handle(Request request, Response response) {
controller(ERROR) {
response.setStatus(Status.valueOf(ERROR.getStatus()), ERROR.getBody())
}
}
})
attachAndWrap(EXCEPTION.path, new Restlet() {
@Override
void handle(Request request, Response response) {
controller(EXCEPTION) {
throw new Exception(EXCEPTION.getBody())
}
}
})
attachAndWrap(QUERY_PARAM.path, new Restlet() {
@Override
void handle(Request request, Response response) {
controller(QUERY_PARAM) {
response.setEntity(QUERY_PARAM.getBody(), MediaType.TEXT_PLAIN)
response.setStatus(Status.valueOf(QUERY_PARAM.getStatus()), QUERY_PARAM.getBody())
}
}
})
attachAndWrap("/path/{id}/param", new Restlet() {
@Override
void handle(Request request, Response response) {
controller(PATH_PARAM) {
response.setEntity(PATH_PARAM.getBody(), MediaType.TEXT_PLAIN)
response.setStatus(Status.valueOf(PATH_PARAM.getStatus()), PATH_PARAM.getBody())
}
}
})
attachAndWrap("/captureHeaders", new Restlet() {
@Override
void handle(Request request, Response response) {
controller(CAPTURE_HEADERS) {
def requestHeaders = request.getAttributes().get("org.restlet.http.headers")
def responseHeaders
try {
def headerClass = Class.forName("org.restlet.data.Header")
def seriesClass = Class.forName("org.restlet.util.Series")
//to avoid constructor error (Series is abstract in 2.0.x)
responseHeaders = response.getAttributes().computeIfAbsent("org.restlet.http.headers", { seriesClass.newInstance(headerClass) })
} catch (ClassNotFoundException | NoClassDefFoundError e) {
responseHeaders = response.getAttributes().computeIfAbsent("org.restlet.http.headers", { new Form() })
}
responseHeaders.add("X-Test-Response", requestHeaders.getValues("X-Test-Request"))
response.setEntity(CAPTURE_HEADERS.getBody(), MediaType.TEXT_PLAIN)
response.setStatus(Status.valueOf(CAPTURE_HEADERS.getStatus()), CAPTURE_HEADERS.getBody())
}
}
})
attachAndWrap(INDEXED_CHILD.path, new Restlet() {
@Override
void handle(Request request, Response response) {
controller(INDEXED_CHILD) {
INDEXED_CHILD.collectSpanAttributes { request.getOriginalRef().getQueryAsForm().getFirst(it).getValue() }
response.setStatus(Status.valueOf(INDEXED_CHILD.status))
}
}
})
}
@Override
boolean testPathParam() {
true
}
@Override
boolean testErrorBody() {
false
}
@Override
String expectedHttpRoute(ServerEndpoint endpoint, String method) {
if (method == HttpConstants._OTHER) {
return getContextPath() + endpoint.path
}
switch (endpoint) {
case PATH_PARAM:
return getContextPath() + "/path/{id}/param"
case NOT_FOUND:
return getContextPath() + "/*"
default:
return super.expectedHttpRoute(endpoint, method)
}
}
Restlet wrapRestlet(Restlet restlet, String path) {
return restlet
}
}

View File

@ -1,137 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0
import org.restlet.data.Form
import org.restlet.data.Reference
import org.restlet.data.Status
import org.restlet.resource.Get
import org.restlet.resource.ServerResource
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS
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.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 io.opentelemetry.instrumentation.test.base.HttpServerTest.controller
class RestletAppTestBase {
static class SuccessResource extends ServerResource {
@Get("txt")
String represent() {
controller(SUCCESS) {
return SUCCESS.getBody()
}
}
}
static class ErrorResource extends ServerResource {
@Get("txt")
String represent() {
controller(ERROR) {
getResponse().setStatus(Status.valueOf(ERROR.getStatus()), ERROR.getBody())
return ERROR.getBody()
}
}
}
static class ExceptionResource extends ServerResource {
@Get("txt")
String represent() {
controller(EXCEPTION) {
throw new Exception(EXCEPTION.getBody())
}
}
}
static class QueryParamResource extends ServerResource {
@Get("txt")
String represent() {
controller(QUERY_PARAM) {
return QUERY_PARAM.getBody()
}
}
}
static class PathParamResource extends ServerResource {
@Get("txt")
String represent() {
controller(PATH_PARAM) {
return PATH_PARAM.getBody()
}
}
}
static class RedirectResource extends ServerResource {
@Get("txt")
String represent() {
controller(REDIRECT) {
redirectSeeOther(new Reference(getRootRef().toString() + REDIRECT.getBody()))
response.setStatus(Status.valueOf(REDIRECT.getStatus()))
return ""
}
}
}
static class CaptureHeadersResource extends ServerResource {
@Get("txt")
String represent() {
controller(CAPTURE_HEADERS) {
def requestHeaders = request.getAttributes().get("org.restlet.http.headers")
def responseHeaders
try {
def headerClass = Class.forName("org.restlet.data.Header")
def seriesClass = Class.forName("org.restlet.util.Series")
//to avoid constructor error (Series is abstract in 2.0.x)
responseHeaders = response.getAttributes().computeIfAbsent("org.restlet.http.headers", { seriesClass.newInstance(headerClass) })
} catch (ClassNotFoundException | NoClassDefFoundError e) {
responseHeaders = response.getAttributes().computeIfAbsent("org.restlet.http.headers", { new Form() })
}
responseHeaders.add("X-Test-Response", requestHeaders.getValues("X-Test-Request"))
return CAPTURE_HEADERS.getBody()
}
}
}
static class IndexedChildResource extends ServerResource {
@Get("txt")
String represent() {
controller(INDEXED_CHILD) {
INDEXED_CHILD.collectSpanAttributes {
request.getOriginalRef().getQueryAsForm().getFirst(it).getValue()
}
//INDEXED_CHILD.getBody() returns an empty string, in which case Restlet sets status to 204
return "child"
}
}
}
}

View File

@ -1,48 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0.spring
import io.opentelemetry.instrumentation.api.internal.HttpConstants
import io.opentelemetry.instrumentation.restlet.v2_0.AbstractRestletServerTest
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
import org.restlet.Component
import org.restlet.Server
import org.restlet.routing.Router
import org.springframework.context.support.ClassPathXmlApplicationContext
abstract class AbstractSpringServerTest extends AbstractRestletServerTest {
Router router
abstract String getConfigurationName()
@Override
Server setupServer(Component component) {
def context = new ClassPathXmlApplicationContext(getConfigurationName())
router = (Router) context.getBean("testRouter")
def server = (Server) context.getBean("testServer", "http", port)
component.getServers().add(server)
return server
}
@Override
void setupRouting() {
host.attach(router)
}
@Override
String expectedHttpRoute(ServerEndpoint endpoint, String method) {
if (method == HttpConstants._OTHER) {
return getContextPath() + endpoint.path
}
return super.expectedHttpRoute(endpoint, method)
}
@Override
int getResponseCodeOnNonStandardHttpMethod() {
405
}
}

View File

@ -0,0 +1,246 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0;
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS;
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 io.opentelemetry.instrumentation.api.internal.HttpConstants;
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint;
import java.lang.reflect.Method;
import org.restlet.Component;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.data.MediaType;
import org.restlet.data.Protocol;
import org.restlet.data.Status;
import org.restlet.routing.Redirector;
import org.restlet.routing.Router;
import org.restlet.routing.Template;
import org.restlet.routing.VirtualHost;
public class AbstractRestletServerTest extends AbstractHttpServerTest<Component> {
protected Component component;
protected VirtualHost host;
@Override
protected Component setupServer() throws Exception {
component = new Component();
host = component.getDefaultHost();
setupServer(component);
setupRouting();
component.start();
return component;
}
protected void setupServer(Component component) {
component.getServers().add(Protocol.HTTP, port);
}
@Override
protected void stopServer(Component component) throws Exception {
component.stop();
}
private void attachAndWrap(ServerEndpoint endpoint, Restlet restlet) {
attachAndWrap(endpoint.getPath(), restlet);
}
private void attachAndWrap(String path, Restlet restlet) {
attach(path, wrapRestlet(restlet, path));
}
// org.restlet.routing.Route is deprecated in 2.0 but not deprecated in later versions
@SuppressWarnings("deprecation")
private org.restlet.routing.Route attach(String path, Restlet restlet) {
try {
// return type is different in latest version
Method method = VirtualHost.class.getMethod("attach", String.class, Restlet.class);
return (org.restlet.routing.Route) method.invoke(host, path, restlet);
} catch (Exception exception) {
throw new IllegalStateException(exception);
}
}
// org.restlet.routing.Route is deprecated in 2.0 but not deprecated in later versions
@SuppressWarnings("deprecation")
protected void attach(Restlet restlet) {
try {
// return type is different in latest version
Method method = VirtualHost.class.getMethod("attach", Restlet.class);
method.invoke(host, restlet);
} catch (Exception exception) {
throw new IllegalStateException(exception);
}
}
private static Template getTemplate(Object route) {
try {
Method getTemplate = route.getClass().getMethod("getTemplate");
return (Template) getTemplate.invoke(route);
} catch (Exception exception) {
throw new IllegalStateException(exception);
}
}
protected void setupRouting() {
Restlet defaultRouter = wrapRestlet(new Router(host.getContext()), "/*");
getTemplate(attach("/", defaultRouter)).setMatchingMode(Template.MODE_STARTS_WITH);
attachAndWrap(
SUCCESS,
new Restlet() {
@Override
public void handle(Request request, Response response) {
controller(
SUCCESS,
() -> {
response.setEntity(SUCCESS.getBody(), MediaType.TEXT_PLAIN);
response.setStatus(Status.valueOf(SUCCESS.getStatus()), SUCCESS.getBody());
});
}
});
attachAndWrap(
REDIRECT,
new Redirector(Context.getCurrent(), REDIRECT.getBody(), Redirector.MODE_CLIENT_FOUND) {
@Override
public void handle(Request request, Response response) {
super.handle(request, response);
controller(REDIRECT, () -> {});
}
});
attachAndWrap(
ERROR,
new Restlet() {
@Override
public void handle(Request request, Response response) {
controller(
ERROR,
() -> response.setStatus(Status.valueOf(ERROR.getStatus()), ERROR.getBody()));
}
});
attachAndWrap(
EXCEPTION,
new Restlet() {
@Override
public void handle(Request request, Response response) {
controller(
EXCEPTION,
() -> {
throw new IllegalStateException(EXCEPTION.getBody());
});
}
});
attachAndWrap(
QUERY_PARAM,
new Restlet() {
@Override
public void handle(Request request, Response response) {
controller(
QUERY_PARAM,
() -> {
response.setEntity(QUERY_PARAM.getBody(), MediaType.TEXT_PLAIN);
response.setStatus(
Status.valueOf(QUERY_PARAM.getStatus()), QUERY_PARAM.getBody());
});
}
});
attachAndWrap(
"/path/{id}/param",
new Restlet() {
@Override
public void handle(Request request, Response response) {
controller(
PATH_PARAM,
() -> {
response.setEntity(PATH_PARAM.getBody(), MediaType.TEXT_PLAIN);
response.setStatus(Status.valueOf(PATH_PARAM.getStatus()), PATH_PARAM.getBody());
});
}
});
attachAndWrap(
"/captureHeaders",
new Restlet() {
@Override
public void handle(Request request, Response response) {
controller(
CAPTURE_HEADERS,
() -> {
RestletAppTestBase.handleCaptureHeaders(request, response);
response.setEntity(CAPTURE_HEADERS.getBody(), MediaType.TEXT_PLAIN);
response.setStatus(
Status.valueOf(CAPTURE_HEADERS.getStatus()), CAPTURE_HEADERS.getBody());
});
}
});
attachAndWrap(
INDEXED_CHILD,
new Restlet() {
@Override
public void handle(Request request, Response response) {
controller(
INDEXED_CHILD,
() -> {
INDEXED_CHILD.collectSpanAttributes(
name -> request.getOriginalRef().getQueryAsForm().getFirstValue(name));
response.setStatus(Status.valueOf(INDEXED_CHILD.getStatus()));
});
}
});
}
protected Restlet wrapRestlet(Restlet restlet, String path) {
return restlet;
}
protected String notFoundRoute() {
return "/*";
}
@Override
protected void configure(HttpServerTestOptions options) {
super.configure(options);
options.setTestPathParam(true);
options.setTestErrorBody(false);
options.setExpectedException(new IllegalStateException(EXCEPTION.getBody()));
options.setExpectedHttpRoute(
(endpoint, method) -> {
if (HttpConstants._OTHER.equals(method)) {
return getContextPath() + endpoint.getPath();
}
if (PATH_PARAM.equals(endpoint)) {
return getContextPath() + "/path/{id}/param";
} else if (NOT_FOUND.equals(endpoint)) {
return getContextPath() + notFoundRoute();
}
return expectedHttpRoute(endpoint, method);
});
}
}

View File

@ -0,0 +1,165 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0;
import static io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest.controller;
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS;
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.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 java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import org.restlet.data.Form;
import org.restlet.data.Reference;
import org.restlet.data.Status;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.restlet.util.Series;
class RestletAppTestBase {
public static class SuccessResource extends ServerResource {
@Get("txt")
public String represent() {
return controller(SUCCESS, SUCCESS::getBody);
}
}
public static class ErrorResource extends ServerResource {
@Get("txt")
public String represent() {
return controller(
ERROR,
() -> {
getResponse().setStatus(Status.valueOf(ERROR.getStatus()), ERROR.getBody());
return ERROR.getBody();
});
}
}
public static class ExceptionResource extends ServerResource {
@Get("txt")
public String represent() {
return controller(
EXCEPTION,
() -> {
throw new IllegalStateException(EXCEPTION.getBody());
});
}
}
public static class QueryParamResource extends ServerResource {
@Get("txt")
public String represent() {
return controller(QUERY_PARAM, QUERY_PARAM::getBody);
}
}
public static class PathParamResource extends ServerResource {
@Get("txt")
public String represent() {
return controller(PATH_PARAM, PATH_PARAM::getBody);
}
}
public static class RedirectResource extends ServerResource {
@Get("txt")
public String represent() {
return controller(
REDIRECT,
() -> {
redirectSeeOther(new Reference(getRootRef().toString() + REDIRECT.getBody()));
getResponse().setStatus(Status.valueOf(REDIRECT.getStatus()));
return "";
});
}
}
@SuppressWarnings("unchecked")
static void handleCaptureHeaders(Object request, Object response) {
Map<String, Object> attributes;
Map<String, Object> responseAttributes;
try {
Method requestAttributesMethod = request.getClass().getMethod("getAttributes");
attributes = (Map<String, Object>) requestAttributesMethod.invoke(request);
Method responseAttributesMethod = response.getClass().getMethod("getAttributes");
responseAttributes = (Map<String, Object>) responseAttributesMethod.invoke(response);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException exception) {
throw new IllegalStateException(exception);
}
Series<?> requestHeaders = (Series<?>) attributes.get("org.restlet.http.headers");
Series<?> responseHeaders;
try {
Class<?> headerClass = Class.forName("org.restlet.data.Header");
Class<?> seriesClass = Class.forName("org.restlet.util.Series");
Constructor<?> constructor = seriesClass.getConstructor(Class.class);
// to avoid constructor error (Series is abstract in 2.0.x)
responseHeaders =
(Series<?>)
responseAttributes.computeIfAbsent(
"org.restlet.http.headers",
(key) -> {
try {
return constructor.newInstance(headerClass);
} catch (Exception exception) {
throw new IllegalStateException(exception);
}
});
} catch (ClassNotFoundException | NoClassDefFoundError | NoSuchMethodException exception) {
responseHeaders =
(Series<?>)
responseAttributes.computeIfAbsent("org.restlet.http.headers", (key) -> new Form());
}
responseHeaders.add("X-Test-Response", requestHeaders.getValues("X-Test-Request"));
}
public static class CaptureHeadersResource extends ServerResource {
@Get("txt")
public String represent() {
return controller(
CAPTURE_HEADERS,
() -> {
handleCaptureHeaders(getRequest(), getResponse());
return CAPTURE_HEADERS.getBody();
});
}
}
public static class IndexedChildResource extends ServerResource {
@Get("txt")
public String represent() {
return controller(
INDEXED_CHILD,
() -> {
INDEXED_CHILD.collectSpanAttributes(
name -> getRequest().getOriginalRef().getQueryAsForm().getFirstValue(name));
// INDEXED_CHILD.getBody() returns an empty string, in which case Restlet sets status to
// 204
return "child";
});
}
}
private RestletAppTestBase() {}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.restlet.v2_0.spring;
import io.opentelemetry.instrumentation.restlet.v2_0.AbstractRestletServerTest;
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions;
import org.restlet.Component;
import org.restlet.Server;
import org.restlet.routing.Router;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public abstract class AbstractSpringServerTest extends AbstractRestletServerTest {
protected Router router;
protected abstract String getConfigurationName();
@Override
protected void setupServer(Component component) {
ApplicationContext context = new ClassPathXmlApplicationContext(getConfigurationName());
router = (Router) context.getBean("testRouter");
Server server = (Server) context.getBean("testServer", new Object[] {"http", port});
component.getServers().add(server);
}
@Override
protected void setupRouting() {
attach(router);
}
@Override
protected void configure(HttpServerTestOptions options) {
super.configure(options);
options.setResponseCodeOnNonStandardHttpMethod(405);
}
}