Skip to content

Commit

Permalink
Utsab | BDSHR - 555 | Adding pagination to duplicate patient response…
Browse files Browse the repository at this point in the history
… along with next & previous page link
  • Loading branch information
Utsab Banerjee committed Jul 7, 2015
1 parent 0ccacb8 commit a1ef135
Show file tree
Hide file tree
Showing 15 changed files with 391 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.TreeSet;
import java.util.UUID;
Expand Down Expand Up @@ -101,7 +100,7 @@ public DeferredResult<ResponseEntity<MCIMultiResponse>> findPendingApprovalList(

MCIMultiResponse mciMultiResponse;
if (response != null) {
mciMultiResponse = buildPendingApprovalResponse(request, response, after, before);
mciMultiResponse = buildPaginatedResponse(request, response, after, before, patientService.getPerPageMaximumLimit());
} else {
mciMultiResponse = new MCIMultiResponse(emptyList(), null, OK);
}
Expand Down Expand Up @@ -284,50 +283,4 @@ private List<FeedEntry> buildFeedEntries(List<PatientData> patients, HttpServlet
}
return entries;
}

MCIMultiResponse buildPendingApprovalResponse(HttpServletRequest request,
List<PendingApprovalListResponse> response,
UUID after, UUID before) {

HashMap<String, String> additionalInfo = new HashMap<>();
int limit = patientService.getPerPageMaximumLimit();

if (response.size() > 0) {
if (after == null && before == null && response.size() > limit) {
response = response.subList(0, response.size() - 1);
additionalInfo.put(NEXT, buildPendingApprovalNextUrl(request, response.get(response.size() - 1).getLastUpdated()));
} else if (after != null && before == null && response.size() > 0) {
if (response.size() > limit) {
response = response.subList(0, response.size() - 1);
additionalInfo.put(NEXT, buildPendingApprovalNextUrl(request, response.get(response.size() - 1).getLastUpdated()));
additionalInfo.put(PREVIOUS, buildPendingApprovalPreviousUrl(request, response.get(0).getLastUpdated()));
} else {
additionalInfo.put(PREVIOUS, buildPendingApprovalPreviousUrl(request, response.get(0).getLastUpdated()));
}
} else if (before != null && after == null) {

if (response.size() > limit) {
response = response.subList(1, response.size());
additionalInfo.put(PREVIOUS, buildPendingApprovalPreviousUrl(request, response.get(0).getLastUpdated()));
additionalInfo.put(NEXT, buildPendingApprovalNextUrl(request, response.get(response.size() - 1).getLastUpdated()));
} else {
additionalInfo.put(NEXT, buildPendingApprovalNextUrl(request, response.get(response.size() - 1).getLastUpdated()));
}
}
}

return new MCIMultiResponse(response, additionalInfo, OK);
}

private String buildPendingApprovalNextUrl(HttpServletRequest request, UUID lastUUID) {
return fromUriString(buildUrl(request))
.queryParam(AFTER, lastUUID)
.build().toString();
}

