From 6a5fb05ac185379a895bba142289e2ebb3d24bd2 Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Tue, 27 May 2025 11:39:51 +0200 Subject: [PATCH 1/9] some changes --- .../kubernetes/KServiceLifecycleManager.java | 4 +++ .../components/helm/HelmKServiceManager.java | 18 ++++++++---- .../orchestration/AppLifecycleManager.java | 10 +++++++ .../orchestration/AppLifecycleState.java | 4 +++ .../DefaultAppLifecycleManager.java | 24 +++++++++++++++ .../AppLifecycleManagerRestController.java | 29 +++++++++++++------ .../entities/AppDeploymentState.java | 17 +++++++++++ 7 files changed, 91 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KServiceLifecycleManager.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KServiceLifecycleManager.java index 8a521c7eb..ab4595b2c 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KServiceLifecycleManager.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KServiceLifecycleManager.java @@ -2,6 +2,7 @@ package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.entities.KubernetesTemplate; import net.geant.nmaas.orchestration.Identifier; +import net.geant.nmaas.orchestration.entities.AppDeployment; public interface KServiceLifecycleManager { @@ -15,4 +16,7 @@ public interface KServiceLifecycleManager { void updateHelmRepo(); + void scaleDeployment(AppDeployment deployment, int replicas); + + } diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java index 753891c45..8767a2a2a 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java @@ -15,10 +15,11 @@ import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.en import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.entities.ServiceStorageVolume; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.exceptions.KServiceManipulationException; import net.geant.nmaas.orchestration.Identifier; +import net.geant.nmaas.orchestration.entities.AppDeployment; import net.geant.nmaas.orchestration.repositories.DomainTechDetailsRepository; +import net.geant.nmaas.utils.bash.CommandExecutionException; import net.geant.nmaas.utils.logging.LogLevel; import net.geant.nmaas.utils.logging.Loggable; -import net.geant.nmaas.utils.bash.CommandExecutionException; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -114,12 +115,12 @@ public class HelmKServiceManager implements KServiceLifecycleManager { static Map<String, String> removeRedundantParameters(Map<String, String> additionalParameters) { return additionalParameters.entrySet().stream().filter(entry -> - !entry.getKey().contains(RANDOM_ARGUMENT_EXPRESSION_PREFIX) - && !entry.getKey().contains(PUBLIC_ACCESS_SELECTOR_ARGUMENT_EXPRESSION_PREFIX) - ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + !entry.getKey().contains(RANDOM_ARGUMENT_EXPRESSION_PREFIX) + && !entry.getKey().contains(PUBLIC_ACCESS_SELECTOR_ARGUMENT_EXPRESSION_PREFIX) + ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } - private Map<String, String> getIngressVariables(IngressResourceConfigOption ingressResourceConfigOption, Set<ServiceAccessMethod> externalAccessMethods, String domain){ + private Map<String, String> getIngressVariables(IngressResourceConfigOption ingressResourceConfigOption, Set<ServiceAccessMethod> externalAccessMethods, String domain) { return HelmChartVariables.ingressVariablesMap( DEPLOY_FROM_CHART.equals(ingressResourceConfigOption), externalAccessMethods, @@ -131,7 +132,7 @@ public class HelmKServiceManager implements KServiceLifecycleManager { ); } - private String getIngressClass(String domain){ + private String getIngressClass(String domain) { if (Boolean.TRUE.equals(ingressManager.getIngressPerDomain())) { return domainTechDetailsRepository.findByDomainCodename(domain).orElseThrow(() -> new IllegalArgumentException("DomainTechDetails cannot be found for domain " + domain)).getKubernetesIngressClass(); } @@ -191,4 +192,9 @@ public class HelmKServiceManager implements KServiceLifecycleManager { } } + @Override + @Loggable(LogLevel.TRACE) + public void scaleDeployment(AppDeployment deployment, int replicas) { + } + } \ No newline at end of file diff --git a/src/main/java/net/geant/nmaas/orchestration/AppLifecycleManager.java b/src/main/java/net/geant/nmaas/orchestration/AppLifecycleManager.java index 94dbad6d4..f96ef0140 100644 --- a/src/main/java/net/geant/nmaas/orchestration/AppLifecycleManager.java +++ b/src/main/java/net/geant/nmaas/orchestration/AppLifecycleManager.java @@ -90,4 +90,14 @@ public interface AppLifecycleManager { * @param deploymentId unique identifier of the deployed user application */ void updateApplicationStatus(Identifier deploymentId); + + /** + * @param deploymentId unique identifier of the deployed user application + */ + void scaleDown(Identifier deploymentId); + + /** + * @param deploymentId unique identifier of the deployed user application + */ + void scaleUp(Identifier deploymentId); } diff --git a/src/main/java/net/geant/nmaas/orchestration/AppLifecycleState.java b/src/main/java/net/geant/nmaas/orchestration/AppLifecycleState.java index 1a0543a6b..cd031bab5 100644 --- a/src/main/java/net/geant/nmaas/orchestration/AppLifecycleState.java +++ b/src/main/java/net/geant/nmaas/orchestration/AppLifecycleState.java @@ -218,6 +218,10 @@ public enum AppLifecycleState { APPLICATION_CONFIGURATION_REMOVAL_FAILED { @Override public String getUserFriendlyState() { return "APP_INSTANCE.PROGRESS.APP_CONF_REMOVE_ERROR"; } + }, + APPLICATION_SCALED_DOWN{ + @Override + public String getUserFriendlyState(){ return "APP_INSTANCE.PROGRESS.APP_SCALED_DOWN"; } }; public abstract String getUserFriendlyState(); diff --git a/src/main/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManager.java b/src/main/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManager.java index 922afaeb1..d05c5d31b 100644 --- a/src/main/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManager.java +++ b/src/main/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManager.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import net.geant.nmaas.nmservice.NmServiceDeploymentStateChangeEvent; import net.geant.nmaas.nmservice.configuration.exceptions.UserConfigHandlingException; import net.geant.nmaas.nmservice.deployment.NmServiceRepositoryManager; +import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.KServiceLifecycleManager; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.janitor.JanitorService; import net.geant.nmaas.nmservice.deployment.entities.NmServiceDeploymentState; import net.geant.nmaas.orchestration.api.model.AppConfigurationView; @@ -54,6 +55,7 @@ public class DefaultAppLifecycleManager implements AppLifecycleManager { private final ApplicationEventPublisher eventPublisher; private final NmServiceRepositoryManager serviceRepositoryManager; private final JanitorService janitorService; + private final KServiceLifecycleManager kServiceLifecycleManager; private final AppTermsAcceptanceService appTermsAcceptanceService; private final ConfigurationManager configurationManager; @@ -278,4 +280,26 @@ public class DefaultAppLifecycleManager implements AppLifecycleManager { eventPublisher.publishEvent(new AppVerifyServiceActionEvent(this, deploymentId)); } + @Override + @Loggable(LogLevel.INFO) + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void scaleDown(Identifier deploymentId) { + AppDeployment appDeployment = deploymentRepositoryManager.load(deploymentId); + kServiceLifecycleManager.scaleDeployment(appDeployment, 0); + appDeployment.setState(AppDeploymentState.SCALED_DOWN); + + log.warn("Scaled down deployment NOT IMPLEMENT YET"); + } + + @Override + @Loggable(LogLevel.INFO) + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void scaleUp(Identifier deploymentId) { + AppDeployment appDeployment = deploymentRepositoryManager.load(deploymentId); + int replicas = 1; + kServiceLifecycleManager.scaleDeployment(appDeployment, replicas); + + log.warn("Scaled up deployment NOT IMPLEMENT YET"); + } + } diff --git a/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java b/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java index 315e0c157..983ae294c 100644 --- a/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java +++ b/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java @@ -11,16 +11,9 @@ import net.geant.nmaas.orchestration.exceptions.InvalidDeploymentIdException; import net.geant.nmaas.portal.persistent.entity.Application; import net.geant.nmaas.portal.persistent.repositories.ApplicationRepository; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.security.Principal; @@ -116,4 +109,22 @@ public class AppLifecycleManagerRestController { return ex.getMessage(); } + /** + * @param deploymentId unique identifier of the deployed user application + */ + @PutMapping("/{deploymentId}/scale-down") + public ResponseEntity<Void> scaleDownApp(@PathVariable String deploymentId) { + lifecycleManager.scaleDown(new Identifier(deploymentId)); + return ResponseEntity.ok().build(); + } + + /** + * @param deploymentId unique identifier of the deployed user application + */ + @PutMapping("/{deploymentId}/scale-up") + public ResponseEntity<Void> scaleUpApp(@PathVariable String deploymentId) { + lifecycleManager.scaleUp(new Identifier(deploymentId)); + return ResponseEntity.ok().build(); + } + } diff --git a/src/main/java/net/geant/nmaas/orchestration/entities/AppDeploymentState.java b/src/main/java/net/geant/nmaas/orchestration/entities/AppDeploymentState.java index b35e07d63..2b06341a8 100644 --- a/src/main/java/net/geant/nmaas/orchestration/entities/AppDeploymentState.java +++ b/src/main/java/net/geant/nmaas/orchestration/entities/AppDeploymentState.java @@ -541,6 +541,23 @@ public enum AppDeploymentState { @Override public boolean isInFailedState() { return true; } + }, + SCALED_DOWN { + @Override + public AppLifecycleState lifecycleState() { + return AppLifecycleState.APPLICATION_SCALED_DOWN; + } + + @Override + public AppDeploymentState nextState(NmServiceDeploymentState state) { + //TODO discous about correct next state + return APPLICATION_CONFIGURED; + } + + @Override + public boolean isInRunningState() { + return true; + } }; public abstract AppLifecycleState lifecycleState(); -- GitLab From 53439bfd7332fe8b3eb4e0b205d0ea3f87664fa0 Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Tue, 27 May 2025 12:09:03 +0200 Subject: [PATCH 2/9] some changes --- .../orchestration/DefaultAppLifecycleManagerTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManagerTest.java b/src/test/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManagerTest.java index 56ac5cd41..32a5fe6b8 100644 --- a/src/test/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManagerTest.java +++ b/src/test/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManagerTest.java @@ -2,6 +2,7 @@ package net.geant.nmaas.orchestration; import net.geant.nmaas.nmservice.NmServiceDeploymentStateChangeEvent; import net.geant.nmaas.nmservice.deployment.NmServiceRepositoryManager; +import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.KServiceLifecycleManager; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.KubernetesRepositoryManager; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.janitor.JanitorService; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.entities.KubernetesNmServiceInfo; @@ -48,6 +49,7 @@ public class DefaultAppLifecycleManagerTest { private final NmServiceRepositoryManager<KubernetesNmServiceInfo> serviceRepositoryManager = mock(KubernetesRepositoryManager.class); private final JanitorService janitorService = mock(JanitorService.class); private final AppTermsAcceptanceService appTermsAcceptanceService = mock(AppTermsAcceptanceService.class); + private final KServiceLifecycleManager kServiceLifecycleManager = mock(KServiceLifecycleManager.class); private DefaultAppLifecycleManager appLifecycleManager; @@ -55,7 +57,7 @@ public class DefaultAppLifecycleManagerTest { @BeforeEach void setup() { - appLifecycleManager = new DefaultAppLifecycleManager(repositoryManager, eventPublisher, serviceRepositoryManager, janitorService, appTermsAcceptanceService, configurationManager); + appLifecycleManager = new DefaultAppLifecycleManager(repositoryManager, eventPublisher, serviceRepositoryManager, janitorService, kServiceLifecycleManager, appTermsAcceptanceService, configurationManager); } @Test @@ -84,7 +86,7 @@ public class DefaultAppLifecycleManagerTest { AppConfigurationView configurationView = mock(AppConfigurationView.class); when(configurationView.getStorageSpace()).thenReturn(null); when(configurationView.getJsonInput()).thenReturn(""); - appLifecycleManager.applyConfiguration(new Identifier(), configurationView, "TEST" ); + appLifecycleManager.applyConfiguration(new Identifier(), configurationView, "TEST"); verify(repositoryManager, times(1)).update(any()); verify(serviceRepositoryManager, times(0)).updateStorageSpace(any(), anyInt()); verify(serviceRepositoryManager, times(0)).addAdditionalParameters(any(), anyMap()); @@ -100,7 +102,7 @@ public class DefaultAppLifecycleManagerTest { when(configurationView.getAdditionalParameters()).thenReturn("{\"keyadd1\": \"valadd1\"}"); when(configurationView.getMandatoryParameters()).thenReturn("{\"keyman1\": \"valman1\", \"keyman2\": \"valman2\"}"); when(configurationView.getJsonInput()).thenReturn(""); - appLifecycleManager.applyConfiguration(Identifier.newInstance(1L), configurationView, "TEST" ); + appLifecycleManager.applyConfiguration(Identifier.newInstance(1L), configurationView, "TEST"); ArgumentCaptor<Identifier> idArg = ArgumentCaptor.forClass(Identifier.class); ArgumentCaptor<Map<String, String>> mapArg = ArgumentCaptor.forClass(Map.class); verify(serviceRepositoryManager, times(1)).updateStorageSpace(Identifier.newInstance(1L), 10); @@ -115,7 +117,7 @@ public class DefaultAppLifecycleManagerTest { when(serviceRepositoryManager.loadService(any())).thenReturn(new KubernetesNmServiceInfo()); AppConfigurationView configurationView = mock(AppConfigurationView.class); when(configurationView.getJsonInput()).thenReturn(""); - appLifecycleManager.applyConfiguration(new Identifier(), configurationView, "TEST" ); + appLifecycleManager.applyConfiguration(new Identifier(), configurationView, "TEST"); verify(eventPublisher, times(1)).publishEvent(any(AppApplyConfigurationActionEvent.class)); } -- GitLab From 17080d3985c10e63a8c0df9c97e6543e84c8907d Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Tue, 27 May 2025 13:57:58 +0200 Subject: [PATCH 3/9] some changes --- .../nmaas/orchestration/entities/AppDeploymentState.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/geant/nmaas/orchestration/entities/AppDeploymentState.java b/src/main/java/net/geant/nmaas/orchestration/entities/AppDeploymentState.java index 2b06341a8..0c7ba812f 100644 --- a/src/main/java/net/geant/nmaas/orchestration/entities/AppDeploymentState.java +++ b/src/main/java/net/geant/nmaas/orchestration/entities/AppDeploymentState.java @@ -551,12 +551,8 @@ public enum AppDeploymentState { @Override public AppDeploymentState nextState(NmServiceDeploymentState state) { //TODO discous about correct next state - return APPLICATION_CONFIGURED; - } - - @Override - public boolean isInRunningState() { - return true; +// return APPLICATION_CONFIGURED; + return nextStateForNotMatchingNmServiceDeploymentState(this, state); } }; -- GitLab From ea8a77eb27bf00301a54d55859d5c236bc48a92a Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Wed, 28 May 2025 13:53:40 +0200 Subject: [PATCH 4/9] some changes --- .../AppLifecycleManagerRestController.java | 17 ------------ .../api/market/AppInstanceController.java | 27 +++++++++++++------ src/test/shell/data/i18n/de.json | 4 ++- src/test/shell/data/i18n/en.json | 4 ++- src/test/shell/data/i18n/fr.json | 4 ++- src/test/shell/data/i18n/pl.json | 4 ++- 6 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java b/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java index 983ae294c..beccf2ed9 100644 --- a/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java +++ b/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java @@ -109,22 +109,5 @@ public class AppLifecycleManagerRestController { return ex.getMessage(); } - /** - * @param deploymentId unique identifier of the deployed user application - */ - @PutMapping("/{deploymentId}/scale-down") - public ResponseEntity<Void> scaleDownApp(@PathVariable String deploymentId) { - lifecycleManager.scaleDown(new Identifier(deploymentId)); - return ResponseEntity.ok().build(); - } - - /** - * @param deploymentId unique identifier of the deployed user application - */ - @PutMapping("/{deploymentId}/scale-up") - public ResponseEntity<Void> scaleUpApp(@PathVariable String deploymentId) { - lifecycleManager.scaleUp(new Identifier(deploymentId)); - return ResponseEntity.ok().build(); - } } diff --git a/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java b/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java index 81365d8a6..0e1299837 100644 --- a/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java +++ b/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java @@ -48,17 +48,11 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.lang.reflect.Field; import java.security.Principal; @@ -763,5 +757,22 @@ public class AppInstanceController extends AppBaseController { } return pageable; } + /** + * @param deploymentId unique identifier of the deployed user application + */ + @PutMapping("/{deploymentId}/scale-down") + public ResponseEntity<Void> scaleDownApp(@PathVariable String deploymentId) { + appLifecycleManager.scaleDown(new Identifier(deploymentId)); + return ResponseEntity.ok().build(); + } + + /** + * @param deploymentId unique identifier of the deployed user application + */ + @PutMapping("/{deploymentId}/scale-up") + public ResponseEntity<Void> scaleUpApp(@PathVariable String deploymentId) { + appLifecycleManager.scaleUp(new Identifier(deploymentId)); + return ResponseEntity.ok().build(); + } } diff --git a/src/test/shell/data/i18n/de.json b/src/test/shell/data/i18n/de.json index 3ffdc0788..44301c83b 100644 --- a/src/test/shell/data/i18n/de.json +++ b/src/test/shell/data/i18n/de.json @@ -314,7 +314,9 @@ "RATING": "Rating", "POPULAR": "Popularity", "DATE" : "Date added" - } + }, + "SCALE_UP": "Fortsetzen", + "SCALE_DOWN": "Pause" }, "MONITOR": { "TITLE": "Überwachungsservice", diff --git a/src/test/shell/data/i18n/en.json b/src/test/shell/data/i18n/en.json index cfdd02ec4..4b2db4c1f 100644 --- a/src/test/shell/data/i18n/en.json +++ b/src/test/shell/data/i18n/en.json @@ -315,7 +315,9 @@ "RATING": "Rating", "POPULAR": "Popularity", "DATE" : "Date added" - } + }, + "SCALE_UP": "Resume", + "SCALE_DOWN": "Pause" }, "MONITOR": { "TITLE": "Monitor service", diff --git a/src/test/shell/data/i18n/fr.json b/src/test/shell/data/i18n/fr.json index 9a2949633..f5e56f1a4 100644 --- a/src/test/shell/data/i18n/fr.json +++ b/src/test/shell/data/i18n/fr.json @@ -316,7 +316,9 @@ "RATING": "Rating", "POPULAR": "Popularity", "DATE" : "Date added" - } + }, + "SCALE_UP": "Reprende", + "SCALE_DOWN": "Pause" }, "MONITOR": { "TITLE": "Monitor service", diff --git a/src/test/shell/data/i18n/pl.json b/src/test/shell/data/i18n/pl.json index 5e12f67b1..445db45ed 100644 --- a/src/test/shell/data/i18n/pl.json +++ b/src/test/shell/data/i18n/pl.json @@ -316,7 +316,9 @@ "RATING": "Ocena", "POPULAR": "Popularność", "DATE" : "Data dodania" - } + }, + "SCALE_UP": "Wznów", + "SCALE_DOWN": "Pauza" }, "MONITOR": { "TITLE": "Monitorowanie", -- GitLab From 3a3ff9c00f6d7bb880748d0a112922468a7de951 Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Wed, 28 May 2025 14:33:46 +0200 Subject: [PATCH 5/9] added service for scaling via event --- .../api/market/AppInstanceController.java | 68 +++++++------------ 1 file changed, 26 insertions(+), 42 deletions(-) diff --git a/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java b/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java index 0e1299837..735f43a87 100644 --- a/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java +++ b/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java @@ -5,50 +5,26 @@ import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import net.geant.nmaas.nmservice.configuration.gitlab.events.AddUserToRepositoryGitlabEvent; import net.geant.nmaas.nmservice.configuration.gitlab.events.RemoveUserFromRepositoryGitlabEvent; -import net.geant.nmaas.orchestration.AppDeploymentMonitor; -import net.geant.nmaas.orchestration.AppDeploymentRepositoryManager; -import net.geant.nmaas.orchestration.AppLifecycleManager; -import net.geant.nmaas.orchestration.AppLifecycleState; -import net.geant.nmaas.orchestration.Identifier; +import net.geant.nmaas.orchestration.*; import net.geant.nmaas.orchestration.api.model.AppDeploymentHistoryView; import net.geant.nmaas.orchestration.entities.AppDeployment; +import net.geant.nmaas.orchestration.events.app.AppScaleActionEvent; import net.geant.nmaas.orchestration.exceptions.InvalidAppStateException; import net.geant.nmaas.orchestration.exceptions.InvalidDeploymentIdException; import net.geant.nmaas.orchestration.exceptions.InvalidDomainException; -import net.geant.nmaas.portal.api.domain.AppInstanceBase; -import net.geant.nmaas.portal.api.domain.AppInstanceRequest; -import net.geant.nmaas.portal.api.domain.AppInstanceState; -import net.geant.nmaas.portal.api.domain.AppInstanceStatus; -import net.geant.nmaas.portal.api.domain.AppInstanceView; -import net.geant.nmaas.portal.api.domain.AppInstanceViewExtended; -import net.geant.nmaas.portal.api.domain.ApplicationBaseView; -import net.geant.nmaas.portal.api.domain.ConfigWizardTemplateView; -import net.geant.nmaas.portal.api.domain.Id; -import net.geant.nmaas.portal.api.domain.UserBase; +import net.geant.nmaas.portal.api.domain.*; import net.geant.nmaas.portal.api.exception.MissingElementException; import net.geant.nmaas.portal.api.exception.ProcessingException; import net.geant.nmaas.portal.exceptions.ApplicationSubscriptionNotActiveException; -import net.geant.nmaas.portal.persistent.entity.AppInstance; -import net.geant.nmaas.portal.persistent.entity.Application; -import net.geant.nmaas.portal.persistent.entity.ApplicationBase; -import net.geant.nmaas.portal.persistent.entity.Domain; -import net.geant.nmaas.portal.persistent.entity.Role; -import net.geant.nmaas.portal.persistent.entity.SSHKeyEntity; -import net.geant.nmaas.portal.persistent.entity.User; -import net.geant.nmaas.portal.persistent.entity.UserRole; -import net.geant.nmaas.portal.service.ApplicationBaseService; -import net.geant.nmaas.portal.service.ApplicationInstanceService; -import net.geant.nmaas.portal.service.ApplicationService; -import net.geant.nmaas.portal.service.ConfigurationManager; -import net.geant.nmaas.portal.service.DomainService; -import net.geant.nmaas.portal.service.UserService; +import net.geant.nmaas.portal.persistent.entity.*; +import net.geant.nmaas.portal.service.*; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.http.ResponseEntity; +import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.transaction.annotation.Transactional; @@ -56,11 +32,7 @@ import org.springframework.web.bind.annotation.*; import java.lang.reflect.Field; import java.security.Principal; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @RestController @@ -248,7 +220,7 @@ public class AppInstanceController extends AppBaseController { public Id createAppInstance(@RequestBody AppInstanceRequest appInstanceRequest, @NotNull Principal principal, @PathVariable Long domainId, - @RequestParam(name = "clusterId",required = false) Long clusterId) { + @RequestParam(name = "clusterId", required = false) Long clusterId) { log.error("Cluster = {}", clusterId); Application app = getApp(appInstanceRequest.getApplicationId()); Domain domain = domainService.findDomain(domainId) @@ -757,22 +729,34 @@ public class AppInstanceController extends AppBaseController { } return pageable; } + /** * @param deploymentId unique identifier of the deployed user application */ @PutMapping("/{deploymentId}/scale-down") - public ResponseEntity<Void> scaleDownApp(@PathVariable String deploymentId) { - appLifecycleManager.scaleDown(new Identifier(deploymentId)); - return ResponseEntity.ok().build(); + @ResponseStatus(HttpStatus.NO_CONTENT) + public void scaleDownApp(@PathVariable String deploymentId) { + eventPublisher.publishEvent( + new AppScaleActionEvent( + this, + new Identifier(deploymentId), + ScaleDirection.DOWN) + ); } /** * @param deploymentId unique identifier of the deployed user application */ @PutMapping("/{deploymentId}/scale-up") - public ResponseEntity<Void> scaleUpApp(@PathVariable String deploymentId) { - appLifecycleManager.scaleUp(new Identifier(deploymentId)); - return ResponseEntity.ok().build(); + @ResponseStatus(HttpStatus.NO_CONTENT) + public void scaleUpApp(@PathVariable String deploymentId) { + + eventPublisher.publishEvent( + new AppScaleActionEvent( + this, + new Identifier(deploymentId), + ScaleDirection.UP) + ); } } -- GitLab From 4c161415eb05b812c8a35aee425b6d0123d70227 Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Wed, 28 May 2025 14:33:59 +0200 Subject: [PATCH 6/9] added event --- .../nmaas/orchestration/ScaleDirection.java | 5 +++ .../events/app/AppScaleActionEvent.java | 27 ++++++++++++ .../orchestration/tasks/app/AppScaleTask.java | 43 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 src/main/java/net/geant/nmaas/orchestration/ScaleDirection.java create mode 100644 src/main/java/net/geant/nmaas/orchestration/events/app/AppScaleActionEvent.java create mode 100644 src/main/java/net/geant/nmaas/orchestration/tasks/app/AppScaleTask.java diff --git a/src/main/java/net/geant/nmaas/orchestration/ScaleDirection.java b/src/main/java/net/geant/nmaas/orchestration/ScaleDirection.java new file mode 100644 index 000000000..434ac8fa4 --- /dev/null +++ b/src/main/java/net/geant/nmaas/orchestration/ScaleDirection.java @@ -0,0 +1,5 @@ +package net.geant.nmaas.orchestration; + +public enum ScaleDirection { + UP, DOWN +} diff --git a/src/main/java/net/geant/nmaas/orchestration/events/app/AppScaleActionEvent.java b/src/main/java/net/geant/nmaas/orchestration/events/app/AppScaleActionEvent.java new file mode 100644 index 000000000..4f6f103d8 --- /dev/null +++ b/src/main/java/net/geant/nmaas/orchestration/events/app/AppScaleActionEvent.java @@ -0,0 +1,27 @@ +package net.geant.nmaas.orchestration.events.app; + +import net.geant.nmaas.orchestration.ScaleDirection; +import org.springframework.context.ApplicationEvent; +import net.geant.nmaas.orchestration.Identifier; + + +public class AppScaleActionEvent extends ApplicationEvent { + + private final Identifier deploymentId; + private final ScaleDirection direction; + + public AppScaleActionEvent(Object source, Identifier deploymentId, ScaleDirection direction) { + super(source); + this.deploymentId = deploymentId; + this.direction = direction; + } + + public Identifier getDeploymentId() { + return deploymentId; + } + + public ScaleDirection getDirection() { + return direction; + } + +} diff --git a/src/main/java/net/geant/nmaas/orchestration/tasks/app/AppScaleTask.java b/src/main/java/net/geant/nmaas/orchestration/tasks/app/AppScaleTask.java new file mode 100644 index 000000000..6e3a84acf --- /dev/null +++ b/src/main/java/net/geant/nmaas/orchestration/tasks/app/AppScaleTask.java @@ -0,0 +1,43 @@ +package net.geant.nmaas.orchestration.tasks.app; + +import lombok.RequiredArgsConstructor; +import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.KServiceLifecycleManager; +import net.geant.nmaas.orchestration.AppDeploymentRepositoryManager; +import net.geant.nmaas.orchestration.entities.AppDeployment; +import net.geant.nmaas.orchestration.entities.AppDeploymentState; +import net.geant.nmaas.orchestration.events.app.AppScaleActionEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class AppScaleTask { + + private final KServiceLifecycleManager kServiceLifecycleManager; + private final AppDeploymentRepositoryManager appDeploymentRepositoryManager; + + + @EventListener + public void handleScaleEvent(AppScaleActionEvent event) { + + AppDeployment appDeployment = appDeploymentRepositoryManager.load(event.getDeploymentId()); + + switch (event.getDirection()) { + case DOWN: + appDeployment.setState(AppDeploymentState.SCALED_DOWN); + appDeploymentRepositoryManager.update(appDeployment); + + kServiceLifecycleManager.scaleDeployment(event.getDeploymentId(), 0); + + break; + case UP: + appDeployment.setState(AppDeploymentState.APPLICATION_CONFIGURED); + appDeploymentRepositoryManager.update(appDeployment); + + kServiceLifecycleManager.scaleDeployment(event.getDeploymentId(), 1); + + break; + } + + } +} -- GitLab From 3122486f8dae92bc665e358d0577527e06ba2439 Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Wed, 28 May 2025 14:34:43 +0200 Subject: [PATCH 7/9] changed argument method from AppDeployment to Identifier --- .../kubernetes/KServiceLifecycleManager.java | 3 +-- .../kubernetes/components/helm/HelmKServiceManager.java | 2 +- .../nmaas/orchestration/DefaultAppLifecycleManager.java | 5 ++--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KServiceLifecycleManager.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KServiceLifecycleManager.java index ab4595b2c..f730fcbeb 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KServiceLifecycleManager.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KServiceLifecycleManager.java @@ -2,7 +2,6 @@ package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.entities.KubernetesTemplate; import net.geant.nmaas.orchestration.Identifier; -import net.geant.nmaas.orchestration.entities.AppDeployment; public interface KServiceLifecycleManager { @@ -16,7 +15,7 @@ public interface KServiceLifecycleManager { void updateHelmRepo(); - void scaleDeployment(AppDeployment deployment, int replicas); + void scaleDeployment(Identifier deploymentId, int replicas); } diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java index 8767a2a2a..54f10b9f4 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java @@ -194,7 +194,7 @@ public class HelmKServiceManager implements KServiceLifecycleManager { @Override @Loggable(LogLevel.TRACE) - public void scaleDeployment(AppDeployment deployment, int replicas) { + public void scaleDeployment(Identifier deploymentId, int replicas) { } } \ No newline at end of file diff --git a/src/main/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManager.java b/src/main/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManager.java index d05c5d31b..e73935198 100644 --- a/src/main/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManager.java +++ b/src/main/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManager.java @@ -285,7 +285,7 @@ public class DefaultAppLifecycleManager implements AppLifecycleManager { @Transactional(propagation = Propagation.REQUIRES_NEW) public void scaleDown(Identifier deploymentId) { AppDeployment appDeployment = deploymentRepositoryManager.load(deploymentId); - kServiceLifecycleManager.scaleDeployment(appDeployment, 0); + kServiceLifecycleManager.scaleDeployment(deploymentId, 0); appDeployment.setState(AppDeploymentState.SCALED_DOWN); log.warn("Scaled down deployment NOT IMPLEMENT YET"); @@ -295,9 +295,8 @@ public class DefaultAppLifecycleManager implements AppLifecycleManager { @Loggable(LogLevel.INFO) @Transactional(propagation = Propagation.REQUIRES_NEW) public void scaleUp(Identifier deploymentId) { - AppDeployment appDeployment = deploymentRepositoryManager.load(deploymentId); int replicas = 1; - kServiceLifecycleManager.scaleDeployment(appDeployment, replicas); + kServiceLifecycleManager.scaleDeployment(deploymentId, replicas); log.warn("Scaled up deployment NOT IMPLEMENT YET"); } -- GitLab From 9b6744f9c5c191951ad666d405342f80b5f52d33 Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Wed, 28 May 2025 14:52:46 +0200 Subject: [PATCH 8/9] some changes --- src/test/shell/data/i18n/de.json | 4 ++-- src/test/shell/data/i18n/en.json | 4 ++-- src/test/shell/data/i18n/fr.json | 4 ++-- src/test/shell/data/i18n/pl.json | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/shell/data/i18n/de.json b/src/test/shell/data/i18n/de.json index 44301c83b..ba1a92fa2 100644 --- a/src/test/shell/data/i18n/de.json +++ b/src/test/shell/data/i18n/de.json @@ -315,8 +315,8 @@ "POPULAR": "Popularity", "DATE" : "Date added" }, - "SCALE_UP": "Fortsetzen", - "SCALE_DOWN": "Pause" + "SCALED_UP": "Fortsetzen", + "SCALED_DOWN": "Pause" }, "MONITOR": { "TITLE": "Überwachungsservice", diff --git a/src/test/shell/data/i18n/en.json b/src/test/shell/data/i18n/en.json index 4b2db4c1f..ad5555bd1 100644 --- a/src/test/shell/data/i18n/en.json +++ b/src/test/shell/data/i18n/en.json @@ -316,8 +316,8 @@ "POPULAR": "Popularity", "DATE" : "Date added" }, - "SCALE_UP": "Resume", - "SCALE_DOWN": "Pause" + "SCALED_UP": "Resume", + "SCALED_DOWN": "Pause" }, "MONITOR": { "TITLE": "Monitor service", diff --git a/src/test/shell/data/i18n/fr.json b/src/test/shell/data/i18n/fr.json index f5e56f1a4..49995a806 100644 --- a/src/test/shell/data/i18n/fr.json +++ b/src/test/shell/data/i18n/fr.json @@ -317,8 +317,8 @@ "POPULAR": "Popularity", "DATE" : "Date added" }, - "SCALE_UP": "Reprende", - "SCALE_DOWN": "Pause" + "SCALED_UP": "Reprende", + "SCALED_DOWN": "Pause" }, "MONITOR": { "TITLE": "Monitor service", diff --git a/src/test/shell/data/i18n/pl.json b/src/test/shell/data/i18n/pl.json index 445db45ed..76d6f8a01 100644 --- a/src/test/shell/data/i18n/pl.json +++ b/src/test/shell/data/i18n/pl.json @@ -317,8 +317,8 @@ "POPULAR": "Popularność", "DATE" : "Data dodania" }, - "SCALE_UP": "Wznów", - "SCALE_DOWN": "Pauza" + "SCALED_UP": "Wznów", + "SCALED_DOWN": "Pauza" }, "MONITOR": { "TITLE": "Monitorowanie", -- GitLab From f978cfb5671e610262c22dc23049dd4d3a156c2e Mon Sep 17 00:00:00 2001 From: pkazimierowski <pkazimierowski@man.poznan.pl> Date: Wed, 28 May 2025 15:11:30 +0200 Subject: [PATCH 9/9] fixed imports --- .../api/market/AppInstanceController.java | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java b/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java index baf2bd768..a0df53777 100644 --- a/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java +++ b/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java @@ -5,16 +5,18 @@ import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import net.geant.nmaas.nmservice.configuration.gitlab.events.AddUserToRepositoryGitlabEvent; import net.geant.nmaas.nmservice.configuration.gitlab.events.RemoveUserFromRepositoryGitlabEvent; -import net.geant.nmaas.orchestration.*; +import net.geant.nmaas.orchestration.AppDeploymentMonitor; +import net.geant.nmaas.orchestration.AppDeploymentRepositoryManager; +import net.geant.nmaas.orchestration.AppLifecycleManager; +import net.geant.nmaas.orchestration.AppLifecycleState; +import net.geant.nmaas.orchestration.Identifier; +import net.geant.nmaas.orchestration.ScaleDirection; import net.geant.nmaas.orchestration.api.model.AppDeploymentHistoryView; import net.geant.nmaas.orchestration.entities.AppDeployment; import net.geant.nmaas.orchestration.events.app.AppScaleActionEvent; import net.geant.nmaas.orchestration.exceptions.InvalidAppStateException; import net.geant.nmaas.orchestration.exceptions.InvalidDeploymentIdException; import net.geant.nmaas.orchestration.exceptions.InvalidDomainException; -import net.geant.nmaas.portal.api.domain.*; -import net.geant.nmaas.portal.api.exception.MissingElementException; -import net.geant.nmaas.portal.api.exception.ProcessingException; import net.geant.nmaas.portal.api.domain.AppInstanceBase; import net.geant.nmaas.portal.api.domain.AppInstanceRequest; import net.geant.nmaas.portal.api.domain.AppInstanceState; @@ -28,8 +30,20 @@ import net.geant.nmaas.portal.api.domain.UserBase; import net.geant.nmaas.portal.api.exceptions.MissingElementException; import net.geant.nmaas.portal.api.exceptions.ProcessingException; import net.geant.nmaas.portal.exceptions.ApplicationSubscriptionNotActiveException; -import net.geant.nmaas.portal.persistent.entity.*; -import net.geant.nmaas.portal.service.*; +import net.geant.nmaas.portal.persistent.entity.AppInstance; +import net.geant.nmaas.portal.persistent.entity.Application; +import net.geant.nmaas.portal.persistent.entity.ApplicationBase; +import net.geant.nmaas.portal.persistent.entity.Domain; +import net.geant.nmaas.portal.persistent.entity.Role; +import net.geant.nmaas.portal.persistent.entity.SSHKeyEntity; +import net.geant.nmaas.portal.persistent.entity.User; +import net.geant.nmaas.portal.persistent.entity.UserRole; +import net.geant.nmaas.portal.service.ApplicationBaseService; +import net.geant.nmaas.portal.service.ApplicationInstanceService; +import net.geant.nmaas.portal.service.ApplicationService; +import net.geant.nmaas.portal.service.ConfigurationManager; +import net.geant.nmaas.portal.service.DomainService; +import net.geant.nmaas.portal.service.UserService; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -40,11 +54,24 @@ import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; import java.lang.reflect.Field; import java.security.Principal; -import java.util.*; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; @RestController -- GitLab