Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SONAR-7299 Move code related to project creation to ComponentUpdater
- Loading branch information
1 parent
8996815
commit 4fc7e70
Showing
14 changed files
with
563 additions
and
456 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,151 @@ | |||
/* | |||
* 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 java.util.Date; | |||
import java.util.List; | |||
import java.util.Locale; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.i18n.I18n; | |||
import org.sonar.api.resources.Scopes; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.component.ComponentKeys; | |||
import org.sonar.core.util.Uuids; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.server.component.index.ComponentIndexer; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.favorite.FavoriteUpdater; | |||
import org.sonar.server.measure.index.ProjectMeasuresIndexer; | |||
import org.sonar.server.permission.PermissionTemplateService; | |||
|
|||
import static org.sonar.api.resources.Qualifiers.PROJECT; | |||
import static org.sonar.core.component.ComponentKeys.isValidModuleKey; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
|
|||
public class ComponentUpdater { | |||
|
|||
private final DbClient dbClient; | |||
private final I18n i18n; | |||
private final System2 system2; | |||
private final PermissionTemplateService permissionTemplateService; | |||
private final FavoriteUpdater favoriteUpdater; | |||
private final ProjectMeasuresIndexer projectMeasuresIndexer; | |||
private final ComponentIndexer componentIndexer; | |||
|
|||
public ComponentUpdater(DbClient dbClient, I18n i18n, System2 system2, | |||
PermissionTemplateService permissionTemplateService, FavoriteUpdater favoriteUpdater, | |||
ProjectMeasuresIndexer projectMeasuresIndexer, ComponentIndexer componentIndexer) { | |||
this.dbClient = dbClient; | |||
this.i18n = i18n; | |||
this.system2 = system2; | |||
this.projectMeasuresIndexer = projectMeasuresIndexer; | |||
this.componentIndexer = componentIndexer; | |||
this.permissionTemplateService = permissionTemplateService; | |||
this.favoriteUpdater = favoriteUpdater; | |||
} | |||
|
|||
/** | |||
* - Create component | |||
* - Apply default permission template | |||
* - Add component to favorite if the component has the 'Project Creators' permission | |||
* - Index component if es indexes | |||
*/ | |||
public ComponentDto create(DbSession dbSession, NewComponent newComponent, @Nullable Long userId) { | |||
checkKeyFormat(newComponent.qualifier(), newComponent.key()); | |||
ComponentDto componentDto = createRootComponent(dbSession, newComponent); | |||
removeDuplicatedProjects(dbSession, componentDto.getKey()); | |||
handlePermissionTemplate(dbSession, componentDto, newComponent.getOrganizationUuid(), userId); | |||
dbSession.commit(); | |||
index(componentDto.uuid()); | |||
return componentDto; | |||
} | |||
|
|||
private ComponentDto createRootComponent(DbSession session, NewComponent newComponent) { | |||
checkBranchFormat(newComponent.qualifier(), newComponent.branch()); | |||
String keyWithBranch = ComponentKeys.createKey(newComponent.key(), newComponent.branch()); | |||
if (dbClient.componentDao().selectByKey(session, keyWithBranch).isPresent()) { | |||
throw new BadRequestException(formatMessage("Could not create %s, key already exists: %s", newComponent.qualifier(), keyWithBranch)); | |||
} | |||
|
|||
String uuid = Uuids.create(); | |||
ComponentDto component = new ComponentDto() | |||
.setOrganizationUuid(newComponent.getOrganizationUuid()) | |||
.setUuid(uuid) | |||
.setUuidPath(ComponentDto.UUID_PATH_OF_ROOT) | |||
.setRootUuid(uuid) | |||
.setModuleUuid(null) | |||
.setModuleUuidPath(ComponentDto.UUID_PATH_SEPARATOR + uuid + ComponentDto.UUID_PATH_SEPARATOR) | |||
.setProjectUuid(uuid) | |||
.setKey(keyWithBranch) | |||
.setDeprecatedKey(keyWithBranch) | |||
.setName(newComponent.name()) | |||
.setLongName(newComponent.name()) | |||
.setScope(Scopes.PROJECT) | |||
.setQualifier(newComponent.qualifier()) | |||
.setCreatedAt(new Date(system2.now())); | |||
dbClient.componentDao().insert(session, component); | |||
dbClient.componentIndexDao().indexResource(session, component.uuid()); | |||
return component; | |||
} | |||
|
|||
/** | |||
* On MySQL, as PROJECTS.KEE is not unique, if the same project is provisioned multiple times, then it will be duplicated in the database. | |||
* So, after creating a project, we commit, and we search in the db if their are some duplications and we remove them. | |||
* | |||
* SONAR-6332 | |||
*/ | |||
private void removeDuplicatedProjects(DbSession session, String projectKey) { | |||
List<ComponentDto> duplicated = dbClient.componentDao().selectComponentsHavingSameKeyOrderedById(session, projectKey); | |||
for (int i = 1; i < duplicated.size(); i++) { | |||
dbClient.componentDao().delete(session, duplicated.get(i).getId()); | |||
} | |||
} | |||
|
|||
private void handlePermissionTemplate(DbSession dbSession, ComponentDto componentDto, String organizationUuid, @Nullable Long userId) { | |||
permissionTemplateService.applyDefault(dbSession, organizationUuid, componentDto, userId); | |||
if (componentDto.qualifier().equals(PROJECT) && permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, organizationUuid, componentDto)) { | |||
favoriteUpdater.add(dbSession, componentDto, userId); | |||
} | |||
} | |||
|
|||
private void checkKeyFormat(String qualifier, String kee) { | |||
checkRequest(isValidModuleKey(kee), formatMessage("Malformed key for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", | |||
qualifier, kee)); | |||
} | |||
|
|||
private void checkBranchFormat(String qualifier, @Nullable String branch) { | |||
if (branch != null && !ComponentKeys.isValidBranch(branch)) { | |||
throw new BadRequestException(formatMessage("Malformed branch for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and '/', with at least one non-digit.", | |||
qualifier, branch)); | |||
} | |||
} | |||
|
|||
private String formatMessage(String message, String qualifier, String key) { | |||
return String.format(message, i18n.message(Locale.getDefault(), "qualifier." + qualifier, "Project"), key); | |||
} | |||
|
|||
private void index(String projectUuid) { | |||
projectMeasuresIndexer.index(projectUuid); | |||
componentIndexer.indexByProjectUuid(projectUuid); | |||
} | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.