diff --git a/CHANGELOG.md b/CHANGELOG.md index 170988a..a9091e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [8.4.0] — 2026-08-29 + +### Added + +- `delete(String id)` — deletes a previously processed file + (`DELETE /v2.2/files/{id}`). Returns `true` on success; its trace is unaffected. +- `deleteTrace(String id)` — deletes the processing trace separately + (`DELETE /v2.2/files/{id}/trace`). Returns `true` on success. + ## [8.3.0] — 2026-08-14 ### Changed diff --git a/README.md b/README.md index 76b3034..44a11ba 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ System.out.printf("findings: %s%n", result.getFindings()); | `processFromUrl(URI location)` | Synchronous remote-URL scan | | `processFromUrl(URI location, Map metadata)` | Remote-URL scan with metadata | | `retrieve(String id)` | Retrieve previous scan result | +| `delete(String id)` | Delete a previous scan result | +| `deleteTrace(String id)` | Delete the processing trace for a previous scan result | | `retrieveTrace(String id)` | Retrieve ordered processing events for a result (preview) | | `fetch(String location)` | Server-side async fetch-and-scan of a remote URL | | `ping()` | Health check | diff --git a/src/main/java/com/scanii/ScaniiClient.java b/src/main/java/com/scanii/ScaniiClient.java index daae1b8..8377001 100644 --- a/src/main/java/com/scanii/ScaniiClient.java +++ b/src/main/java/com/scanii/ScaniiClient.java @@ -132,6 +132,24 @@ public interface ScaniiClient { */ Optional retrieve(String id); + /** + * Deletes a previously processed file. Its processing trace is unaffected. + * + * @param id id of the previously processed content + * @return true when the resource was deleted + * @see spec + */ + boolean delete(String id); + + /** + * Deletes the processing trace for a previously processed file. + * + * @param id id of the previously processed content + * @return true when the trace was deleted + * @see spec + */ + boolean deleteTrace(String id); + /** * Retrieves the processing trace for a previously processed file. * Returns an ordered list of events describing each stage of the processing pipeline. diff --git a/src/main/java/com/scanii/internal/DefaultScaniiClient.java b/src/main/java/com/scanii/internal/DefaultScaniiClient.java index e8fe499..b7fcaef 100644 --- a/src/main/java/com/scanii/internal/DefaultScaniiClient.java +++ b/src/main/java/com/scanii/internal/DefaultScaniiClient.java @@ -187,6 +187,36 @@ public Optional retrieve(String id) { return Optional.of(result); } + @Override + public boolean delete(String id) { + Objects.requireNonNull(id, "resource id cannot be null"); + + HttpRequest req = newRequestBuilder(target.resolve("/v2.2/files/" + id)) + .DELETE() + .build(); + HttpResponse response = send(req); + + if (response.statusCode() != 204) { + parseAndThrowError(response); + } + return true; + } + + @Override + public boolean deleteTrace(String id) { + Objects.requireNonNull(id, "resource id cannot be null"); + + HttpRequest req = newRequestBuilder(target.resolve("/v2.2/files/" + id + "/trace")) + .DELETE() + .build(); + HttpResponse response = send(req); + + if (response.statusCode() != 204) { + parseAndThrowError(response); + } + return true; + } + @Override public Optional retrieveTrace(String id) { Objects.requireNonNull(id, "resource id cannot be null"); diff --git a/src/test/java/com/scanii/ScaniiClientTest.java b/src/test/java/com/scanii/ScaniiClientTest.java index 9695614..ec64379 100644 --- a/src/test/java/com/scanii/ScaniiClientTest.java +++ b/src/test/java/com/scanii/ScaniiClientTest.java @@ -204,6 +204,28 @@ void testRetrieveTraceUnknownId() { assertTrue(opt.isEmpty()); } + @Test + void testDelete() throws Exception { + ScaniiProcessingResult processed = client.process(Systems.randomFile(1024)); + assertNotNull(processed.getResourceId()); + + assertTrue(client.delete(processed.getResourceId())); + assertTrue(client.retrieve(processed.getResourceId()).isEmpty()); + assertTrue(client.retrieveTrace(processed.getResourceId()).isPresent()); + assertTrue(client.deleteTrace(processed.getResourceId())); + assertTrue(client.retrieveTrace(processed.getResourceId()).isEmpty()); + } + + @Test + void testDeleteUnknownId() { + assertThrows(ScaniiException.class, () -> client.delete("doesnotexist")); + } + + @Test + void testDeleteTraceUnknownId() { + assertThrows(ScaniiException.class, () -> client.deleteTrace("doesnotexist")); + } + @Test void testProcessFromUrl() throws Exception { // scanii-cli serves the EICAR file at this well-known path