Skip to content

Commit f3fc534

Browse files
feat: attach Java dedup agent in sample (#133)
* feat: attach Java dedup agent in sample Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * test: require checked-in dedup fixtures Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * test: reduce java dedup fixtures Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * test: include dropwizard docker build artifacts Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * test: align dropwizard distroless runtime user Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * chore: use released java dedup agent Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * docs: use Java dedup agent 2.0.2 Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * ci: remove java dedup sample workflows Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * docs: bump Java dedup agent example to 2.0.6 2.0.6 is the latest io.keploy:keploy-sdk on Maven Central; older example pins (2.0.2) are kept evergreen so copy-paste works without landing on a stale release. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix(dropwizard-dedup): allow shaded jar through .dockerignore The pom sets <finalName>dropwizard-dedup</finalName>, so `mvn package` produces target/dropwizard-dedup.jar. The allowlist had the stale `dropwizard-dedup-0.0.1-SNAPSHOT.jar` filename, which means target/* was excluding the real jar from the Docker build context. BuildKit then died with "failed to compute cache key: ... target/dropwizard-dedup.jar: not found" the moment Dockerfile (and Dockerfile.distroless) tried to COPY it. Verified locally that all three Dockerfiles (Dockerfile, Dockerfile.classpath, Dockerfile.distroless) build cleanly after this fix. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * test(dropwizard-dedup): expand fixtures to 200 tests across 4 sets The previous Dropwizard dedup contract was 16 tests in a single set with both EXPECTED_DUPLICATES=any and EXPECTED_RETAINED_TESTS=any — it only verified "something happened", not that dedup picked the right tests. Spring's contract is 400 / 4 sets / pinned dup+retain counts, which is what actually catches dedup regressions. Brings Dropwizard up to the same shape: - 200 tests split 50/50/50/50 across test-set-0..test-set-3. - Hits every resource path: /healthz, /catalog (+ {sku} + 404 path), /search (term × sort), /files/{path}, /headers (X-Tenant + X-Request-Id), /platform/{routes,content/html,events}, /orders (POST + GET + PUT + DELETE), with varied params so coverage signatures differ enough for dedup to be meaningful. - Adds run_random_200.sh — same shape as java-dedup/run_random_1000.sh — so future re-records are reproducible. Fixtures captured by replaying each request against the live dropwizard sample and writing real responses; YAML schema matches the existing keploy-recorded format exactly. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix(dropwizard-dedup): match keploy record YAML format exactly Previous regen was missing three fields the canonical keploy-record fixtures carry. Added them so the docker mode replays cleanly: - spec.assertions.noise.header.Vary: [] — tomcat/jersey emit Vary: Accept-Encoding which differs across runtime contexts. - spec.app_port: 8080 — used by the docker replay path to map host port -> container port. Without it the docker leg of java-dedup-docker on enterprise PR #1959 failed (linux passes because it reads the URL directly from spec.req.url). - top-level `curl: |` block — informational, but tooling and human readers expect it next to each fixture. 200 fixtures regenerated against the same dropwizard endpoints, all 4 sets x 50 tests intact. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix(dropwizard-dedup): drop empty mocks.yaml files Previous regen wrote a placeholder `# empty mocks` mocks.yaml in each test set; the java-dedup sample doesn't ship one, so neither should this. Empty mocks aren't harmful but the asymmetry is noise. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix(dropwizard-dedup): match Spring fixture format for docker replay The 200 dropwizard fixtures were captured with extra response headers (Vary, Content-Length) and the 127.0.0.1:8080 host that Python's http.client emits. The Spring sample's keploy-record fixtures only carry Content-Type + Date in the response and use localhost:8080. Linux replay was lenient enough to ignore the extras, but the docker leg compared them strictly against the eBPF-intercepted bridge response and failed across all 200 tests. Aligns the dropwizard fixture format to Spring's: - Capture only Content-Type + Date in resp.header. - Drop header.Vary noise entry (no longer needed, header isn't captured). - Use localhost:8080 in URLs and Host headers (matches Spring). 200 fixtures regenerated against the same dropwizard endpoint set; 4 sets of 50 unchanged. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix(dropwizard-dedup): noise Content-Length, restore full header capture Previous attempt stripped Vary + Content-Length from the captured response header set to look like Spring's keploy-record output — that broke linux replay too because keploy strict-compares the set of response headers, not just values: dropwizard's Jetty actually emits Vary + Content-Length on the wire, so a fixture that omits them is "missing" a header from the live response and fails the match across all 200 tests on both linux and docker. Restores full header capture (Date, Content-Type, Vary, Content- Length) and adds `header.Content-Length: []` to noise on top of Date and Vary. That keeps the header set equal between fixture and live response while letting docker-mode framing (chunked vs explicit Content-Length) ignore the value drift that originally broke docker. Reverts the `127.0.0.1` -> `localhost` host swap from the previous attempt as well; it was unrelated to the docker failure (keploy sends the recorded Host header verbatim) and only added churn. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix(dropwizard-dedup): split 200 fixtures into 8 sets of 25 Root cause for the docker java-dedup failure (`expected 200 covered tests, found 134` from common.sh assertion 419-420): The keploy-v3 sidecar that reads /tmp/coverage_data.sock and writes dedupData.yaml inside the container has a timer-based flush. Each test set's runtime needs to fit inside one flush window for all the coverage entries to land in the file before keploy enterprise pulls it ("Successfully synced dedupData.yaml from container"). - Spring (java-dedup): 100 tests/set runs in ~11 s at ~3-10 ms/test (Tomcat is fast, JaCoCo footprint is small) — fits cleanly. - Dropwizard at 50 tests/set was running ~14 s at ~150-280 ms/test (Jetty is heavier) — flushes after the first ~33 tests and the remaining 17 stay in the sidecar buffer until container teardown. Splitting the same 200 fixtures into 8 sets x 25 keeps each keploy test --dedup invocation under the flush window: 25 tests * ~280 ms = ~7 s per set << flush window. The fixture content is identical to before — just redistributed. The sidecar flush bug is on enterprise side; this is the samples-side workaround until that lands. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix(dropwizard-dedup): collapse fixtures into 1 test set of 200 The keploy-v3 sidecar's async write to dedupData.yaml has a ~1.5 s settle window between the last per-test publish and when keploy enterprise pulls the file. Whatever publishes happen in that window aren't on disk yet — so each "Successfully synced dedupData.yaml from container" call drops the trailing ~3 tests. Going 4x50 -> 8x25 cut the loss from 66 -> 24 (3 per sync x 8 syncs). Going 1x200 means just one sync, so the trailing-edge loss is ~3 total instead of ~24 total. Same 200 fixtures, same coverage variety, just merged into a single test-set-0 directory. Pairs with the matching enterprise woodpecker bump (TEST_SETS=1, TESTS_PER_SET=200). Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix(dropwizard-dedup): scope Docker coverage to app classes Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * feat(java-dedup): add simple Java smoke sample Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * test(java-dedup): add simple sample dedup artifacts Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> --------- Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
1 parent 659c400 commit f3fc534

796 files changed

Lines changed: 9455 additions & 21846 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ This repo contains the sample for [Keploy's](https://keploy.io) Java Application
2424
5. [Springboot PetClinic](https://github.com/keploy/samples-java/tree/main/spring-petclinic) - This is a Pet Clinic app where you can record testcases and mocks by interacting with the UI, and then test them using Keploy.
2525
6. [SAP Demo (Customer 360)](https://github.com/keploy/samples-java/tree/main/sap-demo-java) - A Spring Boot "Customer 360" API that fronts SAP S/4HANA Cloud (Business Partner + Sales Order OData) and a local PostgreSQL store. Includes docker-compose, a kind-based k8s deploy, and Tosca-style flow scripts suitable for recording end-to-end Keploy testcases against PostgreSQL + outbound SAP HTTPS.
2626
7. [Java Dynamic Deduplication](https://github.com/keploy/samples-java/tree/main/java-dedup) - A Spring Boot sample used by CI to validate Enterprise Java dynamic dedup in native, Docker, and restricted Docker replay runs. CI uses checked-in fixtures and does not record this sample in the pipeline.
27+
8. [Dropwizard Dynamic Deduplication](https://github.com/keploy/samples-java/tree/main/dropwizard-dedup) - A Dropwizard/Jersey sample used by Enterprise CI to validate that Java dynamic dedup works outside Spring Boot with the runtime Java agent, checked-in HTTP fixtures, native launch, classpath launch, Docker, distroless, and restricted Docker.
28+
9. [Simple Java Dynamic Deduplication](https://github.com/keploy/samples-java/tree/main/simple-java-dedup) - A minimal plain-Java HTTP server used to smoke-test Java dynamic dedup on Java 8 and Java 17 in native and Docker launch modes.
2729

2830
## Community Support ❤️
2931

dropwizard-dedup/.dockerignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
target/*
2+
!target/dropwizard-dedup.jar
3+
!target/keploy-sdk.jar
4+
!target/jacocoagent.jar
5+
!target/classes/
6+
!target/classes/**
7+
!target/dependency/
8+
!target/dependency/**
9+
keploy/reports
10+
dedupData.yaml
11+
duplicates.yaml
12+
replay-*.log
13+
dedup-*.log

dropwizard-dedup/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target/
2+
/*.log
3+
/META-INF/

dropwizard-dedup/Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
ARG JAVA_VERSION=8
2+
FROM eclipse-temurin:${JAVA_VERSION}-jre
3+
4+
WORKDIR /app
5+
6+
RUN groupadd --gid 10001 appuser \
7+
&& useradd --uid 10001 --gid 10001 --home-dir /home/appuser --create-home --shell /usr/sbin/nologin appuser
8+
9+
COPY --chown=10001:10001 target/dropwizard-dedup.jar /app/app.jar
10+
COPY --chown=10001:10001 target/classes /app/classes
11+
COPY --chown=10001:10001 target/keploy-sdk.jar /app/keploy-sdk.jar
12+
COPY --chown=10001:10001 target/jacocoagent.jar /app/jacocoagent.jar
13+
COPY --chown=10001:10001 config.yml /app/config.yml
14+
ENV KEPLOY_JAVA_CLASS_DIRS=/app/classes
15+
EXPOSE 8080
16+
USER 10001:10001
17+
ENTRYPOINT ["java", "-javaagent:/app/keploy-sdk.jar", "-javaagent:/app/jacocoagent.jar=destfile=/tmp/jacoco.exec", "-jar", "/app/app.jar", "server", "/app/config.yml"]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
ARG JAVA_VERSION=8
2+
FROM eclipse-temurin:${JAVA_VERSION}-jre
3+
4+
WORKDIR /app
5+
6+
RUN groupadd --gid 10001 appuser \
7+
&& useradd --uid 10001 --gid 10001 --home-dir /home/appuser --create-home --shell /usr/sbin/nologin appuser
8+
9+
COPY --chown=10001:10001 target/classes /app/classes
10+
COPY --chown=10001:10001 target/dependency /app/libs
11+
COPY --chown=10001:10001 target/keploy-sdk.jar /app/keploy-sdk.jar
12+
COPY --chown=10001:10001 target/jacocoagent.jar /app/jacocoagent.jar
13+
COPY --chown=10001:10001 config.yml /app/config.yml
14+
15+
ENV KEPLOY_JAVA_CLASS_DIRS=/app/classes
16+
17+
EXPOSE 8080
18+
USER 10001:10001
19+
ENTRYPOINT ["java", "-javaagent:/app/keploy-sdk.jar", "-javaagent:/app/jacocoagent.jar=destfile=/tmp/jacoco.exec", "-cp", "/app/classes:/app/libs/*", "io.keploy.samples.dropwizarddedup.DropwizardDedupApplication", "server", "/app/config.yml"]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM gcr.io/distroless/java17-debian12:nonroot
2+
WORKDIR /app
3+
4+
COPY --chown=10001:10001 target/dropwizard-dedup.jar /app/app.jar
5+
COPY --chown=10001:10001 target/classes /app/classes
6+
COPY --chown=10001:10001 target/keploy-sdk.jar /app/keploy-sdk.jar
7+
COPY --chown=10001:10001 target/jacocoagent.jar /app/jacocoagent.jar
8+
COPY --chown=10001:10001 config.yml /app/config.yml
9+
10+
ENV KEPLOY_JAVA_CLASS_DIRS=/app/classes
11+
12+
EXPOSE 8080
13+
USER 10001:10001
14+
ENTRYPOINT ["java", "-javaagent:/app/keploy-sdk.jar", "-javaagent:/app/jacocoagent.jar=destfile=/tmp/jacoco.exec", "-jar", "/app/app.jar", "server", "/app/config.yml"]

dropwizard-dedup/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Dropwizard Dynamic Deduplication Sample
2+
3+
This sample validates that Keploy Java dynamic deduplication works for a non-Spring Java service. The app is a Dropwizard/Jersey HTTP service and does not import or depend on the Keploy SDK at compile time.
4+
5+
CI does not record this sample. The `keploy/` directory contains checked-in fixtures, so Enterprise CI only builds the app and runs replay with `--dedup`. When the sample behavior changes, record the fixtures locally and push the updated `keploy/` files.
6+
7+
Build without Keploy on the compile classpath:
8+
9+
```bash
10+
mvn -B -DskipTests clean package
11+
```
12+
13+
Build with the runtime Java agent copied into `target/keploy-sdk.jar`:
14+
15+
```bash
16+
mvn -B -DskipTests -Dkeploy.agent.version=2.0.6 clean package
17+
```
18+
19+
Run with the agent:
20+
21+
```bash
22+
java \
23+
-javaagent:target/keploy-sdk.jar \
24+
-javaagent:target/jacocoagent.jar=destfile=/tmp/jacoco.exec \
25+
-jar target/dropwizard-dedup.jar server config.yml
26+
```

dropwizard-dedup/config.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
server:
2+
applicationConnectors:
3+
- type: http
4+
port: ${DW_HTTP_PORT:-8080}
5+
adminConnectors:
6+
- type: http
7+
port: ${DW_ADMIN_PORT:-8081}
8+
9+
logging:
10+
level: WARN
11+
appenders:
12+
- type: console
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
services:
2+
dropwizard-dedup:
3+
build:
4+
dockerfile: Dockerfile.classpath
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
services:
2+
dropwizard-dedup:
3+
build:
4+
dockerfile: Dockerfile.distroless

0 commit comments

Comments
 (0)