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

Dev reindex proj #836

Open
wants to merge 5 commits into
base: UCEM-1060
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 @@ -367,4 +367,38 @@ public Integer getProjectCount(ProjectSearch projectSearch, ProjectSearchURLPara
log.info("Total project count is : " + count);
return count;
}

public List<Project> getProjectsForBulkSearch(String tenantId, Integer limit, Integer offset) {
List<Object> preparedStmtList = new ArrayList<>();
String query = queryBuilder.getProjectQueryForBulkSearch(tenantId, limit, offset, preparedStmtList);
List<Project> projects = jdbcTemplate.query(query, addressRowMapper, preparedStmtList.toArray());

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
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
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 documents based on Project Ids
List<Document> documents = getDocumentsBasedOnProjectIds(projectIds);

//Construct Project Objects with fetched projects, targets and documents using Project id
return buildProjectSearchResult(projects, targets, documents, ancestors, descendants);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -377,4 +377,28 @@ public String getSearchCountQueryString(ProjectSearch projectSearch, ProjectSear
String query = getProjectSearchQuery(projectSearch, urlParams, preparedStatement, Boolean.TRUE);
return query;
}

public String getProjectQueryForBulkSearch(String tenantId, Integer limit, Integer offset, List<Object> preparedStmtList) {

StringBuilder queryBuilder = new StringBuilder(FETCH_PROJECT_ADDRESS_QUERY);

// Check if tenant ID is provided in URL parameters
if (StringUtils.isNotBlank(tenantId)) {
addClauseIfRequired(preparedStmtList, queryBuilder);
if (!tenantId.contains(DOT)) {
// State level tenant ID: use LIKE for partial matching
log.info("State level tenant");
queryBuilder.append(" prj.tenantId like ? ");
preparedStmtList.add(tenantId + '%');
} else {
// City level tenant ID: use exact match
log.info("City level tenant");
queryBuilder.append(" prj.tenantId=? ");
preparedStmtList.add(tenantId);
}
}

// Wrap constructed SQL query with pagination criteria
return addPaginationWrapper(queryBuilder.toString(), preparedStmtList, limit, offset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,13 @@ public Integer countAllProjects(ProjectRequest project, String tenantId, Long la
public Integer countAllProjects(ProjectSearchRequest projectSearchRequest, ProjectSearchURLParams urlParams) {
return projectRepository.getProjectCount(projectSearchRequest.getProject(), urlParams);
}

public List<Project> plainsearchProject(String tenantId, Integer limit, Integer offset) {
List<Project> projects = projectRepository.getProjectsForBulkSearch(tenantId, limit, offset);

// enrichment if needed

return projects;
}

}
190 changes: 95 additions & 95 deletions backend/project/src/main/java/org/egov/project/util/BoundaryUtil.java
Original file line number Diff line number Diff line change
@@ -1,95 +1,95 @@
package org.egov.project.util;

import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import digit.models.coremodels.RequestInfoWrapper;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.egov.common.contract.request.RequestInfo;
import org.egov.common.http.client.ServiceRequestClient;
import org.egov.tracer.model.CustomException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;


@Component
@Slf4j
public class BoundaryUtil {

@Value("${egov.location.host}")
private String locationHost;

@Value("${egov.location.context.path}")
private String locationContextPath;

@Value("${egov.location.endpoint}")
private String locationEndpoint;

@Value("${egov.location.code.query.param:codes}")
private String codeQueryParam;

@Autowired
private ServiceRequestClient serviceRequestRepository;

/* Takes map of locations with boundaryType as key and list of boundaries as its values, tenantId, requestInfo and hierarchyType.
* For each boundaryType, egov-location service is called with hierarchyType, tenantId and codes as parameters. The boundaries in request are validated against the egov-location response*/
public void validateBoundaryDetails(Map<String, List<String>> locations, String tenantId, RequestInfo requestInfo, String hierarchyTypeCode) {
for (Map.Entry<String, List<String>> entry : locations.entrySet()) {
String boundaryType = entry.getKey();
List<String> boundaries = entry.getValue();

log.info("Validating boundary for boundary type " + boundaryType + " with hierarchyType " + hierarchyTypeCode);
StringBuilder uri = new StringBuilder(locationHost);
uri.append(locationContextPath).append(locationEndpoint);
uri.append("?").append("tenantId=").append(tenantId);

if (hierarchyTypeCode != null)
uri.append("&").append("hierarchyTypeCode=").append(hierarchyTypeCode);

uri.append("&").append("boundaryType=").append(boundaryType).append("&")
.append(String.format("%s=", codeQueryParam))
.append(StringUtils.join(boundaries, ','));

Optional<Object> response = null;
try {
response = Optional.ofNullable(serviceRequestRepository.fetchResult(uri,
RequestInfoWrapper.builder().requestInfo(requestInfo).build(), LinkedHashMap.class));
} catch (Exception e) {
log.error("error while calling boundary service", ExceptionUtils.getStackTrace(e));
throw new CustomException("BOUNDARY_ERROR", "error while calling boundary service");
}

if (response.isPresent()) {
LinkedHashMap responseMap = (LinkedHashMap) response.get();
if (CollectionUtils.isEmpty(responseMap))
throw new CustomException("BOUNDARY ERROR", "The response from location service is empty or null");
String jsonString = new JSONObject(responseMap).toString();

for (String boundary : boundaries) {
String jsonpath = "$..boundary[?(@.code==\"{}\")]";
jsonpath = jsonpath.replace("{}", boundary);
DocumentContext context = JsonPath.parse(jsonString);
Object boundaryObject = context.read(jsonpath);

if (!(boundaryObject instanceof ArrayList) || CollectionUtils.isEmpty((ArrayList) boundaryObject)) {
log.error("The boundary data for the code " + boundary + " is not available");
throw new CustomException("INVALID_BOUNDARY_DATA", "The boundary data for the code "
+ boundary + " is not available");
}
}
}
log.info("The boundaries " + StringUtils.join(boundaries, ',') + " validated for boundary type " + boundaryType + " with tenantId " + tenantId);
}
}

}
//package org.egov.project.util;
//
//import com.jayway.jsonpath.DocumentContext;
//import com.jayway.jsonpath.JsonPath;
//import digit.models.coremodels.RequestInfoWrapper;
//import lombok.extern.slf4j.Slf4j;
//import net.minidev.json.JSONObject;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.commons.lang3.exception.ExceptionUtils;
//import org.egov.common.contract.request.RequestInfo;
//import org.egov.common.http.client.ServiceRequestClient;
//import org.egov.tracer.model.CustomException;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Component;
//import org.springframework.util.CollectionUtils;
//
//import java.util.ArrayList;
//import java.util.LinkedHashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.Optional;
//
//
//@Component
//@Slf4j
//public class BoundaryUtil {
//
// @Value("${egov.location.host}")
// private String locationHost;
//
// @Value("${egov.location.context.path}")
// private String locationContextPath;
//
// @Value("${egov.location.endpoint}")
// private String locationEndpoint;
//
// @Value("${egov.location.code.query.param:codes}")
// private String codeQueryParam;
//
// @Autowired
// private ServiceRequestClient serviceRequestRepository;
//
// /* Takes map of locations with boundaryType as key and list of boundaries as its values, tenantId, requestInfo and hierarchyType.
// * For each boundaryType, egov-location service is called with hierarchyType, tenantId and codes as parameters. The boundaries in request are validated against the egov-location response*/
// public void validateBoundaryDetails(Map<String, List<String>> locations, String tenantId, RequestInfo requestInfo, String hierarchyTypeCode) {
// for (Map.Entry<String, List<String>> entry : locations.entrySet()) {
// String boundaryType = entry.getKey();
// List<String> boundaries = entry.getValue();
//
// log.info("Validating boundary for boundary type " + boundaryType + " with hierarchyType " + hierarchyTypeCode);
// StringBuilder uri = new StringBuilder(locationHost);
// uri.append(locationContextPath).append(locationEndpoint);
// uri.append("?").append("tenantId=").append(tenantId);
//
// if (hierarchyTypeCode != null)
// uri.append("&").append("hierarchyTypeCode=").append(hierarchyTypeCode);
//
// uri.append("&").append("boundaryType=").append(boundaryType).append("&")
// .append(String.format("%s=", codeQueryParam))
// .append(StringUtils.join(boundaries, ','));
//
// Optional<Object> response = null;
// try {
// response = Optional.ofNullable(serviceRequestRepository.fetchResult(uri,
// RequestInfoWrapper.builder().requestInfo(requestInfo).build(), LinkedHashMap.class));
// } catch (Exception e) {
// log.error("error while calling boundary service", ExceptionUtils.getStackTrace(e));
// throw new CustomException("BOUNDARY_ERROR", "error while calling boundary service");
// }
//
// if (response.isPresent()) {
// LinkedHashMap responseMap = (LinkedHashMap) response.get();
// if (CollectionUtils.isEmpty(responseMap))
// throw new CustomException("BOUNDARY ERROR", "The response from location service is empty or null");
// String jsonString = new JSONObject(responseMap).toString();
//
// for (String boundary : boundaries) {
// String jsonpath = "$..boundary[?(@.code==\"{}\")]";
// jsonpath = jsonpath.replace("{}", boundary);
// DocumentContext context = JsonPath.parse(jsonString);
// Object boundaryObject = context.read(jsonpath);
//
// if (!(boundaryObject instanceof ArrayList) || CollectionUtils.isEmpty((ArrayList) boundaryObject)) {
// log.error("The boundary data for the code " + boundary + " is not available");
// throw new CustomException("INVALID_BOUNDARY_DATA", "The boundary data for the code "
// + boundary + " is not available");
// }
// }
// }
// log.info("The boundaries " + StringUtils.join(boundaries, ',') + " validated for boundary type " + boundaryType + " with tenantId " + tenantId);
// }
// }
//
//}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.egov.common.contract.models.RequestInfoWrapper;
import org.egov.common.contract.response.ResponseInfo;
import org.egov.common.models.core.ProjectSearchURLParams;
import org.egov.common.models.core.SearchResponse;
Expand Down Expand Up @@ -529,4 +530,20 @@ public ResponseEntity<ProjectResponse> updateProject(@ApiParam(value = "Details
return new ResponseEntity<ProjectResponse>(projectResponse, HttpStatus.OK);
}

@RequestMapping(value = "/v1/_plainsearch", method = RequestMethod.POST)
public ResponseEntity<ProjectResponse> plainsearchV1Project(
@Valid @RequestBody RequestInfoWrapper requestInfoWrapper,
@ApiParam(value = "Tenant id", defaultValue = "false") @Valid @RequestParam(value = "TenantId", required = false) String tenantId,
@ApiParam(value = "Limit", defaultValue = "false") @Valid @RequestParam(value = "limit", required = true) Integer limit,
@ApiParam(value = "Offset", defaultValue = "false") @Valid @RequestParam(value = "offset", required = true) Integer offset
) {
List<Project> projects = projectService.plainsearchProject(tenantId, limit, offset);
ResponseInfo responseInfo = ResponseInfoFactory.createResponseInfo(requestInfoWrapper.getRequestInfo(), true);
ProjectResponse projectResponse = ProjectResponse.builder()
.responseInfo(responseInfo)
.project(projects)
.build();
return new ResponseEntity<ProjectResponse>(projectResponse, HttpStatus.OK);
}

}
10 changes: 9 additions & 1 deletion build/build-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,15 @@ config:
dockerfile: "build/maven-java17/Dockerfile"
image-name: "rate-analysis"
- work-dir: "backend/rate-analysis/src/main/resources/db"
image-name: "rate-analysis-db"
image-name: "rate-analysis-db"

- name: "builds/mukta_impl/backend/project"
build:
- work-dir: "backend/project"
image-name: "project"
dockerfile: "build/maven-java17/Dockerfile"
- work-dir: "backend/project/src/main/resources/db"
image-name: "project-db"

# utilities
- name: "builds/mukta_impl/utilities/egov-pdf"
Expand Down