From d23fe756e855396751bd4f0b33e9a8bf758f24f8 Mon Sep 17 00:00:00 2001 From: Aliaksandr Stsiapanay Date: Tue, 18 Feb 2025 19:45:12 +0300 Subject: [PATCH] fix: resolve PR comments --- .../server/service/ApplicationService.java | 44 +++++----- .../server/ApplicationDeploymentApiTest.java | 85 +++++++++++++++++++ 2 files changed, 106 insertions(+), 23 deletions(-) diff --git a/server/src/main/java/com/epam/aidial/core/server/service/ApplicationService.java b/server/src/main/java/com/epam/aidial/core/server/service/ApplicationService.java index a9491f40..ea93894a 100644 --- a/server/src/main/java/com/epam/aidial/core/server/service/ApplicationService.java +++ b/server/src/main/java/com/epam/aidial/core/server/service/ApplicationService.java @@ -25,6 +25,7 @@ import com.epam.aidial.core.storage.service.ResourceService; import com.epam.aidial.core.storage.util.EtagHeader; import com.epam.aidial.core.storage.util.UrlUtil; +import io.vertx.core.Future; import io.vertx.core.Vertx; import io.vertx.core.json.JsonObject; import lombok.Getter; @@ -343,12 +344,11 @@ public Application redeployApplication(ProxyContext context, ResourceDescriptor verifyApplication(resource); controller.verifyActive(); - Application application = prepareApplicationToUndeploy(resource); + Pair> result = undeployApplicationInternal(resource); - vertx.executeBlocking(() -> terminateApplication(resource, null), false) - .map(ignore -> deployApplication(context, resource)) + result.getValue().map(ignore -> deployApplication(context, resource)) .onFailure(error -> log.error("Application redeployment is failed due to the error", error)); - return application; + return result.getKey(); } public Application deployApplication(ProxyContext context, ResourceDescriptor resource) { @@ -386,29 +386,13 @@ public Application deployApplication(ProxyContext context, ResourceDescriptor re } public Application undeployApplication(ResourceDescriptor resource) { - verifyApplication(resource); - controller.verifyActive(); - - Application application = prepareApplicationToUndeploy(resource); - - vertx.executeBlocking(() -> terminateApplication(resource, null), false); - return application; + return undeployApplicationInternal(resource).getKey(); } - public Application.Logs getApplicationLogs(ResourceDescriptor resource) { + private Pair> undeployApplicationInternal(ResourceDescriptor resource) { verifyApplication(resource); controller.verifyActive(); - Application application = getApplication(resource).getValue(); - - if (application.getFunction() == null || application.getFunction().getStatus() != Application.Function.Status.DEPLOYED) { - throw new HttpException(HttpStatus.CONFLICT, "Application is not started: " + resource.getUrl()); - } - - return controller.getApplicationLogs(application.getFunction()); - } - - private Application prepareApplicationToUndeploy(ResourceDescriptor resource) { MutableObject result = new MutableObject<>(); resourceService.computeResource(resource, json -> { Application application = ProxyUtil.convertToObject(json, Application.class); @@ -437,7 +421,21 @@ private Application prepareApplicationToUndeploy(ResourceDescriptor resource) { return ProxyUtil.convertToString(application); }); - return result.getValue(); + Future future = vertx.executeBlocking(() -> terminateApplication(resource, null), false); + return Pair.of(result.getValue(), future); + } + + public Application.Logs getApplicationLogs(ResourceDescriptor resource) { + verifyApplication(resource); + controller.verifyActive(); + + Application application = getApplication(resource).getValue(); + + if (application.getFunction() == null || application.getFunction().getStatus() != Application.Function.Status.DEPLOYED) { + throw new HttpException(HttpStatus.CONFLICT, "Application is not started: " + resource.getUrl()); + } + + return controller.getApplicationLogs(application.getFunction()); } private void prepareApplication(ResourceDescriptor resource, Application application) { diff --git a/server/src/test/java/com/epam/aidial/core/server/ApplicationDeploymentApiTest.java b/server/src/test/java/com/epam/aidial/core/server/ApplicationDeploymentApiTest.java index 8b041f14..36e89afe 100644 --- a/server/src/test/java/com/epam/aidial/core/server/ApplicationDeploymentApiTest.java +++ b/server/src/test/java/com/epam/aidial/core/server/ApplicationDeploymentApiTest.java @@ -221,6 +221,91 @@ void testApplicationStopped() { """); } + @Test + void testApplicationRestarted() { + testApplicationStarted(); + + webServer.map(HttpMethod.DELETE, "/v1/image/0123", 200, + """ + event: result + data: {} + """); + webServer.map(HttpMethod.DELETE, "/v1/deployment/0123", 200, + """ + event: result + data: {"deleted":true} + """); + + Response response = send(HttpMethod.POST, "/v1/ops/application/redeploy", null, """ + { + "url": "applications/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/my-app" + } + """); + verifyJsonNotExact(response, 200, """ + { + "name" : "applications/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/my-app", + "display_name" : "My App", + "display_version" : "1.0", + "icon_url" : "http://application1/icon.svg", + "description" : "My App Description", + "reference" : "@ignore", + "forward_auth_token" : false, + "features" : { }, + "defaults" : { }, + "interceptors" : [ ], + "description_keywords" : [ ], + "max_retry_attempts" : 1, + "function" : { + "id" : "0123", + "runtime": "python3.11", + "author_bucket" : "3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST", + "source_folder" : "files/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/my-app/", + "target_folder" : "files/2CZ9i2bcBACFts8JbBu3MdcF8sdwTbELGXeFRV6CVDwnPEU8vWC1y8PpXyRChHQvzt/", + "status" : "UNDEPLOYING", + "mapping" : { + "chat_completion" : "/application" + }, + "env" : { + "VAR" : "VAL" + } + } + } + """); + + response = awaitApplicationStatus("/v1/applications/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/my-app", "DEPLOYED"); + verifyJsonNotExact(response, 200, """ + { + "name" : "applications/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/my-app", + "endpoint" : "http://localhost:17321/application", + "display_name" : "My App", + "display_version" : "1.0", + "icon_url" : "http://application1/icon.svg", + "description" : "My App Description", + "reference" : "@ignore", + "forward_auth_token" : false, + "features" : { }, + "defaults" : { }, + "interceptors" : [ ], + "description_keywords" : [ ], + "max_retry_attempts" : 1, + "function" : { + "id" : "0123", + "runtime": "python3.11", + "author_bucket" : "3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST", + "source_folder" : "files/3CcedGxCx23EwiVbVmscVktScRyf46KypuBQ65miviST/my-app/", + "target_folder" : "files/2CZ9i2bcBACFts8JbBu3MdcF8sdwTbELGXeFRV6CVDwnPEU8vWC1y8PpXyRChHQvzt/", + "status" : "DEPLOYED", + "mapping" : { + "chat_completion" : "/application" + }, + "env" : { + "VAR" : "VAL" + } + } + } + """); + } + @Test void testApplicationFailed() { testApplicationCreated();