private String buildPendingApprovalPreviousUrl(HttpServletRequest request, UUID lastUUID) {
return fromUriString(buildUrl(request))
.queryParam(BEFORE, lastUUID)
.build().toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.sharedhealth.mci.web.controller;

import org.apache.commons.collections4.Predicate;
import org.sharedhealth.mci.web.config.MCIProperties;
import org.sharedhealth.mci.web.exception.Forbidden;
import org.sharedhealth.mci.web.exception.ValidationException;
import org.sharedhealth.mci.web.handler.MCIMultiResponse;
Expand All @@ -10,6 +11,7 @@
import org.sharedhealth.mci.web.mapper.DuplicatePatientData;
import org.sharedhealth.mci.web.mapper.DuplicatePatientMergeData;
import org.sharedhealth.mci.web.service.DuplicatePatientService;
import org.sharedhealth.mci.web.service.SettingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -19,19 +21,24 @@
import org.springframework.web.bind.annotation.PathVariable;
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.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.apache.commons.collections4.CollectionUtils.find;
import static org.sharedhealth.mci.web.infrastructure.security.UserProfile.ADMIN_TYPE;
import static org.sharedhealth.mci.web.utils.JsonConstants.AFTER;
import static org.sharedhealth.mci.web.utils.JsonConstants.BEFORE;
import static org.springframework.http.HttpStatus.ACCEPTED;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
Expand All @@ -43,17 +50,26 @@
public class DuplicatePatientController extends MciController {

private static final Logger logger = LoggerFactory.getLogger(DuplicatePatientController.class);
public static final String PER_PAGE_MAXIMUM_LIMIT_NOTE = "PER_PAGE_MAXIMUM_LIMIT_NOTE";

private DuplicatePatientService duplicatePatientService;
private SettingService settingService;
private static final int PER_PAGE_MAXIMUM_LIMIT = 25;

@Autowired
public DuplicatePatientController(DuplicatePatientService duplicatePatientService) {
public DuplicatePatientController(DuplicatePatientService duplicatePatientService, SettingService settingService, MCIProperties properties) {
super(properties);
this.duplicatePatientService = duplicatePatientService;
this.settingService = settingService;
}

@PreAuthorize("hasAnyRole('ROLE_MCI Approver')")
@RequestMapping(value = "/catchments/{catchmentId}", method = GET, produces = APPLICATION_JSON_VALUE)
public DeferredResult<ResponseEntity<MCIMultiResponse>> findAllByCatchment(@PathVariable String catchmentId) {
public DeferredResult<ResponseEntity<MCIMultiResponse>> findAllByCatchment(
@PathVariable String catchmentId,
@RequestParam(value = AFTER, required = false) UUID after,
@RequestParam(value = BEFORE, required = false) UUID before,
HttpServletRequest request) {

UserInfo userInfo = getUserInfo();
String message = format("Find list of patient duplicates for catchment %s", catchmentId);
Expand All @@ -69,22 +85,20 @@ public DeferredResult<ResponseEntity<MCIMultiResponse>> findAllByCatchment(@Path
logger.debug(errorMessage);
return deferredResult;
}

List<DuplicatePatientData> response = findDuplicatesByCatchment(catchmentId);

List<DuplicatePatientData> response = findDuplicatesByCatchment(catchmentId, after, before);
MCIMultiResponse mciMultiResponse;
if (response != null) {
mciMultiResponse = new MCIMultiResponse(response, null, OK);
mciMultiResponse = buildPaginatedResponse(request, response, after, before, getPerPageMaximumLimit());
} else {
mciMultiResponse = new MCIMultiResponse(emptyList(), null, OK);
}
deferredResult.setResult(new ResponseEntity<>(mciMultiResponse, mciMultiResponse.httpStatusObject));
return deferredResult;
}

private List<DuplicatePatientData> findDuplicatesByCatchment(String catchmentId) {
private List<DuplicatePatientData> findDuplicatesByCatchment(String catchmentId, UUID after, UUID before) {
ArrayList<DuplicatePatientData> duplicates = new ArrayList<>(
duplicatePatientService.findAllByCatchment(new Catchment(catchmentId)));
duplicatePatientService.findAllByCatchment(new Catchment(catchmentId), after, before, (1 + getPerPageMaximumLimit()) * 3));
DuplicatePatientData duplicate;
for (Iterator<DuplicatePatientData> it = duplicates.iterator(); it.hasNext(); ) {
duplicate = it.next();
Expand Down Expand Up @@ -138,4 +152,12 @@ private void setRequester(DuplicatePatientMergeData data, UserInfo userInfo) {
data.getPatient1().setRequester(properties);
data.getPatient2().setRequester(properties);
}

public int getPerPageMaximumLimit() {
try {
return Integer.parseInt(settingService.getSettingAsStringByKey(PER_PAGE_MAXIMUM_LIMIT_NOTE));
} catch (Exception e) {
return PER_PAGE_MAXIMUM_LIMIT;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@

import static java.lang.String.format;
import static org.sharedhealth.mci.web.config.MCIConfig.getSupportedRequestUris;
import static org.springframework.web.util.UriComponentsBuilder.fromHttpUrl;

public class FeedController extends MciController {

protected PatientService patientService;
protected MCIProperties properties;

public FeedController(PatientService patientService, MCIProperties properties) {
super(properties);
this.patientService = patientService;
this.properties = properties;
}

protected String buildFeedUrl(HttpServletRequest request) {
Expand All @@ -37,8 +35,8 @@ protected String buildPatientLink(String healthId, HttpServletRequest request) {

private String buildPatientRequestUri(HttpServletRequest request) {
String requestUri = request.getRequestURI();
List<String> supportedRequestUris = getSupportedRequestUris(properties.getApiVersion(),
properties.isLatestApiVersion());
List<String> supportedRequestUris = getSupportedRequestUris(getProperties().getApiVersion(),
getProperties().isLatestApiVersion());

for (String mapping : supportedRequestUris) {
if (requestUri.startsWith(mapping)) {
Expand All @@ -48,17 +46,4 @@ private String buildPatientRequestUri(HttpServletRequest request) {
// should never happen
return "";
}

protected String buildUrl(HttpServletRequest request) {
return format("%s%s", buildServerUrl(request), request.getRequestURI());
}

String buildServerUrl(HttpServletRequest request) {
String url = properties.getServerUrl();
String host = fromHttpUrl(url).build().getHost();
if (host.equals(request.getServerName())) {
return url;
}
return format("%s://%s:%s", request.getScheme(), request.getServerName(), request.getServerPort());
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
package org.sharedhealth.mci.web.controller;

import org.sharedhealth.mci.web.config.MCIProperties;
import org.sharedhealth.mci.web.handler.MCIMultiResponse;
import org.sharedhealth.mci.web.infrastructure.security.UserInfo;
import org.sharedhealth.mci.web.mapper.ResponseWithAdditionalInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import static java.lang.String.format;
import static org.sharedhealth.mci.web.utils.JsonConstants.AFTER;
import static org.sharedhealth.mci.web.utils.JsonConstants.BEFORE;
import static org.sharedhealth.mci.web.utils.JsonConstants.NEXT;
import static org.sharedhealth.mci.web.utils.JsonConstants.PREVIOUS;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.web.util.UriComponentsBuilder.fromHttpUrl;
import static org.springframework.web.util.UriComponentsBuilder.fromUriString;

public class MciController {
private static final Logger logger = LoggerFactory.getLogger(MciController.class);

private MCIProperties properties;

public MciController() {
properties = new MCIProperties();
}

public MciController(MCIProperties properties) {
this.properties = properties;
}

protected UserInfo getUserInfo() {
return (UserInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
Expand All @@ -16,4 +43,64 @@ protected void logAccessDetails(UserInfo userInfo, String action) {
logger.info(String.format("ACCESS: USER=%s EMAIL=%s ACTION=%s",
userInfo.getProperties().getId(), userInfo.getProperties().getEmail(), action));
}

protected MCIMultiResponse buildPaginatedResponse(HttpServletRequest request,
List<? extends ResponseWithAdditionalInfo> response,
UUID after, UUID before, int limit) {

HashMap<String, String> additionalInfo = new HashMap<>();

if (response.size() > 0) {
if (after == null && before == null && response.size() > limit) {
response = response.subList(0, limit);
additionalInfo.put(NEXT, buildNextUrl(request, response.get(response.size() - 1).getModifiedAt()));
} else if (after != null && before == null && response.size() > 0) {
if (response.size() > limit) {
response = response.subList(0, limit);
additionalInfo.put(NEXT, buildNextUrl(request, response.get(response.size() - 1).getModifiedAt()));
additionalInfo.put(PREVIOUS, buildPreviousUrl(request, response.get(0).getModifiedAt()));
} else {
additionalInfo.put(PREVIOUS, buildPreviousUrl(request, response.get(0).getModifiedAt()));
}
} else if (before != null && after == null) {
if (response.size() > limit) {
response = response.subList(response.size() - limit, limit);
additionalInfo.put(PREVIOUS, buildPreviousUrl(request, response.get(0).getModifiedAt()));
additionalInfo.put(NEXT, buildNextUrl(request, response.get(response.size() - 1).getModifiedAt()));
} else {
additionalInfo.put(NEXT, buildNextUrl(request, response.get(response.size() - 1).getModifiedAt()));
}
}
}
return new MCIMultiResponse(response, additionalInfo, OK);
}

protected String buildNextUrl(HttpServletRequest request, UUID lastUUID) {
return fromUriString(buildUrl(request))
.queryParam(AFTER, lastUUID)
.build().toString();
}

protected String buildPreviousUrl(HttpServletRequest request, UUID lastUUID) {
return fromUriString(buildUrl(request))
.queryParam(BEFORE, lastUUID)
.build().toString();
}

protected String buildUrl(HttpServletRequest request) {
return format("%s%s", buildServerUrl(request), request.getRequestURI());
}

protected String buildServerUrl(HttpServletRequest request) {
String url = getProperties().getServerUrl();
String host = fromHttpUrl(url).build().getHost();
if (host.equals(request.getServerName())) {
return url;
}
return format("%s://%s:%s", request.getScheme(), request.getServerName(), request.getServerPort());
}

protected MCIProperties getProperties() {
return properties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,35 @@

import com.datastax.driver.core.querybuilder.Batch;
import com.datastax.driver.core.querybuilder.Delete;
import com.datastax.driver.core.querybuilder.Select;
import org.sharedhealth.mci.web.mapper.Catchment;
import org.sharedhealth.mci.web.model.DuplicatePatient;
import org.sharedhealth.mci.web.model.DuplicatePatientIgnored;
import org.springframework.data.cassandra.convert.CassandraConverter;

import java.util.List;
import java.util.Set;
import java.util.UUID;

import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
import static com.datastax.driver.core.querybuilder.QueryBuilder.timestamp;
import static com.datastax.driver.core.querybuilder.QueryBuilder.*;
import static org.sharedhealth.mci.web.infrastructure.persistence.RepositoryConstants.*;
import static org.springframework.data.cassandra.core.CassandraTemplate.createDeleteQuery;
import static org.springframework.data.cassandra.core.CassandraTemplate.createInsertQuery;

public class DuplicatePatientQueryBuilder {

public static String buildFindByCatchmentStmt(Catchment catchment) {
return select().from(CF_PATIENT_DUPLICATE).where(eq(CATCHMENT_ID, catchment.getId())).toString();
public static String buildFindByCatchmentStmt(Catchment catchment, UUID after, UUID before, int limit) {
Select.Where where = select().from(CF_PATIENT_DUPLICATE).where(eq(CATCHMENT_ID, catchment.getId()));

if (after != null) {
where.and(lt(CREATED_AT, after));
}

if (before != null) {
where.and(gt(CREATED_AT, before));
}

return where.limit(limit).toString();
}

public static String buildFindByCatchmentAndHealthIdsStmt(String catchmentId, String healthId1, String healthId2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public DuplicatePatientRepository(PatientRepository patientRepository,
/**
* Finds by exact catchment id.
*/
public List<DuplicatePatient> findByCatchment(Catchment catchment) {
return cassandraOps.select(buildFindByCatchmentStmt(catchment), DuplicatePatient.class);
public List<DuplicatePatient> findByCatchment(Catchment catchment, UUID after, UUID before, int limit) {
return cassandraOps.select(buildFindByCatchmentStmt(catchment, after, before, limit), DuplicatePatient.class);
}

public void processDuplicates(PatientData patientData1, PatientData patientData2, boolean isMerged) {
Expand Down
Loading

0 comments on commit a1ef135

Please sign in to comment.