Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support to search projects based on ancestor project id #1298

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,37 +69,41 @@ public ProjectRepository(Producer producer, NamedParameterJdbcTemplate namedPara
}


public List<Project> getProjects(ProjectRequest project, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Boolean includeAncestors, Boolean includeDescendants, Long createdFrom, Long createdTo) {
public List<Project> getProjects(ProjectRequest project, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Boolean includeAncestors, Boolean includeDescendants, Long createdFrom, Long createdTo, boolean isAncestorProjectId) {

//Fetch Projects based on search criteria
List<Project> projects = getProjectsBasedOnSearchCriteria(project.getProjects(), limit, offset, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo);
List<Project> projects = getProjectsBasedOnSearchCriteria(project.getProjects(), limit, offset, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, isAncestorProjectId);

Set<String> projectIds = projects.stream().map(Project :: getId).collect(Collectors.toSet());

List<Project> ancestors = null;
List<Project> descendants = null;
//Get Project ancestors if includeAncestors flag is true
if (includeAncestors) {
ancestors = getProjectAncestors(projects);
if (ancestors != null && !ancestors.isEmpty()) {
List<String> ancestorProjectIds = ancestors.stream().map(Project :: getId).collect(Collectors.toList());
projectIds.addAll(ancestorProjectIds);
List<Target> targets = new ArrayList<>();
List<Document> documents = new ArrayList<>();
if(!projectIds.isEmpty()) {
//Get Project ancestors if includeAncestors flag is true
if (includeAncestors) {
ancestors = getProjectAncestors(projects);
if (ancestors != null && !ancestors.isEmpty()) {
List<String> ancestorProjectIds = ancestors.stream().map(Project :: getId).collect(Collectors.toList());
projectIds.addAll(ancestorProjectIds);
}
}
}
//Get Project descendants if includeDescendants flag is true
if (includeDescendants) {
descendants = getProjectDescendants(projects);
if (descendants != null && !descendants.isEmpty()) {
List<String> descendantsProjectIds = descendants.stream().map(Project :: getId).collect(Collectors.toList());
projectIds.addAll(descendantsProjectIds);
//Get Project descendants if includeDescendants flag is true
if (includeDescendants) {
descendants = getProjectDescendants(projects);
if (descendants != null && !descendants.isEmpty()) {
List<String> descendantsProjectIds = descendants.stream().map(Project :: getId).collect(Collectors.toList());
projectIds.addAll(descendantsProjectIds);
}
}
}

//Fetch targets based on Project Ids
List<Target> targets = getTargetsBasedOnProjectIds(projectIds);
//Fetch targets based on Project Ids
targets = getTargetsBasedOnProjectIds(projectIds);

//Fetch documents based on Project Ids
List<Document> documents = getDocumentsBasedOnProjectIds(projectIds);
//Fetch documents based on Project Ids
documents = getDocumentsBasedOnProjectIds(projectIds);
}

//Construct Project Objects with fetched projects, targets and documents using Project id
return buildProjectSearchResult(projects, targets, documents, ancestors, descendants);
Expand All @@ -114,28 +118,32 @@ public List<Project> getProjects(@NotNull @Valid ProjectSearch projectSearch, @V

List<Project> ancestors = null;
List<Project> descendants = null;
//Get Project ancestors if includeAncestors flag is true
if (urlParams.getIncludeAncestors()) {
ancestors = getProjectAncestors(projects);
if (ancestors != null && !ancestors.isEmpty()) {
List<String> ancestorProjectIds = ancestors.stream().map(Project :: getId).collect(Collectors.toList());
projectIds.addAll(ancestorProjectIds);
List<Target> targets = new ArrayList<>();
List<Document> documents = new ArrayList<>();
if(!projectIds.isEmpty()) {
//Get Project ancestors if includeAncestors flag is true
if (urlParams.getIncludeAncestors()) {
ancestors = getProjectAncestors(projects);
if (ancestors != null && !ancestors.isEmpty()) {
List<String> ancestorProjectIds = ancestors.stream().map(Project :: getId).toList();
projectIds.addAll(ancestorProjectIds);
}
}
}
//Get Project descendants if includeDescendants flag is true
if (urlParams.getIncludeDescendants()) {
descendants = getProjectDescendants(projects);
if (descendants != null && !descendants.isEmpty()) {
List<String> descendantsProjectIds = descendants.stream().map(Project :: getId).collect(Collectors.toList());
projectIds.addAll(descendantsProjectIds);
//Get Project descendants if includeDescendants flag is true
if (urlParams.getIncludeDescendants()) {
descendants = getProjectDescendants(projects);
if (descendants != null && !descendants.isEmpty()) {
List<String> descendantsProjectIds = descendants.stream().map(Project :: getId).toList();
projectIds.addAll(descendantsProjectIds);
}
}
}

//Fetch targets based on Project Ids
List<Target> targets = getTargetsBasedOnProjectIds(projectIds);
//Fetch targets based on Project Ids
targets = getTargetsBasedOnProjectIds(projectIds);

//Fetch documents based on Project Ids
List<Document> documents = getDocumentsBasedOnProjectIds(projectIds);
//Fetch documents based on Project Ids
documents = getDocumentsBasedOnProjectIds(projectIds);
}

//Construct Project Objects with fetched projects, targets and documents using Project id
return buildProjectSearchResult(projects, targets, documents, ancestors, descendants);
Expand All @@ -151,9 +159,9 @@ private List<Project> getProjectsBasedOnV2SearchCriteria(@NotNull @Valid Project
}

/* Fetch Projects based on search criteria */
private List<Project> getProjectsBasedOnSearchCriteria(List<Project> projectsRequest, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo) {
private List<Project> getProjectsBasedOnSearchCriteria(List<Project> projectsRequest, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId) {
List<Object> preparedStmtList = new ArrayList<>();
String query = queryBuilder.getProjectSearchQuery(projectsRequest, limit, offset, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, preparedStmtList, false);
String query = queryBuilder.getProjectSearchQuery(projectsRequest, limit, offset, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, isAncestorProjectId, preparedStmtList, false);
List<Project> projects = jdbcTemplate.query(query, addressRowMapper, preparedStmtList.toArray());

log.info("Fetched project list based on given search criteria");
Expand Down Expand Up @@ -339,9 +347,9 @@ private void addDescendantsToProjectSearchResult(Project project, List<Project>
* query build at the run time)
* @return
*/
public Integer getProjectCount(ProjectRequest project, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo) {
public Integer getProjectCount(ProjectRequest project, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId) {
List<Object> preparedStatement = new ArrayList<>();
String query = queryBuilder.getSearchCountQueryString(project.getProjects(), tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, preparedStatement);
String query = queryBuilder.getSearchCountQueryString(project.getProjects(), tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, isAncestorProjectId, preparedStatement);

if (query == null)
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class ProjectAddressQueryBuilder {
"on prj.id = addr.projectId ";;

/* Constructs project search query based on conditions */
public String getProjectSearchQuery(List<Project> projects, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, List<Object> preparedStmtList, boolean isCountQuery) {
public String getProjectSearchQuery(List<Project> projects, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId, List<Object> preparedStmtList, boolean isCountQuery) {
//This uses a ternary operator to choose between PROJECTS_COUNT_QUERY or FETCH_PROJECT_ADDRESS_QUERY based on the value of isCountQuery.
String query = isCountQuery ? PROJECTS_COUNT_QUERY : FETCH_PROJECT_ADDRESS_QUERY;
StringBuilder queryBuilder = new StringBuilder(query);
Expand All @@ -69,7 +69,12 @@ public String getProjectSearchQuery(List<Project> projects, Integer limit, Integ
}
}

if (StringUtils.isNotBlank(project.getId())) {
if (isAncestorProjectId && StringUtils.isNotBlank(project.getId())) {
addClauseIfRequired(preparedStmtList, queryBuilder);
queryBuilder.append(" ( prj.projectHierarchy LIKE ? OR prj.id =? ) ");
preparedStmtList.add('%' + project.getId() + '%');
preparedStmtList.add(project.getId());
} else if (StringUtils.isNotBlank(project.getId())) {
addClauseIfRequired(preparedStmtList, queryBuilder);
queryBuilder.append(" prj.id =? ");
preparedStmtList.add(project.getId());
Expand Down Expand Up @@ -379,8 +384,8 @@ public String getProjectDescendantsSearchQueryBasedOnIds(List<String> projectIds
}

/* Returns query to get total projects count based on project search params */
public String getSearchCountQueryString(List<Project> projects, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, List<Object> preparedStatement) {
String query = getProjectSearchQuery(projects, config.getMaxLimit(), config.getDefaultOffset(), tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, preparedStatement, true);
public String getSearchCountQueryString(List<Project> projects, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId, List<Object> preparedStatement) {
String query = getProjectSearchQuery(projects, config.getMaxLimit(), config.getDefaultOffset(), tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, isAncestorProjectId, preparedStatement, true);
return query;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ public List<Project> searchProject(
Boolean includeAncestors,
Boolean includeDescendants,
Long createdFrom,
Long createdTo
Long createdTo,
boolean isAncestorProjectId
) {
projectValidator.validateSearchProjectRequest(project, limit, offset, tenantId, createdFrom, createdTo);
List<Project> projects = projectRepository.getProjects(
Expand All @@ -102,7 +103,8 @@ public List<Project> searchProject(
includeAncestors,
includeDescendants,
createdFrom,
createdTo
createdTo,
isAncestorProjectId
);
return projects;
}
Expand All @@ -125,7 +127,7 @@ public ProjectRequest updateProject(ProjectRequest request) {
List<Project> projectsFromDB = searchProject(
getSearchProjectRequest(request.getProjects(), request.getRequestInfo(), false),
projectConfiguration.getMaxLimit(), projectConfiguration.getDefaultOffset(),
request.getProjects().get(0).getTenantId(), null, false, false, false, null, null
request.getProjects().get(0).getTenantId(), null, false, false, false, null, null, false
);
log.info("Fetched projects for update request");

Expand Down Expand Up @@ -280,7 +282,8 @@ private void checkAndEnrichCascadingProjectDates(ProjectRequest request, Project
true,
true,
null,
null
null,
false
);

/*
Expand All @@ -301,7 +304,7 @@ private List<Project> getParentProjects(ProjectRequest projectRequest) {
List<Project> parentProjects = null;
List<Project> projectsForSearchRequest = projectRequest.getProjects().stream().filter(p -> StringUtils.isNotBlank(p.getParent())).collect(Collectors.toList());
if (projectsForSearchRequest.size() > 0) {
parentProjects = searchProject(getSearchProjectRequest(projectsForSearchRequest, projectRequest.getRequestInfo(), true), projectConfiguration.getMaxLimit(), projectConfiguration.getDefaultOffset(), projectRequest.getProjects().get(0).getTenantId(), null, false, false, false, null, null);
parentProjects = searchProject(getSearchProjectRequest(projectsForSearchRequest, projectRequest.getRequestInfo(), true), projectConfiguration.getMaxLimit(), projectConfiguration.getDefaultOffset(), projectRequest.getProjects().get(0).getTenantId(), null, false, false, false, null, null, false);
}
log.info("Fetched parent projects from DB");
return parentProjects;
Expand Down Expand Up @@ -329,8 +332,8 @@ private ProjectRequest getSearchProjectRequest(List<Project> projects, RequestIn
/**
* @return Count of List of matching projects
*/
public Integer countAllProjects(ProjectRequest project, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo) {
return projectRepository.getProjectCount(project, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo);
public Integer countAllProjects(ProjectRequest project, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId) {
return projectRepository.getProjectCount(project, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, isAncestorProjectId);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ public ResponseEntity<ProjectResponse> searchProject(
@ApiParam(value = "Used in project search API to specify if response should include project elements that are in the preceding hierarchy of matched projects.", defaultValue = "false") @Valid @RequestParam(value = "includeAncestors", required = false, defaultValue = "false") Boolean includeAncestors,
@ApiParam(value = "Used in project search API to specify if response should include project elements that are in the following hierarchy of matched projects.", defaultValue = "false") @Valid @RequestParam(value = "includeDescendants", required = false, defaultValue = "false") Boolean includeDescendants,
@ApiParam(value = "Used in project search API to limit the search results to only those projects whose creation date is after the specified 'createdFrom' date", defaultValue = "false") @Valid @RequestParam(value = "createdFrom", required = false) Long createdFrom,
@ApiParam(value = "Used in project search API to limit the search results to only those projects whose creation date is before the specified 'createdTo' date", defaultValue = "false") @Valid @RequestParam(value = "createdTo", required = false) Long createdTo
@ApiParam(value = "Used in project search API to limit the search results to only those projects whose creation date is before the specified 'createdTo' date", defaultValue = "false") @Valid @RequestParam(value = "createdTo", required = false) Long createdTo,
@ApiParam(value = "Used in project search API to specify if response should be one which is in the preceding hierarchy of matched projects.") @Valid @RequestParam(value = "isAncestorProjectId", required = false, defaultValue = "false") boolean isAncestorProjectId
) {
List<Project> projects = projectService.searchProject(
project,
Expand All @@ -498,10 +499,11 @@ public ResponseEntity<ProjectResponse> searchProject(
includeAncestors,
includeDescendants,
createdFrom,
createdTo
createdTo,
isAncestorProjectId
);
ResponseInfo responseInfo = ResponseInfoFactory.createResponseInfo(project.getRequestInfo(), true);
Integer count = projectService.countAllProjects(project, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo);
Integer count = projectService.countAllProjects(project, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, isAncestorProjectId);
ProjectResponse projectResponse = ProjectResponse.builder().responseInfo(responseInfo).project(projects).totalCount(count).build();
return new ResponseEntity<ProjectResponse>(projectResponse, HttpStatus.OK);
}
Expand Down
Loading