use of org.finos.legend.sdlc.domain.model.project.Project in project legend-sdlc by finos.
the class GitLabProjectApi method getProjects.
@Override
public List<Project> getProjects(boolean user, String search, Iterable<String> tags, Iterable<ProjectType> types, Integer limit) {
try {
Set<ProjectType> typesSet;
if (types == null) {
typesSet = Collections.emptySet();
} else if (types instanceof Set) {
typesSet = (Set<ProjectType>) types;
} else {
typesSet = EnumSet.noneOf(ProjectType.class);
types.forEach(typesSet::add);
}
Iterable<GitLabMode> modes = typesSet.isEmpty() ? getValidGitLabModes() : typesSet.stream().map(GitLabProjectApi::getGitLabModeFromProjectType).filter(this::isValidGitLabMode).collect(Collectors.toList());
List<Project> projects = Lists.mutable.empty();
Set<String> tagSet = (tags == null) ? Collections.emptySet() : toLegendSDLCTagSet(tags);
for (GitLabMode mode : modes) {
Pager<org.gitlab4j.api.models.Project> pager = withRetries(() -> getGitLabApi(mode).getProjectApi().getProjects(null, null, null, null, search, true, null, user, null, null, ITEMS_PER_PAGE));
Stream<org.gitlab4j.api.models.Project> stream = PagerTools.stream(pager).filter(this::isLegendSDLCProject);
if (!tagSet.isEmpty()) {
stream = stream.filter(p -> p.getTagList().stream().anyMatch(tagSet::contains));
}
if (limit != null) {
// NOTE: this check implies that the mode that is scanned first could take all the slots within the
// limit. This limitation hopefully will be removed when we remove support for prototype (UAT) mode.
stream = stream.limit(limit - projects.size());
}
stream.map(p -> fromGitLabProject(p, mode)).forEach(projects::add);
if (limit != null && projects.size() >= limit) {
// If the number of projects found already exceed the limit, skip the check for the other modes
break;
}
}
// ensure the list of returned projects cannot exceed the limit (if specified) for whatever reasons
if (limit != null && projects.size() > limit) {
return projects.subList(0, limit);
}
return projects;
} catch (Exception e) {
throw buildException(e, () -> {
StringBuilder message = new StringBuilder("Failed to find ");
if (user) {
message.append("user ");
}
message.append("projects");
List<String> tagList = (tags == null) ? Collections.emptyList() : StreamSupport.stream(tags.spliterator(), false).collect(Collectors.toList());
if ((search != null) || !tagList.isEmpty()) {
message.append(" (");
if (search != null) {
message.append("search=\"").append(search).append("\"");
if (!tagList.isEmpty()) {
message.append(", ");
}
}
if (!tagList.isEmpty()) {
tagList.sort(Comparator.naturalOrder());
message.append("tags=[").append(String.join(", ", tagList)).append("]");
}
message.append(')');
}
return message.toString();
});
}
}
use of org.finos.legend.sdlc.domain.model.project.Project in project legend-sdlc by finos.
the class GitLabProjectApi method importProject.
@Override
public ImportReport importProject(String id, ProjectType type, String groupId, String artifactId) {
LegendSDLCServerException.validateNonNull(id, "id may not be null");
LegendSDLCServerException.validateNonNull(type, "type may not be null");
LegendSDLCServerException.validate(groupId, ProjectStructure::isValidGroupId, g -> "Invalid groupId: " + g);
LegendSDLCServerException.validate(artifactId, ProjectStructure::isValidArtifactId, a -> "Invalid artifactId: " + a);
// Get project id
GitLabProjectId projectId;
if (id.chars().allMatch(Character::isDigit)) {
projectId = GitLabProjectId.newProjectId(getGitLabModeFromProjectType(type), Integer.parseInt(id));
} else {
projectId = parseProjectId(id);
if (projectId.getGitLabMode() != getGitLabModeFromProjectType(type)) {
throw new LegendSDLCServerException("Invalid project id \"" + id + "\" for project type " + type, Status.BAD_REQUEST);
}
}
// Find project
GitLabApi gitLabApi = getGitLabApi(projectId.getGitLabMode());
org.gitlab4j.api.ProjectApi gitLabProjectApi = gitLabApi.getProjectApi();
org.gitlab4j.api.models.Project currentProject;
try {
currentProject = withRetries(() -> gitLabProjectApi.getProject(projectId.getGitLabId()));
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to access project " + id + " of type " + type, () -> "Could not find project " + id + " of type " + type, () -> "Failed to access project " + id + " of type " + type);
}
// Create a workspace for project configuration
RepositoryApi repositoryApi = gitLabApi.getRepositoryApi();
String workspaceId = "ProjectConfiguration_" + getRandomIdString();
Branch workspaceBranch;
try {
workspaceBranch = GitLabApiTools.createBranchFromSourceBranchAndVerify(repositoryApi, projectId.getGitLabId(), getWorkspaceBranchName(workspaceId, WorkspaceType.USER, ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE), MASTER_BRANCH, 30, 1_000);
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create a workspace for initial configuration of project " + id + " of type " + type, () -> "Could not find project " + id + " of type " + type, () -> "Failed to create workspace for initial configuration of project " + id + " of type " + type);
}
if (workspaceBranch == null) {
throw new LegendSDLCServerException("Failed to create workspace " + workspaceId + " in project " + projectId);
}
// Configure project in workspace
ProjectFileAccessProvider projectFileAccessProvider = getProjectFileAccessProvider();
Revision configRevision;
try {
ProjectConfiguration currentConfig = ProjectStructure.getProjectConfiguration(projectId.toString(), null, null, projectFileAccessProvider, WorkspaceType.USER, ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE);
ProjectConfigurationUpdateBuilder builder = ProjectConfigurationUpdateBuilder.newBuilder(projectFileAccessProvider, type, projectId.toString()).withWorkspace(workspaceId, WorkspaceType.USER, ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE).withGroupId(groupId).withArtifactId(artifactId).withProjectStructureExtensionProvider(this.projectStructureExtensionProvider).withProjectStructurePlatformExtensions(this.projectStructurePlatformExtensions);
int defaultProjectStructureVersion = getDefaultProjectStructureVersion();
if (currentConfig == null) {
// No current project structure: build a new one
configRevision = builder.withProjectStructureVersion(defaultProjectStructureVersion).withMessage("Build project structure").buildProjectStructure();
} else {
// Existing project structure: update
if (currentConfig.getProjectType() != type) {
throw new LegendSDLCServerException("Mismatch between requested project type (" + type + ") and found project type (" + currentConfig.getProjectType() + ")", Status.BAD_REQUEST);
}
ProjectStructureVersion currentVersion = currentConfig.getProjectStructureVersion();
if ((currentVersion == null) || (currentVersion.getVersion() < defaultProjectStructureVersion)) {
builder.withProjectStructureVersion(defaultProjectStructureVersion).withProjectStructureExtensionVersion(null);
}
configRevision = builder.withMessage("Update project structure").updateProjectConfiguration();
}
} catch (Exception e) {
// Try to delete the branch in case of exception
deleteWorkspace(projectId, repositoryApi, workspaceId);
throw e;
}
// Submit workspace changes, if any, for review
String reviewId;
if (configRevision == null) {
// No changes: nothing to submit
reviewId = null;
// Try to delete the branch
deleteWorkspace(projectId, repositoryApi, workspaceId);
} else {
MergeRequest mergeRequest;
try {
mergeRequest = gitLabApi.getMergeRequestApi().createMergeRequest(projectId.getGitLabId(), getWorkspaceBranchName(workspaceId, WorkspaceType.USER, ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE), MASTER_BRANCH, "Project structure", "Set up project structure", null, null, null, null, true, false);
} catch (Exception e) {
// Try to delete the branch in case of exception
deleteWorkspace(projectId, repositoryApi, workspaceId);
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to submit project configuration changes create a workspace for initial configuration of project " + id + " of type " + type, () -> "Could not find workspace " + workspaceId + " project " + id + " of type " + type, () -> "Failed to create a review for configuration of project " + id + " of type " + type);
}
reviewId = toStringIfNotNull(mergeRequest.getIid());
}
// Add tags
Project finalProject;
List<String> currentTags = currentProject.getTagList();
if ((currentTags != null) && currentTags.stream().anyMatch(this::isLegendSDLCProjectTag)) {
// already has the necessary tag
finalProject = fromGitLabProject(currentProject, projectId.getGitLabMode());
} else {
List<String> updatedTags = Lists.mutable.ofInitialCapacity((currentTags == null) ? 1 : (currentTags.size() + 1));
if (currentTags != null) {
updatedTags.addAll(currentTags);
}
updatedTags.add(getLegendSDLCProjectTag());
org.gitlab4j.api.models.Project updatedProject;
try {
updatedProject = gitLabProjectApi.updateProject(new org.gitlab4j.api.models.Project().withId(currentProject.getId()).withTagList(updatedTags));
} catch (Exception e) {
// Try to delete the branch in case of exception
deleteWorkspace(projectId, repositoryApi, workspaceId);
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to import project " + id + " of type " + type, () -> "Could not find project " + id + " of type " + type, () -> "Failed to import project " + id + " of type " + type);
}
finalProject = fromGitLabProject(updatedProject, projectId.getGitLabMode());
}
return new ImportReport() {
@Override
public Project getProject() {
return finalProject;
}
@Override
public String getReviewId() {
return reviewId;
}
};
}
use of org.finos.legend.sdlc.domain.model.project.Project in project legend-sdlc by finos.
the class GitLabProjectApi method checkUserAuthorizationActions.
@Override
public Set<ProjectAuthorizationAction> checkUserAuthorizationActions(String id, Set<ProjectAuthorizationAction> actions) {
try {
GitLabProjectId projectId = parseProjectId(id);
org.gitlab4j.api.models.Project gitLabProject = withRetries(() -> getGitLabApi(projectId.getGitLabMode()).getProjectApi().getProject(projectId.getGitLabId()));
if (!isLegendSDLCProject(gitLabProject)) {
throw new LegendSDLCServerException("Failed to get project " + id);
}
AccessLevel userLevel = getUserAccess(gitLabProject);
if (userLevel == null) {
return Collections.emptySet();
}
return actions.stream().filter(Objects::nonNull).filter(a -> checkUserAction(projectId, a, userLevel)).collect(Collectors.toSet());
} catch (Exception e) {
throw buildException(e, () -> "Failed to get project " + id);
}
}
use of org.finos.legend.sdlc.domain.model.project.Project in project legend-sdlc by finos.
the class GitLabProjectApi method createProject.
@Override
public Project createProject(String name, String description, ProjectType type, String groupId, String artifactId, Iterable<String> tags) {
LegendSDLCServerException.validate(name, n -> (n != null) && !n.isEmpty(), "name may not be null or empty");
LegendSDLCServerException.validateNonNull(description, "description may not be null");
LegendSDLCServerException.validateNonNull(type, "type may not be null");
LegendSDLCServerException.validate(groupId, ProjectStructure::isValidGroupId, g -> "Invalid groupId: " + g);
LegendSDLCServerException.validate(artifactId, ProjectStructure::isValidArtifactId, a -> "Invalid artifactId: " + a);
validateProjectCreation(name, description, type, groupId, artifactId);
try {
GitLabMode mode = getGitLabModeFromProjectType(type);
GitLabApi gitLabApi = getGitLabApi(mode);
List<String> tagList = Lists.mutable.empty();
tagList.add(getLegendSDLCProjectTag());
if (tags != null) {
tagList.addAll(toLegendSDLCTagSet(tags));
}
org.gitlab4j.api.models.Project gitLabProjectSpec = new org.gitlab4j.api.models.Project().withName(name).withDescription(description).withTagList(tagList).withVisibility(getNewProjectVisibility()).withMergeRequestsEnabled(true).withIssuesEnabled(true).withWikiEnabled(false).withSnippetsEnabled(false);
org.gitlab4j.api.models.Project gitLabProject = gitLabApi.getProjectApi().createProject(gitLabProjectSpec);
if (gitLabProject == null) {
throw new LegendSDLCServerException("Failed to create project: " + name);
}
// protect from commits on master
gitLabApi.getProtectedBranchesApi().protectBranch(gitLabProject.getId(), MASTER_BRANCH, AccessLevel.NONE, AccessLevel.MAINTAINER);
// build project structure
ProjectConfigurationUpdateBuilder.newBuilder(getProjectFileAccessProvider(), type, GitLabProjectId.getProjectIdString(mode, gitLabProject)).withMessage("Build project structure").withGroupId(groupId).withArtifactId(artifactId).withProjectStructureVersion(getDefaultProjectStructureVersion()).withProjectStructureExtensionProvider(this.projectStructureExtensionProvider).withProjectStructurePlatformExtensions(this.projectStructurePlatformExtensions).buildProjectStructure();
return fromGitLabProject(gitLabProject, mode);
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create project " + name, () -> "Failed to create project: " + name, () -> "Failed to create project: " + name);
}
}
use of org.finos.legend.sdlc.domain.model.project.Project in project legend-sdlc by finos.
the class GitLabProjectApi method changeProjectDescription.
@Override
public void changeProjectDescription(String id, String newDescription) {
LegendSDLCServerException.validateNonNull(id, "id may not be null");
LegendSDLCServerException.validateNonNull(newDescription, "newDescription may not be null");
try {
GitLabProjectId projectId = parseProjectId(id);
org.gitlab4j.api.models.Project currentProject = getPureGitLabProjectById(projectId);
org.gitlab4j.api.models.Project updatedProject = new org.gitlab4j.api.models.Project().withId(currentProject.getId()).withDescription(newDescription);
withRetries(() -> getGitLabApi(projectId.getGitLabMode()).getProjectApi().updateProject(updatedProject));
} catch (LegendSDLCServerException e) {
throw e;
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to change the description of project " + id + " to \"" + newDescription + "\"", () -> "Unknown project: " + id, () -> "Failed to change the description of project " + id + " to \"" + newDescription + "\"");
}
}
Aggregations