diff --git a/pom.xml b/pom.xml index bced9f9c1..7bf491c98 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ opensrp-server-web war - 3.2.11-SNAPSHOT + 3.2.12-SNAPSHOT opensrp-server-web OpenSRP Server Web Application https://github.com/OpenSRP/opensrp-server-web diff --git a/src/main/java/org/opensrp/web/rest/ClientResource.java b/src/main/java/org/opensrp/web/rest/ClientResource.java index 2aa4a53a5..89f9aee42 100644 --- a/src/main/java/org/opensrp/web/rest/ClientResource.java +++ b/src/main/java/org/opensrp/web/rest/ClientResource.java @@ -22,7 +22,11 @@ import static org.opensrp.common.AllConstants.Event.LOCATION_ID; import java.text.ParseException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -129,7 +133,8 @@ public Client update(Client entity) {//TODO check if send property and id matche } @Override - public List search(HttpServletRequest request) throws ParseException {//TODO search should not call different url but only add params + public List search(HttpServletRequest request) + throws ParseException {//TODO search should not call different url but only add params List clients = new ArrayList<>(); ClientSearchBean searchBean = new ClientSearchBean(); searchBean.setNameLike(getStringFilter("name", request)); @@ -224,7 +229,8 @@ private List getDependants(List clients, String searchRelationsh List dependantClients = new ArrayList<>(); List clientsToRemove = new ArrayList<>(); for (Client client : clients) { - List dependants = clientService.findByRelationshipIdAndType(searchRelationship, client.getBaseEntityId()); + List dependants = clientService + .findByRelationshipIdAndType(searchRelationship, client.getBaseEntityId()); if (dependants.size() > 0) { dependantClients.addAll(dependants); } else { @@ -304,7 +310,8 @@ public ResponseEntity searchByCriteria(HttpServletRequest request) throw searchBean.setStartDate(startDate); DateTime endDate = getDateFilter(ENDDATE, request); searchBean.setEndDate(endDate); - } catch (ParseException e) { + } + catch (ParseException e) { logger.error(e.getMessage()); } @@ -376,7 +383,8 @@ private int getTotal(ClientSearchBean clientSearchBean, AddressSearchBean addres if (HOUSEHOLD.equalsIgnoreCase(clientType)) { total = clientService.findTotalCountHouseholdByCriteria(clientSearchBean, addressSearchBean).getTotalCount(); } else if (ALLCLIENTS.equalsIgnoreCase(clientType)) { - total = clientService.findTotalCountAllClientsByCriteria(clientSearchBean, addressSearchBean).getTotalCount(); + total = clientService.findTotalCountAllClientsByCriteria(clientSearchBean, addressSearchBean) + .getTotalCount(); } else if (ANC.equalsIgnoreCase(clientType)) { clientSearchBean.setClientType(null); total = clientService.findCountANCByCriteria(clientSearchBean, addressSearchBean); @@ -427,27 +435,27 @@ public ResponseEntity getAllChild(ClientSearchBean clientSearchBean, Add @RequestMapping(value = "/findIds", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity findIds( - @RequestParam(value = SERVER_VERSIOIN) long serverVersion, + @RequestParam(value = SERVER_VERSIOIN) long serverVersion, @RequestParam(value = IS_ARCHIVED, defaultValue = FALSE, required = false) boolean isArchived, @RequestParam(value = "fromDate", required = false) String fromDate, @RequestParam(value = "toDate", required = false) String toDate) { Pair, Long> taskIdsPair = clientService.findAllIds(serverVersion, DEFAULT_GET_ALL_IDS_LIMIT, isArchived, - Utils.getDateTimeFromString(fromDate), Utils.getDateTimeFromString(toDate)); + Utils.getDateFromString(fromDate), Utils.getDateFromString(toDate)); Identifier identifiers = new Identifier(); identifiers.setIdentifiers(taskIdsPair.getLeft()); identifiers.setLastServerVersion(taskIdsPair.getRight()); return new ResponseEntity<>(identifiers, HttpStatus.OK); } - + /** * Fetch clients ordered by serverVersion ascending order * * @return a response with clients */ - @GetMapping(value = "/getAll", produces = {MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = "/getAll", produces = { MediaType.APPLICATION_JSON_VALUE }) public List getAll( - @RequestParam(value = SERVER_VERSIOIN) long serverVersion, - @RequestParam(required = false, defaultValue = DEFAULT_LIMIT + "") int limit){ + @RequestParam(value = SERVER_VERSIOIN) long serverVersion, + @RequestParam(required = false, defaultValue = DEFAULT_LIMIT + "") int limit) { return clientService.findByServerVersion(serverVersion, limit); } @@ -457,9 +465,9 @@ public List getAll( * * @return a response with clients */ - @GetMapping(value = "/countAll", produces = {MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = "/countAll", produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity countAll( - @RequestParam(value = SERVER_VERSIOIN) long serverVersion){ + @RequestParam(value = SERVER_VERSIOIN) long serverVersion) { Long countOfClients = clientService.countAll(serverVersion); ModelMap modelMap = new ModelMap(); modelMap.put("count", countOfClients != null ? countOfClients : 0); diff --git a/src/main/java/org/opensrp/web/rest/EventResource.java b/src/main/java/org/opensrp/web/rest/EventResource.java index 9eeb56f1f..6daf22584 100755 --- a/src/main/java/org/opensrp/web/rest/EventResource.java +++ b/src/main/java/org/opensrp/web/rest/EventResource.java @@ -140,7 +140,8 @@ protected ResponseEntity sync(HttpServletRequest request) throws JsonPro if (team != null || providerId != null || locationId != null || baseEntityId != null || teamId != null) { - EventSyncBean eventSyncBean = sync(providerId, locationId, baseEntityId, serverVersion, team, teamId, limit, returnCount, false); + EventSyncBean eventSyncBean = sync(providerId, locationId, baseEntityId, serverVersion, team, teamId, limit, + returnCount, false); HttpHeaders headers = getJSONUTF8Headers(); if (returnCount) { @@ -202,7 +203,8 @@ protected ResponseEntity syncByPost(@RequestBody SyncParam syncParam) th * @return Events found matching the client IDs * @throws JsonProcessingException */ - @RequestMapping(value = "/sync-out-of-catchment", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) + @RequestMapping(value = "/sync-out-of-catchment", method = RequestMethod.GET, produces = { + MediaType.APPLICATION_JSON_VALUE }) protected ResponseEntity syncOutOfCatchment(HttpServletRequest request) throws JsonProcessingException { EventSyncBean response = new EventSyncBean(); @@ -216,7 +218,8 @@ protected ResponseEntity syncOutOfCatchment(HttpServletRequest request) boolean returnCount = Boolean.getBoolean(getStringFilter(RETURN_COUNT, request)); if (team != null || providerId != null || locationId != null || baseEntityId != null || teamId != null) { - EventSyncBean eventSyncBean = sync(providerId, locationId, baseEntityId, serverVersion, team, teamId, limit, returnCount, true); + EventSyncBean eventSyncBean = sync(providerId, locationId, baseEntityId, serverVersion, team, teamId, limit, + returnCount, true); HttpHeaders headers = getJSONUTF8Headers(); if (returnCount) { @@ -231,7 +234,8 @@ protected ResponseEntity syncOutOfCatchment(HttpServletRequest request) } @RequestMapping(value = "/sync-out-of-catchment", method = POST, produces = { MediaType.APPLICATION_JSON_VALUE }) - protected ResponseEntity syncOutOfCatchmentByPost(@RequestBody SyncParam syncParam) throws JsonProcessingException { + protected ResponseEntity syncOutOfCatchmentByPost(@RequestBody SyncParam syncParam) + throws JsonProcessingException { EventSyncBean response = new EventSyncBean(); try { @@ -343,7 +347,8 @@ public EventSyncBean sync(String providerId, String locationId, String baseEntit return getEventsAndClients(eventSearchBean, limit == null || limit == 0 ? 25 : limit, returnCount, isOutOfCatchment); } - private EventSyncBean getEventsAndClients(EventSearchBean eventSearchBean, Integer limit, boolean returnCount, boolean isOutOfCatchment) { + private EventSyncBean getEventsAndClients(EventSearchBean eventSearchBean, Integer limit, boolean returnCount, + boolean isOutOfCatchment) { List events = new ArrayList(); List clientIds = new ArrayList(); List clients = new ArrayList(); @@ -406,7 +411,8 @@ private List getEvents(EventSearchBean eventSearchBean, Integer limit, bo List relationships = getRelationships(baseEntityIds); eventSearchBean.setBaseEntityId(eventSearchBean.getBaseEntityId() + "," + String.join(",", relationships)); - return eventService.findOutOfCatchmentEvents(eventSearchBean, BaseEntity.SERVER_VERSIOIN, "asc", limit == null ? 25 : limit); + return eventService.findOutOfCatchmentEvents(eventSearchBean, BaseEntity.SERVER_VERSIOIN, "asc", + limit == null ? 25 : limit); } else { return eventService.findEvents(eventSearchBean, BaseEntity.SERVER_VERSIOIN, "asc", limit == null ? 25 : limit); } @@ -449,7 +455,8 @@ protected ResponseEntity getAll(@RequestParam long serverVersion, eventSearchBean.setServerVersion(serverVersion > 0 ? serverVersion + 1 : serverVersion); eventSearchBean.setEventType(eventType); return new ResponseEntity<>( - objectMapper.writeValueAsString(getEventsAndClients(eventSearchBean, limit == null ? 25 : limit, false, false)), + objectMapper + .writeValueAsString(getEventsAndClients(eventSearchBean, limit == null ? 25 : limit, false, false)), getJSONUTF8Headers(), OK); } @@ -509,7 +516,8 @@ public ResponseEntity save(@RequestBody String data, Authentication auth clientService.addorUpdate(client); } catch (Exception e) { - logger.error("[SYNC_INFO] Sync failed for client {}; identifiers: {}", client.getBaseEntityId(), gson.toJson(client.getIdentifiers()), e); + logger.error("[SYNC_INFO] Sync failed for client {}; identifiers: {}", client.getBaseEntityId(), + gson.toJson(client.getIdentifiers()), e); failedClientsIds.add(client.getBaseEntityId()); } } @@ -528,7 +536,8 @@ public ResponseEntity save(@RequestBody String data, Authentication auth event = eventService.processOutOfArea(event); eventService.addorUpdateEvent(event, username); - logger.info("[SYNC_INFO] Event {} of type {} saved", event.getFormSubmissionId(), event.getEventType()); + logger.info("[SYNC_INFO] Event {} of type {} saved", event.getFormSubmissionId(), + event.getEventType()); } catch (Exception e) { logger.error( @@ -647,8 +656,8 @@ protected ResponseEntity getAllIdsByEventType( try { Pair, Long> eventIdsPair = eventService.findAllIdsByEventType(eventType, isDeleted, serverVersion, - Constants.DEFAULT_GET_ALL_IDS_LIMIT, Utils.getDateTimeFromString(fromDate), - Utils.getDateTimeFromString(toDate)); + Constants.DEFAULT_GET_ALL_IDS_LIMIT, Utils.getDateFromString(fromDate), + Utils.getDateFromString(toDate)); Identifier identifiers = new Identifier(); identifiers.setIdentifiers(eventIdsPair.getLeft()); identifiers.setLastServerVersion(eventIdsPair.getRight()); @@ -682,8 +691,8 @@ public ResponseEntity exportEventData(@RequestParam List getLocations(@RequestBody LocationSyncRequestWrapp Boolean isJurisdiction = locationSyncRequestWrapper.getIsJurisdiction(); String locationNames = StringUtils.join(locationSyncRequestWrapper.getLocationNames(), ","); String parentIds = StringUtils.join(locationSyncRequestWrapper.getParentId(), ","); - List locationIds=locationSyncRequestWrapper.getLocationIds(); + List locationIds = locationSyncRequestWrapper.getLocationIds(); boolean returnCount = locationSyncRequestWrapper.isReturnCount(); HttpHeaders headers = RestUtils.getJSONUTF8Headers(); Long locationCount = 0l; if (isJurisdiction) { - String locations="[]"; + String locations = "[]"; if (locationIds != null && !locationIds.isEmpty()) { - locations = gson.toJson(locationService.findLocationsByIds(true, locationIds,currentServerVersion)); + locations = gson.toJson(locationService.findLocationsByIds(true, locationIds, currentServerVersion)); if (returnCount) { locationCount = locationService.countLocationsByIds(locationIds, currentServerVersion); headers.add(TOTAL_RECORDS, String.valueOf(locationCount)); @@ -207,19 +207,23 @@ public ResponseEntity getLocations(@RequestBody LocationSyncRequestWrapp return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - String structures = gson.toJson(locationService.findStructuresByParentAndServerVersion(parentIds, currentServerVersion)); - if (returnCount){ - Long structureCount = locationService.countStructuresByParentAndServerVersion(parentIds, currentServerVersion); + String structures = gson + .toJson(locationService.findStructuresByParentAndServerVersion(parentIds, currentServerVersion)); + if (returnCount) { + Long structureCount = locationService + .countStructuresByParentAndServerVersion(parentIds, currentServerVersion); headers.add(TOTAL_RECORDS, String.valueOf(structureCount)); } return new ResponseEntity<>(structures, headers, HttpStatus.OK); } } - @RequestMapping(value = "/findStructuresByAncestor", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE}) - public ResponseEntity getStructuresByAncestor(@RequestParam(name = "id") final String ancestorId){ + @RequestMapping(value = "/findStructuresByAncestor", method = RequestMethod.GET, produces = { + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getStructuresByAncestor(@RequestParam(name = "id") final String ancestorId) { final long serverVersion = 0L; - List locationAndTheirChildren = locationService.findLocationByIdWithChildren(false, ancestorId, Integer.MAX_VALUE); + List locationAndTheirChildren = locationService + .findLocationByIdWithChildren(false, ancestorId, Integer.MAX_VALUE); String parentIds = locationAndTheirChildren.stream() .map(PhysicalLocation::getId) .collect(Collectors.joining(",")); @@ -247,14 +251,14 @@ public ResponseEntity getLocationsTwo(@RequestParam(BaseEntity.SERVER_VE if (isJurisdiction) { if (StringUtils.isBlank(locationNames)) { String locations = gson.toJson(locationService.findLocationsByServerVersion(currentServerVersion)); - if (returnCount){ + if (returnCount) { locationCount = locationService.countLocationsByServerVersion(currentServerVersion); headers.add(TOTAL_RECORDS, String.valueOf(locationCount)); } return new ResponseEntity<>(locations, headers, HttpStatus.OK); } String locations = gson.toJson(locationService.findLocationsByNames(locationNames, currentServerVersion)); - if (returnCount){ + if (returnCount) { locationCount = locationService.countLocationsByNames(locationNames, currentServerVersion); headers.add(TOTAL_RECORDS, String.valueOf(locationCount)); } @@ -264,9 +268,11 @@ public ResponseEntity getLocationsTwo(@RequestParam(BaseEntity.SERVER_VE if (StringUtils.isBlank(parentIds)) { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - String structures = gson.toJson(locationService.findStructuresByParentAndServerVersion(parentIds, currentServerVersion)); - if (returnCount){ - Long structureCount = locationService.countStructuresByParentAndServerVersion(parentIds, currentServerVersion); + String structures = gson + .toJson(locationService.findStructuresByParentAndServerVersion(parentIds, currentServerVersion)); + if (returnCount) { + Long structureCount = locationService + .countStructuresByParentAndServerVersion(parentIds, currentServerVersion); headers.add(TOTAL_RECORDS, String.valueOf(structureCount)); } return new ResponseEntity<>(structures, headers, HttpStatus.OK); @@ -284,7 +290,7 @@ public ResponseEntity create(@RequestBody String entity, return new ResponseEntity<>(HttpStatus.CREATED); } catch (JsonSyntaxException e) { - logger.error("The request doesnt contain a valid location representation",e); + logger.error("The request doesnt contain a valid location representation", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } @@ -300,7 +306,7 @@ public ResponseEntity update(@RequestBody String entity, return new ResponseEntity<>(HttpStatus.CREATED); } catch (JsonSyntaxException e) { - logger.error("The request doesnt contain a valid location representation",e); + logger.error("The request doesnt contain a valid location representation", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } @@ -323,7 +329,7 @@ public ResponseEntity saveBatch(@RequestBody String entity, } catch (JsonSyntaxException e) { - logger.error("The request doesnt contain a valid location representation",e); + logger.error("The request doesnt contain a valid location representation", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } @@ -364,7 +370,7 @@ public ResponseEntity findByLocationProperties( if (filterArray.length == 2 && (PARENT_ID.equalsIgnoreCase(filterArray[0]) || PARENT_ID_NO_UNDERSCORE.equalsIgnoreCase(filterArray[0]))) { parentId = Constants.NULL.equalsIgnoreCase(filterArray[1]) || StringUtils.isBlank(filterArray[1]) - ? "" : filterArray [1]; + ? "" : filterArray[1]; } else if (filterArray.length == 2) { filters.put(filterArray[0], filterArray[1]); @@ -435,12 +441,13 @@ public ResponseEntity findByIdWithChildren( @RequestMapping(value = "/findStructureIds", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity findIds( - @RequestParam(value = SERVER_VERSION) long serverVersion, + @RequestParam(value = SERVER_VERSION) long serverVersion, @RequestParam(value = "fromDate", required = false) String fromDate, @RequestParam(value = "toDate", required = false) String toDate) { - Pair, Long> structureIdsPair = locationService.findAllStructureIds(serverVersion, DEFAULT_GET_ALL_IDS_LIMIT, - Utils.getDateTimeFromString(fromDate), Utils.getDateTimeFromString(toDate)); + Pair, Long> structureIdsPair = locationService + .findAllStructureIds(serverVersion, DEFAULT_GET_ALL_IDS_LIMIT, + Utils.getDateFromString(fromDate), Utils.getDateFromString(toDate)); Identifier identifiers = new Identifier(); identifiers.setIdentifiers(structureIdsPair.getLeft()); identifiers.setLastServerVersion(structureIdsPair.getRight()); @@ -478,7 +485,9 @@ public ResponseEntity getAll( RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } else { return new ResponseEntity<>( - gson.toJson(locationService.findAllStructures(returnGeometry, serverVersion, pageLimit, pageNumber, orderByType, orderByFieldName)), + gson.toJson(locationService + .findAllStructures(returnGeometry, serverVersion, pageLimit, pageNumber, orderByType, + orderByFieldName)), RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } @@ -520,12 +529,13 @@ public ResponseEntity countAll( @RequestMapping(value = "/findLocationIds", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity findLocationIds( - @RequestParam(value = SERVER_VERSION) long serverVersion, + @RequestParam(value = SERVER_VERSION) long serverVersion, @RequestParam(value = "fromDate", required = false) String fromDate, @RequestParam(value = "toDate", required = false) String toDate) { - Pair, Long> locationIdsPair = locationService.findAllLocationIds(serverVersion, DEFAULT_GET_ALL_IDS_LIMIT, - Utils.getDateTimeFromString(fromDate), Utils.getDateTimeFromString(toDate)); + Pair, Long> locationIdsPair = locationService + .findAllLocationIds(serverVersion, DEFAULT_GET_ALL_IDS_LIMIT, + Utils.getDateFromString(fromDate), Utils.getDateFromString(toDate)); Identifier identifiers = new Identifier(); identifiers.setIdentifiers(locationIdsPair.getLeft()); identifiers.setLastServerVersion(locationIdsPair.getRight()); @@ -574,7 +584,7 @@ public ResponseEntity generateLocationTree( return new ResponseEntity<>(gson.toJson(tree), RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } - + @RequestMapping(value = "/hierarchy/plan/{plan}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity generateLocationTreeForPlan( @@ -603,7 +613,7 @@ public ResponseEntity generateLocationTreeForPlan( @PostMapping(value = "/dhis2/import", consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE }) - public ResponseEntity importLocations(@RequestParam(value = "startPage",required = false) String startPage, + public ResponseEntity importLocations(@RequestParam(value = "startPage", required = false) String startPage, @RequestParam("beginning") Boolean beginning) { final String DHIS_IMPORT_JOB_STATUS_END_POINT = "/rest/location/dhis2/status"; @@ -641,7 +651,6 @@ public Set generateLocationTreeWithAncestors(@PathVariable("loca return locationService.buildLocationHeirarchyWithAncestors(locationId); } - @Data static class LocationSyncRequestWrapper { diff --git a/src/main/java/org/opensrp/web/rest/PlanResource.java b/src/main/java/org/opensrp/web/rest/PlanResource.java index 5f340906d..6993167d0 100644 --- a/src/main/java/org/opensrp/web/rest/PlanResource.java +++ b/src/main/java/org/opensrp/web/rest/PlanResource.java @@ -61,16 +61,16 @@ @Controller @RequestMapping(value = "/rest/plans") public class PlanResource { - + private static Logger logger = LogManager.getLogger(PlanResource.class.toString()); - + public static Gson gson = new GsonBuilder() .registerTypeAdapter(DateTime.class, new TaskDateTimeTypeConverter("yyyy-MM-dd")) - .registerTypeAdapter(LocalDate.class, new DateTypeConverter()) + .registerTypeAdapter(LocalDate.class, new DateTypeConverter()) .registerTypeAdapter(Time.class, new TimingRepeatTimeTypeConverter()).create(); - + private PlanService planService; - + private PhysicalLocationService locationService; private static final String IS_DELETED = "is_deleted"; @@ -78,11 +78,11 @@ public class PlanResource { private static final String FALSE = "false"; public static final String OPERATIONAL_AREA_ID = "operational_area_id"; - + public static final String IDENTIFIERS = "identifiers"; - + public static final String FIELDS = "fields"; - + public static final String USERNAME = "username"; public static final String IS_TEMPLATE = "is_template"; @@ -90,32 +90,34 @@ public class PlanResource { public static final String PLAN_STATUS = "planStatus"; public static final String USE_CONTEXT = "useContext"; - + public static final String OPENSRP_EVENT_ID = "opensrpEventId"; @Autowired public void setPlanService(PlanService planService) { this.planService = planService; } - + @Autowired public void setLocationService(PhysicalLocationService locationService) { this.locationService = locationService; } - + @RequestMapping(value = "/{identifier}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getPlanByUniqueId(@PathVariable("identifier") String identifier, - @RequestParam(value = FIELDS, required = false) List fields , @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { + @RequestParam(value = FIELDS, required = false) List fields, + @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { if (identifier == null) { return new ResponseEntity<>("Plan Id is required", HttpStatus.BAD_REQUEST); } return new ResponseEntity<>( - gson.toJson(planService.getPlansByIdsReturnOptionalFields(Collections.singletonList(identifier), fields, isTemplateParam)), - RestUtils.getJSONUTF8Headers(), HttpStatus.OK); + gson.toJson(planService + .getPlansByIdsReturnOptionalFields(Collections.singletonList(identifier), fields, isTemplateParam)), + RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } - + @RequestMapping(method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getPlans(@RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam, @RequestParam(value = PAGE_NUMBER, required = false) Integer pageNumber, @@ -123,7 +125,7 @@ public ResponseEntity getPlans(@RequestParam(value = IS_TEMPLATE, requir @RequestParam(value = ORDER_BY_TYPE, required = false) String orderByType, @RequestParam(value = ORDER_BY_FIELD_NAME, required = false) String orderByFieldName, @RequestParam(value = PLAN_STATUS, required = false) String planStatus, - @RequestParam(value = USE_CONTEXT, required = false) List useContextList) { + @RequestParam(value = USE_CONTEXT, required = false) List useContextList) { Map useContextFilters = null; if (useContextList != null) { @@ -135,31 +137,35 @@ public ResponseEntity getPlans(@RequestParam(value = IS_TEMPLATE, requir } } } - PlanSearchBean planSearchBean = createPlanSearchBean(isTemplateParam, pageNumber, pageSize, orderByType, orderByFieldName, planStatus, useContextFilters); - return new ResponseEntity<>(gson.toJson(planService.getAllPlans(planSearchBean)),RestUtils.getJSONUTF8Headers(), HttpStatus.OK); + PlanSearchBean planSearchBean = createPlanSearchBean(isTemplateParam, pageNumber, pageSize, orderByType, + orderByFieldName, planStatus, useContextFilters); + return new ResponseEntity<>(gson.toJson(planService.getAllPlans(planSearchBean)), RestUtils.getJSONUTF8Headers(), + HttpStatus.OK); } - + @RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE }) public ResponseEntity create(@RequestBody String entity, Authentication authentication) { try { PlanDefinition plan = gson.fromJson(entity, PlanDefinition.class); - - //check whether a case triggered plan with a given opensrp event id exists + + //check whether a case triggered plan with a given opensrp event id exists PlanDefinition.UseContext opensrpEventIdUseContext = getUseContextWithCode(plan, OPENSRP_EVENT_ID); if (opensrpEventIdUseContext != null && !isValidCaseTriggeredPlan(opensrpEventIdUseContext)) { - return new ResponseEntity<>("Case triggered plan with opensrpEventId " + opensrpEventIdUseContext.getValueCodableConcept() + " already exists", HttpStatus.CONFLICT); + return new ResponseEntity<>( + "Case triggered plan with opensrpEventId " + opensrpEventIdUseContext.getValueCodableConcept() + + " already exists", HttpStatus.CONFLICT); } - + planService.addPlan(plan, RestUtils.currentUser(authentication).getUsername()); return new ResponseEntity<>(HttpStatus.CREATED); } catch (JsonSyntaxException e) { - logger.error("The request doesn't contain a valid plan representation",e); + logger.error("The request doesn't contain a valid plan representation", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } - + @RequestMapping(method = RequestMethod.PUT, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE }) public ResponseEntity update(@RequestBody String entity, Authentication authentication) { try { @@ -173,12 +179,13 @@ public ResponseEntity update(@RequestBody String entity, Authenticat } } - + @RequestMapping(value = "/sync", method = RequestMethod.POST, consumes = { - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity syncByServerVersionAndAssignedPlansOnOrganization( - @RequestBody PlanSyncRequestWrapper planSyncRequestWrapper, Authentication authentication, @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { - + @RequestBody PlanSyncRequestWrapper planSyncRequestWrapper, Authentication authentication, + @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { + List operationalAreaIds = planSyncRequestWrapper.getOperationalAreaId(); String username = null; if (authentication != null) @@ -194,30 +201,33 @@ public ResponseEntity syncByServerVersionAndAssignedPlansOnOrganization( planSyncRequestWrapper.getServerVersion(), isTemplateParam); if (planSyncRequestWrapper.isReturnCount()) { planCount = planService.countPlansByOrganizationsAndServerVersion(planSyncRequestWrapper.organizations, - planSyncRequestWrapper.getServerVersion()); + planSyncRequestWrapper.getServerVersion()); } } else if (username != null) { - plans = planService.getPlansByUsernameAndServerVersion(username, planSyncRequestWrapper.getServerVersion(), isTemplateParam); + plans = planService.getPlansByUsernameAndServerVersion(username, planSyncRequestWrapper.getServerVersion(), + isTemplateParam); if (planSyncRequestWrapper.isReturnCount()) { - planCount = planService.countPlansByUsernameAndServerVersion(username, planSyncRequestWrapper.getServerVersion()); + planCount = planService + .countPlansByUsernameAndServerVersion(username, planSyncRequestWrapper.getServerVersion()); } } else { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } HttpHeaders headers = RestUtils.getJSONUTF8Headers(); - if (planSyncRequestWrapper.isReturnCount()){ + if (planSyncRequestWrapper.isReturnCount()) { headers.add(TOTAL_RECORDS, String.valueOf(planCount)); } return new ResponseEntity<>(gson.toJson(plans), headers, HttpStatus.OK); } - + // here for backward compatibility @RequestMapping(value = "/sync", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity syncByServerVersionAndOperationalAreaTwo(HttpServletRequest request, - @RequestParam(value = OPERATIONAL_AREA_ID) List operationalAreaIds , @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { + @RequestParam(value = OPERATIONAL_AREA_ID) List operationalAreaIds, + @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { String serverVersion = getStringFilter(SERVER_VERSIOIN, request); long currentServerVersion = 0; try { @@ -231,25 +241,26 @@ public ResponseEntity syncByServerVersionAndOperationalAreaTwo(HttpServl } return new ResponseEntity<>( - gson.toJson(planService.getPlansByServerVersionAndOperationalArea(currentServerVersion, operationalAreaIds, isTemplateParam)), - RestUtils.getJSONUTF8Headers(), HttpStatus.OK); + gson.toJson(planService.getPlansByServerVersionAndOperationalArea(currentServerVersion, operationalAreaIds, + isTemplateParam)), + RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } - + /** * This method provides an API endpoint that searches for plans using a list of provided plan * identifiers and returns a subset of fields determined by the list of provided fields If no * plan identifier(s) are provided the method returns all available plans If no fields are * provided the method returns all the available fields - * + * * @param identifiers list of plan identifiers - * @param fields list of fields to return + * @param fields list of fields to return * @return plan definitions whose identifiers match the provided params */ @RequestMapping(value = "/findByIdsWithOptionalFields", method = RequestMethod.GET, produces = { - MediaType.APPLICATION_JSON_VALUE }) + MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity findByIdentifiersReturnOptionalFields(HttpServletRequest request, - @RequestParam(value = IDENTIFIERS) List identifiers, - @RequestParam(value = FIELDS, required = false) List fields, + @RequestParam(value = IDENTIFIERS) List identifiers, + @RequestParam(value = FIELDS, required = false) List fields, @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { if (fields != null && !fields.isEmpty()) { @@ -259,10 +270,11 @@ public ResponseEntity findByIdentifiersReturnOptionalFields(HttpServletR } } } - return new ResponseEntity<>(gson.toJson(planService.getPlansByIdsReturnOptionalFields(identifiers, fields, isTemplateParam)), - RestUtils.getJSONUTF8Headers(), HttpStatus.OK); + return new ResponseEntity<>( + gson.toJson(planService.getPlansByIdsReturnOptionalFields(identifiers, fields, isTemplateParam)), + RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } - + /** * This method provides an endpoint that searches for location details i.e. identifier and name * using a provided plan identifier @@ -271,28 +283,29 @@ public ResponseEntity findByIdentifiersReturnOptionalFields(HttpServletR * @return A list of location names and identifiers */ @RequestMapping(value = "/findLocationNames/{planIdentifier}", method = RequestMethod.GET, produces = { - MediaType.APPLICATION_JSON_VALUE }) + MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity> findLocationDetailsByPlanId( - @PathVariable("planIdentifier") String planIdentifier) { + @PathVariable("planIdentifier") String planIdentifier) { return new ResponseEntity<>(locationService.findLocationDetailsByPlanId(planIdentifier), - RestUtils.getJSONUTF8Headers(), HttpStatus.OK); + RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } /** * Fetch plans ordered by serverVersion ascending * * @param serverVersion serverVersion using to filter by - * @param limit upper limit on number os plas to fetch + * @param limit upper limit on number os plas to fetch * @return A list of plan definitions */ @RequestMapping(value = "/getAll", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getAll(@RequestParam(value = SERVER_VERSIOIN) long serverVersion, - @RequestParam(value = LIMIT, required = false) Integer limit, @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { + @RequestParam(value = LIMIT, required = false) Integer limit, + @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { Integer pageLimit = limit == null ? DEFAULT_LIMIT : limit; return new ResponseEntity<>(gson.toJson(planService.getAllPlans(serverVersion, pageLimit, isTemplateParam)), - RestUtils.getJSONUTF8Headers(), HttpStatus.OK); + RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } @@ -319,12 +332,12 @@ public ResponseEntity countAll(@RequestParam(value = SERVER_VERSIOIN) */ @RequestMapping(value = "/findIds", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity findIds(@RequestParam(value = SERVER_VERSIOIN, required = false) long serverVersion, - @RequestParam(value = IS_DELETED, defaultValue = FALSE, required = false) boolean isDeleted, - @RequestParam(value = "fromDate", required = false) String fromDate, - @RequestParam(value = "toDate", required = false) String toDate) { + @RequestParam(value = IS_DELETED, defaultValue = FALSE, required = false) boolean isDeleted, + @RequestParam(value = "fromDate", required = false) String fromDate, + @RequestParam(value = "toDate", required = false) String toDate) { Pair, Long> planIdsPair = planService.findAllIds(serverVersion, DEFAULT_GET_ALL_IDS_LIMIT, isDeleted, - Utils.getDateTimeFromString(fromDate), Utils.getDateTimeFromString(toDate)); + Utils.getDateFromString(fromDate), Utils.getDateFromString(toDate)); Identifier identifiers = new Identifier(); identifiers.setIdentifiers(planIdsPair.getLeft()); identifiers.setLastServerVersion(planIdsPair.getRight()); @@ -339,15 +352,16 @@ public ResponseEntity findIds(@RequestParam(value = SERVER_VERSIOIN, * @param username * @return plan definitions whose identifiers match the provided param */ - @RequestMapping(value = "/user/{username:.+}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) + @RequestMapping(value = "/user/{username:.+}", method = RequestMethod.GET, produces = { + MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity fetchPlansForUser(@PathVariable(USERNAME) String username, - @RequestParam(value = SERVER_VERSIOIN, required = false) String serverVersion, + @RequestParam(value = SERVER_VERSIOIN, required = false) String serverVersion, @RequestParam(value = IS_TEMPLATE, required = false) boolean isTemplateParam) { - + if (StringUtils.isBlank(username)) { return new ResponseEntity<>("Request Param missing", RestUtils.getJSONUTF8Headers(), HttpStatus.BAD_REQUEST); } - + long currentServerVersion = 0; try { currentServerVersion = Long.parseLong(serverVersion); @@ -363,7 +377,7 @@ public ResponseEntity fetchPlansForUser(@PathVariable(USERNAME) String u return new ResponseEntity<>(gson.toJson(plans), RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } - + public boolean doesObjectContainField(Object object, String fieldName) { Class objectClass = object.getClass(); for (Field field : objectClass.getDeclaredFields()) { @@ -376,34 +390,33 @@ else if (sName == null && field.getName().equals(fieldName)) { } return false; } - + static class PlanSyncRequestWrapper { - + @JsonProperty("operational_area_id") private List operationalAreaId; - + @JsonProperty private long serverVersion; - + @JsonProperty private List organizations; - + @JsonProperty(RETURN_COUNT) private boolean returnCount; public List getOperationalAreaId() { return operationalAreaId; } - + public long getServerVersion() { return serverVersion; } - + public List getOrganizations() { return organizations; } - public boolean isReturnCount() { return returnCount; } @@ -430,14 +443,15 @@ private PlanSearchBean createPlanSearchBean(boolean isTemplateParam, Integer pag return planSearchBean; } - + /** * This method retrieves a usecontext with a particular code from a plan + * * @param plan * @return PlanDefinition.UseContext */ private PlanDefinition.UseContext getUseContextWithCode(PlanDefinition plan, String useContextCode) { - for (PlanDefinition.UseContext useContext: plan.getUseContext() ) { + for (PlanDefinition.UseContext useContext : plan.getUseContext()) { if (useContext.getCode().equalsIgnoreCase(useContextCode)) { return useContext; } @@ -448,16 +462,17 @@ private PlanDefinition.UseContext getUseContextWithCode(PlanDefinition plan, Str /** * This method validates whether there is an existing case triggered * plan for a given opensrpEventId + * * @param useContext useContext that contains the opensrpEventId * @return boolean whether the plan is valid (it's not a duplicate) */ private boolean isValidCaseTriggeredPlan(PlanDefinition.UseContext useContext) { Map useContextFilters = new HashMap<>(); - useContextFilters.put(useContext.getCode(),useContext.getValueCodableConcept()); + useContextFilters.put(useContext.getCode(), useContext.getValueCodableConcept()); PlanSearchBean planSearchBean = createPlanSearchBean(false, 0, 5, null, null, null, useContextFilters); List plans = planService.getAllPlans(planSearchBean); return (plans != null && !plans.isEmpty()) ? false : true; } - + } diff --git a/src/main/java/org/opensrp/web/rest/RestUtils.java b/src/main/java/org/opensrp/web/rest/RestUtils.java index 86631fca7..d392ce830 100644 --- a/src/main/java/org/opensrp/web/rest/RestUtils.java +++ b/src/main/java/org/opensrp/web/rest/RestUtils.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.joda.time.DateTime; +import org.json.JSONObject; import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakSecurityContext; import org.keycloak.representations.AccessToken; @@ -11,6 +12,7 @@ import org.opensrp.domain.Multimedia; import org.opensrp.service.multimedia.MultimediaFileManager; import org.opensrp.service.multimedia.S3MultimediaFileManager; +import org.opensrp.web.utils.Utils; import org.springframework.http.HttpHeaders; import org.springframework.security.core.Authentication; @@ -30,58 +32,70 @@ import java.util.zip.ZipOutputStream; public class RestUtils { + public static final String DATE_FORMAT = "dd-MM-yyyy"; + public static final SimpleDateFormat SDF = new SimpleDateFormat("dd-MM-yyyy"); + public static final String DATETIME_FORMAT = "dd-MM-yyyy HH:mm"; + public static final SimpleDateFormat SDTF = new SimpleDateFormat("dd-MM-yyyy HH:mm"); private static final Logger logger = LogManager.getLogger(RestUtils.class.toString()); + public static String getStringFilter(String filter, HttpServletRequest req) { + return StringUtils.isBlank(req.getParameter(filter)) ? null : req.getParameter(filter); + } - public static String getStringFilter(String filter, HttpServletRequest req) - { - return StringUtils.isBlank(req.getParameter(filter)) ? null : req.getParameter(filter); + public static String getStringFilter(String filter, JSONObject jsonObject) { + return jsonObject.optString(filter); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Enum getEnumFilter(String filter, Class cls, HttpServletRequest req) - { - String filterVal = getStringFilter(filter, req); - if (filterVal != null) { - return Enum.valueOf(cls, filterVal); - } - return null; - } - - public static Integer getIntegerFilter(String filter, HttpServletRequest req) - { - String strval = getStringFilter(filter, req); - return strval == null ? null : Integer.parseInt(strval); + public static Enum getEnumFilter(String filter, Class cls, HttpServletRequest req) { + String filterVal = getStringFilter(filter, req); + if (filterVal != null) { + return Enum.valueOf(cls, filterVal); + } + return null; } - - public static Float getFloatFilter(String filter, HttpServletRequest req) - { - String strval = getStringFilter(filter, req); - return strval == null ? null : Float.parseFloat(strval); + + public static Integer getIntegerFilter(String filter, HttpServletRequest req) { + String strval = getStringFilter(filter, req); + return strval == null ? null : Integer.parseInt(strval); } - - public static DateTime getDateFilter(String filter, HttpServletRequest req) throws ParseException - { - String strval = getStringFilter(filter, req); - return strval == null ? null : new DateTime(strval); + + public static Float getFloatFilter(String filter, HttpServletRequest req) { + String strval = getStringFilter(filter, req); + return strval == null ? null : Float.parseFloat(strval); } - - public static DateTime[] getDateRangeFilter(String filter, HttpServletRequest req) throws ParseException { + + public static DateTime getDateFilter(String filter, HttpServletRequest req) throws ParseException { String strval = getStringFilter(filter, req); - if (strval == null) { - return null; + return strval == null ? null : new DateTime(strval); + } + + public static DateTime[] getDateRangeFilter(String filter, Object object) throws ParseException { + String strval = null; + + if (object instanceof HttpServletRequest) { + HttpServletRequest req = (HttpServletRequest) object; + strval = getStringFilter(filter, req); + } else { + JSONObject jsonObject = (JSONObject) object; + strval = getStringFilter(filter, jsonObject); } - if (!strval.contains(":")) { - return new DateTime[] { new DateTime(strval), new DateTime(strval) }; + + if (strval != null) { + if (!strval.contains(":")) { + return new DateTime[] { Utils.getDateTimeFromString(strval), Utils.getDateTimeFromString(strval) }; + } + DateTime d1 = Utils.getDateTimeFromString(strval.substring(0, strval.indexOf(":"))); + DateTime d2 = Utils.getDateTimeFromString(strval.substring(strval.indexOf(":") + 1)); + return new DateTime[] { d1, d2 }; + } else { + return null; } - DateTime d1 = new DateTime(strval.substring(0, strval.indexOf(":"))); - DateTime d2 = new DateTime(strval.substring(strval.indexOf(":") + 1)); - return new DateTime[] { d1, d2 }; } public static boolean getBooleanFilter(String filter, HttpServletRequest req) { @@ -89,51 +103,49 @@ public static boolean getBooleanFilter(String filter, HttpServletRequest req) { return Boolean.parseBoolean(stringFilter); } - public static void main(String[] args) { - System.out.println(new DateTime("​1458932400000")); + public static synchronized String setDateFilter(Date date) throws ParseException { + return date == null ? null : SDF.format(date); } - - public static synchronized String setDateFilter(Date date) throws ParseException - { - return date == null ? null : SDF.format(date); - } - + public static void verifyRequiredProperties(List properties, T entity) { - if(properties != null) - for (String p : properties) { - Field[] aaa = entity.getClass().getDeclaredFields(); - for (Field field : aaa) { - if(field.getName().equals(p)){ - field.setAccessible(true); - try { - if(field.get(entity) == null || field.get(entity).toString().trim().equalsIgnoreCase("")){ - throw new RuntimeException("A required field "+p+" was found empty"); + if (properties != null) + for (String p : properties) { + Field[] aaa = entity.getClass().getDeclaredFields(); + for (Field field : aaa) { + if (field.getName().equals(p)) { + field.setAccessible(true); + try { + if (field.get(entity) == null || field.get(entity).toString().trim().equalsIgnoreCase("")) { + throw new RuntimeException("A required field " + p + " was found empty"); + } + } + catch (IllegalArgumentException e) { + logger.error(e); + throw new RuntimeException("A required field " + p + " was not found in resource class"); + } + catch (IllegalAccessException e) { + logger.error(e); } - } catch (IllegalArgumentException e) { - e.printStackTrace(); - throw new RuntimeException("A required field "+p+" was not found in resource class"); - } catch (IllegalAccessException e) { - e.printStackTrace(); } } } - } } - + public static HttpHeaders getJSONUTF8Headers() { HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Content-Type", "application/json; charset=utf-8"); return responseHeaders; } - /** - * Zips multimedia files and writes content to {@param zipOutputStream} - * - * @param zipOutputStream - * @param multimediaFiles - * @throws IOException - */ - public static void zipFiles(ZipOutputStream zipOutputStream, List multimediaFiles, MultimediaFileManager fileManager) throws + /** + * Zips multimedia files and writes content to {@param zipOutputStream} + * + * @param zipOutputStream + * @param multimediaFiles + * @throws IOException + */ + public static void zipFiles(ZipOutputStream zipOutputStream, List multimediaFiles, + MultimediaFileManager fileManager) throws IOException { for (Multimedia multiMedia : multimediaFiles) { FileInputStream inputStream; @@ -143,7 +155,8 @@ public static void zipFiles(ZipOutputStream zipOutputStream, List mu zipOutputStream.putNextEntry(new ZipEntry(file.getName())); try { inputStream = new FileInputStream(file); - } catch (FileNotFoundException e) { + } + catch (FileNotFoundException e) { logger.warn("Could not find file " + file.getAbsolutePath()); continue; } @@ -165,18 +178,18 @@ public static void zipFiles(ZipOutputStream zipOutputStream, List mu } } } - + public static User currentUser(Authentication authentication) { if (authentication != null && authentication.getPrincipal() instanceof KeycloakPrincipal) { @SuppressWarnings("unchecked") KeycloakPrincipal kp = (KeycloakPrincipal) authentication - .getPrincipal(); + .getPrincipal(); AccessToken token = kp.getKeycloakSecurityContext().getToken(); User user = new User(authentication.getName()); user.setPreferredName(token.getName()); user.setUsername(token.getPreferredUsername()); List authorities = authentication.getAuthorities().stream().map(e -> e.getAuthority()) - .collect(Collectors.toList()); + .collect(Collectors.toList()); user.setAttributes(token.getOtherClaims()); user.setRoles(authorities); user.setPermissions(authorities); @@ -190,14 +203,13 @@ public static void writeToZipFile(String fileName, ZipOutputStream zipStream, St FileInputStream fis = null; ZipEntry zipEntry; String tempDirectory = System.getProperty("java.io.tmpdir"); - try{ - if(StringUtils.isNotBlank(fileName)) { + try { + if (StringUtils.isNotBlank(fileName)) { aFile = new File(StringUtils.isNotBlank(filePath) ? filePath : fileName); fis = new FileInputStream(aFile); zipEntry = new ZipEntry(StringUtils.isNotBlank(filePath) ? filePath.replace(tempDirectory, "") : fileName); logger.info("Writing file : '" + fileName + "' to zip file"); - } - else { + } else { fis = new FileInputStream(filePath); zipEntry = new ZipEntry(filePath); logger.info("Writing file : '" + filePath + "' to zip file"); diff --git a/src/main/java/org/opensrp/web/rest/SearchResource.java b/src/main/java/org/opensrp/web/rest/SearchResource.java index d5749ee4b..449939a10 100644 --- a/src/main/java/org/opensrp/web/rest/SearchResource.java +++ b/src/main/java/org/opensrp/web/rest/SearchResource.java @@ -1,9 +1,12 @@ package org.opensrp.web.rest; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.joda.time.DateTime; +import org.json.JSONObject; import org.opensrp.common.AllConstants.BaseEntity; import org.opensrp.search.ClientSearchBean; import org.opensrp.service.ClientService; @@ -17,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -41,19 +45,20 @@ import static org.opensrp.common.AllConstants.Client.ALT_PHONE_NUMBER; import static org.opensrp.common.AllConstants.Client.BIRTH_DATE; import static org.opensrp.web.rest.RestUtils.getStringFilter; +import static org.opensrp.web.rest.RestUtils.getDateRangeFilter; @Controller @RequestMapping(value = "/rest/search") public class SearchResource extends RestResource { - + private static Logger logger = LogManager.getLogger(SearchResource.class.toString()); - + private SearchService searchService; - + private ClientService clientService; - + private EventService eventService; - + @Autowired public SearchResource(SearchService searchService, ClientService clientService, EventService eventService) { this.searchService = searchService; @@ -62,144 +67,135 @@ public SearchResource(SearchService searchService, ClientService clientService, } /** - * @param request - * contains search parameter of with attributes and full colon e.g - * 1. search?attributes=phone_number:072700000 - * or search parameter without attribute and without colon e.g - * 2. search?phone_number=072700000 + * @param request contains search parameter of with attributes and full colon e.g + * 1. search?attributes=phone_number:072700000 + * or search parameter without attribute and without colon e.g + * 2. search?phone_number=072700000 * @throws ParseException */ @Override - public List search(HttpServletRequest request) throws ParseException {//TODO search should not call different url but only add params - String firstName = getStringFilter(FIRST_NAME, request); - String middleName = getStringFilter(MIDDLE_NAME, request); - String lastName = getStringFilter(LAST_NAME, request); - Optional phoneNumber = Optional.ofNullable(getStringFilter(PHONE_NUMBER, request)); - Optional altPhoneNumber = Optional.ofNullable(getStringFilter(ALT_PHONE_NUMBER, request)); - Optional alternateName = Optional.ofNullable(getStringFilter(ALT_NAME, request)); - ClientSearchBean searchBean = new ClientSearchBean(); - searchBean.setNameLike(getStringFilter(NAME, request)); + public List search(HttpServletRequest request) + throws ParseException {//TODO search should not call different url but only add params + Pair> result = extractSearchParams(request); + return searchService.searchClient(result.getLeft(), result.getRight().getLeft(), result.getRight().getMiddle(), + result.getRight().getRight(), null); + } - searchBean.setGender(getStringFilter(GENDER, request)); - DateTime[] birthdate = RestUtils.getDateRangeFilter(BIRTH_DATE, - request);//TODO add ranges like fhir do http://hl7.org/fhir/search.html - DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, request);//TODO client by provider id - //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a + @RequestMapping(method = RequestMethod.POST, value = "/search", produces = { MediaType.APPLICATION_JSON_VALUE }) + public List searchByPost(@RequestBody String jsonRequestBody) + throws ParseException {//TODO search should not call different url but only add params + Pair> result = extractSearchParams( + jsonRequestBody); + return searchService.searchClient(result.getLeft(), result.getRight().getLeft(), result.getRight().getMiddle(), + result.getRight().getRight(), null); - if (birthdate != null) { - searchBean.setBirthdateFrom(birthdate[0]); - searchBean.setBirthdateTo(birthdate[1]); - } - if (lastEdit != null) { - searchBean.setLastEditFrom(lastEdit[0]); - searchBean.setLastEditTo(lastEdit[1]); - } + } - Map attributeMap = new HashMap<>(); - String attributes = getStringFilter(ATTRIBUTE, request); - if (!StringUtils.isBlank(attributes)) { - String attributeType = StringUtils.isBlank(attributes) ? null : attributes.split(":", -1)[0]; - String attributeValue = StringUtils.isBlank(attributes) ? null : attributes.split(":", -1)[1]; - attributeMap.put(attributeType, attributeValue); - } - phoneNumber.ifPresent(phoneValue -> attributeMap.put(PHONE_NUMBER, phoneValue)); - altPhoneNumber.ifPresent(altPhoneValue -> attributeMap.put(ALT_PHONE_NUMBER, altPhoneValue)); - alternateName.ifPresent(altNameValue -> attributeMap.put(ALT_NAME, altNameValue)); - searchBean.setAttributes(attributeMap); + @RequestMapping(method = RequestMethod.GET, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) + public List searchPathByGet(HttpServletRequest request) throws ParseException { - Map identifierMap = null; - String identifiers = getStringFilter(IDENTIFIER, request); - if (!StringUtils.isBlank(identifiers)) { - String identifierType = StringUtils.isBlank(identifiers) ? null : identifiers.split(":", -1)[0]; - String identifierValue = StringUtils.isBlank(identifiers) ? null : identifiers.split(":", -1)[1]; + String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(request); + SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(request); + SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(request); - identifierMap = new HashMap<>(); - identifierMap.put(identifierType, identifierValue); - } - - searchBean.setIdentifiers(identifierMap); - return searchService.searchClient(searchBean, firstName, middleName, lastName, null); + return searchAndProcess(childSearchEntity, motherSearchEntity, contactPhoneNumber); } - @RequestMapping(method = RequestMethod.GET, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) - private List searchPathBy(HttpServletRequest request) throws ParseException { - //Process clients search via demographics + @RequestMapping(method = RequestMethod.POST, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) + public List searchPathByPost(@RequestBody String jsonRequestBody) throws ParseException { - ClientSearchBean searchBean = new ClientSearchBean(); - List children = new ArrayList(); + JSONObject jsonRequestBodyObject = new JSONObject(jsonRequestBody); - SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(request); + String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(jsonRequestBodyObject); + SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(jsonRequestBodyObject); + SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(jsonRequestBodyObject); - if (childSearchEntity.isValid()) { - searchBean = childSearchEntity.getClientSearchBean(); - children = searchService.searchGlobalClient(searchBean, searchBean.getFirstName(), searchBean.getMiddleName(), - searchBean.getLastName(), childSearchEntity.getLimit()); - } + return searchAndProcess(childSearchEntity, motherSearchEntity, contactPhoneNumber); - //Process mothers search via mother demographics + } - SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(request); - ClientSearchBean motherSearchBean = new ClientSearchBean(); - List mothers = new ArrayList(); + private List searchAndProcess(SearchEntityWrapper childSearchEntity, SearchEntityWrapper motherSearchEntity, + String contactPhoneNumber) { + try { + //Process clients search via demographics - if (motherSearchEntity.isValid()) { - motherSearchBean = motherSearchEntity.getClientSearchBean(); - mothers = searchService.searchGlobalClient(motherSearchBean, motherSearchBean.getFirstName(), - motherSearchBean.getMiddleName(), motherSearchBean.getLastName(), motherSearchEntity.getLimit()); - } + ClientSearchBean searchBean = new ClientSearchBean(); + List children = new ArrayList(); + if (childSearchEntity.isValid()) { + searchBean = childSearchEntity.getClientSearchBean(); + children = searchService + .searchGlobalClient(searchBean, searchBean.getFirstName(), searchBean.getMiddleName(), + searchBean.getLastName(), childSearchEntity.getLimit()); + } - //Process clients search via contact phone number + //Process mothers search via mother demographics - String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(request); + ClientSearchBean motherSearchBean = new ClientSearchBean(); + List mothers = new ArrayList(); + + if (motherSearchEntity.isValid()) { + motherSearchBean = motherSearchEntity.getClientSearchBean(); + mothers = searchService.searchGlobalClient(motherSearchBean, motherSearchBean.getFirstName(), + motherSearchBean.getMiddleName(), motherSearchBean.getLastName(), motherSearchEntity.getLimit()); + } - List clientBaseEntityIds = getClientBaseEntityIdsByContactPhoneNumber(contactPhoneNumber); + //Process clients search via contact phone number - List eventChildren = clientService.findGlobalByFieldValue(BaseEntity.BASE_ENTITY_ID, clientBaseEntityIds); + List clientBaseEntityIds = getClientBaseEntityIdsByContactPhoneNumber(contactPhoneNumber); - children = SearchHelper.intersection(children, eventChildren);// Search conjunction is "AND" find intersection + List eventChildren = clientService.findGlobalByFieldValue(BaseEntity.BASE_ENTITY_ID, clientBaseEntityIds); - List linkedMothers = new ArrayList(); + children = SearchHelper.intersection(children, eventChildren);// Search conjunction is "AND" find intersection - String RELATIONSHIP_KEY = "mother"; - if (!children.isEmpty()) { - List clientIds = new ArrayList(); - for (Client c : children) { - String relationshipId = SearchHelper.getRelationalId(c, RELATIONSHIP_KEY); - if (relationshipId != null && !clientIds.contains(relationshipId)) { - clientIds.add(relationshipId); + List linkedMothers = new ArrayList(); + + String RELATIONSHIP_KEY = "mother"; + if (!children.isEmpty()) { + List clientIds = new ArrayList(); + for (Client c : children) { + String relationshipId = SearchHelper.getRelationalId(c, RELATIONSHIP_KEY); + if (relationshipId != null && !clientIds.contains(relationshipId)) { + clientIds.add(relationshipId); + } } - } - linkedMothers = clientService.findGlobalByFieldValue(BaseEntity.BASE_ENTITY_ID, clientIds); + linkedMothers = clientService.findGlobalByFieldValue(BaseEntity.BASE_ENTITY_ID, clientIds); - } + } - List linkedChildren = new ArrayList(); + List linkedChildren = new ArrayList(); - if (!mothers.isEmpty()) { - for (Client client : mothers) { - linkedChildren.addAll(clientService.findGlobalByRelationship(client.getBaseEntityId())); + if (!mothers.isEmpty()) { + for (Client client : mothers) { + linkedChildren.addAll(clientService.findGlobalByRelationship(client.getBaseEntityId())); + } } - } - children = SearchHelper.intersection(children, linkedChildren);// Search conjunction is "AND" find intersection + children = SearchHelper.intersection(children, linkedChildren);// Search conjunction is "AND" find intersection - for (Client linkedMother : linkedMothers) { - if (!SearchHelper.contains(mothers, linkedMother)) { - mothers.add(linkedMother); + for (Client linkedMother : linkedMothers) { + if (!SearchHelper.contains(mothers, linkedMother)) { + mothers.add(linkedMother); + } } + + return SearchHelper.processSearchResult(children, mothers, RELATIONSHIP_KEY); + } + catch (Exception e) { - return SearchHelper.processSearchResult(children, mothers, RELATIONSHIP_KEY); + logger.error("", e); + return new ArrayList(); + } } - + public List getClientBaseEntityIdsByContactPhoneNumber(String motherGuardianPhoneNumber) { List clientBaseEntityIds = new ArrayList(); - + if (!StringUtils.isBlank(motherGuardianPhoneNumber)) { - + List events = eventService.findEventsByConceptAndValue("159635AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - motherGuardianPhoneNumber); + motherGuardianPhoneNumber); if (events != null && !events.isEmpty()) { for (Event event : events) { String entityId = event.getBaseEntityId(); @@ -207,40 +203,144 @@ public List getClientBaseEntityIdsByContactPhoneNumber(String motherGuar clientBaseEntityIds.add(entityId); } } - + } } return clientBaseEntityIds; } - + + public Pair> extractSearchParams(Object object) + throws ParseException { + + String firstName; + String middleName; + String lastName; + String name; + String gender; + String attributes; + String identifiers; + Optional phoneNumber; + Optional altPhoneNumber; + Optional alternateName; + DateTime[] birthdate; + DateTime[] lastEdit; + + ClientSearchBean searchBean = new ClientSearchBean(); + + if (object instanceof HttpServletRequest) { + HttpServletRequest request = (HttpServletRequest) object; + firstName = getStringFilter(FIRST_NAME, request); + middleName = getStringFilter(MIDDLE_NAME, request); + lastName = getStringFilter(LAST_NAME, request); + + phoneNumber = Optional.ofNullable(getStringFilter(PHONE_NUMBER, request)); + altPhoneNumber = Optional.ofNullable(getStringFilter(ALT_PHONE_NUMBER, request)); + alternateName = Optional.ofNullable(getStringFilter(ALT_NAME, request)); + + name = getStringFilter(NAME, request); + gender = getStringFilter(GENDER, request); + + birthdate = getDateRangeFilter(BIRTH_DATE, + request);//TODO add ranges like fhir do http://hl7.org/fhir/search.html + lastEdit = getDateRangeFilter(LAST_UPDATE, request);//TODO client by provider id + //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a + attributes = getStringFilter(ATTRIBUTE, request); + identifiers = getStringFilter(IDENTIFIER, request); + + } else { + JSONObject jsonObject = new JSONObject((String) object); + + firstName = getStringFilter(FIRST_NAME, jsonObject); + middleName = getStringFilter(MIDDLE_NAME, jsonObject); + lastName = getStringFilter(LAST_NAME, jsonObject); + + phoneNumber = Optional.ofNullable(getStringFilter(PHONE_NUMBER, jsonObject)); + altPhoneNumber = Optional.ofNullable(getStringFilter(ALT_PHONE_NUMBER, jsonObject)); + alternateName = Optional.ofNullable(getStringFilter(ALT_NAME, jsonObject)); + + name = getStringFilter(NAME, jsonObject); + gender = getStringFilter(GENDER, jsonObject); + + birthdate = getDateRangeFilter(BIRTH_DATE, + jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html + lastEdit = getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id + //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a + + attributes = getStringFilter(ATTRIBUTE, jsonObject); + identifiers = getStringFilter(IDENTIFIER, jsonObject); + + } + + searchBean.setNameLike(name); + searchBean.setGender(gender); + + if (birthdate != null) { + searchBean.setBirthdateFrom(birthdate[0]); + searchBean.setBirthdateTo(birthdate[1]); + } + if (lastEdit != null) { + searchBean.setLastEditFrom(lastEdit[0]); + searchBean.setLastEditTo(lastEdit[1]); + } + + Map attributeMap = new HashMap<>(); + + if (!StringUtils.isBlank(attributes)) { + String[] attributeParts = attributes.split(":", -1); + if (attributeParts.length == 2) { + attributeMap + .put(attributeParts[0], attributeParts[1]); // put attributeType and attributeValue as key value pair + } + } + + phoneNumber.ifPresent(phoneValue -> attributeMap.put(PHONE_NUMBER, phoneValue)); + altPhoneNumber.ifPresent(altPhoneValue -> attributeMap.put(ALT_PHONE_NUMBER, altPhoneValue)); + alternateName.ifPresent(altNameValue -> attributeMap.put(ALT_NAME, altNameValue)); + + searchBean.setAttributes(attributeMap); + + Map identifierMap = new HashMap<>(); + if (!StringUtils.isBlank(identifiers)) { + String[] identifierParts = identifiers.split(":", -1); + if (identifierParts.length == 2) { + identifierMap.put(identifierParts[0], + identifierParts[1]); // put identifierType and identifierValue key value pair + } + } + + searchBean.setIdentifiers(identifierMap); + + return Pair.of(searchBean, Triple.of(firstName, lastName, middleName)); + } + @Override public List filter(String query) { // TODO Auto-generated method stub return null; } - + @Override public Client getByUniqueId(String uniqueId) { // TODO Auto-generated method stub return null; } - + @Override public List requiredProperties() { // TODO Auto-generated method stub return null; } - + @Override public Client create(Client entity) { // TODO Auto-generated method stub return null; } - + @Override public Client update(Client entity) { // TODO Auto-generated method stub return null; } - + } diff --git a/src/main/java/org/opensrp/web/rest/TaskResource.java b/src/main/java/org/opensrp/web/rest/TaskResource.java index ad5c4bf12..ddd4bb7b5 100644 --- a/src/main/java/org/opensrp/web/rest/TaskResource.java +++ b/src/main/java/org/opensrp/web/rest/TaskResource.java @@ -67,47 +67,47 @@ @Validated @RequestMapping(value = "/rest/task") public class TaskResource { - + private static Logger logger = LogManager.getLogger(TaskResource.class.toString()); - + public Gson gson = new GsonBuilder().registerTypeAdapter(DateTime.class, new TaskDateTimeTypeConverter()) - .registerTypeAdapter(TaskPriority.class, new PriorityOrdinalConverter()).create(); - + .registerTypeAdapter(TaskPriority.class, new PriorityOrdinalConverter()).create(); + public static final String PLAN = "plan"; - + public static final String GROUP = "group"; - + public static final String OWNER = "owner"; - + private TaskService taskService; - + @Autowired public void setTaskService(TaskService taskService) { this.taskService = taskService; } - + /** * @param gson the gson to set */ public void setGson(Gson gson) { this.gson = gson; } - + @RequestMapping(value = "/{identifier}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getByUniqueId(@PathVariable("identifier") String identifier) { return new ResponseEntity<>(gson.toJson(convertToDTO(taskService.getTask(identifier))), - RestUtils.getJSONUTF8Headers(), HttpStatus.OK); + RestUtils.getJSONUTF8Headers(), HttpStatus.OK); } - + @RequestMapping(value = "/sync", method = RequestMethod.POST, consumes = { - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getTasksByTaskAndGroup(@RequestBody TaskSyncRequestWrapper taskSyncRequestWrapper) { String plan = StringUtils.join(taskSyncRequestWrapper.getPlan(), ","); String group = StringUtils.join(taskSyncRequestWrapper.getGroup(), ","); String owner = taskSyncRequestWrapper.getOwner(); long serverVersion = taskSyncRequestWrapper.getServerVersion(); boolean returnCount = taskSyncRequestWrapper.isReturnCount(); - + long currentServerVersion = 0; try { currentServerVersion = serverVersion; @@ -117,7 +117,7 @@ public ResponseEntity getTasksByTaskAndGroup(@RequestBody TaskSyncReques } return getTaskSyncResponse(plan, group, owner, currentServerVersion, returnCount); } - + // here for backward compatibility @RequestMapping(value = "/sync", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getTasksByTaskAndGroupTwo(HttpServletRequest request) { @@ -126,7 +126,7 @@ public ResponseEntity getTasksByTaskAndGroupTwo(HttpServletRequest reque String serverVersion = getStringFilter(BaseEntity.SERVER_VERSIOIN, request); String owner = getStringFilter(OWNER, request); boolean returnCount = Boolean.getBoolean(getStringFilter(RETURN_COUNT, request)); - + long currentServerVersion = 0; try { currentServerVersion = Long.parseLong(serverVersion); @@ -136,14 +136,14 @@ public ResponseEntity getTasksByTaskAndGroupTwo(HttpServletRequest reque } return getTaskSyncResponse(plan, group, owner, currentServerVersion, returnCount); } - + private ResponseEntity getTaskSyncResponse(String plan, String group, String owner, long currentServerVersion, - boolean returnCount) { + boolean returnCount) { if (StringUtils.isBlank(plan)) { logger.error("Plan Identifier is missing"); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - + if (!StringUtils.isBlank(group)) { String tasks = gson.toJson(convertToDTO(taskService.getTasksByTaskAndGroup(plan, group, currentServerVersion))); HttpHeaders headers = RestUtils.getJSONUTF8Headers(); @@ -151,7 +151,7 @@ private ResponseEntity getTaskSyncResponse(String plan, String group, St Long taskCount = taskService.countTasksByPlanAndGroup(plan, group, currentServerVersion); headers.add(TOTAL_RECORDS, String.valueOf(taskCount)); } - + return new ResponseEntity<>(tasks, headers, HttpStatus.OK); } else if (!StringUtils.isBlank(owner)) { String tasks = gson.toJson(convertToDTO(taskService.getTasksByPlanAndOwner(plan, owner, currentServerVersion))); @@ -160,14 +160,14 @@ private ResponseEntity getTaskSyncResponse(String plan, String group, St Long taskCount = taskService.countTasksByPlanAndOwner(plan, owner, currentServerVersion); headers.add(TOTAL_RECORDS, String.valueOf(taskCount)); } - + return new ResponseEntity<>(tasks, headers, HttpStatus.OK); } else { logger.error("Either owner or group identifier field is missing"); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } - + @RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE }) public ResponseEntity create(@RequestBody String entity) { try { @@ -179,9 +179,9 @@ public ResponseEntity create(@RequestBody String entity) { logger.error("The request doesnt contain a valid task representation", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - + } - + @RequestMapping(method = RequestMethod.PUT, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE }) public ResponseEntity update(@RequestBody String entity) { try { @@ -193,34 +193,38 @@ public ResponseEntity update(@RequestBody String entity) { logger.error("The request doesnt contain a valid task representation", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - + } - + @RequestMapping(value = "/add", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, - MediaType.TEXT_PLAIN_VALUE }) + MediaType.TEXT_PLAIN_VALUE }) public ResponseEntity batchSave(@RequestBody String entity) { try { - Type listType = new TypeToken>() {}.getType(); + Type listType = new TypeToken>() { + + }.getType(); List tasks = gson.fromJson(entity, listType); Set tasksWithErrors = taskService.saveTasks(convertToDomain(tasks)); if (tasksWithErrors.isEmpty()) return new ResponseEntity<>("All Tasks processed", HttpStatus.CREATED); else return new ResponseEntity<>("Tasks with identifiers not processed: " + String.join(",", tasksWithErrors), - HttpStatus.CREATED); + HttpStatus.CREATED); } catch (JsonSyntaxException e) { logger.error("The request doesnt contain a valid task representation", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - + } - + @RequestMapping(value = "/update_status", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, - MediaType.TEXT_PLAIN_VALUE }) + MediaType.TEXT_PLAIN_VALUE }) public ResponseEntity updateStatus(@RequestBody String entity) { try { - Type listType = new TypeToken>() {}.getType(); + Type listType = new TypeToken>() { + + }.getType(); List taskUpdates = gson.fromJson(entity, listType); List updateTasks = taskService.updateTaskStatus(taskUpdates); if (updateTasks.size() > 0) { @@ -235,9 +239,9 @@ public ResponseEntity updateStatus(@RequestBody String entity) { logger.error("The request doesnt contain a valid task update representation", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } - + } - + /** * This methods provides an API endpoint that searches for all task Ids ordered by server * version ascending @@ -247,34 +251,34 @@ public ResponseEntity updateStatus(@RequestBody String entity) { */ @RequestMapping(value = "/findIds", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity findIds(@RequestParam(value = SERVER_VERSION) long serverVersion, - @RequestParam(value = "fromDate", required = false) String fromDate, - @RequestParam(value = "toDate", required = false) String toDate) { - + @RequestParam(value = "fromDate", required = false) String fromDate, + @RequestParam(value = "toDate", required = false) String toDate) { + Pair, Long> taskIdsPair = taskService.findAllTaskIds(serverVersion, DEFAULT_GET_ALL_IDS_LIMIT, - Utils.getDateTimeFromString(fromDate), Utils.getDateTimeFromString(toDate)); + Utils.getDateFromString(fromDate), Utils.getDateFromString(toDate)); Identifier identifiers = new Identifier(); identifiers.setIdentifiers(taskIdsPair.getLeft()); identifiers.setLastServerVersion(taskIdsPair.getRight()); return new ResponseEntity<>(identifiers, HttpStatus.OK); } - + /** * Fetch tasks ordered by serverVersion ascending * * @param serverVersion serverVersion using to filter by - * @param limit upper limit on number of tasks to fetch + * @param limit upper limit on number of tasks to fetch * @return A list of tasks */ @RequestMapping(value = "/getAll", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getAll(@RequestParam(value = SERVER_VERSION) long serverVersion, - @RequestParam(value = LIMIT, required = false) Integer limit) { - + @RequestParam(value = LIMIT, required = false) Integer limit) { + Integer pageLimit = limit == null ? DEFAULT_LIMIT : limit; return new ResponseEntity<>(gson.toJson(convertToDTO(taskService.getAllTasks(serverVersion, pageLimit))), - RestUtils.getJSONUTF8Headers(), HttpStatus.OK); - + RestUtils.getJSONUTF8Headers(), HttpStatus.OK); + } - + /** * Fetch count of tasks * @@ -306,9 +310,10 @@ public ResponseEntity getOptionalTasksWithCount(@Valid TaskSearchBean ta response.put(TOTAL_RECORDS, taskCount); return new ResponseEntity<>(gson.toJson(response), headers, HttpStatus.OK); } - + /** * Converts a Task to DTO object so that data model for V1 API is maintained + * * @param task the task to convert * @return TaskDTO v1 task contract */ @@ -322,32 +327,35 @@ public Task convertToDTO(Task task) { taskDto.setExecutionPeriod(null); return taskDto; } - + /** * Converts a list of Tasks to DTO objects so that data model for V1 API is maintained + * * @param list of tasks to convert * @return list of TaskDTO objects */ public List convertToDTO(List taskList) { return taskList.stream().map(t -> convertToDTO(t)).collect(Collectors.toList()); } - + /** * Converts a TaskDTO to domain object for persistence - * @param the TaskDTO object to convert + * + * @param the TaskDTO object to convert * @return the converted task domain objects */ public Task convertToDomain(TaskDto taskDto) { Task task = new Task(); BeanUtils.copyProperties(taskDto, task); - if(taskDto.getExecutionStartDate()!=null || taskDto.getExecutionEndDate()!=null) { - task.setExecutionPeriod(new Period(taskDto.getExecutionStartDate(),taskDto.getExecutionEndDate())); + if (taskDto.getExecutionStartDate() != null || taskDto.getExecutionEndDate() != null) { + task.setExecutionPeriod(new Period(taskDto.getExecutionStartDate(), taskDto.getExecutionEndDate())); } return task; } - + /** * Converts a list of TaskDTO to domain objects for persistence + * * @param list of TaskDTO objects to convert * @return list of converted task domain objects */ diff --git a/src/main/java/org/opensrp/web/utils/SearchHelper.java b/src/main/java/org/opensrp/web/utils/SearchHelper.java index bf111db4f..5918b32b0 100644 --- a/src/main/java/org/opensrp/web/utils/SearchHelper.java +++ b/src/main/java/org/opensrp/web/utils/SearchHelper.java @@ -2,6 +2,7 @@ import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; +import org.json.JSONObject; import org.opensrp.search.ClientSearchBean; import org.opensrp.web.rest.RestUtils; import org.smartregister.domain.Client; @@ -18,24 +19,43 @@ public class SearchHelper { - public static SearchEntityWrapper childSearchParamProcessor(HttpServletRequest request) throws ParseException { + public static final String ZEIR_ID = "zeir_id"; - ClientSearchBean searchBean = new ClientSearchBean(); + public static final String OPENSRP_ID = "opensrp_id"; + + public static final String SIM_PRINT_GUID = "simprints_guid"; + + public static final String FIRST_NAME = "first_name"; + + public static final String MIDDLE_NAME = "middle_name"; + + public static final String LAST_NAME = "last_name"; + + public static final String BIRTH_DATE = "birth_date"; + + //Attributes + public static final String INACTIVE = "inactive"; + + public static final String LOST_TO_FOLLOW_UP = "lost_to_follow_up"; + + public static final String NFC_CARD_IDENTIFIER = "nfc_card_identifier"; - String ZEIR_ID = "zeir_id"; - String OPENSRP_ID = "opensrp_id"; + // Mother + public static final String MOTHER_GUARDIAN_FIRST_NAME = "mother_first_name"; - String SIM_PRINT_GUID = "simprints_guid"; + public static final String MOTHER_GUARDIAN_LAST_NAME = "mother_last_name"; - String FIRST_NAME = "first_name"; - String MIDDLE_NAME = "middle_name"; - String LAST_NAME = "last_name"; - String BIRTH_DATE = "birth_date"; + public static final String MOTHER_GUARDIAN_NRC_NUMBER = "mother_nrc_number"; - //Attributes - String INACTIVE = "inactive"; - String LOST_TO_FOLLOW_UP = "lost_to_follow_up"; - String NFC_CARD_IDENTIFIER = "nfc_card_identifier"; + public static final String MOTHER_COMPASS_RELATIONSHIP_ID = "mother_compass_relationship_id"; + + public static final String NRC_NUMBER_KEY = "NRC_Number"; + + public static final String COMPASS_RELATIONSHIP_ID = "Compass_Relationship_ID"; + + public static SearchEntityWrapper childSearchParamProcessor(HttpServletRequest request) throws ParseException { + + ClientSearchBean searchBean = new ClientSearchBean(); Integer limit = RestUtils.getIntegerFilter("limit", request); if (limit == null || limit.intValue() == 0) { @@ -48,19 +68,11 @@ public static SearchEntityWrapper childSearchParamProcessor(HttpServletRequest r searchBean.setLastEditTo(lastEdit[1]); } - String zeirId = RestUtils.getStringFilter(ZEIR_ID, request); - String opensrpId = RestUtils.getStringFilter(OPENSRP_ID, request); - String simprintsGuid = RestUtils.getStringFilter(SIM_PRINT_GUID, request); - searchBean.setFirstName(RestUtils.getStringFilter(FIRST_NAME, request)); searchBean.setMiddleName(RestUtils.getStringFilter(MIDDLE_NAME, request)); searchBean.setLastName(RestUtils.getStringFilter(LAST_NAME, request)); searchBean.setGender(RestUtils.getStringFilter(GENDER, request)); - String inActive = RestUtils.getStringFilter(INACTIVE, request); - String lostToFollowUp = RestUtils.getStringFilter(LOST_TO_FOLLOW_UP, request); - String nfcCardIdentifier = RestUtils.getStringFilter(NFC_CARD_IDENTIFIER, request); - DateTime[] birthdate = RestUtils .getDateRangeFilter(BIRTH_DATE, request);//TODO add ranges like fhir do http://hl7.org/fhir/search.html @@ -70,66 +82,109 @@ public static SearchEntityWrapper childSearchParamProcessor(HttpServletRequest r searchBean.setBirthdateFrom(birthdate[0]); searchBean.setBirthdateTo(birthdate[1]); } - Map identifiers = new HashMap(); - // - if (!StringUtils.isBlank(zeirId)) { - identifiers.put(ZEIR_ID, zeirId); - identifiers.put("ZEIR_ID", zeirId); //Maintains backward compatibility with upper case key - } - if (!StringUtils.isBlank(opensrpId)) { - identifiers.put(OPENSRP_ID, opensrpId); + Map commonSearchParams = new HashMap<>(); + commonSearchParams.put(ZEIR_ID, RestUtils.getStringFilter(ZEIR_ID, request)); + commonSearchParams.put(OPENSRP_ID, RestUtils.getStringFilter(OPENSRP_ID, request)); + commonSearchParams.put(SIM_PRINT_GUID, RestUtils.getStringFilter(SIM_PRINT_GUID, request)); + commonSearchParams.put(INACTIVE, RestUtils.getStringFilter(INACTIVE, request)); + commonSearchParams.put(LOST_TO_FOLLOW_UP, RestUtils.getStringFilter(LOST_TO_FOLLOW_UP, request)); + commonSearchParams.put(NFC_CARD_IDENTIFIER, RestUtils.getStringFilter(NFC_CARD_IDENTIFIER, request)); + + setIdentifiersAndAttributeToChildSearchBean(commonSearchParams, searchBean); + + boolean isValid = isSearchValid(searchBean); + + return new SearchEntityWrapper(isValid, searchBean, limit); + } + + public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest request) throws ParseException { + + ClientSearchBean motherSearchBean = new ClientSearchBean(); + + Integer limit = setCoreFilters(request, motherSearchBean); + + String motherGuardianNrc = RestUtils.getStringFilter(MOTHER_GUARDIAN_NRC_NUMBER, request); + String compassRelationshipId = RestUtils.getStringFilter(MOTHER_COMPASS_RELATIONSHIP_ID, request); + + motherSearchBean.setFirstName(RestUtils.getStringFilter(MOTHER_GUARDIAN_FIRST_NAME, request)); + motherSearchBean.setLastName(RestUtils.getStringFilter(MOTHER_GUARDIAN_LAST_NAME, request)); + + setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc, compassRelationshipId, motherSearchBean); + + boolean isValid = isSearchValid(motherSearchBean); + + return new SearchEntityWrapper(isValid, motherSearchBean, limit); + } + + public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObject) throws ParseException { + + ClientSearchBean searchBean = new ClientSearchBean(); + + Integer limit = !jsonObject.optString("limit").equals("") ? Integer.parseInt(jsonObject.optString("limit")) + : jsonObject.optInt("limit"); + if (limit == 0) { + limit = 100; } - if (!StringUtils.isBlank(simprintsGuid)) { - identifiers.put(SIM_PRINT_GUID, simprintsGuid); + + DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id + if (lastEdit != null) { + searchBean.setLastEditFrom(lastEdit[0]); + searchBean.setLastEditTo(lastEdit[1]); } - Map attributes = new HashMap(); - if (!StringUtils.isBlank(inActive) || !StringUtils.isBlank(lostToFollowUp) - || !StringUtils.isBlank(nfcCardIdentifier)) { + searchBean.setFirstName(RestUtils.getStringFilter(FIRST_NAME, jsonObject)); + searchBean.setMiddleName(RestUtils.getStringFilter(MIDDLE_NAME, jsonObject)); + searchBean.setLastName(RestUtils.getStringFilter(LAST_NAME, jsonObject)); + searchBean.setGender(RestUtils.getStringFilter(GENDER, jsonObject)); - if (!StringUtils.isBlank(inActive)) { - attributes.put(INACTIVE, inActive); - } + DateTime[] birthdate = RestUtils + .getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html - if (!StringUtils.isBlank(lostToFollowUp)) { - attributes.put(LOST_TO_FOLLOW_UP, lostToFollowUp); - } + //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a - if (!StringUtils.isBlank(nfcCardIdentifier)) { - attributes.put("NFC_Card_Identifier", nfcCardIdentifier);//Key different case than constant - } + if (birthdate != null) { + searchBean.setBirthdateFrom(birthdate[0]); + searchBean.setBirthdateTo(birthdate[1]); } - searchBean.setIdentifiers(identifiers); - searchBean.setAttributes(attributes); + Map commonSearchParams = new HashMap<>(); + commonSearchParams.put(ZEIR_ID, RestUtils.getStringFilter(ZEIR_ID, jsonObject)); + commonSearchParams.put(OPENSRP_ID, RestUtils.getStringFilter(OPENSRP_ID, jsonObject)); + commonSearchParams.put(SIM_PRINT_GUID, RestUtils.getStringFilter(SIM_PRINT_GUID, jsonObject)); + commonSearchParams.put(INACTIVE, RestUtils.getStringFilter(INACTIVE, jsonObject)); + commonSearchParams.put(LOST_TO_FOLLOW_UP, RestUtils.getStringFilter(LOST_TO_FOLLOW_UP, jsonObject)); + commonSearchParams.put(NFC_CARD_IDENTIFIER, RestUtils.getStringFilter(NFC_CARD_IDENTIFIER, jsonObject)); + + setIdentifiersAndAttributeToChildSearchBean(commonSearchParams, searchBean); boolean isValid = isSearchValid(searchBean); return new SearchEntityWrapper(isValid, searchBean, limit); } - public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest request) throws ParseException { + public static SearchEntityWrapper motherSearchParamProcessor(JSONObject jsonObject) throws ParseException { ClientSearchBean motherSearchBean = new ClientSearchBean(); - Integer limit = setCoreFilters(request, motherSearchBean); + Integer limit = setCoreFilters(jsonObject, motherSearchBean); - // Mother - String MOTHER_GUARDIAN_FIRST_NAME = "mother_first_name"; - String MOTHER_GUARDIAN_LAST_NAME = "mother_last_name"; - String MOTHER_GUARDIAN_NRC_NUMBER = "mother_nrc_number"; - String MOTHER_COMPASS_RELATIONSHIP_ID = "mother_compass_relationship_id"; + String motherGuardianNrc = RestUtils.getStringFilter(MOTHER_GUARDIAN_NRC_NUMBER, jsonObject); + String compassRelationshipId = RestUtils.getStringFilter(MOTHER_COMPASS_RELATIONSHIP_ID, jsonObject); - String motherGuardianNrc = RestUtils.getStringFilter(MOTHER_GUARDIAN_NRC_NUMBER, request); - String compassRelationshipId = RestUtils.getStringFilter(MOTHER_COMPASS_RELATIONSHIP_ID, request); + motherSearchBean.setFirstName(RestUtils.getStringFilter(MOTHER_GUARDIAN_FIRST_NAME, jsonObject)); + motherSearchBean.setLastName(RestUtils.getStringFilter(MOTHER_GUARDIAN_LAST_NAME, jsonObject)); - motherSearchBean.setFirstName(RestUtils.getStringFilter(MOTHER_GUARDIAN_FIRST_NAME, request)); - motherSearchBean.setLastName(RestUtils.getStringFilter(MOTHER_GUARDIAN_LAST_NAME, request)); + setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc, compassRelationshipId, motherSearchBean); - String NRC_NUMBER_KEY = "NRC_Number"; - String COMPASS_RELATIONSHIP_ID = "Compass_Relationship_ID"; + boolean isValid = isSearchValid(motherSearchBean); + return new SearchEntityWrapper(isValid, motherSearchBean, limit); + } + + public static void setNameLikeAndAtrributesOnMotherSearchBean(String motherGuardianNrc, + String compassRelationshipId, + ClientSearchBean motherSearchBean) { Map motherAttributes = new HashMap<>(); if (!StringUtils.isBlank(motherGuardianNrc)) { motherAttributes.put(NRC_NUMBER_KEY, motherGuardianNrc); @@ -151,25 +206,82 @@ public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest motherSearchBean.setNameLike(nameLike); motherSearchBean.setAttributes(motherAttributes); - boolean isValid = isSearchValid(motherSearchBean); + } + + public static void setIdentifiersAndAttributeToChildSearchBean(Map commonSearchParams, + ClientSearchBean searchBean) { + Map identifiers = new HashMap(); + + String zeirId = commonSearchParams.get(ZEIR_ID); + String opensrpId = commonSearchParams.get(OPENSRP_ID); + String simprintsGuid = commonSearchParams.get(SIM_PRINT_GUID); + String lostToFollowUp = commonSearchParams.get(LOST_TO_FOLLOW_UP); + String inActive = commonSearchParams.get(INACTIVE); + String nfcCardIdentifier = commonSearchParams.get(NFC_CARD_IDENTIFIER); + + if (!StringUtils.isBlank(zeirId)) { + identifiers.put(ZEIR_ID, zeirId); + identifiers.put("ZEIR_ID", zeirId); //Maintains backward compatibility with upper case key + } + + if (!StringUtils.isBlank(opensrpId)) { + identifiers.put(OPENSRP_ID, opensrpId); + } + if (!StringUtils.isBlank(simprintsGuid)) { + identifiers.put(SIM_PRINT_GUID, simprintsGuid); + } + + Map attributes = new HashMap(); + if (!StringUtils.isBlank(inActive) || !StringUtils.isBlank(lostToFollowUp) + || !StringUtils.isBlank(nfcCardIdentifier)) { + + if (!StringUtils.isBlank(inActive)) { + attributes.put(INACTIVE, inActive); + } + + if (!StringUtils.isBlank(lostToFollowUp)) { + attributes.put(LOST_TO_FOLLOW_UP, lostToFollowUp); + } + + if (!StringUtils.isBlank(nfcCardIdentifier)) { + attributes.put("NFC_Card_Identifier", nfcCardIdentifier);//Key different case than constant + } + } + + searchBean.setIdentifiers(identifiers); + searchBean.setAttributes(attributes); - return new SearchEntityWrapper(isValid, motherSearchBean, limit); } - public static Integer setCoreFilters(HttpServletRequest request, ClientSearchBean searchBean) throws ParseException { + public static Integer setCoreFilters(Object object, ClientSearchBean searchBean) throws ParseException { - Integer limit = RestUtils.getIntegerFilter("limit", request); - if (limit == null || limit.intValue() == 0) { + Integer limit = 0; + DateTime[] lastEdit = null; + + if (object instanceof HttpServletRequest) { + HttpServletRequest request = (HttpServletRequest) object; + lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, request);//TODO client by provider id + limit = RestUtils.getIntegerFilter("limit", request); + } + + if (object instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) object; + lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id + limit = !jsonObject.optString("limit").equals("") ? Integer.parseInt(jsonObject.optString("limit")) + : jsonObject.optInt("limit"); + } + + if (limit == null || limit == 0) { limit = 100; } - DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, request);//TODO client by provider id if (lastEdit != null) { searchBean.setLastEditFrom(lastEdit[0]); searchBean.setLastEditTo(lastEdit[1]); } return limit; + } /** @@ -271,6 +383,18 @@ public static String getContactPhoneNumberParam(HttpServletRequest request) { return motherGuardianPhoneNumber; } + public static String getContactPhoneNumberParam(JSONObject jsonObject) { + //Search by mother contact number + String MOTHER_GUARDIAN_PHONE_NUMBER = "mother_contact_phone_number"; + String CONTACT_PHONE_NUMBER = "contact_phone_number"; + String motherGuardianPhoneNumber = jsonObject.optString(MOTHER_GUARDIAN_PHONE_NUMBER); + motherGuardianPhoneNumber = StringUtils.isBlank(motherGuardianPhoneNumber) + ? jsonObject.optString(CONTACT_PHONE_NUMBER) + : motherGuardianPhoneNumber; + + return motherGuardianPhoneNumber; + } + public static List processSearchResult(List children, List mothers, String RELATIONSHIP_KEY) { List childMotherList = new ArrayList(); diff --git a/src/main/java/org/opensrp/web/utils/Utils.java b/src/main/java/org/opensrp/web/utils/Utils.java index 210561d67..5df6b6850 100644 --- a/src/main/java/org/opensrp/web/utils/Utils.java +++ b/src/main/java/org/opensrp/web/utils/Utils.java @@ -1,5 +1,5 @@ /** - * + * */ package org.opensrp.web.utils; @@ -16,7 +16,7 @@ * @author Samuel Githengi created on 06/12/20 */ public class Utils { - + public static String getStringFromJSON(JSONObject jsonObject, String key) { Object value = jsonObject.get(key); if (value instanceof JSONArray) { @@ -26,15 +26,23 @@ public static String getStringFromJSON(JSONObject jsonObject, String key) { } } - public static Date getDateTimeFromString(@Nullable String date) { + public static Date getDateFromString(@Nullable String date) { + DateTime dateTime = getDateTimeFromString(date); + if (dateTime != null) { + return dateTime.toDate(); + } + return null; + } + + public static DateTime getDateTimeFromString(@Nullable String date) { if (StringUtils.isNotBlank(date)) { try { Long aLong = Long.parseLong(date); - return new DateTime(aLong).toDate(); + return new DateTime(aLong); } catch (NumberFormatException e) { try { - return new DateTime(date).toDate(); + return new DateTime(date); } catch (IllegalArgumentException illegalArgumentException) { return null; @@ -45,7 +53,6 @@ public static Date getDateTimeFromString(@Nullable String date) { } } - public static boolean checkRoleIfRoleExists(List roleList, String role) { for (String roleName : roleList) if (StringUtils.containsIgnoreCase(roleName, role)) diff --git a/src/test/java/org/opensrp/web/rest/SearchResourceTest.java b/src/test/java/org/opensrp/web/rest/SearchResourceTest.java index a02f90a29..bcf8941ec 100755 --- a/src/test/java/org/opensrp/web/rest/SearchResourceTest.java +++ b/src/test/java/org/opensrp/web/rest/SearchResourceTest.java @@ -12,7 +12,11 @@ import org.opensrp.repository.EventsRepository; import org.opensrp.repository.PlanRepository; import org.opensrp.repository.SearchRepository; -import org.opensrp.service.*; +import org.opensrp.service.ClientService; +import org.opensrp.service.EventService; +import org.opensrp.service.ExportEventDataMapper; +import org.opensrp.service.SearchService; +import org.opensrp.service.TaskGenerator; import org.opensrp.web.rest.it.TestWebContextLoader; import org.opensrp.web.utils.SearchHelper; import org.smartregister.domain.Client; @@ -44,17 +48,15 @@ public class SearchResourceTest { private TaskGenerator taskGenerator; private PlanRepository planRepository; + MockHttpServletRequest mockHttpServletRequest; + String phoneNumber = "0727000000"; - String town = "town"; String firstName = "name"; - String male = "male"; - DateTime birthDate = new DateTime(0l, DateTimeZone.UTC); - @Before public void setUp() { SearchRepository searchRepository = Mockito.mock(SearchRepository.class); @@ -87,7 +89,7 @@ public void testIntersectionMethodReturnsCorrectResult() { } @Test - public void shouldSearchClient() throws ParseException { + public void shouldSearchClientWithGetRequest() throws ParseException { mockHttpServletRequest = new MockHttpServletRequest(); mockHttpServletRequest.addParameter("ff", "ona"); mockHttpServletRequest.addParameter("phone_number", phoneNumber); @@ -95,9 +97,20 @@ public void shouldSearchClient() throws ParseException { mockHttpServletRequest.addParameter("alt_name", firstName); mockHttpServletRequest.addParameter("attribute", "next_contact_date:2022-06-15"); mockHttpServletRequest.addParameter("dob", String.valueOf(birthDate)); - mockHttpServletRequest.addParameter("identifier", "fsdf"+":"+ "sfdf"); - SearchResource searchResource=new SearchResource(searchService,clientService,eventService); + mockHttpServletRequest.addParameter("identifier", "fsdf" + ":" + "sfdf"); + SearchResource searchResource = new SearchResource(searchService, clientService, eventService); List clients = searchResource.search(mockHttpServletRequest); Assert.assertNotNull(clients); } + + @Test + public void shouldSearchClientWithPostRequest() throws ParseException { + String jsonRequestString = "{\"ff\":\"ona\",\"identifier\":\"fsdf:sfdf\",\"alt_name\":\"name\"," + + "\"alt_phone_number\":\"0727000000\",\"dob\":\"1970-01-01T00:00:00.000Z\",\"phone_number\":\"0727000000\"," + + "\"attribute\":\"next_contact_date:2022-06-15\"}"; + SearchResource searchResource = new SearchResource(searchService, clientService, eventService); + List clients = searchResource.searchByPost(jsonRequestString); + Assert.assertNotNull(clients); + + } } diff --git a/src/test/java/org/opensrp/web/utils/SearchHelperTest.java b/src/test/java/org/opensrp/web/utils/SearchHelperTest.java index d43337dc8..d11f40534 100644 --- a/src/test/java/org/opensrp/web/utils/SearchHelperTest.java +++ b/src/test/java/org/opensrp/web/utils/SearchHelperTest.java @@ -1,9 +1,11 @@ package org.opensrp.web.utils; +import org.json.JSONObject; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; import org.opensrp.common.util.EasyMap; +import org.opensrp.search.ClientSearchBean; import org.smartregister.domain.Client; import org.springframework.mock.web.MockHttpServletRequest; @@ -250,7 +252,7 @@ public void testProcessSearchResult() { } @Test - public void testMotherSearchParamProcessor() throws ParseException { + public void testMotherSearchParamProcessorForHttpServletRequest() throws ParseException { HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class); Mockito.when(httpServletRequest.getParameter("limit")).thenReturn("0"); Mockito.when(httpServletRequest.getParameter("mother_first_name")).thenReturn("Jane"); @@ -260,10 +262,118 @@ public void testMotherSearchParamProcessor() throws ParseException { Mockito.when(httpServletRequest.getParameter("mother_compass_relationship_id")).thenReturn("dab102f71bd"); SearchEntityWrapper searchEntityWrapper = SearchHelper.motherSearchParamProcessor(httpServletRequest); Map result = searchEntityWrapper.getClientSearchBean().getAttributes(); - Assert.assertEquals(2, result.size()); - Assert.assertTrue( result.containsKey("NRC_Number")); - Assert.assertTrue( result.containsKey("Compass_Relationship_ID")); + Assert.assertEquals(2, result.size()); + Assert.assertTrue(result.containsKey("NRC_Number")); + Assert.assertTrue(result.containsKey("Compass_Relationship_ID")); Assert.assertEquals("2093980", result.get("NRC_Number")); } + @Test + public void testMotherSearchParamProcessorForJSONObject() throws ParseException { + JSONObject jsonObject = Mockito.mock(JSONObject.class); + Mockito.when(jsonObject.optString("limit")).thenReturn("0"); + Mockito.when(jsonObject.optString("mother_first_name")).thenReturn("Jane"); + Mockito.when(jsonObject.optString("mother_last_name")).thenReturn("Doe"); + Mockito.when(jsonObject.optString("mother_nrc_number")).thenReturn("2093980"); + Mockito.when(jsonObject.optString("NRC_Number")).thenReturn("20939801123"); + Mockito.when(jsonObject.optString("mother_compass_relationship_id")).thenReturn("dab102f71bd"); + Mockito.when(jsonObject.optString("lastEdited")).thenReturn(""); + SearchEntityWrapper searchEntityWrapper = SearchHelper.motherSearchParamProcessor(jsonObject); + Map result = searchEntityWrapper.getClientSearchBean().getAttributes(); + Assert.assertEquals(2, result.size()); + Assert.assertTrue(result.containsKey("NRC_Number")); + Assert.assertTrue(result.containsKey("Compass_Relationship_ID")); + Assert.assertEquals("2093980", result.get("NRC_Number")); + } + + @Test + public void testChildSearchParamProcessorForJSONObject() throws ParseException { + JSONObject jsonObject = Mockito.mock(JSONObject.class); + Mockito.when(jsonObject.optString("limit")).thenReturn("50"); + Mockito.when(jsonObject.optString("lastEdited")).thenReturn(""); + Mockito.when(jsonObject.optString(SearchHelper.BIRTH_DATE)).thenReturn(""); + Mockito.when(jsonObject.optString(SearchHelper.ZEIR_ID)).thenReturn("1234"); + Mockito.when(jsonObject.optString(SearchHelper.OPENSRP_ID)).thenReturn("4567"); + Mockito.when(jsonObject.optString(SearchHelper.SIM_PRINT_GUID)).thenReturn("91011"); + Mockito.when(jsonObject.optString(SearchHelper.INACTIVE)).thenReturn("false"); + Mockito.when(jsonObject.optString(SearchHelper.LOST_TO_FOLLOW_UP)).thenReturn("true"); + Mockito.when(jsonObject.optString(SearchHelper.NFC_CARD_IDENTIFIER)).thenReturn("nfc_card_identifier_1"); + SearchEntityWrapper searchEntityWrapper = SearchHelper.childSearchParamProcessor(jsonObject); + + Map attributes = searchEntityWrapper.getClientSearchBean().getAttributes(); + Assert.assertEquals(3, attributes.size()); + + Map identifiers = searchEntityWrapper.getClientSearchBean().getIdentifiers(); + Assert.assertEquals(4, identifiers.size()); + + Assert.assertTrue(identifiers.containsKey(SearchHelper.ZEIR_ID)); + Assert.assertTrue(identifiers.containsKey("ZEIR_ID")); //check backward compatibility with upper case key + Assert.assertTrue(identifiers.containsKey(SearchHelper.SIM_PRINT_GUID)); + + Assert.assertTrue(attributes.containsKey(SearchHelper.INACTIVE)); + Assert.assertTrue(attributes.containsKey(SearchHelper.LOST_TO_FOLLOW_UP)); + Assert.assertTrue(attributes.containsKey("NFC_Card_Identifier")); + + Assert.assertEquals(identifiers.get(SearchHelper.ZEIR_ID), "1234"); + Assert.assertEquals(attributes.get("NFC_Card_Identifier"), "nfc_card_identifier_1"); + } + + @Test + public void testChildSearchParamProcessorForHttpServletRequest() throws ParseException { + HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class); + Mockito.when(httpServletRequest.getParameter("limit")).thenReturn("50"); + Mockito.when(httpServletRequest.getParameter("lastEdited")).thenReturn(""); + Mockito.when(httpServletRequest.getParameter(SearchHelper.BIRTH_DATE)).thenReturn(""); + Mockito.when(httpServletRequest.getParameter(SearchHelper.ZEIR_ID)).thenReturn("1234"); + Mockito.when(httpServletRequest.getParameter(SearchHelper.OPENSRP_ID)).thenReturn("4567"); + Mockito.when(httpServletRequest.getParameter(SearchHelper.SIM_PRINT_GUID)).thenReturn("91011"); + Mockito.when(httpServletRequest.getParameter(SearchHelper.INACTIVE)).thenReturn("false"); + Mockito.when(httpServletRequest.getParameter(SearchHelper.LOST_TO_FOLLOW_UP)).thenReturn("true"); + Mockito.when(httpServletRequest.getParameter(SearchHelper.NFC_CARD_IDENTIFIER)).thenReturn("nfc_card_identifier_1"); + SearchEntityWrapper searchEntityWrapper = SearchHelper.childSearchParamProcessor(httpServletRequest); + + Map attributes = searchEntityWrapper.getClientSearchBean().getAttributes(); + Assert.assertEquals(3, attributes.size()); + + Map identifiers = searchEntityWrapper.getClientSearchBean().getIdentifiers(); + Assert.assertEquals(4, identifiers.size()); + + Assert.assertTrue(identifiers.containsKey(SearchHelper.ZEIR_ID)); + Assert.assertTrue(identifiers.containsKey("ZEIR_ID")); //check backward compatibility with upper case key + Assert.assertTrue(identifiers.containsKey(SearchHelper.SIM_PRINT_GUID)); + + Assert.assertTrue(attributes.containsKey(SearchHelper.INACTIVE)); + Assert.assertTrue(attributes.containsKey(SearchHelper.LOST_TO_FOLLOW_UP)); + Assert.assertTrue(attributes.containsKey("NFC_Card_Identifier")); + + Assert.assertEquals(identifiers.get(SearchHelper.ZEIR_ID), "1234"); + Assert.assertEquals(attributes.get("NFC_Card_Identifier"), "nfc_card_identifier_1"); + } + + @Test + public void testSetCoreFiltersForJSONObjectWithIntegerLimitReturnsValue() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("limit", 50); + try { + int result = SearchHelper.setCoreFilters(jsonObject, new ClientSearchBean()); + Assert.assertEquals(50, result); + } + catch (ParseException e) { + e.printStackTrace(); + } + } + + @Test + public void testSetCoreFiltersForJSONObjectWithStringLimitReturnsValue() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("limit", "50"); + try { + int result = SearchHelper.setCoreFilters(jsonObject, new ClientSearchBean()); + Assert.assertEquals(50, result); + } + catch (ParseException e) { + e.printStackTrace(); + } + } + } diff --git a/src/test/java/org/opensrp/web/utils/UtilsTest.java b/src/test/java/org/opensrp/web/utils/UtilsTest.java index f8c48891e..f45c981db 100644 --- a/src/test/java/org/opensrp/web/utils/UtilsTest.java +++ b/src/test/java/org/opensrp/web/utils/UtilsTest.java @@ -13,39 +13,39 @@ import org.opensrp.web.config.Role; public class UtilsTest { - + @Test public void testGetStringFromJSONForObject() { - + JSONObject obj = new JSONObject(); obj.put("location", "Roysa"); - + String result = Utils.getStringFromJSON(obj, "location"); - + Assert.assertNotNull(result); Assert.assertEquals("Roysa", result); } - + @Test public void testGetStringFromJSONForArray() { - + JSONArray obj = new JSONArray(); obj.put("address1"); obj.put("address2"); obj.put("address3"); - + JSONObject parentObj = new JSONObject(); parentObj.put("addresses", obj); - + String result = Utils.getStringFromJSON(parentObj, "addresses"); - + Assert.assertNotNull(result); Assert.assertEquals("[\"address1\",\"address2\",\"address3\"]", result); } @Test - public void testGetDateTimeFromStringShouldReturnDate(){ - Date date = Utils.getDateTimeFromString("1615895228000"); + public void testGetDateTimeFromStringShouldReturnDate() { + Date date = Utils.getDateFromString("1615895228000"); Assert.assertNotNull(date); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); @@ -55,29 +55,29 @@ public void testGetDateTimeFromStringShouldReturnDate(){ } @Test - public void testGetDateTimeFromStringShouldReturnNull(){ - Date date = Utils.getDateTimeFromString("wrongdate"); + public void testGetDateTimeFromStringShouldReturnNull() { + Date date = Utils.getDateFromString("wrongdate"); Assert.assertNull(date); - date = Utils.getDateTimeFromString(null); + date = Utils.getDateFromString(null); Assert.assertNull(date); } @Test public void testCheckRoleIfRoleExists() { - + List roleList = new ArrayList<>(); roleList.add(Role.OPENSRP_GENERATE_QR_CODE); roleList.add(Role.PII_DATA_MASK); roleList.add(Role.PLANS_FOR_USER); - + boolean result = Utils.checkRoleIfRoleExists(roleList, Role.PLANS_FOR_USER); Assert.assertTrue(result); - + result = Utils.checkRoleIfRoleExists(roleList, Role.OPENSRP_GENERATE_QR_CODE.toUpperCase(Locale.ENGLISH)); Assert.assertTrue(result); - + result = Utils.checkRoleIfRoleExists(roleList, Role.OPENMRS); Assert.assertFalse(result); - + } }