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 8a521c7ebcf5d8d38530da81cc97bd68dd9fcb51..f730fcbebcab631b4607c061b402258445e0810a 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 @@ -15,4 +15,7 @@ public interface KServiceLifecycleManager { void updateHelmRepo(); + 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 5419effb43ab57463fd89c96edb50d578694d7b7..f8b3e1aa50039a106cfb4eb9ee31e4646b46f4f4 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 @@ -16,10 +16,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; @@ -130,12 +131,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, @@ -147,7 +148,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(); } @@ -207,4 +208,9 @@ public class HelmKServiceManager implements KServiceLifecycleManager { } } + @Override + @Loggable(LogLevel.TRACE) + public void scaleDeployment(Identifier deploymentId, 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 94dbad6d4c431158915338caf4d0cd809f778e56..f96ef014020b7c7a4b8d1698dfba790ae804babd 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 1a0543a6b25b8720aab58840c013655be902930e..cd031bab5e9b572adf7b9a1b4b805675d839f86f 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 002a19f318cf343a71ec92866e55dd60e8420291..289409f9a5bd512c24d4f1d48464602ef5698bb6 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,25 @@ 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(deploymentId, 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) { + int replicas = 1; + kServiceLifecycleManager.scaleDeployment(deploymentId, replicas); + + log.warn("Scaled up deployment NOT IMPLEMENT YET"); + } + } 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 0000000000000000000000000000000000000000..434ac8fa48fcdacb3e5fa88ad08220e916c04902 --- /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/api/AppLifecycleManagerRestController.java b/src/main/java/net/geant/nmaas/orchestration/api/AppLifecycleManagerRestController.java index 315e0c1578bc90fc42aee76873dfa3480566d33a..beccf2ed97fdde74a3c2b7bb6b17af52468fe1f9 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,5 @@ public class AppLifecycleManagerRestController { return ex.getMessage(); } + } 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 b35e07d6321a576a04040fb6928e7bd8cd4c0c96..0c7ba812fb2f26c9ddd5fc339a2579fa680dc838 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,19 @@ 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; + return nextStateForNotMatchingNmServiceDeploymentState(this, state); + } }; public abstract AppLifecycleState lifecycleState(); 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 0000000000000000000000000000000000000000..4f6f103d8026247f081203eeaaa39d6c74a0500e --- /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 0000000000000000000000000000000000000000..6e3a84acfc568b41e0ef5469461e95953342ca93 --- /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; + } + + } +} 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 939bbedeff525ffbff54e956aeb68696c9fd8fc3..a0df5377727aa0256a1f0789612914638624cb70 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 @@ -10,8 +10,10 @@ 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; @@ -48,6 +50,7 @@ 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.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.transaction.annotation.Transactional; @@ -55,9 +58,11 @@ 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; @@ -254,7 +259,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) @@ -765,4 +770,33 @@ public class AppInstanceController extends AppBaseController { return pageable; } + /** + * @param deploymentId unique identifier of the deployed user application + */ + @PutMapping("/{deploymentId}/scale-down") + @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") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void scaleUpApp(@PathVariable String deploymentId) { + + eventPublisher.publishEvent( + new AppScaleActionEvent( + this, + new Identifier(deploymentId), + ScaleDirection.UP) + ); + } + } diff --git a/src/test/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManagerTest.java b/src/test/java/net/geant/nmaas/orchestration/DefaultAppLifecycleManagerTest.java index 56ac5cd411410824419eca167674bca53885e804..32a5fe6b834c1bef8b58f52902f5cbc497d1fba5 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)); } diff --git a/src/test/shell/data/i18n/de.json b/src/test/shell/data/i18n/de.json index 3c41aede4d90d8ebf6629eb2403fc703ec43c86d..da39ebf6f21962821bd320953016ce9481aa4939 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" - } + }, + "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 d3c53fa9cb8cadcf0ff094629360a2b88a501516..7e72dc93321aa42f566df167d0a7899a4cf16403 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" - } + }, + "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 bb3d002a589907554502336bf0e76009455c20a1..798c4dd6756eff885a9eee4173f511d8f7a15db5 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" - } + }, + "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 251192c6f1fd5f0dea948567c3a94f5ae67d4ef7..c666060a7c33958662a64d5620f23ffa2e23cbf5 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" - } + }, + "SCALED_UP": "Wznów", + "SCALED_DOWN": "Pauza" }, "MONITOR": { "TITLE": "Monitorowanie",