diff --git a/docker/nmaas-platform.properties.template b/docker/nmaas-platform.properties.template index 93cec7bb271b472a93c632e9a3f8388b75a1eef2..3c3612040d65754cfe9dc412d26e803c5848e77c 100644 --- a/docker/nmaas-platform.properties.template +++ b/docker/nmaas-platform.properties.template @@ -141,8 +141,7 @@ janitor.port=${JANITOR_PORT} # -------------------- # # GitLab configuration # # -------------------- # -gitlab.address=${GITLAB_ADDRESS} -gitlab.port=${GITLAB_PORT} +gitlab.apiUrl=${GITLAB_API_URL} gitlab.token=${GITLAB_TOKEN} # ------------------------ # diff --git a/src/integrationTest/resources/application.properties b/src/integrationTest/resources/application.properties index f97e69412aab321e14b36f930f78ccb9105ef1c5..cba386b644c32db8498fd14e6eff98ffbb8db03f 100644 --- a/src/integrationTest/resources/application.properties +++ b/src/integrationTest/resources/application.properties @@ -118,8 +118,7 @@ janitor.port=5000 # -------------------- # # GitLab configuration # # -------------------- # -gitlab.address=nmaas-gitlab-unicorn -gitlab.port=8080 +gitlab.apiUrl=http://nmaas-gitlab-unicorn:8080 gitlab.token=test_gitlab_token # ------------------------ # diff --git a/src/main/java/net/geant/nmaas/externalservices/gitlab/GitLabManager.java b/src/main/java/net/geant/nmaas/externalservices/gitlab/GitLabManager.java index f763eff5655241556b5973edf1795d09d1cb082d..a833ba2ef14981fdaeb4967eceda955fecccd8a5 100644 --- a/src/main/java/net/geant/nmaas/externalservices/gitlab/GitLabManager.java +++ b/src/main/java/net/geant/nmaas/externalservices/gitlab/GitLabManager.java @@ -22,21 +22,16 @@ import static com.google.common.base.Preconditions.checkArgument; @Log4j2 public class GitLabManager { - @Value("${gitlab.address}") - private String gitLabAddress; + private static final String GITLAB_API_NAMESPACE = "/api/v4"; - @Value("${gitlab.port}") - private Integer gitLabPort; + @Value("${gitlab.apiUrl}") + private String gitLabApiUrl; @Value("${gitlab.token}") private String gitLabToken; - public String getGitlabServer() { - return this.gitLabAddress; - } - - public int getGitlabPort() { - return this.gitLabPort; + public String getGitLabApiUrl() { + return this.gitLabApiUrl; } public GroupApi groups() { @@ -59,19 +54,20 @@ public class GitLabManager { return new GitLabApi(GitLabApi.ApiVersion.V4, getApiUrl(), this.gitLabToken); } - private String getApiUrl(){ - return String.format("http://%s:%d", this.gitLabAddress, this.gitLabPort); + String getApiUrl() { + return gitLabApiUrl.endsWith(GITLAB_API_NAMESPACE) + ? gitLabApiUrl.substring(0, gitLabApiUrl.length() - GITLAB_API_NAMESPACE.length()) + : gitLabApiUrl; } public void validateGitLabInstance() { - checkArgument(this.gitLabAddress != null && !this.gitLabAddress.isEmpty(), "GitLab address is null or empty"); - checkArgument(this.gitLabPort != null, "GitLab port is null"); + checkArgument(this.gitLabApiUrl != null && !this.gitLabApiUrl.isEmpty(), "GitLab api URL is null or empty"); checkArgument(this.gitLabToken != null && !this.gitLabToken.isEmpty(), "GitLab token is null or empty"); try { api().getVersion(); log.trace("GitLab instance is running"); - } catch (GitLabApiException e){ - throw new GitLabInvalidConfigurationException("GitLab instance is not running -> " + e.getMessage()); + } catch (GitLabApiException e) { + throw new GitLabInvalidConfigurationException("GitLab instance doesn't respond -> " + e.getMessage()); } } diff --git a/src/main/java/net/geant/nmaas/nmservice/configuration/gitlab/GitLabConfigHandler.java b/src/main/java/net/geant/nmaas/nmservice/configuration/gitlab/GitLabConfigHandler.java index 1ae22d4c96ef0bd1975b28de4655bbcd1fa319ff..646309ed57fd872851bf36787ae1380beea50bc7 100644 --- a/src/main/java/net/geant/nmaas/nmservice/configuration/gitlab/GitLabConfigHandler.java +++ b/src/main/java/net/geant/nmaas/nmservice/configuration/gitlab/GitLabConfigHandler.java @@ -201,8 +201,8 @@ public class GitLabConfigHandler implements GitConfigHandler { String getHttpUrlToRepo(Integer gitLabProjectId) throws GitLabApiException { String[] urlFromGitlabApiParts = gitLabManager.projects().getProject(gitLabProjectId).getHttpUrlToRepo().split("//"); String[] urlParts = urlFromGitlabApiParts[1].split("/"); - urlParts[0] = gitLabManager.getGitlabServer() + ":" + gitLabManager.getGitlabPort(); - return urlFromGitlabApiParts[0] + "//" + String.join("/", urlParts); + urlParts[0] = gitLabManager.getGitLabApiUrl(); + return String.join("/", urlParts); } @Override @@ -261,8 +261,8 @@ public class GitLabConfigHandler implements GitConfigHandler { * * @param deploymentId unique identifier of service deployment * @param configIds list of identifiers of configuration files that should be loaded from database and uploaded to the git repository - * @throws InvalidDeploymentIdException if a service for given deployment identifier could not be found in database - * @throws ConfigFileNotFoundException if any of the configuration files for which an identifier is given could not be found in database + * @throws InvalidDeploymentIdException if a service for given deployment identifier could not be found in the database + * @throws ConfigFileNotFoundException if any of the configuration files for which an identifier is given could not be found in the database * @throws FileTransferException if any error occurs during communication with the git repository API */ @Override diff --git a/src/main/java/net/geant/nmaas/portal/api/market/ApplicationController.java b/src/main/java/net/geant/nmaas/portal/api/market/ApplicationController.java index dc805ba395ab1d9dcef873917da84a768beb3a20..b5c106c37295a6a8a86314799fa46509977a444a 100644 --- a/src/main/java/net/geant/nmaas/portal/api/market/ApplicationController.java +++ b/src/main/java/net/geant/nmaas/portal/api/market/ApplicationController.java @@ -10,12 +10,23 @@ import net.geant.nmaas.notifications.MailAttributes; import net.geant.nmaas.notifications.NotificationEvent; import net.geant.nmaas.notifications.templates.MailType; import net.geant.nmaas.orchestration.AppLifecycleManager; -import net.geant.nmaas.portal.api.domain.*; +import net.geant.nmaas.portal.api.domain.AppInstanceState; +import net.geant.nmaas.portal.api.domain.AppRateView; +import net.geant.nmaas.portal.api.domain.ApplicationBaseView; +import net.geant.nmaas.portal.api.domain.ApplicationStateChangeRequest; +import net.geant.nmaas.portal.api.domain.ApplicationView; +import net.geant.nmaas.portal.api.domain.Id; +import net.geant.nmaas.portal.api.domain.UserView; import net.geant.nmaas.portal.api.exception.MarketException; import net.geant.nmaas.portal.api.exception.MissingElementException; import net.geant.nmaas.portal.api.exception.ProcessingException; import net.geant.nmaas.portal.exceptions.ObjectAlreadyExistsException; -import net.geant.nmaas.portal.persistent.entity.*; +import net.geant.nmaas.portal.persistent.entity.Application; +import net.geant.nmaas.portal.persistent.entity.ApplicationBase; +import net.geant.nmaas.portal.persistent.entity.ApplicationState; +import net.geant.nmaas.portal.persistent.entity.ApplicationVersion; +import net.geant.nmaas.portal.persistent.entity.Role; +import net.geant.nmaas.portal.persistent.entity.User; import net.geant.nmaas.portal.persistent.repositories.RatingRepository; import net.geant.nmaas.portal.service.ApplicationInstanceService; import net.geant.nmaas.portal.service.impl.ApplicationServiceImpl; @@ -141,8 +152,7 @@ public class ApplicationController extends AppBaseController { @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_TOOL_MANAGER')") @Transactional public void updateApplicationBaseOwner(@PathVariable Long id, @PathVariable String owner, Principal principal) { - // only system admin and owner can update application base - log.info("Upate owner for application {} to {}", id, owner); + log.info("Updating owner of application {} to {}", id, owner); this.applicationBaseOwnerCheck(id, principal); appBaseService.updateOwner(id, owner); } @@ -154,10 +164,11 @@ public class ApplicationController extends AppBaseController { ApplicationBase base = appBaseService.getBaseApp(id); // only system admin and owner can update application base this.applicationBaseOwnerCheck(base.getName(), principal); - ApplicationState state = ApplicationState.DELETED; for (ApplicationVersion appVersion : base.getVersions()) { Application app = getApp(appVersion.getAppVersionId()); - if(app.getState() != ApplicationState.DELETED) throw new ProcessingException("Can not delete base, version " + app.getVersion() +" is not deleted"); + if (app.getState() != ApplicationState.DELETED) { + throw new ProcessingException("Can't delete " + base.getName() + " application base since version " + app.getVersion() + " is not deleted"); + } } appBaseService.deleteAppBase(base); } @@ -203,25 +214,26 @@ public class ApplicationController extends AppBaseController { ); } - @GetMapping(value="/base/allversions/{id}") + @GetMapping(value = "/base/allversions/{id}") @Transactional public ApplicationDTOVersionList getApplicationDTOWithAllVersions(@PathVariable Long id) { ApplicationBase base = appBaseService.getBaseApp(id); - List<Application> versionList = this.applicationService.findAll().stream().filter(app -> app.getName().equalsIgnoreCase(base.getName())).collect(Collectors.toList()); + List<Application> versionList = this.applicationService.findAll().stream() + .filter(app -> app.getName().equalsIgnoreCase(base.getName())) + .collect(Collectors.toList()); return new ApplicationDTOVersionList( modelMapper.map(base, ApplicationBaseView.class), versionList.stream().map(app->modelMapper.map(app, ApplicationView.class)).collect(Collectors.toList()) ); } - - @GetMapping(value="/versions/{id}") + @GetMapping(value = "/versions/{id}") @Transactional public Set<ApplicationVersion> getApplicationVersion(@PathVariable Long id) { return this.getVersions(id); } - @GetMapping(value="/version/{id}") + @GetMapping(value = "/version/{id}") @Transactional public ApplicationView getApplication(@PathVariable Long id) { Application app = getApp(id); @@ -285,7 +297,7 @@ public class ApplicationController extends AppBaseController { this.applicationBaseOwnerCheck(view.getName(), principal); // check if id exists - if(view.getId() == null) { + if (view.getId() == null) { log.error("ID is not present in Application update"); throw new ProcessingException("Cannot update application without id"); } @@ -294,12 +306,12 @@ public class ApplicationController extends AppBaseController { Optional<Application> optId = applicationService.findApplication(view.getId()); Optional<Application> optNameVersion = applicationService.findApplication(view.getName(), view.getVersion()); - if(optId.isEmpty() || optNameVersion.isEmpty()) { + if (optId.isEmpty() || optNameVersion.isEmpty()) { log.error("Requested application does not exist"); throw new MissingElementException("Application does not exist"); } - if(!optId.get().equals(optNameVersion.get())) { + if (!optId.get().equals(optNameVersion.get())) { log.error("Retrieved different applications using id and name&version, update aborted"); throw new ProcessingException("You cannot change application name, version and id"); } @@ -337,20 +349,14 @@ public class ApplicationController extends AppBaseController { @Transactional public void changeApplicationState(@PathVariable long id, @RequestBody ApplicationStateChangeRequest stateChangeRequest, Principal principal) { Application app = getApp(id); - if(stateChangeRequest.getState().equals(ApplicationState.DELETED)) { - applicationInstanceService.findAllByApplication(app).forEach(ai -> { - AppInstanceStatus instanceState = appInstanceController.getState(ai.getId(), principal); - int numberOfRunningInstances = 0; - if(!(instanceState.getState().equals(AppInstanceState.DONE) - || instanceState.getState().equals(AppInstanceState.FAILURE) - || instanceState.getState().equals(AppInstanceState.REMOVED) )) { - numberOfRunningInstances = +1; - } - if(numberOfRunningInstances > 0) { - throw new ProcessingException("Can not set state to Disabled. There is still " + numberOfRunningInstances + " running instances of this version."); - } + if (stateChangeRequest.getState().equals(ApplicationState.DELETED)) { + long numberOfRunningInstances = applicationInstanceService.findAllByApplication(app).stream() + .map(ai -> appInstanceController.getState(ai.getId(), principal)) + .filter(s -> !List.of(AppInstanceState.DONE, AppInstanceState.FAILURE, AppInstanceState.REMOVED).contains(s.getState())) + .count(); + if (numberOfRunningInstances > 0) { + throw new ProcessingException("Can not set state to Disabled. There is still " + numberOfRunningInstances + " running instances of this version."); } - ); } applicationService.changeApplicationState(app, stateChangeRequest.getState()); appBaseService.updateApplicationVersionState(app.getName(), app.getVersion(), stateChangeRequest.getState()); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 0b9ab5204f2c92aabb1e019738959b35b1074cf9..218b67437f063485bd2735c3ecaae9037ba1f040 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -138,7 +138,7 @@ helm.repositoryName=nmaas-test helm.repositoryUrl=https://nmaas-test.helm.repository helm.chartsDirectory=/home/nmaas/charts helm.enableTls=false -# possible values for Helm version are v2 and v3 (if none is provided v3 is used by default) +# possible values for the Helm version are v2 and v3 (if none is provided v3 is used by default) helm.version=v2 # --------------------- # @@ -150,8 +150,7 @@ janitor.port=5000 # -------------------- # # GitLab configuration # # -------------------- # -gitlab.address=nmaas-gitlab-unicorn -gitlab.port=8080 +gitlab.apiUrl=http://nmaas-gitlab-unicorn:8080 gitlab.token=test_gitlab_token # ------------------------ # diff --git a/src/test/java/net/geant/nmaas/externalservices/gitlab/GitLabManagerTest.java b/src/test/java/net/geant/nmaas/externalservices/gitlab/GitLabManagerTest.java index 87508027859755e52512538a480d677a114e970b..f280101b031cee1aac45bdebd2b3f9b64f654b36 100644 --- a/src/test/java/net/geant/nmaas/externalservices/gitlab/GitLabManagerTest.java +++ b/src/test/java/net/geant/nmaas/externalservices/gitlab/GitLabManagerTest.java @@ -3,31 +3,37 @@ package net.geant.nmaas.externalservices.gitlab; import net.geant.nmaas.externalservices.gitlab.exceptions.GitLabInvalidConfigurationException; import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; public class GitLabManagerTest { - private GitLabManager manager; + private final GitLabManager manager = new GitLabManager(); @Test void shouldValidateGitLabInstance() { - manager = new GitLabManager(); Exception thrown; - thrown = assertThrows(IllegalArgumentException.class, () -> manager.validateGitLabInstance()); - assertTrue(thrown.getMessage().contains("GitLab address is null or empty")); + thrown = assertThrows(IllegalArgumentException.class, manager::validateGitLabInstance); + assertTrue(thrown.getMessage().contains("GitLab api URL is null or empty")); - manager.setGitLabAddress("localhost"); - thrown = assertThrows(IllegalArgumentException.class, () -> manager.validateGitLabInstance()); - assertTrue(thrown.getMessage().contains("GitLab port is null")); - - manager.setGitLabPort(8080); - thrown = assertThrows(IllegalArgumentException.class, () -> manager.validateGitLabInstance()); - assertTrue(thrown.getMessage().contains("GitLab token is null or empty")); + manager.setGitLabApiUrl("http://localhost:8080"); + thrown = assertThrows(IllegalArgumentException.class, manager::validateGitLabInstance); + assertThat(thrown.getMessage()).contains("GitLab token is null or empty"); manager.setGitLabToken("token"); - assertThrows(GitLabInvalidConfigurationException.class, () -> manager.validateGitLabInstance()); + assertThrows(GitLabInvalidConfigurationException.class, manager::validateGitLabInstance); + } + + @Test + void shouldPrepareApiBaseUrl() { + manager.setGitLabApiUrl("http://localhost:8080"); + assertEquals("http://localhost:8080", manager.getApiUrl()); + + manager.setGitLabApiUrl("http://localhost:8080/api/v4"); + assertEquals("http://localhost:8080", manager.getApiUrl()); } } diff --git a/src/test/java/net/geant/nmaas/nmservice/configuration/gitlab/GitLabConfigHandlerTest.java b/src/test/java/net/geant/nmaas/nmservice/configuration/gitlab/GitLabConfigHandlerTest.java index 13e2796521e34dbba0988c556cb9724b7a25de45..aaa8d4661a966fad4e81c43cf9ca4874a87e4ebb 100644 --- a/src/test/java/net/geant/nmaas/nmservice/configuration/gitlab/GitLabConfigHandlerTest.java +++ b/src/test/java/net/geant/nmaas/nmservice/configuration/gitlab/GitLabConfigHandlerTest.java @@ -47,8 +47,7 @@ public class GitLabConfigHandlerTest { Project project = mock(Project.class); when(projectApi.getProject(anyInt())).thenReturn(project); when(project.getHttpUrlToRepo()).thenReturn("http://example.gitlab.com/group/project.git"); - when(gitLabManager.getGitlabServer()).thenReturn("test-server"); - when(gitLabManager.getGitlabPort()).thenReturn(80); + when(gitLabManager.getGitLabApiUrl()).thenReturn("http://test-server:80"); when(gitLabManager.projects()).thenReturn(projectApi); String result = handler.getHttpUrlToRepo(1); diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 0ba2e0bc557f21f092dac9c74f826626c5265095..e5c378cb9c4a0d2a3293faa2b8a10c7ade3944ba 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -131,8 +131,7 @@ janitor.port=5000 # -------------------- # # GitLab configuration # # -------------------- # -gitlab.address=nmaas-gitlab-unicorn -gitlab.port=8080 +gitlab.apiUrl=http://nmaas-gitlab-unicorn:8080 gitlab.token=test_gitlab_token # ------------------------ #