in server/src/main/java/com/epam/aidial/core/server/controller/ResourceController.java [186:243]
private Future<?> putResource(ResourceDescriptor descriptor) {
if (descriptor.isFolder()) {
return context.respond(BAD_REQUEST, "Folder not allowed: " + descriptor.getUrl());
}
if (!ResourceDescriptorFactory.isValidResourcePath(descriptor)) {
return context.respond(BAD_REQUEST, "Resource name and/or parent folders must not end with .(dot)");
}
int contentLength = ProxyUtil.contentLength(context.getRequest(), 0);
int contentLimit = resourceService.getMaxSize();
if (contentLength > contentLimit) {
String message = "Resource size: %s exceeds max limit: %s".formatted(contentLength, contentLimit);
return context.respond(HttpStatus.REQUEST_ENTITY_TOO_LARGE, message);
}
Future<Pair<EtagHeader, String>> requestFuture = context.getRequest().body().map(bytes -> {
if (bytes.length() > contentLimit) {
String message = "Resource size: %s exceeds max limit: %s".formatted(bytes.length(), contentLimit);
throw new HttpException(HttpStatus.REQUEST_ENTITY_TOO_LARGE, message);
}
EtagHeader etag = ProxyUtil.etag(context.getRequest());
String body = bytes.toString(StandardCharsets.UTF_8);
return Pair.of(etag, body);
});
Future<ResourceItemMetadata> responseFuture;
if (descriptor.getType() == ResourceTypes.APPLICATION) {
responseFuture = requestFuture.compose(pair -> {
EtagHeader etag = pair.getKey();
Application application = ProxyUtil.convertToObject(pair.getValue(), Application.class);
return vertx.executeBlocking(() -> {
validateCustomApplication(application);
return applicationService.putApplication(descriptor, etag, application).getKey();
}, false);
});
} else {
responseFuture = requestFuture.compose(pair -> {
EtagHeader etag = pair.getKey();
String body = pair.getValue();
validateRequestBody(descriptor, body);
return vertx.executeBlocking(() -> resourceService.putResource(descriptor, body, etag), false);
});
}
responseFuture.onSuccess((metadata) -> {
context.putHeader(HttpHeaders.ETAG, metadata.getEtag())
.exposeHeaders()
.respond(HttpStatus.OK, metadata);
})
.onFailure(error -> handleError(descriptor, error));
return Future.succeededFuture();
}