Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9c89071
feat: attach Java dedup agent in sample
officialasishkumar Apr 29, 2026
ac87dbd
test: require checked-in dedup fixtures
officialasishkumar Apr 30, 2026
6ba4150
test: reduce java dedup fixtures
officialasishkumar Apr 30, 2026
c040034
test: include dropwizard docker build artifacts
officialasishkumar Apr 30, 2026
ca3b86e
test: align dropwizard distroless runtime user
officialasishkumar Apr 30, 2026
a4c721d
chore: use released java dedup agent
officialasishkumar Apr 30, 2026
6d1bb42
docs: use Java dedup agent 2.0.2
officialasishkumar Apr 30, 2026
500c67f
ci: remove java dedup sample workflows
officialasishkumar Apr 30, 2026
a8cc8cd
docs: bump Java dedup agent example to 2.0.6
officialasishkumar Apr 30, 2026
ce0c318
fix(dropwizard-dedup): allow shaded jar through .dockerignore
officialasishkumar Apr 30, 2026
3577a5b
test(dropwizard-dedup): expand fixtures to 200 tests across 4 sets
officialasishkumar Apr 30, 2026
05ac1cf
fix(dropwizard-dedup): match keploy record YAML format exactly
officialasishkumar Apr 30, 2026
cea0bec
fix(dropwizard-dedup): drop empty mocks.yaml files
officialasishkumar Apr 30, 2026
200c22c
fix(dropwizard-dedup): match Spring fixture format for docker replay
officialasishkumar Apr 30, 2026
89f2a72
fix(dropwizard-dedup): noise Content-Length, restore full header capture
officialasishkumar Apr 30, 2026
bcf652d
fix(dropwizard-dedup): split 200 fixtures into 8 sets of 25
officialasishkumar Apr 30, 2026
e3d51b5
fix(dropwizard-dedup): collapse fixtures into 1 test set of 200
officialasishkumar Apr 30, 2026
dcef3ad
fix(dropwizard-dedup): scope Docker coverage to app classes
officialasishkumar Apr 30, 2026
92dad43
feat(java-dedup): add simple Java smoke sample
officialasishkumar Apr 30, 2026
b3d776d
test(java-dedup): add simple sample dedup artifacts
officialasishkumar Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ This repo contains the sample for [Keploy's](https://keploy.io) Java Application
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.
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.
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.
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.
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.

## Community Support ❤️

Expand Down
13 changes: 13 additions & 0 deletions dropwizard-dedup/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
target/*
!target/dropwizard-dedup.jar
!target/keploy-sdk.jar
!target/jacocoagent.jar
!target/classes/
!target/classes/**
!target/dependency/
!target/dependency/**
keploy/reports
dedupData.yaml
duplicates.yaml
replay-*.log
dedup-*.log
3 changes: 3 additions & 0 deletions dropwizard-dedup/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target/
/*.log
/META-INF/
17 changes: 17 additions & 0 deletions dropwizard-dedup/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
ARG JAVA_VERSION=8
FROM eclipse-temurin:${JAVA_VERSION}-jre

WORKDIR /app

RUN groupadd --gid 10001 appuser \
&& useradd --uid 10001 --gid 10001 --home-dir /home/appuser --create-home --shell /usr/sbin/nologin appuser

COPY --chown=10001:10001 target/dropwizard-dedup.jar /app/app.jar
COPY --chown=10001:10001 target/classes /app/classes
COPY --chown=10001:10001 target/keploy-sdk.jar /app/keploy-sdk.jar
COPY --chown=10001:10001 target/jacocoagent.jar /app/jacocoagent.jar
COPY --chown=10001:10001 config.yml /app/config.yml
ENV KEPLOY_JAVA_CLASS_DIRS=/app/classes
EXPOSE 8080
USER 10001:10001
ENTRYPOINT ["java", "-javaagent:/app/keploy-sdk.jar", "-javaagent:/app/jacocoagent.jar=destfile=/tmp/jacoco.exec", "-jar", "/app/app.jar", "server", "/app/config.yml"]
19 changes: 19 additions & 0 deletions dropwizard-dedup/Dockerfile.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ARG JAVA_VERSION=8
FROM eclipse-temurin:${JAVA_VERSION}-jre

WORKDIR /app

RUN groupadd --gid 10001 appuser \
&& useradd --uid 10001 --gid 10001 --home-dir /home/appuser --create-home --shell /usr/sbin/nologin appuser

COPY --chown=10001:10001 target/classes /app/classes
COPY --chown=10001:10001 target/dependency /app/libs
COPY --chown=10001:10001 target/keploy-sdk.jar /app/keploy-sdk.jar
COPY --chown=10001:10001 target/jacocoagent.jar /app/jacocoagent.jar
COPY --chown=10001:10001 config.yml /app/config.yml

ENV KEPLOY_JAVA_CLASS_DIRS=/app/classes

EXPOSE 8080
USER 10001:10001
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"]
14 changes: 14 additions & 0 deletions dropwizard-dedup/Dockerfile.distroless
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM gcr.io/distroless/java17-debian12:nonroot
WORKDIR /app

COPY --chown=10001:10001 target/dropwizard-dedup.jar /app/app.jar
COPY --chown=10001:10001 target/classes /app/classes
COPY --chown=10001:10001 target/keploy-sdk.jar /app/keploy-sdk.jar
COPY --chown=10001:10001 target/jacocoagent.jar /app/jacocoagent.jar
COPY --chown=10001:10001 config.yml /app/config.yml

ENV KEPLOY_JAVA_CLASS_DIRS=/app/classes

EXPOSE 8080
USER 10001:10001
ENTRYPOINT ["java", "-javaagent:/app/keploy-sdk.jar", "-javaagent:/app/jacocoagent.jar=destfile=/tmp/jacoco.exec", "-jar", "/app/app.jar", "server", "/app/config.yml"]
26 changes: 26 additions & 0 deletions dropwizard-dedup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Dropwizard Dynamic Deduplication Sample

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.

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.

Build without Keploy on the compile classpath:

```bash
mvn -B -DskipTests clean package
```

Build with the runtime Java agent copied into `target/keploy-sdk.jar`:

```bash
mvn -B -DskipTests -Dkeploy.agent.version=2.0.6 clean package
```

Run with the agent:

```bash
java \
-javaagent:target/keploy-sdk.jar \
-javaagent:target/jacocoagent.jar=destfile=/tmp/jacoco.exec \
-jar target/dropwizard-dedup.jar server config.yml
```
12 changes: 12 additions & 0 deletions dropwizard-dedup/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
server:
applicationConnectors:
- type: http
port: ${DW_HTTP_PORT:-8080}
adminConnectors:
- type: http
port: ${DW_ADMIN_PORT:-8081}

logging:
level: WARN
appenders:
- type: console
4 changes: 4 additions & 0 deletions dropwizard-dedup/docker-compose.classpath.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
dropwizard-dedup:
build:
dockerfile: Dockerfile.classpath
4 changes: 4 additions & 0 deletions dropwizard-dedup/docker-compose.distroless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
dropwizard-dedup:
build:
dockerfile: Dockerfile.distroless
7 changes: 7 additions & 0 deletions dropwizard-dedup/docker-compose.restricted.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
dropwizard-dedup:
read_only: true
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
13 changes: 13 additions & 0 deletions dropwizard-dedup/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
services:
dropwizard-dedup:
image: ${JAVA_DEDUP_IMAGE:-dropwizard-dedup:local}
build:
context: .
dockerfile: Dockerfile
args:
JAVA_VERSION: ${JAVA_VERSION:-8}
environment:
KEPLOY_JAVA_DEDUP_DIAGNOSTICS: ${KEPLOY_JAVA_DEDUP_DIAGNOSTICS:-}
container_name: dedup-java
ports:
- "${JAVA_DEDUP_HOST_PORT:-8080}:8080"
91 changes: 91 additions & 0 deletions dropwizard-dedup/keploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Generated by Keploy (3-dev)
path: ""
appId: 0
appName: ""
command: ""
templatize:
testSets: []
port: 0
proxyPort: 16789
incomingProxyPort: 36789
dnsPort: 26789
debug: false
disableANSI: false
disableTele: false
generateGithubActions: false
containerName: ""
networkName: ""
buildDelay: 30
test:
selectedTests: {}
ignoredTests: {}
globalNoise:
global: {}
test-sets: {}
replaceWith:
global: {}
test-sets: {}
delay: 5
host: "localhost"
port: 0
grpcPort: 0
ssePort: 0
protocol:
http:
port: 0
sse:
port: 0
grpc:
port: 0
apiTimeout: 5
skipCoverage: false
coverageReportPath: ""
ignoreOrdering: true
mongoPassword: "default@123"
language: ""
removeUnusedMocks: false
fallBackOnMiss: false
jacocoAgentPath: ""
basePath: ""
mocking: true
disableLineCoverage: false
disableMockUpload: false
useLocalMock: false
updateTemplate: false
mustPass: false
maxFailAttempts: 5
maxFlakyChecks: 1
protoFile: ""
protoDir: ""
protoInclude: []
compareAll: false
updateTestMapping: false
disableAutoHeaderNoise: false
strictMockWindow: true
dedup: false
freezeTime: false
fuzzyMatch: false
record:
recordTimer: 0s
filters: []
sync: false
memoryLimit: 0
configPath: ""
bypassRules: []
disableMapping: true
contract:
driven: "consumer"
mappings:
servicesMapping: {}
self: "s1"
services: []
tests: []
path: ""
download: false
generate: false
inCi: false
cmdType: "native"
enableTesting: false
inDocker: false
keployContainer: "keploy-v3"
keployNetwork: "keploy-network"
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Generated by Keploy (3-dev)
version: api.keploy.io/v1beta1
kind: Http
name: test-134
name: test-1
spec:
metadata: {}
req:
Expand All @@ -10,30 +10,34 @@ spec:
proto_minor: 1
url: http://127.0.0.1:8080/healthz
header:
Accept: '*/*'
Host: 127.0.0.1:8080
Host: '127.0.0.1:8080'
User-Agent: curl/8.19.0
body: ""
timestamp: 2026-04-24T12:48:16.682031005+05:30
Accept: '*/*'
body: ''
timestamp: 2026-04-30T21:29:55Z
resp:
status_code: 200
header:
Date: 'Thu, 30 Apr 2026 21:29:55 GMT'
Content-Type: application/json
Date: Fri, 24 Apr 2026 07:18:16 GMT
Vary: Accept-Encoding
Content-Length: 16
body: '{"healthy":true}'
status_message: OK
proto_major: 0
proto_minor: 0
timestamp: 2026-04-24T12:48:16.684674594+05:30
timestamp: 2026-04-30T21:29:55Z
objects: []
assertions:
noise:
header.Date: []
created: 1777015096
header.Vary: []
header.Content-Length: []
created: 1777584595
app_port: 8080
curl: |
curl --request GET \
--url http://127.0.0.1:8080/healthz \
--header 'User-Agent: curl/8.19.0' \
--header 'Accept: */*' \
--header 'Host: 127.0.0.1:8080' \
--header 'User-Agent: curl/8.19.0' \
--header 'Accept: */*'
43 changes: 43 additions & 0 deletions dropwizard-dedup/keploy/test-set-0/tests/test-10.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generated by Keploy (3-dev)
version: api.keploy.io/v1beta1
kind: Http
name: test-10
spec:
metadata: {}
req:
method: GET
proto_major: 1
proto_minor: 1
url: http://127.0.0.1:8080/catalog?category=books&limit=2
header:
Host: '127.0.0.1:8080'
User-Agent: curl/8.19.0
Accept: '*/*'
body: ''
timestamp: 2026-04-30T21:29:55Z
resp:
status_code: 200
header:
Date: 'Thu, 30 Apr 2026 21:29:55 GMT'
Content-Type: application/json
Vary: Accept-Encoding
Content-Length: 257
body: '{"category":"books","limit":2,"items":[{"sku":"BK-1","name":"Clean Architecture","category":"books","status":"available","price":"32.50"},{"sku":"BK-2","name":"Effective Java","category":"books","status":"available","price":"45.00"}],"source":"warehouse-a"}'
status_message: OK
proto_major: 0
proto_minor: 0
timestamp: 2026-04-30T21:29:55Z
objects: []
assertions:
noise:
header.Date: []
header.Vary: []
header.Content-Length: []
created: 1777584595
app_port: 8080
curl: |
curl --request GET \
--url 'http://127.0.0.1:8080/catalog?category=books&limit=2' \
--header 'Host: 127.0.0.1:8080' \
--header 'User-Agent: curl/8.19.0' \
--header 'Accept: */*'
47 changes: 47 additions & 0 deletions dropwizard-dedup/keploy/test-set-0/tests/test-100.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Keploy (3-dev)
version: api.keploy.io/v1beta1
kind: Http
name: test-100
spec:
metadata: {}
req:
method: GET
proto_major: 1
proto_minor: 1
url: http://127.0.0.1:8080/headers
header:
Host: '127.0.0.1:8080'
User-Agent: curl/8.19.0
Accept: '*/*'
X-Tenant: globex
X-Request-Id: req-001
body: ''
timestamp: 2026-04-30T21:29:55Z
resp:
status_code: 200
header:
Date: 'Thu, 30 Apr 2026 21:29:55 GMT'
Content-Type: application/json
Vary: Accept-Encoding
Content-Length: 41
body: '{"tenant":"globex","requestId":"req-001"}'
status_message: OK
proto_major: 0
proto_minor: 0
timestamp: 2026-04-30T21:29:55Z
objects: []
assertions:
noise:
header.Date: []
header.Vary: []
header.Content-Length: []
created: 1777584595
app_port: 8080
curl: |
curl --request GET \
--url http://127.0.0.1:8080/headers \
--header 'Host: 127.0.0.1:8080' \
--header 'User-Agent: curl/8.19.0' \
--header 'Accept: */*' \
--header 'X-Tenant: globex' \
--header 'X-Request-Id: req-001'
Loading
Loading