Skip to content

Commit ead8d0a

Browse files
committed
WIP
1 parent 2aeb457 commit ead8d0a

File tree

6 files changed

+119
-0
lines changed

6 files changed

+119
-0
lines changed

dd-java-agent/instrumentation/resteasy-appsec/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ dependencies {
4040
exclude group: 'org.eclipse.jetty', module: 'jetty-server'
4141
}
4242

43+
testFixturesImplementation project(':dd-java-agent:instrumentation:jax-rs-annotations-2')
44+
4345
nettyTestImplementation group: 'io.netty', name: 'netty', version: '3.8.0.Final' // upgrade netty to a version we support
4446
nettyTestImplementation group: 'org.jboss.resteasy', name: 'resteasy-netty', version :'3.0.0.Final'
4547
nettyTestImplementation project(':dd-java-agent:instrumentation:netty-3.8')

dd-smoke-tests/resteasy/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dependencies {
1616
implementation group: 'org.jboss.resteasy', name: 'resteasy-undertow', version:'3.1.0.Final'
1717
implementation group: 'org.jboss.resteasy', name: 'resteasy-cdi', version:'3.1.0.Final'
1818
implementation group: 'org.jboss.weld.servlet', name: 'weld-servlet', version: '2.4.8.Final'
19+
implementation 'org.jboss.resteasy:resteasy-jackson2-provider:3.1.0.Final'
1920

2021
implementation group: 'javax.el', name: 'javax.el-api', version:'3.0.0'
2122

@@ -24,6 +25,7 @@ dependencies {
2425

2526
testImplementation project(':dd-smoke-tests')
2627
testImplementation(testFixtures(project(":dd-smoke-tests:iast-util")))
28+
testImplementation project(':dd-smoke-tests:appsec')
2729
}
2830

2931
tasks.withType(Test).configureEach {

dd-smoke-tests/resteasy/src/main/java/smoketest/resteasy/App.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package smoketest.resteasy;
22

3+
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
4+
35
import java.util.HashSet;
46
import java.util.Set;
57
import javax.ws.rs.core.Application;
@@ -10,6 +12,8 @@ public class App extends Application {
1012

1113
public App() {
1214
singletons.add(new Resource());
15+
singletons.add(org.jboss.resteasy.plugins.providers.StringTextStar.class); // Writer for String
16+
singletons.add(new JacksonJsonProvider()); // Writer for json
1317
}
1418

1519
@Override

dd-smoke-tests/resteasy/src/main/java/smoketest/resteasy/Resource.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,18 @@ public Response responseLocation(@QueryParam("param") String param) throws URISy
9494
public Response getCookie() throws SQLException {
9595
return Response.ok().cookie(new NewCookie("user-id", "7")).build();
9696
}
97+
98+
@Path("/api_security/response")
99+
@GET
100+
@Produces(MediaType.APPLICATION_JSON)
101+
public Response bodyJson() {
102+
TestEntity testEntity = new TestEntity("testing", "test");
103+
return Response.ok().entity(testEntity).build();
104+
}
105+
106+
@GET
107+
@Path("/api_security/sampling/{i}")
108+
public Response apiSecuritySamplingWithStatus(@PathParam("i") int i) {
109+
return Response.status(i).header("content-type", "text/plain").entity("Hello!\n").build();
110+
}
97111
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package smoketest.resteasy;
2+
3+
public class TestEntity {
4+
public String param1;
5+
public String param2;
6+
7+
public TestEntity() {
8+
super();
9+
}
10+
11+
public TestEntity(String param1, String param2) {
12+
this.param1 = param1;
13+
this.param2 = param2;
14+
}
15+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package smoketest
2+
3+
import datadog.smoketest.appsec.AbstractAppSecServerSmokeTest
4+
import datadog.trace.api.Platform
5+
import okhttp3.Request
6+
import okhttp3.Response
7+
import spock.lang.IgnoreIf
8+
9+
@IgnoreIf({
10+
System.getProperty("java.vendor").contains("IBM") && System.getProperty("java.version").contains("1.8.")
11+
})
12+
class ResteasyAppsecSmokeTest extends AbstractAppSecServerSmokeTest {
13+
14+
@Override
15+
ProcessBuilder createProcessBuilder() {
16+
String jarPath = System.getProperty("datadog.smoketest.resteasy.jar.path")
17+
18+
List<String> command = new ArrayList<>()
19+
command.add(javaPath())
20+
command.addAll(defaultJavaProperties)
21+
22+
if (Platform.isJavaVersionAtLeast(17)) {
23+
command.addAll(["--add-opens", "java.base/java.lang=ALL-UNNAMED"])
24+
}
25+
command.addAll(["-jar", jarPath, Integer.toString(httpPort)])
26+
ProcessBuilder processBuilder = new ProcessBuilder(command)
27+
processBuilder.directory(new File(buildDirectory))
28+
}
29+
30+
void 'API Security samples only one request per endpoint'() {
31+
given:
32+
def url = "http://localhost:${httpPort}/hello/api_security/sampling/200?test=value"
33+
def request = new Request.Builder()
34+
.url(url)
35+
.addHeader('X-My-Header', "value")
36+
.get()
37+
.build()
38+
39+
when:
40+
List<Response> responses = (1..3).collect {
41+
client.newCall(request).execute()
42+
}
43+
44+
then:
45+
responses.each {
46+
assert it.code() == 200
47+
}
48+
waitForTraceCount(3)
49+
def spans = rootSpans.toList().toSorted { it.span.duration }
50+
spans.size() == 3
51+
def sampledSpans = spans.findAll {
52+
it.meta.keySet().any {
53+
it.startsWith('_dd.appsec.s.req.')
54+
}
55+
}
56+
sampledSpans.size() == 1
57+
def span = sampledSpans[0]
58+
span.meta.containsKey('_dd.appsec.s.req.query')
59+
span.meta.containsKey('_dd.appsec.s.req.params')
60+
span.meta.containsKey('_dd.appsec.s.req.headers')
61+
}
62+
63+
64+
void 'test response schema extraction'() {
65+
given:
66+
def url = "http://localhost:${httpPort}/hello/api_security/response"
67+
def request = new Request.Builder()
68+
.url(url)
69+
.get()
70+
.build()
71+
72+
when:
73+
final response = client.newCall(request).execute()
74+
waitForTraceCount(1)
75+
76+
then:
77+
response.code() == 200
78+
def span = rootSpans.first()
79+
span.meta.containsKey('_dd.appsec.s.res.headers')
80+
span.meta.containsKey('_dd.appsec.s.res.body')
81+
}
82+
}

0 commit comments

Comments
 (0)