From: Sébastien Lesaint Date: Fri, 6 Jan 2017 09:05:18 +0000 (+0100) Subject: SONAR-8429 add organization parameter to api/ce/submit X-Git-Tag: 6.3-RC1~541 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c63bba383207809b3c6f49cbb40d2bd03bec1f17;p=sonarqube.git SONAR-8429 add organization parameter to api/ce/submit remove hardcode to default organization from ComponentService --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/SubmitAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/SubmitAction.java index a623c16c4ac..9400798c8a9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/SubmitAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/SubmitAction.java @@ -27,20 +27,24 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.ce.queue.CeTask; import org.sonar.server.computation.queue.ReportSubmitter; +import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.ws.WsUtils; import org.sonarqube.ws.WsCe; public class SubmitAction implements CeWsAction { - public static final String PARAM_PROJECT_KEY = "projectKey"; - public static final String PARAM_PROJECT_BRANCH = "projectBranch"; - public static final String PARAM_PROJECT_NAME = "projectName"; - public static final String PARAM_REPORT_DATA = "report"; + private static final String PARAM_ORGANIZATION_KEY = "organization"; + private static final String PARAM_PROJECT_KEY = "projectKey"; + private static final String PARAM_PROJECT_BRANCH = "projectBranch"; + private static final String PARAM_PROJECT_NAME = "projectName"; + private static final String PARAM_REPORT_DATA = "report"; private final ReportSubmitter reportSubmitter; + private final DefaultOrganizationProvider defaultOrganizationProvider; - public SubmitAction(ReportSubmitter reportSubmitter) { + public SubmitAction(ReportSubmitter reportSubmitter, DefaultOrganizationProvider defaultOrganizationProvider) { this.reportSubmitter = reportSubmitter; + this.defaultOrganizationProvider = defaultOrganizationProvider; } @Override @@ -54,6 +58,12 @@ public class SubmitAction implements CeWsAction { .setHandler(this) .setResponseExample(getClass().getResource("submit-example.json")); + action.createParam(PARAM_ORGANIZATION_KEY) + .setDescription("Key of the organization the project belongs to") + .setExampleValue("my-org") + .setSince("6.3") + .setInternal(true); + action .createParam(PARAM_PROJECT_KEY) .setRequired(true) @@ -79,13 +89,16 @@ public class SubmitAction implements CeWsAction { @Override public void handle(Request wsRequest, Response wsResponse) throws Exception { + String organizationKey = wsRequest.getParam(PARAM_ORGANIZATION_KEY) + .emptyAsNull() + .or(defaultOrganizationProvider.get()::getKey); String projectKey = wsRequest.mandatoryParam(PARAM_PROJECT_KEY); String projectBranch = wsRequest.param(PARAM_PROJECT_BRANCH); String projectName = StringUtils.defaultIfBlank(wsRequest.param(PARAM_PROJECT_NAME), projectKey); CeTask task; try (InputStream report = new BufferedInputStream(wsRequest.paramAsInputStream(PARAM_REPORT_DATA))) { - task = reportSubmitter.submit(projectKey, projectBranch, projectName, report); + task = reportSubmitter.submit(organizationKey, projectKey, projectBranch, projectName, report); } WsCe.SubmitResponse submitResponse = WsCe.SubmitResponse.newBuilder() diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java index 9e3ab3dd071..760a2726b2d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java @@ -45,7 +45,6 @@ import org.sonar.db.component.ComponentDto; import org.sonar.server.component.es.ProjectMeasuresIndexer; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.user.UserSession; import static com.google.common.collect.Lists.newArrayList; @@ -63,18 +62,15 @@ public class ComponentService { private final System2 system2; private final ComponentFinder componentFinder; private final ProjectMeasuresIndexer projectMeasuresIndexer; - private final DefaultOrganizationProvider defaultOrganizationProvider; public ComponentService(DbClient dbClient, I18n i18n, UserSession userSession, System2 system2, - ComponentFinder componentFinder, ProjectMeasuresIndexer projectMeasuresIndexer, - DefaultOrganizationProvider defaultOrganizationProvider) { + ComponentFinder componentFinder, ProjectMeasuresIndexer projectMeasuresIndexer) { this.dbClient = dbClient; this.i18n = i18n; this.userSession = userSession; this.system2 = system2; this.componentFinder = componentFinder; this.projectMeasuresIndexer = projectMeasuresIndexer; - this.defaultOrganizationProvider = defaultOrganizationProvider; } public ComponentDto getByKey(String key) { @@ -162,7 +158,7 @@ public class ComponentService { String uuid = Uuids.create(); ComponentDto component = new ComponentDto() - .setOrganizationUuid(defaultOrganizationProvider.get().getUuid()) + .setOrganizationUuid(newComponent.getOrganizationUuid()) .setUuid(uuid) .setUuidPath(ComponentDto.UUID_PATH_OF_ROOT) .setRootUuid(uuid) diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java index 9d3ac588b40..35a868e4e4b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java @@ -33,9 +33,12 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ResourceDao; import org.sonar.db.component.ResourceDto; import org.sonar.server.favorite.FavoriteUpdater; +import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.util.RubyUtils; +import static org.sonar.server.component.NewComponent.newComponentBuilder; + public class DefaultRubyComponentService implements RubyComponentService { private final DbClient dbClient; @@ -43,14 +46,17 @@ public class DefaultRubyComponentService implements RubyComponentService { private final ComponentService componentService; private final PermissionTemplateService permissionTemplateService; private final FavoriteUpdater favoriteUpdater; + private final DefaultOrganizationProvider defaultOrganizationProvider; - public DefaultRubyComponentService(DbClient dbClient, ResourceDao resourceDao, ComponentService componentService, PermissionTemplateService permissionTemplateService, - FavoriteUpdater favoriteUpdater) { + public DefaultRubyComponentService(DbClient dbClient, ResourceDao resourceDao, ComponentService componentService, + PermissionTemplateService permissionTemplateService, FavoriteUpdater favoriteUpdater, + DefaultOrganizationProvider defaultOrganizationProvider) { this.dbClient = dbClient; this.resourceDao = resourceDao; this.componentService = componentService; this.permissionTemplateService = permissionTemplateService; this.favoriteUpdater = favoriteUpdater; + this.defaultOrganizationProvider = defaultOrganizationProvider; } @Override @@ -84,7 +90,15 @@ public class DefaultRubyComponentService implements RubyComponentService { } public long createComponent(DbSession dbSession, String key, @Nullable String branch, String name, @Nullable String qualifier) { - ComponentDto provisionedComponent = componentService.create(dbSession, NewComponent.create(key, name).setQualifier(qualifier).setBranch(branch)); + ComponentDto provisionedComponent = componentService.create( + dbSession, + newComponentBuilder() + .setOrganizationUuid(defaultOrganizationProvider.get().getUuid()) + .setKey(key) + .setName(name) + .setQualifier(qualifier) + .setBranch(branch) + .build()); permissionTemplateService.applyDefaultPermissionTemplate(dbSession, provisionedComponent.getKey()); if (Qualifiers.PROJECT.equals(provisionedComponent.qualifier()) && permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, provisionedComponent)) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/NewComponent.java b/server/sonar-server/src/main/java/org/sonar/server/component/NewComponent.java index ce0a0d60cf5..d9e51441396 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/NewComponent.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/NewComponent.java @@ -20,24 +20,36 @@ package org.sonar.server.component; import javax.annotation.CheckForNull; -import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; import org.sonar.api.resources.Qualifiers; -import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; import static org.sonar.db.component.ComponentValidator.checkComponentKey; import static org.sonar.db.component.ComponentValidator.checkComponentName; import static org.sonar.db.component.ComponentValidator.checkComponentQualifier; +@Immutable public class NewComponent { + private final String organizationUuid; + private final String key; + private final String branch; + private final String qualifier; + private final String name; - private String key; - private String branch; - private String qualifier; - private String name; + private NewComponent(NewComponent.Builder builder) { + this.organizationUuid = builder.organizationUuid; + this.key = builder.key; + this.branch = builder.branch; + this.qualifier = builder.qualifier == null ? Qualifiers.PROJECT : checkComponentQualifier(builder.qualifier); + this.name = builder.name; + } + + public static Builder newComponentBuilder() { + return new Builder(); + } - public NewComponent(String key, String name) { - this.key = key; - this.name = name; + public String getOrganizationUuid() { + return organizationUuid; } public String key() { @@ -53,25 +65,52 @@ public class NewComponent { return branch; } - public NewComponent setBranch(@Nullable String branch) { - this.branch = branch; - return this; - } - public String qualifier() { - return qualifier != null ? qualifier : Qualifiers.PROJECT; + return qualifier; } - public NewComponent setQualifier(@Nullable String qualifier) { - this.qualifier = qualifier == null ? null : checkComponentQualifier(qualifier); - return this; - } + public static class Builder { + private String organizationUuid; + private String key; + private String branch; + private String qualifier; + private String name; + + private Builder() { + // use static factory method newComponentBuilder() + } - public static NewComponent create(String key, String name) { - checkArgument(key!=null, "Key can't be null"); - checkComponentKey(key); - checkArgument(name!=null, "Name can't be null"); - checkComponentName(name); - return new NewComponent(key, name); + public Builder setOrganizationUuid(String organizationUuid) { + this.organizationUuid = organizationUuid; + return this; + } + + public Builder setKey(String key) { + this.key = key; + return this; + } + + public Builder setBranch(String branch) { + this.branch = branch; + return this; + } + + public Builder setQualifier(String qualifier) { + this.qualifier = qualifier; + return this; + } + + public Builder setName(String name) { + this.name = name; + return this; + } + + public NewComponent build() { + requireNonNull(organizationUuid, "organization uuid can't be null"); + checkComponentKey(requireNonNull(key, "key can't be null")); + checkComponentName(requireNonNull(name, "name can't be null")); + return new NewComponent(this); + } } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java index 0fda8c44569..1748c51ddca 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java @@ -33,13 +33,18 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.ce.CeTaskTypes; import org.sonar.db.component.ComponentDto; +import org.sonar.db.organization.OrganizationDto; import org.sonar.server.component.ComponentService; -import org.sonar.server.favorite.FavoriteUpdater; import org.sonar.server.component.NewComponent; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.favorite.FavoriteUpdater; import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.user.UserSession; +import static com.google.common.base.Preconditions.checkArgument; +import static java.lang.String.format; import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; +import static org.sonar.server.component.NewComponent.newComponentBuilder; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; @ServerSide @@ -62,17 +67,36 @@ public class ReportSubmitter { this.favoriteUpdater = favoriteUpdater; } - public CeTask submit(String projectKey, @Nullable String projectBranch, @Nullable String projectName, InputStream reportInput) { + /** + * @throws NotFoundException if the organization with the specified key does not exist + * @throws IllegalArgumentException if the organization with the specified key is not the organization of the specified project (when it already exists in DB) + */ + public CeTask submit(String organizationKey, String projectKey, @Nullable String projectBranch, @Nullable String projectName, InputStream reportInput) { try (DbSession dbSession = dbClient.openSession(false)) { String effectiveProjectKey = ComponentKeys.createKey(projectKey, projectBranch); + OrganizationDto organizationDto = getOrganizationDtoOrFail(dbSession, organizationKey); Optional opt = dbClient.componentDao().selectByKey(dbSession, effectiveProjectKey); - ComponentDto project = opt.or(() -> createProject(dbSession, projectKey, projectBranch, projectName)); + ensureOrganizationIsConsistent(opt, organizationDto); + ComponentDto project = opt.or(() -> createProject(dbSession, organizationDto.getUuid(), projectKey, projectBranch, projectName)); userSession.checkComponentUuidPermission(SCAN_EXECUTION, project.uuid()); return submitReport(dbSession, reportInput, project); } } - private ComponentDto createProject(DbSession dbSession, String projectKey, @Nullable String projectBranch, @Nullable String projectName) { + private OrganizationDto getOrganizationDtoOrFail(DbSession dbSession, String organizationKey) { + return dbClient.organizationDao().selectByKey(dbSession, organizationKey) + .orElseThrow(() -> new NotFoundException(format("Organization with key '%s' does not exist", organizationKey))); + } + + private void ensureOrganizationIsConsistent(Optional project, OrganizationDto organizationDto) { + if (project.isPresent()) { + checkArgument(project.get().getOrganizationUuid().equals(organizationDto.getUuid()), + "Organization of component with key '%s' does not match specified organization '%s'", + project.get().key(), organizationDto.getKey()); + } + } + + private ComponentDto createProject(DbSession dbSession, String organizationUuid, String projectKey, @Nullable String projectBranch, @Nullable String projectName) { Integer userId = userSession.getUserId(); Long projectCreatorUserId = userId == null ? null : userId.longValue(); @@ -82,9 +106,13 @@ public class ReportSubmitter { throw insufficientPrivilegesException(); } - NewComponent newProject = new NewComponent(projectKey, StringUtils.defaultIfBlank(projectName, projectKey)); - newProject.setBranch(projectBranch); - newProject.setQualifier(Qualifiers.PROJECT); + NewComponent newProject = newComponentBuilder() + .setOrganizationUuid(organizationUuid) + .setKey(projectKey) + .setName(StringUtils.defaultIfBlank(projectName, projectKey)) + .setBranch(projectBranch) + .setQualifier(Qualifiers.PROJECT) + .build(); // "provisioning" permission is check in ComponentService ComponentDto project = componentService.create(dbSession, newProject); if (permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, project)) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsTest.java index 16f7dd9b2f5..27da12849b8 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.mockito.Mockito; import org.sonar.api.server.ws.WebService; import org.sonar.server.computation.queue.ReportSubmitter; +import org.sonar.server.organization.DefaultOrganizationProvider; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -31,7 +32,7 @@ public class CeWsTest { @Test public void define() throws Exception { - CeWsAction wsAction = new SubmitAction(mock(ReportSubmitter.class)); + CeWsAction wsAction = new SubmitAction(mock(ReportSubmitter.class), mock(DefaultOrganizationProvider.class)); CeWs ws = new CeWs(wsAction); WebService.Context context = mock(WebService.Context.class, Mockito.RETURNS_DEEP_STUBS); diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/SubmitActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/SubmitActionTest.java index 8204f84c83a..7e552cfff9a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/SubmitActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/SubmitActionTest.java @@ -26,6 +26,8 @@ import org.sonar.ce.queue.CeTask; import org.sonar.core.util.Protobuf; import org.sonar.db.ce.CeTaskTypes; import org.sonar.server.computation.queue.ReportSubmitter; +import org.sonar.server.organization.DefaultOrganizationProvider; +import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; import org.sonar.test.JsonAssert; @@ -48,13 +50,15 @@ public class SubmitActionTest { .setComponentUuid("PROJECT_1").setSubmitterLogin("robert") .build(); + private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("org1"); + private String organizationKey = defaultOrganizationProvider.get().getKey(); private ReportSubmitter reportSubmitter = mock(ReportSubmitter.class); - private SubmitAction underTest = new SubmitAction(reportSubmitter); + private SubmitAction underTest = new SubmitAction(reportSubmitter, defaultOrganizationProvider); private WsActionTester tester = new WsActionTester(underTest); @Test public void submit_task_to_the_queue_and_ask_for_immediate_processing() { - when(reportSubmitter.submit(eq("my_project"), Matchers.isNull(String.class), eq("My Project"), any(InputStream.class))) + when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), Matchers.isNull(String.class), eq("My Project"), any(InputStream.class))) .thenReturn(A_CE_TASK); TestResponse wsResponse = tester.newRequest() @@ -65,7 +69,7 @@ public class SubmitActionTest { .setMethod("POST") .execute(); - verify(reportSubmitter).submit(eq("my_project"), Matchers.isNull(String.class), eq("My Project"), any(InputStream.class)); + verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), Matchers.isNull(String.class), eq("My Project"), any(InputStream.class)); WsCe.SubmitResponse submitResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.SubmitResponse.PARSER); assertThat(submitResponse.getTaskId()).isEqualTo("TASK_1"); @@ -74,7 +78,7 @@ public class SubmitActionTest { @Test public void test_example_json_response() { - when(reportSubmitter.submit(eq("my_project"), Matchers.isNull(String.class), eq("My Project"), any(InputStream.class))) + when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), Matchers.isNull(String.class), eq("My Project"), any(InputStream.class))) .thenReturn(A_CE_TASK); TestResponse wsResponse = tester.newRequest() @@ -93,7 +97,7 @@ public class SubmitActionTest { */ @Test public void project_name_is_optional() { - when(reportSubmitter.submit(eq("my_project"), Matchers.isNull(String.class), eq("my_project"), any(InputStream.class))) + when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), Matchers.isNull(String.class), eq("my_project"), any(InputStream.class))) .thenReturn(A_CE_TASK); tester.newRequest() @@ -103,7 +107,7 @@ public class SubmitActionTest { .setMethod("POST") .execute(); - verify(reportSubmitter).submit(eq("my_project"), Matchers.isNull(String.class), eq("my_project"), any(InputStream.class)); + verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), Matchers.isNull(String.class), eq("my_project"), any(InputStream.class)); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java index a6b58d9aa61..2d2c5013967 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java @@ -43,8 +43,6 @@ import org.sonar.server.es.EsTester; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.i18n.I18nRule; -import org.sonar.server.organization.DefaultOrganizationProvider; -import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.tester.UserSessionRule; import static com.google.common.collect.Lists.newArrayList; @@ -60,11 +58,14 @@ import static org.sonar.core.permission.GlobalPermissions.PROVISIONING; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newModuleDto; import static org.sonar.db.component.ComponentTesting.newProjectDto; +import static org.sonar.server.component.NewComponent.newComponentBuilder; import static org.sonar.server.component.es.ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES; import static org.sonar.server.component.es.ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES; public class ComponentServiceTest { + private static final String ORGANIZATION_UUID = "org 1A"; + private System2 system2 = System2.INSTANCE; @Rule @@ -81,7 +82,6 @@ public class ComponentServiceTest { private DbSession dbSession = dbTester.getSession(); private I18nRule i18n = new I18nRule(); private ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(system2, dbClient, es.client()); - private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester); private ComponentService underTest; @@ -89,8 +89,7 @@ public class ComponentServiceTest { public void setUp() { i18n.put("qualifier.TRK", "Project"); - underTest = new ComponentService(dbClient, i18n, userSession, system2, new ComponentFinder(dbClient), - projectMeasuresIndexer, defaultOrganizationProvider); + underTest = new ComponentService(dbClient, i18n, userSession, system2, new ComponentFinder(dbClient), projectMeasuresIndexer); } @Test @@ -123,9 +122,17 @@ public class ComponentServiceTest { public void create_project() { userSession.login("john").setGlobalPermissions(PROVISIONING); - String key = underTest.create(dbSession, NewComponent.create("struts", "Struts project")).getKey(); + String key = underTest.create( + dbSession, + newComponentBuilder() + .setOrganizationUuid(ORGANIZATION_UUID) + .setKey("struts") + .setName("Struts project") + .build()) + .getKey(); ComponentDto project = underTest.getNullableByKey(key); + assertThat(project.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(project.key()).isEqualTo("struts"); assertThat(project.deprecatedKey()).isEqualTo("struts"); assertThat(project.uuid()).isNotNull(); @@ -145,9 +152,18 @@ public class ComponentServiceTest { public void create_new_project_with_branch() { userSession.login("john").setGlobalPermissions(PROVISIONING); - String key = underTest.create(dbSession, NewComponent.create("struts", "Struts project").setBranch("origin/branch")).getKey(); + String key = underTest.create( + dbSession, + newComponentBuilder() + .setOrganizationUuid(ORGANIZATION_UUID) + .setKey("struts") + .setName("Struts project") + .setBranch("origin/branch") + .build()) + .getKey(); ComponentDto project = underTest.getNullableByKey(key); + assertThat(project.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(project.key()).isEqualTo("struts:origin/branch"); assertThat(project.deprecatedKey()).isEqualTo("struts:origin/branch"); } @@ -156,9 +172,18 @@ public class ComponentServiceTest { public void create_view() { userSession.login("john").setGlobalPermissions(PROVISIONING); - String key = underTest.create(dbSession, NewComponent.create("all-project", "All Projects").setQualifier(Qualifiers.VIEW)).getKey(); + String key = underTest.create( + dbSession, + newComponentBuilder() + .setOrganizationUuid(ORGANIZATION_UUID) + .setKey("all-project") + .setName("All Projects") + .setQualifier(Qualifiers.VIEW) + .build()) + .getKey(); ComponentDto project = underTest.getNullableByKey(key); + assertThat(project.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(project.key()).isEqualTo("all-project"); assertThat(project.deprecatedKey()).isEqualTo("all-project"); assertThat(project.uuid()).isNotNull(); @@ -179,10 +204,19 @@ public class ComponentServiceTest { // No permission should be required to create a developer userSession.anonymous(); - String key = underTest.createDeveloper(dbTester.getSession(), NewComponent.create("DEV:jon.name@mail.com", "John").setQualifier("DEV")).getKey(); + String key = underTest.createDeveloper( + dbSession, + newComponentBuilder() + .setOrganizationUuid(ORGANIZATION_UUID) + .setKey("DEV:jon.name@mail.com") + .setName("John") + .setQualifier("DEV") + .build()) + .getKey(); dbTester.getSession().commit(); ComponentDto dev = underTest.getNullableByKey(key); + assertThat(dev.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); assertThat(dev.key()).isEqualTo("DEV:jon.name@mail.com"); assertThat(dev.deprecatedKey()).isEqualTo("DEV:jon.name@mail.com"); assertThat(dev.uuid()).isNotNull(); @@ -204,7 +238,13 @@ public class ComponentServiceTest { expectedException.expect(BadRequestException.class); expectedException.expectMessage("Malformed key for Project: struts?parent. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); - underTest.create(dbSession, NewComponent.create("struts?parent", "Struts project")); + underTest.create( + dbSession, + newComponentBuilder() + .setOrganizationUuid(ORGANIZATION_UUID) + .setKey("struts?parent") + .setName("Struts project") + .build()); } @Test @@ -214,7 +254,14 @@ public class ComponentServiceTest { userSession.login("john").setGlobalPermissions(PROVISIONING); - underTest.create(dbSession, NewComponent.create("struts", "Struts project").setBranch("origin?branch")); + underTest.create( + dbSession, + newComponentBuilder() + .setOrganizationUuid(ORGANIZATION_UUID) + .setKey("struts") + .setName("Struts project") + .setBranch("origin?branch") + .build()); } @Test @@ -227,7 +274,13 @@ public class ComponentServiceTest { dbClient.componentDao().insert(dbSession, project); dbSession.commit(); - underTest.create(dbSession, NewComponent.create("struts", "Struts project")); + underTest.create( + dbSession, + newComponentBuilder() + .setOrganizationUuid(ORGANIZATION_UUID) + .setKey("struts") + .setName("Struts project") + .build()); } @Test @@ -256,9 +309,14 @@ public class ComponentServiceTest { ComponentTesting.newProjectDto().setId(2L).setKey(projectKey), ComponentTesting.newProjectDto().setId(3L).setKey(projectKey))); - underTest = new ComponentService(dbClient, i18n, userSession, System2.INSTANCE, new ComponentFinder(dbClient), projectMeasuresIndexer, - defaultOrganizationProvider); - underTest.create(session, NewComponent.create(projectKey, projectKey)); + underTest = new ComponentService(dbClient, i18n, userSession, System2.INSTANCE, new ComponentFinder(dbClient), projectMeasuresIndexer); + underTest.create( + session, + newComponentBuilder() + .setOrganizationUuid(ORGANIZATION_UUID) + .setKey(projectKey) + .setName(projectKey) + .build()); verify(componentDao).delete(session, 2L); verify(componentDao).delete(session, 3L); diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java index fd1a0efa57b..324d72fdffe 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java @@ -41,7 +41,6 @@ import org.sonar.server.es.EsTester; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.i18n.I18nRule; -import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.tester.UserSessionRule; import static org.assertj.core.api.Assertions.assertThat; @@ -76,14 +75,11 @@ public class ComponentServiceUpdateKeyTest { private ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(system2, dbClient, es.client()); - private ComponentService underTest; + private ComponentService underTest = new ComponentService(dbClient, i18n, userSession, system2, new ComponentFinder(dbClient), projectMeasuresIndexer); @Before public void setUp() { i18n.put("qualifier.TRK", "Project"); - - underTest = new ComponentService(dbClient, i18n, userSession, system2, new ComponentFinder(dbClient), projectMeasuresIndexer, - TestDefaultOrganizationProvider.from(db)); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java index 65f19cec59d..da8334572ac 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java @@ -39,6 +39,7 @@ import org.sonar.server.es.EsTester; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.favorite.FavoriteUpdater; import org.sonar.server.i18n.I18nRule; +import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.tester.UserSessionRule; @@ -71,13 +72,15 @@ public class DefaultRubyComponentServiceTest { private ResourceDao resourceDao = dbClient.resourceDao(); private ComponentService componentService = new ComponentService(dbClient, i18n, userSession, system2, new ComponentFinder(dbClient), - new ProjectMeasuresIndexer(system2, dbClient, es.client()), TestDefaultOrganizationProvider.from(db)); + new ProjectMeasuresIndexer(system2, dbClient, es.client())); private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); private FavoriteUpdater favoriteUpdater = mock(FavoriteUpdater.class); + private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); private ComponentDbTester componentDb = new ComponentDbTester(db); - private DefaultRubyComponentService underTest = new DefaultRubyComponentService(dbClient, resourceDao, componentService, permissionTemplateService, favoriteUpdater); + private DefaultRubyComponentService underTest = new DefaultRubyComponentService(dbClient, resourceDao, componentService, + permissionTemplateService, favoriteUpdater, defaultOrganizationProvider); @Test public void find_by_key() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/NewComponentTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/NewComponentTest.java index 4312778d1dd..637286daf07 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/NewComponentTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/NewComponentTest.java @@ -22,50 +22,89 @@ package org.sonar.server.component; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.resources.Qualifiers; import static com.google.common.base.Strings.repeat; +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.sonar.server.component.NewComponent.newComponentBuilder; public class NewComponentTest { + private static final String ORGANIZATION_UUID = "org1"; + private static final String KEY = "key"; + private static final String NAME = "name"; + @Rule public ExpectedException expectedException = ExpectedException.none(); + private NewComponent.Builder underTest = newComponentBuilder(); + + @Test + public void build_throws_NPE_if_organizationUuid_is_null() { + expectBuildException(NullPointerException.class, "organization uuid can't be null"); + } + + @Test + public void build_throws_NPE_when_key_is_null() { + underTest.setOrganizationUuid(ORGANIZATION_UUID); + + expectBuildException(NullPointerException.class, "key can't be null"); + } + @Test - public void fail_when_key_is_null() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Key can't be null"); + public void build_throws_IAE_when_key_is_longer_than_400_characters() { + underTest.setOrganizationUuid(ORGANIZATION_UUID) + .setKey(repeat("a", 400 + 1)); - NewComponent.create(null, "name"); + expectBuildException( + IllegalArgumentException.class, + "Component key length (401) is longer than the maximum authorized (400)"); } @Test - public void fail_when_key_is_longer_than_400_characters() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Component key length (401) is longer than the maximum authorized (400)"); + public void build_fails_with_NPE_when_name_is_null() { + underTest.setOrganizationUuid(ORGANIZATION_UUID) + .setKey(KEY); - NewComponent.create(repeat("a", 400 + 1), "name"); + expectBuildException(NullPointerException.class, "name can't be null"); } @Test - public void fail_when_name_is_null() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Name can't be null"); + public void build_fails_with_IAE_when_name_is_longer_than_2000_characters() { + underTest.setOrganizationUuid(ORGANIZATION_UUID) + .setKey(KEY) + .setName(repeat("a", 2001)); - NewComponent.create("key", null); + expectBuildException( + IllegalArgumentException.class, + "Component name length (2001) is longer than the maximum authorized (2000)"); } @Test - public void fail_when_name_is_longer_than_2000_characters() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Component name length (2001) is longer than the maximum authorized (2000)"); + public void build_fails_with_IAE_when_qualifier_is_longer_than_10_characters() { + underTest.setOrganizationUuid(ORGANIZATION_UUID) + .setKey(KEY) + .setName(NAME) + .setQualifier(repeat("a", 10 + 1)); - NewComponent.create("key", repeat("a", 2001)); + expectBuildException( + IllegalArgumentException.class, + "Component qualifier length (11) is longer than the maximum authorized (10)"); } @Test - public void fail_when_qualifier_is_longer_than_10_characters() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Component qualifier length (11) is longer than the maximum authorized (10)"); + public void getQualifier_returns_PROJECT_when_no_set_in_builder() { + NewComponent newComponent = underTest.setOrganizationUuid(ORGANIZATION_UUID) + .setKey(KEY) + .setName(NAME) + .build(); + + assertThat(newComponent.qualifier()).isEqualTo(Qualifiers.PROJECT); + } + + private void expectBuildException(Class expectedExceptionType, String expectedMessage) { + expectedException.expect(expectedExceptionType); + expectedException.expectMessage(expectedMessage); - NewComponent.create("key", "name").setQualifier(repeat("a", 10 + 1)); + underTest.build(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/BulkUpdateKeyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/BulkUpdateKeyActionTest.java index 8a1c5a37bd9..7cafec2fe40 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/BulkUpdateKeyActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/BulkUpdateKeyActionTest.java @@ -88,7 +88,7 @@ public class BulkUpdateKeyActionTest { private ComponentFinder componentFinder = new ComponentFinder(dbClient); private WsActionTester ws = new WsActionTester( - new BulkUpdateKeyAction(dbClient, componentFinder, new ComponentService(dbClient, null, null, null, null, new ProjectMeasuresIndexer(system2, dbClient, es.client()), null), userSession)); + new BulkUpdateKeyAction(dbClient, componentFinder, new ComponentService(dbClient, null, null, null, null, new ProjectMeasuresIndexer(system2, dbClient, es.client())), userSession)); @Before public void setUp() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java index ef5839bb0b0..0e43e04d89b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java @@ -22,6 +22,7 @@ package org.sonar.server.computation.queue; import org.apache.commons.io.IOUtils; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -35,7 +36,9 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.ce.CeTaskTypes; import org.sonar.db.component.ComponentDto; +import org.sonar.db.organization.OrganizationDto; import org.sonar.server.component.ComponentService; +import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.favorite.FavoriteUpdater; import org.sonar.server.component.NewComponent; import org.sonar.server.exceptions.ForbiddenException; @@ -64,13 +67,12 @@ public class ReportSubmitterTest { @Rule public ExpectedException thrown = ExpectedException.none(); - @Rule public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule public DbTester db = DbTester.create(System2.INSTANCE); + private String defaultOrganizationKey; private CeQueue queue = mock(CeQueueImpl.class); private ComponentService componentService = mock(ComponentService.class); private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); @@ -78,14 +80,37 @@ public class ReportSubmitterTest { private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentService, permissionTemplateService, db.getDbClient(), favoriteUpdater); + @Before + public void setUp() throws Exception { + defaultOrganizationKey = db.getDefaultOrganization().getKey(); + } + + @Test + public void submit_fails_with_NotFoundException_if_organization_with_specified_key_does_not_exist() { + thrown.expect(NotFoundException.class); + thrown.expectMessage("Organization with key 'fop' does not exist"); + + underTest.submit("fop", PROJECT_KEY, null, null, null /*method will fail before parameter is used*/); + } + + @Test + public void submit_fails_with_organizationKey_does_not_match_organization_of_specified_component() { + userSession.setGlobalPermissions(SCAN_EXECUTION); + OrganizationDto organization = db.organizations().insert(); + ComponentDto project = db.components().insertProject(organization); + mockSuccessfulPrepareSubmitCall(); + + underTest.submit(organization.getKey(), project.getKey(), null, project.name(), IOUtils.toInputStream("{binary}")); + } + @Test public void submit_a_report_on_existing_project() { userSession.setGlobalPermissions(SCAN_EXECUTION); - ComponentDto project = db.components().insertProject(); + ComponentDto project = db.components().insertProject(db.getDefaultOrganization()); - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + mockSuccessfulPrepareSubmitCall(); - underTest.submit(project.getKey(), null, project.name(), IOUtils.toInputStream("{binary}")); + underTest.submit(defaultOrganizationKey, project.getKey(), null, project.name(), IOUtils.toInputStream("{binary}")); verifyReportIsPersisted(TASK_UUID); verifyZeroInteractions(permissionTemplateService); @@ -106,16 +131,17 @@ public class ReportSubmitterTest { @Test public void provision_project_if_does_not_exist() throws Exception { + OrganizationDto organization = db.organizations().insert(); userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + mockSuccessfulPrepareSubmitCall(); ComponentDto createdProject = new ComponentDto().setId(23L).setUuid(PROJECT_UUID).setKey(PROJECT_KEY); when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(createdProject); when(permissionTemplateService.wouldUserHavePermissionWithDefaultTemplate(any(DbSession.class), anyLong(), eq(SCAN_EXECUTION), anyString(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT))) .thenReturn(true); when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true); - underTest.submit(PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); + underTest.submit(organization.getKey(), PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); verifyReportIsPersisted(TASK_UUID); verify(permissionTemplateService).applyDefault(any(DbSession.class), eq(createdProject), anyLong()); @@ -138,14 +164,14 @@ public class ReportSubmitterTest { public void no_favorite_when_no_project_creator_permission_on_permission_template() { userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + mockSuccessfulPrepareSubmitCall(); ComponentDto createdProject = new ComponentDto().setId(23L).setUuid(PROJECT_UUID).setKey(PROJECT_KEY); when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(createdProject); when(permissionTemplateService.wouldUserHavePermissionWithDefaultTemplate(any(DbSession.class), anyLong(), eq(SCAN_EXECUTION), anyString(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT))) .thenReturn(true); when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(false); - underTest.submit(PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); + underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); verifyZeroInteractions(favoriteUpdater); } @@ -154,36 +180,37 @@ public class ReportSubmitterTest { public void submit_a_report_on_new_project_with_global_scan_permission() { userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + mockSuccessfulPrepareSubmitCall(); when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(new ComponentDto().setId(23L).setUuid(PROJECT_UUID).setKey(PROJECT_KEY)); when(permissionTemplateService.wouldUserHavePermissionWithDefaultTemplate(any(DbSession.class), anyLong(), eq(SCAN_EXECUTION), anyString(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT))) .thenReturn(true); - underTest.submit(PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); + underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); verify(queue).submit(any(CeTaskSubmit.class)); } @Test public void submit_a_report_on_existing_project_with_global_scan_permission() { - ComponentDto project = db.components().insertProject(); userSession.setGlobalPermissions(SCAN_EXECUTION); - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + ComponentDto project = db.components().insertProject(db.getDefaultOrganization()); - underTest.submit(project.getKey(), null, project.name(), IOUtils.toInputStream("{binary}")); + mockSuccessfulPrepareSubmitCall(); + + underTest.submit(defaultOrganizationKey, project.getKey(), null, project.name(), IOUtils.toInputStream("{binary}")); verify(queue).submit(any(CeTaskSubmit.class)); } @Test public void submit_a_report_on_existing_project_with_project_scan_permission() { - ComponentDto project = db.components().insertProject(); + ComponentDto project = db.components().insertProject(db.getDefaultOrganization()); userSession.addProjectUuidPermissions(SCAN_EXECUTION, project.uuid()); - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + mockSuccessfulPrepareSubmitCall(); - underTest.submit(project.getKey(), null, project.name(), IOUtils.toInputStream("{binary}")); + underTest.submit(defaultOrganizationKey, project.getKey(), null, project.name(), IOUtils.toInputStream("{binary}")); verify(queue).submit(any(CeTaskSubmit.class)); } @@ -193,22 +220,26 @@ public class ReportSubmitterTest { userSession.setGlobalPermissions(GlobalPermissions.QUALITY_GATE_ADMIN); thrown.expect(ForbiddenException.class); - underTest.submit(PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); + underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); } @Test public void fail_with_forbidden_exception_on_new_project_when_only_project_scan_permission() { userSession.addProjectUuidPermissions(SCAN_EXECUTION, PROJECT_UUID); - when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + mockSuccessfulPrepareSubmitCall(); when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(new ComponentDto().setUuid(PROJECT_UUID).setKey(PROJECT_KEY)); thrown.expect(ForbiddenException.class); - underTest.submit(PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); + underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}")); } private void verifyReportIsPersisted(String taskUuid) { assertThat(db.selectFirst("select task_uuid from ce_task_input where task_uuid='" + taskUuid + "'")).isNotNull(); } + private void mockSuccessfulPrepareSubmitCall() { + when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/TestDefaultOrganizationProvider.java b/server/sonar-server/src/test/java/org/sonar/server/organization/TestDefaultOrganizationProvider.java index de614392c7a..23aca29a723 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/organization/TestDefaultOrganizationProvider.java +++ b/server/sonar-server/src/test/java/org/sonar/server/organization/TestDefaultOrganizationProvider.java @@ -19,33 +19,77 @@ */ package org.sonar.server.organization; +import java.util.Date; import org.sonar.db.DbTester; import org.sonar.db.organization.OrganizationDto; public class TestDefaultOrganizationProvider implements DefaultOrganizationProvider { - private final DbTester dbTester; + private final DefaultOrganizationProvider delegate; - private TestDefaultOrganizationProvider(DbTester dbTester) { - this.dbTester = dbTester; + private TestDefaultOrganizationProvider(DefaultOrganizationProvider delegate) { + this.delegate = delegate; } public static TestDefaultOrganizationProvider from(DbTester dbTester) { - return new TestDefaultOrganizationProvider(dbTester); + return new TestDefaultOrganizationProvider(new DbTesterDefaultOrganizationProvider(dbTester)); + } + + public static TestDefaultOrganizationProvider fromUuid(String uuid) { + long createdAt = new Date().getTime(); + return new TestDefaultOrganizationProvider( + new ImmutableDefaultOrganizationProvider( + DefaultOrganization.newBuilder() + .setUuid(uuid) + .setKey("key_" + uuid) + .setName("name_" + uuid) + .setCreatedAt(createdAt) + .setUpdatedAt(createdAt) + .build())); } @Override public DefaultOrganization get() { - return toDefaultOrganization(dbTester.getDefaultOrganization()); + return delegate.get(); } - private static DefaultOrganization toDefaultOrganization(OrganizationDto organizationDto) { - return DefaultOrganization.newBuilder() - .setUuid(organizationDto.getUuid()) - .setKey(organizationDto.getKey()) - .setName(organizationDto.getName()) - .setCreatedAt(organizationDto.getCreatedAt()) - .setUpdatedAt(organizationDto.getUpdatedAt()) - .build(); + private static final class ImmutableDefaultOrganizationProvider implements DefaultOrganizationProvider { + private final DefaultOrganization defaultOrganization; + + private ImmutableDefaultOrganizationProvider(DefaultOrganization defaultOrganization) { + this.defaultOrganization = defaultOrganization; + } + + @Override + public DefaultOrganization get() { + return defaultOrganization; + } + } + + private static final class DbTesterDefaultOrganizationProvider implements DefaultOrganizationProvider { + private final DbTester dbTester; + private DefaultOrganization defaultOrganization = null; + + private DbTesterDefaultOrganizationProvider(DbTester dbTester) { + this.dbTester = dbTester; + } + + @Override + public DefaultOrganization get() { + if (defaultOrganization == null) { + defaultOrganization = toDefaultOrganization(dbTester.getDefaultOrganization()); + } + return defaultOrganization; + } + + private static DefaultOrganization toDefaultOrganization(OrganizationDto organizationDto) { + return DefaultOrganization.newBuilder() + .setUuid(organizationDto.getUuid()) + .setKey(organizationDto.getKey()) + .setName(organizationDto.getName()) + .setCreatedAt(organizationDto.getCreatedAt()) + .setUpdatedAt(organizationDto.getUpdatedAt()) + .build(); + } } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/AddProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/AddProjectActionTest.java index 4217a8ebb0b..6e7352ef64e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/AddProjectActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/AddProjectActionTest.java @@ -39,7 +39,6 @@ import org.sonar.server.component.es.ProjectMeasuresIndexDefinition; import org.sonar.server.component.es.ProjectMeasuresIndexer; import org.sonar.server.es.EsTester; import org.sonar.server.language.LanguageTesting; -import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.qualityprofile.QProfileLookup; import org.sonar.server.qualityprofile.QProfileName; import org.sonar.server.qualityprofile.QProfileProjectOperations; @@ -80,8 +79,7 @@ public class AddProjectActionTest { private WsActionTester ws = new WsActionTester(new AddProjectAction(projectAssociationParameters, qProfileProjectOperations, new ProjectAssociationFinder(new QProfileLookup(dbClient), - new ComponentService(dbClient, null, userSession, null, new ComponentFinder(dbClient), new ProjectMeasuresIndexer(system2, dbClient, es.client()), - TestDefaultOrganizationProvider.from(dbTester))), + new ComponentService(dbClient, null, userSession, null, new ComponentFinder(dbClient), new ProjectMeasuresIndexer(system2, dbClient, es.client()))), userSession)); @Before diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java index 0760f437d74..07fab0ab11e 100644 --- a/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java @@ -24,6 +24,7 @@ import org.sonar.api.resources.Qualifiers; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; +import org.sonar.db.organization.OrganizationDto; import static java.util.Arrays.asList; import static org.sonar.db.component.ComponentTesting.newProjectDto; @@ -78,6 +79,14 @@ public class ComponentDbTester { return project; } + public ComponentDto insertProject(OrganizationDto organizationDto) { + ComponentDto project = newProjectDto().setOrganizationUuid(organizationDto.getUuid()); + dbClient.componentDao().insert(dbSession, project); + db.commit(); + + return project; + } + public void insertComponents(ComponentDto... components) { dbClient.componentDao().insert(dbSession, asList(components)); db.commit(); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java index b5eb78f7d8d..9296817a6b1 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java @@ -445,7 +445,7 @@ public abstract class Request { /** * Extends {@link Param} with convenience methods specific to the type {@link String}. */ - interface StringParam extends Param { + public interface StringParam extends Param { /** * Returns a {@link StringParam} object which methods {@link #getValue()} and {@link #or(Supplier)} will * return {@code null} rather than an empty String when the param is present and its value is an empty String.