v2.0 changes

This commit is contained in:
pratik
2025-10-22 14:00:32 -05:00
parent da16787fb2
commit 05d452c250
3 changed files with 94 additions and 5 deletions

View File

@@ -182,6 +182,39 @@ public class CfDeployController {
}
}
@PostMapping(value = "/upload/chunk", consumes = "application/octet-stream")
public ResponseEntity<ChunkUploadResponse> uploadChunkRaw(
@RequestParam("uploadSessionId") String uploadSessionId,
@RequestParam("fileType") String fileType,
@RequestParam("chunkIndex") Integer chunkIndex,
@RequestParam("totalChunks") Integer totalChunks,
@RequestParam(value = "fileName", required = false) String fileName,
@RequestBody byte[] chunkData) {
try {
log.debug("Receiving raw chunk {}/{} for session: {}, fileType: {} ({} bytes)",
chunkIndex + 1, totalChunks, uploadSessionId, fileType, chunkData.length);
// Validate file type
if (!fileType.equals("jarFile") && !fileType.equals("manifest")) {
throw new IllegalArgumentException("Invalid file type. Must be 'jarFile' or 'manifest'");
}
chunkedUploadService.uploadChunkRaw(uploadSessionId, fileType, fileName,
chunkIndex, totalChunks, chunkData);
var session = chunkedUploadService.getSession(uploadSessionId);
var fileState = session.getFileStates().get(fileType);
return ResponseEntity.ok(ChunkUploadResponse.success(
uploadSessionId, fileType, chunkIndex, totalChunks,
fileState.getReceivedChunkCount()));
} catch (Exception e) {
log.error("Error uploading raw chunk", e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(ChunkUploadResponse.failure("Failed to upload chunk: " + e.getMessage()));
}
}
@PostMapping("/upload/finalize")
public ResponseEntity<DeploymentStatus> finalizeUpload(
@RequestParam("uploadSessionId") String uploadSessionId,

View File

@@ -101,6 +101,62 @@ public class ChunkedUploadService {
}
}
public synchronized void uploadChunkRaw(String sessionId, String fileType, String fileName,
int chunkIndex, int totalChunks, byte[] chunkData) throws IOException {
UploadSession session = activeSessions.get(sessionId);
if (session == null) {
throw new IllegalArgumentException("Upload session not found or expired: " + sessionId);
}
session.updateLastAccessed();
// Get or create file upload state
UploadSession.FileUploadState fileState = session.getFileStates()
.computeIfAbsent(fileType, k -> {
String targetFileName = fileType.equals("manifest") ? "manifest.yml" : fileName;
Path targetPath = session.getWorkingDirectory().resolve(targetFileName);
return new UploadSession.FileUploadState(fileName, totalChunks, targetPath);
});
// Validate total chunks consistency
if (fileState.getTotalChunks() != totalChunks) {
throw new IllegalArgumentException(
String.format("Total chunks mismatch for %s: expected %d, got %d",
fileType, fileState.getTotalChunks(), totalChunks));
}
// Write chunk to file using sequential append mode
// This supports variable chunk sizes - chunks MUST be uploaded in order (0, 1, 2, ...)
Path targetPath = fileState.getTargetPath();
// Verify chunks are uploaded in order
if (chunkIndex != fileState.getReceivedChunkCount()) {
throw new IllegalArgumentException(
String.format("Chunks must be uploaded in order. Expected chunk %d but received %d",
fileState.getReceivedChunkCount(), chunkIndex));
}
try (var outputStream = Files.newOutputStream(targetPath,
java.nio.file.StandardOpenOption.CREATE,
java.nio.file.StandardOpenOption.APPEND)) {
// Write raw byte array directly
outputStream.write(chunkData);
log.debug("Appended raw chunk {} ({} bytes) to {}",
chunkIndex, chunkData.length, targetPath.getFileName());
}
fileState.markChunkReceived(chunkIndex);
log.info("Session {}: Received raw chunk {}/{} for {} ({} bytes)",
sessionId, chunkIndex + 1, totalChunks, fileType, chunkData.length);
if (fileState.isComplete()) {
log.info("Session {}: File {} upload completed ({} chunks)",
sessionId, fileType, totalChunks);
}
}
public UploadSession getSession(String sessionId) {
UploadSession session = activeSessions.get(sessionId);
if (session != null) {