Add UUID-based file download support to NotificationServer
- Introduce `/notify/{uuid}/{file}.json` endpoint in `NotificationServer`.
- Validate UUID format and handle bad requests with appropriate error responses.
- Extend `FileDownloadService` to support downloads using UUIDs.
- Refactor common file download logic for reuse across endpoints.
This commit is contained in:
parent
fbc9b5a9c6
commit
48a01e0a98
|
|
@ -7,6 +7,8 @@ import io.javalin.http.HttpStatus;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,6 +38,7 @@ public class NotificationServer {
|
||||||
}).start(port);
|
}).start(port);
|
||||||
|
|
||||||
app.get("/notify/{file}.json", this::handleNotifyRequest);
|
app.get("/notify/{file}.json", this::handleNotifyRequest);
|
||||||
|
app.get("/notify/{uuid}/{file}.json", this::handleNotifyRequestUuid);
|
||||||
|
|
||||||
log.info("NotificationServer started on port {}", port);
|
log.info("NotificationServer started on port {}", port);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -58,12 +61,45 @@ public class NotificationServer {
|
||||||
*/
|
*/
|
||||||
private void handleNotifyRequest(Context ctx) {
|
private void handleNotifyRequest(Context ctx) {
|
||||||
String uri = ctx.path();
|
String uri = ctx.path();
|
||||||
log.info("Received request: {} {}", ctx.method(), uri);
|
log.info("Received download request: {} {}", ctx.method(), uri);
|
||||||
|
|
||||||
String fileName = ctx.pathParam("file") + ".json";
|
String fileName = ctx.pathParam("file") + ".json";
|
||||||
log.info("Requested file: {}", fileName);
|
log.info("Requested file: {}", fileName);
|
||||||
|
|
||||||
FileDownloadService.downloadFileAsync(fileName).thenAccept(fileData -> {
|
CompletableFuture<Optional<byte[]>> optionalCompletableFuture = FileDownloadService.downloadFileAsync(fileName);
|
||||||
|
downloadFile(ctx, optionalCompletableFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles requests to the /notify/<file>.json endpoint.
|
||||||
|
*/
|
||||||
|
private void handleNotifyRequestUuid(Context ctx) {
|
||||||
|
String uri = ctx.path();
|
||||||
|
log.info("Received UUID request: {} {}", ctx.method(), uri);
|
||||||
|
|
||||||
|
String stringUUID = ctx.pathParam("uuid");
|
||||||
|
log.info("Requested uuid: {}", stringUUID);
|
||||||
|
|
||||||
|
UUID uuid;
|
||||||
|
try {
|
||||||
|
uuid = UUID.fromString(stringUUID);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Invalid UUID: {}", stringUUID, e);
|
||||||
|
ctx.status(HttpStatus.BAD_REQUEST);
|
||||||
|
ctx.contentType("text/plain");
|
||||||
|
ctx.result("Invalid UUID format");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileName = ctx.pathParam("file") + ".json";
|
||||||
|
log.info("Requested uuid file: {}", fileName);
|
||||||
|
|
||||||
|
CompletableFuture<Optional<byte[]>> optionalCompletableFuture = FileDownloadService.downloadFileAsync(uuid, fileName);
|
||||||
|
downloadFile(ctx, optionalCompletableFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadFile(Context ctx, CompletableFuture<Optional<byte[]>> optionalCompletableFuture) {
|
||||||
|
optionalCompletableFuture.thenAccept(fileData -> {
|
||||||
if (fileData.isPresent()) {
|
if (fileData.isPresent()) {
|
||||||
ctx.contentType("application/json");
|
ctx.contentType("application/json");
|
||||||
ctx.result(fileData.get());
|
ctx.result(fileData.get());
|
||||||
|
|
@ -73,7 +109,7 @@ public class NotificationServer {
|
||||||
ctx.result("File not found or download failed");
|
ctx.result("File not found or download failed");
|
||||||
}
|
}
|
||||||
}).exceptionally(e -> {
|
}).exceptionally(e -> {
|
||||||
log.error("Error downloading file: {}", fileName, e);
|
log.error("Error downloading file", e);
|
||||||
ctx.status(HttpStatus.INTERNAL_SERVER_ERROR);
|
ctx.status(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
ctx.contentType("text/plain");
|
ctx.contentType("text/plain");
|
||||||
ctx.result("Failed to handle download");
|
ctx.result("Failed to handle download");
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -31,6 +32,20 @@ public class FileDownloadService {
|
||||||
}
|
}
|
||||||
downloadUrl += fileName;
|
downloadUrl += fileName;
|
||||||
|
|
||||||
|
return downloadFileFromUrlAsync(downloadUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompletableFuture<Optional<byte[]>> downloadFileAsync(UUID uuid, String fileName) {
|
||||||
|
String downloadUrl = Config.DOWNLOAD_ENDPOINT;
|
||||||
|
if (!downloadUrl.endsWith("/")) {
|
||||||
|
downloadUrl += "/";
|
||||||
|
}
|
||||||
|
downloadUrl += uuid.toString() + "/";
|
||||||
|
downloadUrl += fileName;
|
||||||
|
return downloadFileFromUrlAsync(downloadUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompletableFuture<Optional<byte[]>> downloadFileFromUrlAsync(String downloadUrl) {
|
||||||
log.debug("Downloading file from {}", downloadUrl);
|
log.debug("Downloading file from {}", downloadUrl);
|
||||||
|
|
||||||
HttpClient client = HttpClient.newHttpClient();
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
|
@ -43,15 +58,15 @@ public class FileDownloadService {
|
||||||
return client.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray())
|
return client.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray())
|
||||||
.thenApply(response -> {
|
.thenApply(response -> {
|
||||||
if (response.statusCode() == HttpServletResponse.SC_OK) {
|
if (response.statusCode() == HttpServletResponse.SC_OK) {
|
||||||
log.debug("Successfully downloaded file: {}", fileName);
|
log.debug("Successfully downloaded file: {}", downloadUrl);
|
||||||
return Optional.of(response.body());
|
return Optional.of(response.body());
|
||||||
} else {
|
} else {
|
||||||
log.error("Failed to download file: {}. Status code: {}", fileName, response.statusCode());
|
log.error("Failed to download file: {}. Status code: {}", downloadUrl, response.statusCode());
|
||||||
return Optional.<byte[]>empty();
|
return Optional.<byte[]>empty();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.exceptionally(e -> {
|
.exceptionally(e -> {
|
||||||
log.error("Exception occurred while downloading file: {}", fileName, e);
|
log.error("Exception occurred while downloading file: {}", downloadUrl, e);
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user