All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.openl.rules.rest.ProjectManagementController Maven / Gradle / Ivy
package org.openl.rules.rest;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.xml.bind.JAXBException;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.openl.rules.common.ProjectException;
import org.openl.rules.project.abstraction.ADeploymentProject;
import org.openl.rules.project.abstraction.RulesProject;
import org.openl.rules.repository.api.Repository;
import org.openl.rules.rest.exception.ConflictException;
import org.openl.rules.rest.exception.NotFoundException;
import org.openl.rules.rest.project.ProjectStateValidator;
import org.openl.rules.rest.resolver.DesignRepository;
import org.openl.rules.rest.service.ProjectDependencyResolver;
import org.openl.rules.rest.service.ProjectDeploymentService;
import org.openl.rules.rest.service.WorkspaceProjectService;
import org.openl.rules.ui.WebStudio;
import org.openl.rules.webstudio.web.repository.DeploymentManager;
import org.openl.rules.webstudio.web.repository.DeploymentProjectItem;
import org.openl.rules.workspace.uw.UserWorkspace;
import org.openl.security.acl.permission.AclPermission;
import org.openl.security.acl.repository.RepositoryAclService;
@RestController
@RequestMapping(value = "/user-workspace", produces = MediaType.APPLICATION_JSON_VALUE)
@Tag(name = "User Workspace")
public class ProjectManagementController {
private final ProjectDependencyResolver projectDependencyResolver;
private final ProjectDeploymentService projectDeploymentService;
private final DeploymentManager deploymentManager;
private final ProjectStateValidator projectStateValidator;
private final RepositoryAclService designRepositoryAclService;
private final RepositoryAclService deployConfigRepositoryAclService;
private final WorkspaceProjectService projectService;
@Autowired
public ProjectManagementController(ProjectDependencyResolver projectDependencyResolver,
ProjectDeploymentService projectDeploymentService,
DeploymentManager deploymentManager,
ProjectStateValidator projectStateValidator,
@Qualifier("designRepositoryAclService") RepositoryAclService designRepositoryAclService,
@Qualifier("deployConfigRepositoryAclService") RepositoryAclService deployConfigRepositoryAclService,
WorkspaceProjectService projectService) {
this.projectDependencyResolver = projectDependencyResolver;
this.projectDeploymentService = projectDeploymentService;
this.deploymentManager = deploymentManager;
this.projectStateValidator = projectStateValidator;
this.designRepositoryAclService = designRepositoryAclService;
this.deployConfigRepositoryAclService = deployConfigRepositoryAclService;
this.projectService = projectService;
}
@Lookup
public UserWorkspace getUserWorkspace() {
return null;
}
@Lookup
public WebStudio getWebStudio() {
return null;
}
/**
* Returns information about the project and its dependencies.
*
* @param repo repository where the project is located.
* @param name project name.
* @return project info.
*/
@GetMapping("/{repo-name}/projects/{proj-name}/info")
@Hidden
public ProjectInfo getInfo(@DesignRepository("repo-name") Repository repo, @PathVariable("proj-name") String name) {
try {
RulesProject project = getUserWorkspace().getProject(repo.getId(), name);
if (!designRepositoryAclService.isGranted(project, List.of(AclPermission.VIEW))) {
throw new SecurityException();
}
ProjectInfo info = new ProjectInfo(project);
info.dependsOn = projectDependencyResolver.getDependsOnProject(project)
.stream()
.map(ProjectInfo::new)
.collect(Collectors.toList());
info.dependencies = projectDependencyResolver.getProjectDependencies(project)
.stream()
.map(ProjectInfo::new)
.collect(Collectors.toList());
return info;
} catch (ProjectException | JAXBException e) {
throw new NotFoundException("project.message", name);
}
}
/**
* Returns deployment items for selected project.
*
* @param repo repository where the project is located.
* @param name project name.
* @param deployRepoName name of deploy repository.
* @return project info.
*/
@GetMapping("/{repo-name}/projects/{proj-name}/deployments/{deploy-repo-name}")
@Hidden
public List getDeploymentItems(@DesignRepository("repo-name") Repository repo,
@PathVariable("proj-name") String name,
@PathVariable("deploy-repo-name") String deployRepoName) {
try {
RulesProject project = getUserWorkspace().getProject(repo.getId(), name);
return projectDeploymentService.getDeploymentProjectItems(project, deployRepoName);
} catch (ProjectException e) {
throw new NotFoundException("project.message", name);
}
}
/**
* Closes the selected project
*
* @param repo repository where the project is located.
* @param name project name.
*/
@PostMapping("/{repo-name}/projects/{proj-name}/close")
@ResponseStatus(HttpStatus.NO_CONTENT)
@Hidden
public void close(@DesignRepository("repo-name") Repository repo, @PathVariable("proj-name") String name) {
var webstudio = getWebStudio();
try {
RulesProject project = getUserWorkspace().getProject(repo.getId(), name);
projectService.close(project);
webstudio.reset();
} catch (ProjectException e) {
throw new NotFoundException("project.message", name);
}
}
/**
* Opens the selected project
*
* @param repo repository where the project is located.
* @param name project name.
*/
@PostMapping("/{repo-name}/projects/{proj-name}/open")
@ResponseStatus(HttpStatus.NO_CONTENT)
@Hidden
public void open(@DesignRepository("repo-name") Repository repo,
@PathVariable("proj-name") String name,
@RequestParam(value = "open-dependencies", required = false, defaultValue = "false") boolean openDependencies) {
var webstudio = getWebStudio();
try {
RulesProject project = getUserWorkspace().getProject(repo.getId(), name);
projectService.open(project, openDependencies);
// User workspace is changed when the project was opened, so we must refresh it to calc dependencies.
// reset() should internally refresh workspace.
webstudio.reset();
} catch (ProjectException e) {
throw new NotFoundException("project.message", name);
}
}
/**
* Deploy the selected project
*
* @param repo repository where the project is located.
* @param name project name.
* @param deployRepoName repository name where to deploy the project.
* @param items items to deploy.
*/
@PostMapping("/{repo-name}/projects/{proj-name}/deploy")
@ResponseStatus(HttpStatus.NO_CONTENT)
@Hidden
public void deploy(@DesignRepository("repo-name") Repository repo,
@PathVariable("proj-name") String name,
@RequestParam("deploy-repo-name") String deployRepoName,
@RequestBody String[] items) {
try {
RulesProject project = getUserWorkspace().getProject(repo.getId(), name);
if (!projectStateValidator.canDeploy(project)) {
if (project.isDeleted()) {
throw new ConflictException("project.deploy.deleted.message");
}
throw new ConflictException("project.deploy.conflict.message");
}
List deploymentProjectItems = projectDeploymentService
.getDeploymentProjectItems(project, repo.getId());
List deploymentProjectsToDeploy = new ArrayList<>();
for (String item : items) {
Optional deploymentProjectItem = deploymentProjectItems.stream()
.filter(p -> p.getName().equals(item))
.findFirst();
if (deploymentProjectItem.isPresent() && deploymentProjectItem.get().isCanDeploy()) {
ADeploymentProject deploymentProject = projectDeploymentService.update(item, project, repo.getId());
if (!deployConfigRepositoryAclService.isGranted(deploymentProject, List.of(AclPermission.DEPLOY))) {
throw new SecurityException();
}
deploymentProjectsToDeploy.add(deploymentProject);
}
}
for (ADeploymentProject deploymentProject : deploymentProjectsToDeploy) {
deploymentManager.deploy(deploymentProject, deployRepoName);
}
} catch (ProjectException e) {
throw new NotFoundException("project.message", name);
}
}
/**
* WARNING: Currently it's used only for testing purpose. Should be finalized before using in real life
*
* @see org.openl.rules.webstudio.web.repository.RepositoryTreeController#deleteNode()
*/
@Hidden
@DeleteMapping(value = "/{repo-name}/projects/{proj-name}/delete", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ResponseStatus(HttpStatus.NOT_IMPLEMENTED) // change status after full implementation
public void delete(@DesignRepository("repo-name") Repository repo,
@PathVariable("proj-name") String name,
@RequestParam(value = "comment", required = false) final String comment) {
// FIXME request body is not allowed for DELETE method.
// see: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.5
// A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE
// request might cause some existing implementations to reject the request.
try {
RulesProject project = getUserWorkspace().getProject(repo.getId(), name);
if (!designRepositoryAclService.isGranted(project, List.of(AclPermission.DELETE))) {
throw new SecurityException();
}
if (!projectStateValidator.canDelete(project)) {
if (project.getDesignRepository().supports().branches() && project.getVersion() == null && !project
.isLocalOnly()) {
throw new ConflictException("project.delete.branch.message");
}
if (project.isLocked() || project.isLockedByMe()) {
throw new ConflictException("project.delete.locked.message");
}
throw new ConflictException("project.delete.message");
}
// TODO: Project should be closed for all users
project.delete(comment);
} catch (ProjectException e) {
throw new NotFoundException("project.message", name);
}
}
/**
* WARNING: Currently it's used only for testing purpose. Should be finalized before using in real life
*
* @see org.openl.rules.webstudio.web.repository.RepositoryTreeController#deleteNode()
*/
@Hidden
@DeleteMapping(value = "/{repo-name}/projects/{proj-name}/erase", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ResponseStatus(HttpStatus.NOT_IMPLEMENTED) // change status after full implementation
public void erase(@DesignRepository("repo-name") Repository repo,
@PathVariable("proj-name") String name,
@RequestParam(value = "comment", required = false) final String comment) {
try {
RulesProject project = getUserWorkspace().getProject(repo.getId(), name);
if (!designRepositoryAclService.isGranted(project, List.of(AclPermission.ERASE))) {
throw new SecurityException();
}
if (!projectStateValidator.canErase(project)) {
throw new ConflictException("project.erase.message");
}
project.erase(getUserWorkspace().getUser(), comment);
designRepositoryAclService.deleteAcl(project);
} catch (ProjectException e) {
throw new NotFoundException("project.message", name);
}
}
public static class ProjectInfo {
ProjectInfo(RulesProject project) {
this.name = project.getBusinessName();
this.modified = project.isModified();
this.opened = project.isOpened();
this.localOnly = project.isLocalOnly();
this.deleted = project.isDeleted();
this.openedForEditing = project.isOpenedForEditing();
}
public String name;
public boolean modified;
public boolean opened;
public boolean localOnly;
public boolean openedForEditing;
public boolean deleted;
public List dependencies;
public List dependsOn;
}
}