@@ -326,7 +326,6 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { | |||
UserPermissionChanger.class, | |||
GroupPermissionChanger.class, | |||
// components | |||
ComponentFinder.class, // used in ComponentService | |||
ComponentService.class, // used in ReportSubmitter |
@@ -126,13 +126,15 @@ public class ComponentService { | |||
projectMeasuresIndexer.index(projectUuid); | |||
} | |||
// Used by SQ and Governance | |||
public ComponentDto create(DbSession session, NewComponent newComponent) { | |||
userSession.checkPermission(GlobalPermissions.PROVISIONING); | |||
checkKeyFormat(newComponent.qualifier(), newComponent.key()); | |||
ComponentDto project = createProject(session, newComponent); | |||
removeDuplicatedProjects(session, project.getKey()); | |||
projectMeasuresIndexer.index(project.uuid()); | |||
return project; | |||
ComponentDto rootComponent = createRootComponent(session, newComponent); | |||
removeDuplicatedProjects(session, rootComponent.getKey()); | |||
projectMeasuresIndexer.index(rootComponent.uuid()); | |||
return rootComponent; | |||
} | |||
/** | |||
@@ -141,10 +143,10 @@ public class ComponentService { | |||
* No need to remove duplicated components as it's not possible to create the same developer twice in the same time. | |||
*/ | |||
public ComponentDto createDeveloper(DbSession session, NewComponent newComponent) { | |||
return createProject(session, newComponent); | |||
return createRootComponent(session, newComponent); | |||
} | |||
private ComponentDto createProject(DbSession session, NewComponent newComponent) { | |||
private ComponentDto createRootComponent(DbSession session, NewComponent newComponent) { | |||
checkBranchFormat(newComponent.qualifier(), newComponent.branch()); | |||
String keyWithBranch = ComponentKeys.createKey(newComponent.key(), newComponent.branch()); | |||
@@ -26,6 +26,7 @@ import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.component.Component; | |||
import org.sonar.api.component.RubyComponentService; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
@@ -40,12 +41,15 @@ public class DefaultRubyComponentService implements RubyComponentService { | |||
private final ResourceDao resourceDao; | |||
private final ComponentService componentService; | |||
private final PermissionTemplateService permissionTemplateService; | |||
private final FavoriteService favoriteService; | |||
public DefaultRubyComponentService(DbClient dbClient, ResourceDao resourceDao, ComponentService componentService, PermissionTemplateService permissionTemplateService) { | |||
public DefaultRubyComponentService(DbClient dbClient, ResourceDao resourceDao, ComponentService componentService, PermissionTemplateService permissionTemplateService, | |||
FavoriteService favoriteService) { | |||
this.dbClient = dbClient; | |||
this.resourceDao = resourceDao; | |||
this.componentService = componentService; | |||
this.permissionTemplateService = permissionTemplateService; | |||
this.favoriteService = favoriteService; | |||
} | |||
@Override | |||
@@ -81,6 +85,11 @@ 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)); | |||
permissionTemplateService.applyDefaultPermissionTemplate(dbSession, provisionedComponent.getKey()); | |||
if (Qualifiers.PROJECT.equals(provisionedComponent.qualifier())) { | |||
favoriteService.put(dbSession, provisionedComponent.getId()); | |||
dbSession.commit(); | |||
} | |||
return provisionedComponent.getId(); | |||
} | |||
@@ -0,0 +1,52 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.component; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.property.PropertyDto; | |||
import org.sonar.server.user.UserSession; | |||
public class FavoriteService { | |||
private static final String PROP_FAVORITE_KEY = "favourite"; | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
public FavoriteService(DbClient dbClient, UserSession userSession) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
} | |||
/** | |||
* Set favorite to the logged in user. If no user is logged, no action is done | |||
*/ | |||
public void put(DbSession dbSession, long componentDbId) { | |||
if (!userSession.isLoggedIn()) { | |||
return; | |||
} | |||
dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() | |||
.setKey(PROP_FAVORITE_KEY) | |||
.setResourceId(componentDbId) | |||
.setUserId(Long.valueOf(userSession.getUserId()))); | |||
} | |||
} |
@@ -34,6 +34,7 @@ import org.sonar.db.DbSession; | |||
import org.sonar.db.ce.CeTaskTypes; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.server.component.ComponentService; | |||
import org.sonar.server.component.FavoriteService; | |||
import org.sonar.server.component.NewComponent; | |||
import org.sonar.server.permission.PermissionTemplateService; | |||
import org.sonar.server.user.UserSession; | |||
@@ -49,14 +50,16 @@ public class ReportSubmitter { | |||
private final ComponentService componentService; | |||
private final PermissionTemplateService permissionTemplateService; | |||
private final DbClient dbClient; | |||
private final FavoriteService favoriteService; | |||
public ReportSubmitter(CeQueue queue, UserSession userSession, | |||
ComponentService componentService, PermissionTemplateService permissionTemplateService, DbClient dbClient) { | |||
ComponentService componentService, PermissionTemplateService permissionTemplateService, DbClient dbClient, FavoriteService favoriteService) { | |||
this.queue = queue; | |||
this.userSession = userSession; | |||
this.componentService = componentService; | |||
this.permissionTemplateService = permissionTemplateService; | |||
this.dbClient = dbClient; | |||
this.favoriteService = favoriteService; | |||
} | |||
public CeTask submit(String projectKey, @Nullable String projectBranch, @Nullable String projectName, InputStream reportInput) { | |||
@@ -84,8 +87,11 @@ public class ReportSubmitter { | |||
newProject.setQualifier(Qualifiers.PROJECT); | |||
// "provisioning" permission is check in ComponentService | |||
ComponentDto project = componentService.create(dbSession, newProject); | |||
favoriteService.put(dbSession, project.getId()); | |||
dbSession.commit(); | |||
permissionTemplateService.applyDefault(dbSession, project, projectCreatorUserId); | |||
return project; | |||
} | |||
@@ -149,7 +149,7 @@ public class PermissionTemplateService { | |||
*/ | |||
public void applyDefault(DbSession dbSession, ComponentDto component, @Nullable Long projectCreatorUserId) { | |||
PermissionTemplateDto template = findDefaultTemplate(dbSession, component); | |||
checkArgument(template != null, "Can not retrieve default permission template"); | |||
checkArgument(template != null, "Cannot retrieve default permission template"); | |||
copyPermissions(dbSession, template, component, projectCreatorUserId); | |||
dbSession.commit(); | |||
indexProjectPermissions(dbSession, asList(component.uuid())); |
@@ -41,6 +41,7 @@ import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.component.ComponentService; | |||
import org.sonar.server.component.DefaultComponentFinder; | |||
import org.sonar.server.component.DefaultRubyComponentService; | |||
import org.sonar.server.component.FavoriteService; | |||
import org.sonar.server.component.es.ProjectsEsModule; | |||
import org.sonar.server.component.ws.ComponentsWsModule; | |||
import org.sonar.server.config.ws.PropertiesWs; | |||
@@ -379,6 +380,7 @@ public class PlatformLevel4 extends PlatformLevel { | |||
NewAlerts.class, | |||
NewAlerts.newMetadata(), | |||
ComponentCleanerService.class, | |||
FavoriteService.class, | |||
// views | |||
ViewIndexDefinition.class, |
@@ -61,19 +61,20 @@ public class DefaultRubyComponentServiceTest { | |||
@Rule | |||
public EsTester es = new EsTester(new ProjectMeasuresIndexDefinition(new MapSettings())); | |||
I18nRule i18n = new I18nRule(); | |||
private I18nRule i18n = new I18nRule(); | |||
DbClient dbClient = db.getDbClient(); | |||
DbSession dbSession = db.getSession(); | |||
private DbClient dbClient = db.getDbClient(); | |||
private DbSession dbSession = db.getSession(); | |||
ResourceDao resourceDao = dbClient.resourceDao(); | |||
ComponentService componentService = new ComponentService(dbClient, i18n, userSession, System2.INSTANCE, new ComponentFinder(dbClient), | |||
private ResourceDao resourceDao = dbClient.resourceDao(); | |||
private ComponentService componentService = new ComponentService(dbClient, i18n, userSession, System2.INSTANCE, new ComponentFinder(dbClient), | |||
new ProjectMeasuresIndexer(dbClient, es.client())); | |||
PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); | |||
private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); | |||
private FavoriteService favoriteService = mock(FavoriteService.class); | |||
ComponentDbTester componentDb = new ComponentDbTester(db); | |||
DefaultRubyComponentService service = new DefaultRubyComponentService(dbClient, resourceDao, componentService, permissionTemplateService); | |||
DefaultRubyComponentService service = new DefaultRubyComponentService(dbClient, resourceDao, componentService, permissionTemplateService, favoriteService); | |||
@Test | |||
public void find_by_key() { | |||
@@ -111,6 +112,7 @@ public class DefaultRubyComponentServiceTest { | |||
assertThat(project.qualifier()).isEqualTo(qualifier); | |||
assertThat(project.getId()).isEqualTo(result); | |||
verify(permissionTemplateService).applyDefaultPermissionTemplate(any(DbSession.class), eq(componentKey)); | |||
verify(favoriteService).put(any(DbSession.class), eq(project.getId())); | |||
} | |||
@Test(expected = BadRequestException.class) |
@@ -0,0 +1,89 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.component; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.property.PropertyQuery; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class FavoriteServiceTest { | |||
private static final long COMPONENT_ID = 23L; | |||
private static final long USER_ID = 42L; | |||
@Rule | |||
public UserSessionRule userSession = UserSessionRule.standalone().login().setUserId((int) USER_ID); | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
private DbClient dbClient = db.getDbClient(); | |||
private DbSession dbSession = db.getSession(); | |||
private FavoriteService underTest = new FavoriteService(dbClient, userSession); | |||
@Test | |||
public void put_favorite() { | |||
assertNoFavorite(); | |||
underTest.put(dbSession, COMPONENT_ID); | |||
assertFavorite(); | |||
} | |||
@Test | |||
public void do_nothing_when_not_logged_in() { | |||
userSession.anonymous(); | |||
underTest.put(dbSession, COMPONENT_ID); | |||
assertNoFavorite(); | |||
} | |||
@Test | |||
public void put_existing_favorite() { | |||
underTest.put(dbSession, COMPONENT_ID); | |||
assertFavorite(); | |||
underTest.put(dbSession, COMPONENT_ID); | |||
assertFavorite(); | |||
} | |||
private void assertFavorite() { | |||
assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder() | |||
.setUserId((int) USER_ID) | |||
.setComponentId(COMPONENT_ID) | |||
.build(), dbSession)).hasSize(1); | |||
} | |||
private void assertNoFavorite() { | |||
assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder() | |||
.setUserId((int) USER_ID) | |||
.setComponentId(COMPONENT_ID) | |||
.build(), dbSession)).isEmpty(); | |||
} | |||
} |
@@ -36,6 +36,7 @@ import org.sonar.db.DbTester; | |||
import org.sonar.db.ce.CeTaskTypes; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.server.component.ComponentService; | |||
import org.sonar.server.component.FavoriteService; | |||
import org.sonar.server.component.NewComponent; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.permission.PermissionTemplateService; | |||
@@ -73,7 +74,9 @@ public class ReportSubmitterTest { | |||
private CeQueue queue = mock(CeQueueImpl.class); | |||
private ComponentService componentService = mock(ComponentService.class); | |||
private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); | |||
private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentService, permissionTemplateService, db.getDbClient()); | |||
private FavoriteService favoriteService = mock(FavoriteService.class); | |||
private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentService, permissionTemplateService, db.getDbClient(), favoriteService); | |||
@Test | |||
public void submit_a_report_on_existing_project() { | |||
@@ -86,6 +89,7 @@ public class ReportSubmitterTest { | |||
verifyReportIsPersisted(TASK_UUID); | |||
verifyZeroInteractions(permissionTemplateService); | |||
verifyZeroInteractions(favoriteService); | |||
verify(queue).submit(argThat(new TypeSafeMatcher<CeTaskSubmit>() { | |||
@Override | |||
protected boolean matchesSafely(CeTaskSubmit submit) { | |||
@@ -105,7 +109,7 @@ public class ReportSubmitterTest { | |||
userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); | |||
when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); | |||
ComponentDto createdProject = new ComponentDto().setUuid(PROJECT_UUID).setKey(PROJECT_KEY); | |||
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); | |||
@@ -114,6 +118,7 @@ public class ReportSubmitterTest { | |||
verifyReportIsPersisted(TASK_UUID); | |||
verify(permissionTemplateService).applyDefault(any(DbSession.class), eq(createdProject), anyLong()); | |||
verify(favoriteService).put(any(DbSession.class), eq(createdProject.getId())); | |||
verify(queue).submit(argThat(new TypeSafeMatcher<CeTaskSubmit>() { | |||
@Override | |||
protected boolean matchesSafely(CeTaskSubmit submit) { | |||
@@ -133,7 +138,7 @@ public class ReportSubmitterTest { | |||
userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); | |||
when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); | |||
when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(new ComponentDto().setUuid(PROJECT_UUID).setKey(PROJECT_KEY)); | |||
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); | |||