From 7d609ac436a8002f354b2878fafd5cc64233910e Mon Sep 17 00:00:00 2001 From: hilpitome Date: Fri, 11 Nov 2022 12:07:18 +0300 Subject: [PATCH 1/9] allow search via post --- .../java/org/opensrp/web/rest/RestUtils.java | 15 ++ .../org/opensrp/web/rest/SearchResource.java | 85 ++++++++- .../org/opensrp/web/utils/SearchHelper.java | 168 ++++++++++++++++++ 3 files changed, 267 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/opensrp/web/rest/RestUtils.java b/src/main/java/org/opensrp/web/rest/RestUtils.java index 56c42e752..2b6a3a113 100644 --- a/src/main/java/org/opensrp/web/rest/RestUtils.java +++ b/src/main/java/org/opensrp/web/rest/RestUtils.java @@ -20,6 +20,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; @@ -87,6 +88,20 @@ public static DateTime[] getDateRangeFilter(String filter, HttpServletRequest re return new DateTime[]{d1,d2}; } + public static DateTime[] getDateRangeFilter(String filter, JSONObject jsonObject) throws ParseException + { + String strval = jsonObject.optString(filter); + if(strval.equals("")){ + return null; + } + if (!strval.contains(":")) { + return new DateTime[] { new DateTime(strval), new DateTime(strval) }; + } + 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) { String stringFilter = getStringFilter(filter, req); return Boolean.parseBoolean(stringFilter); diff --git a/src/main/java/org/opensrp/web/rest/SearchResource.java b/src/main/java/org/opensrp/web/rest/SearchResource.java index 75b1d186d..bc3036b93 100644 --- a/src/main/java/org/opensrp/web/rest/SearchResource.java +++ b/src/main/java/org/opensrp/web/rest/SearchResource.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.opensrp.common.AllConstants.BaseEntity; import org.opensrp.search.ClientSearchBean; import org.opensrp.service.ClientService; @@ -17,6 +18,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; @@ -199,7 +201,88 @@ private List searchPathBy(HttpServletRequest request) throws ParseE return new ArrayList(); } } - + + @RequestMapping(method = RequestMethod.POST, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) + private List searchPathByPost(@RequestBody String jsonRequestBody) throws ParseException { + try { + + //Process clients search via demographics + + ClientSearchBean searchBean = new ClientSearchBean(); + List children = new ArrayList(); + JSONObject jsonRequestBodyObject = new JSONObject(jsonRequestBody); + SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(jsonRequestBodyObject); + + if (childSearchEntity.isValid()) { + searchBean = childSearchEntity.getClientSearchBean(); + children = searchService.searchClient(searchBean, searchBean.getFirstName(), searchBean.getMiddleName(), + searchBean.getLastName(), childSearchEntity.getLimit()); + } + + //Process mothers search via mother demographics + + SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(jsonRequestBodyObject); + ClientSearchBean motherSearchBean = new ClientSearchBean(); + List mothers = new ArrayList(); + + if (motherSearchEntity.isValid()) { + motherSearchBean = motherSearchEntity.getClientSearchBean(); + mothers = searchService.searchClient(motherSearchBean, motherSearchBean.getFirstName(), + motherSearchBean.getMiddleName(), motherSearchBean.getLastName(), motherSearchEntity.getLimit()); + } + + //Process clients search via contact phone number + + String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(jsonRequestBodyObject); + + List clientBaseEntityIds = getClientBaseEntityIdsByContactPhoneNumber(contactPhoneNumber); + + List eventChildren = clientService.findByFieldValue(BaseEntity.BASE_ENTITY_ID, clientBaseEntityIds); + + children = SearchHelper.intersection(children, eventChildren);// Search conjunction is "AND" find intersection + + 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.findByFieldValue(BaseEntity.BASE_ENTITY_ID, clientIds); + + } + + List linkedChildren = new ArrayList(); + + if (!mothers.isEmpty()) { + for (Client client : mothers) { + linkedChildren.addAll(clientService.findByRelationship(client.getBaseEntityId())); + } + } + + children = SearchHelper.intersection(children, linkedChildren);// Search conjunction is "AND" find intersection + + for (Client linkedMother : linkedMothers) { + if (!SearchHelper.contains(mothers, linkedMother)) { + mothers.add(linkedMother); + } + } + + return SearchHelper.processSearchResult(children, mothers, RELATIONSHIP_KEY); + + } + catch (Exception e) { + + logger.error("", e); + return new ArrayList(); + } + } + public List getClientBaseEntityIdsByContactPhoneNumber(String motherGuardianPhoneNumber) { List clientBaseEntityIds = new ArrayList(); diff --git a/src/main/java/org/opensrp/web/utils/SearchHelper.java b/src/main/java/org/opensrp/web/utils/SearchHelper.java index bf111db4f..c473e6733 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; @@ -156,6 +157,145 @@ public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest return new SearchEntityWrapper(isValid, motherSearchBean, limit); } + public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObject) throws ParseException { + + ClientSearchBean searchBean = new ClientSearchBean(); + + String ZEIR_ID = "zeir_id"; + String OPENSRP_ID = "opensrp_id"; + + String SIM_PRINT_GUID = "simprints_guid"; + + String FIRST_NAME = "first_name"; + String MIDDLE_NAME = "middle_name"; + String LAST_NAME = "last_name"; + String BIRTH_DATE = "birth_date"; + + //Attributes + String INACTIVE = "inactive"; + String LOST_TO_FOLLOW_UP = "lost_to_follow_up"; + String NFC_CARD_IDENTIFIER = "nfc_card_identifier"; + + Integer limit = jsonObject.optInt("limit"); + if (limit == 0) { + limit = 100; + } + + DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id + if (lastEdit != null) { + searchBean.setLastEditFrom(lastEdit[0]); + searchBean.setLastEditTo(lastEdit[1]); + } + + String zeirId = jsonObject.getString(ZEIR_ID); + String opensrpId = jsonObject.getString(OPENSRP_ID); + String simprintsGuid = jsonObject.getString(SIM_PRINT_GUID); + + searchBean.setFirstName(jsonObject.getString(FIRST_NAME)); + searchBean.setMiddleName(jsonObject.getString(MIDDLE_NAME)); + searchBean.setLastName(jsonObject.getString(LAST_NAME)); + searchBean.setGender(jsonObject.getString(GENDER)); + + String inActive = jsonObject.getString(INACTIVE); + String lostToFollowUp = jsonObject.getString(LOST_TO_FOLLOW_UP); + String nfcCardIdentifier = jsonObject.getString(NFC_CARD_IDENTIFIER); + + DateTime[] birthdate = RestUtils + .getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html + + //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a + + if (birthdate != null) { + 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); + } + 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); + + boolean isValid = isSearchValid(searchBean); + + return new SearchEntityWrapper(isValid, searchBean, limit); + } + + public static SearchEntityWrapper motherSearchParamProcessor(JSONObject jsonObject) throws ParseException { + + ClientSearchBean motherSearchBean = new ClientSearchBean(); + + 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 = jsonObject.getString(MOTHER_GUARDIAN_NRC_NUMBER); + String compassRelationshipId = jsonObject.getString(MOTHER_COMPASS_RELATIONSHIP_ID); + + motherSearchBean.setFirstName(jsonObject.getString(MOTHER_GUARDIAN_FIRST_NAME)); + motherSearchBean.setLastName(jsonObject.getString(MOTHER_GUARDIAN_LAST_NAME)); + + String NRC_NUMBER_KEY = "NRC_Number"; + String COMPASS_RELATIONSHIP_ID = "Compass_Relationship_ID"; + + Map motherAttributes = new HashMap<>(); + if (!StringUtils.isBlank(motherGuardianNrc)) { + motherAttributes.put(NRC_NUMBER_KEY, motherGuardianNrc); + } + if (!StringUtils.isBlank(compassRelationshipId)) { + motherAttributes.put(COMPASS_RELATIONSHIP_ID, compassRelationshipId); + } + + String nameLike = null; + + if (!StringUtils.isBlank(motherSearchBean.getFirstName()) + && StringUtils.containsWhitespace(motherSearchBean.getFirstName().trim()) + && StringUtils.isBlank(motherSearchBean.getLastName())) { + String[] arr = motherSearchBean.getFirstName().split("\\s+"); + nameLike = arr[0]; + motherSearchBean.setFirstName(null); + } + + motherSearchBean.setNameLike(nameLike); + motherSearchBean.setAttributes(motherAttributes); + + boolean isValid = isSearchValid(motherSearchBean); + + return new SearchEntityWrapper(isValid, motherSearchBean, limit); + } + + public static Integer setCoreFilters(HttpServletRequest request, ClientSearchBean searchBean) throws ParseException { Integer limit = RestUtils.getIntegerFilter("limit", request); @@ -172,6 +312,22 @@ public static Integer setCoreFilters(HttpServletRequest request, ClientSearchBea return limit; } + public static Integer setCoreFilters(JSONObject jsonObject, ClientSearchBean searchBean) throws ParseException { + + Integer limit = jsonObject.getInt("limit"); + if (limit == 0) { + limit = 100; + } + + DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id + if (lastEdit != null) { + searchBean.setLastEditFrom(lastEdit[0]); + searchBean.setLastEditTo(lastEdit[1]); + } + + return limit; + } + /** * Here we check to see if the search entity param is valid for use in child search Some form of * reflections and custom annotations might have been better @@ -271,6 +427,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.getString(MOTHER_GUARDIAN_PHONE_NUMBER); + motherGuardianPhoneNumber = StringUtils.isBlank(motherGuardianPhoneNumber) + ? jsonObject.getString(CONTACT_PHONE_NUMBER) + : motherGuardianPhoneNumber; + + return motherGuardianPhoneNumber; + } + public static List processSearchResult(List children, List mothers, String RELATIONSHIP_KEY) { List childMotherList = new ArrayList(); From 6cfa7486ae089a8683197776730f2e879902d2a0 Mon Sep 17 00:00:00 2001 From: hilpitome Date: Fri, 11 Nov 2022 13:11:54 +0300 Subject: [PATCH 2/9] init refactor to share code --- .../org/opensrp/web/rest/SearchResource.java | 97 +++---------------- .../org/opensrp/web/utils/SearchHelper.java | 69 +++++-------- 2 files changed, 41 insertions(+), 125 deletions(-) diff --git a/src/main/java/org/opensrp/web/rest/SearchResource.java b/src/main/java/org/opensrp/web/rest/SearchResource.java index bc3036b93..d5bd765e1 100644 --- a/src/main/java/org/opensrp/web/rest/SearchResource.java +++ b/src/main/java/org/opensrp/web/rest/SearchResource.java @@ -123,96 +123,33 @@ public List search(HttpServletRequest request) throws ParseException {// @RequestMapping(method = RequestMethod.GET, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) private List searchPathBy(HttpServletRequest request) throws ParseException { - try { - - //Process clients search via demographics - - ClientSearchBean searchBean = new ClientSearchBean(); - List children = new ArrayList(); - + + String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(request); SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(request); - - if (childSearchEntity.isValid()) { - searchBean = childSearchEntity.getClientSearchBean(); - children = searchService.searchClient(searchBean, searchBean.getFirstName(), searchBean.getMiddleName(), - searchBean.getLastName(), childSearchEntity.getLimit()); - } - - //Process mothers search via mother demographics - SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(request); - ClientSearchBean motherSearchBean = new ClientSearchBean(); - List mothers = new ArrayList(); - - if (motherSearchEntity.isValid()) { - motherSearchBean = motherSearchEntity.getClientSearchBean(); - mothers = searchService.searchClient(motherSearchBean, motherSearchBean.getFirstName(), - motherSearchBean.getMiddleName(), motherSearchBean.getLastName(), motherSearchEntity.getLimit()); - } - - //Process clients search via contact phone number - - String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(request); - - List clientBaseEntityIds = getClientBaseEntityIdsByContactPhoneNumber(contactPhoneNumber); - - List eventChildren = clientService.findByFieldValue(BaseEntity.BASE_ENTITY_ID, clientBaseEntityIds); - - children = SearchHelper.intersection(children, eventChildren);// Search conjunction is "AND" find intersection - - 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.findByFieldValue(BaseEntity.BASE_ENTITY_ID, clientIds); - - } - - List linkedChildren = new ArrayList(); - - if (!mothers.isEmpty()) { - for (Client client : mothers) { - linkedChildren.addAll(clientService.findByRelationship(client.getBaseEntityId())); - } - } - - children = SearchHelper.intersection(children, linkedChildren);// Search conjunction is "AND" find intersection - - for (Client linkedMother : linkedMothers) { - if (!SearchHelper.contains(mothers, linkedMother)) { - mothers.add(linkedMother); - } - } - - return SearchHelper.processSearchResult(children, mothers, RELATIONSHIP_KEY); - - } - catch (Exception e) { - - logger.error("", e); - return new ArrayList(); - } + + return searchAndProcess(childSearchEntity, motherSearchEntity, contactPhoneNumber); } @RequestMapping(method = RequestMethod.POST, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) private List searchPathByPost(@RequestBody String jsonRequestBody) throws ParseException { - try { + JSONObject jsonRequestBodyObject = new JSONObject(jsonRequestBody); + SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(jsonRequestBodyObject); + SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(jsonRequestBodyObject); + String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(jsonRequestBodyObject); + + return searchAndProcess(childSearchEntity, motherSearchEntity,contactPhoneNumber); + + } + + private List searchAndProcess(SearchEntityWrapper childSearchEntity, SearchEntityWrapper motherSearchEntity, + String contactPhoneNumber){ + try { //Process clients search via demographics ClientSearchBean searchBean = new ClientSearchBean(); List children = new ArrayList(); - JSONObject jsonRequestBodyObject = new JSONObject(jsonRequestBody); - SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(jsonRequestBodyObject); - if (childSearchEntity.isValid()) { searchBean = childSearchEntity.getClientSearchBean(); children = searchService.searchClient(searchBean, searchBean.getFirstName(), searchBean.getMiddleName(), @@ -221,7 +158,6 @@ private List searchPathByPost(@RequestBody String jsonRequestBody) //Process mothers search via mother demographics - SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(jsonRequestBodyObject); ClientSearchBean motherSearchBean = new ClientSearchBean(); List mothers = new ArrayList(); @@ -233,7 +169,6 @@ private List searchPathByPost(@RequestBody String jsonRequestBody) //Process clients search via contact phone number - String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(jsonRequestBodyObject); List clientBaseEntityIds = getClientBaseEntityIdsByContactPhoneNumber(contactPhoneNumber); diff --git a/src/main/java/org/opensrp/web/utils/SearchHelper.java b/src/main/java/org/opensrp/web/utils/SearchHelper.java index c473e6733..b5e198620 100644 --- a/src/main/java/org/opensrp/web/utils/SearchHelper.java +++ b/src/main/java/org/opensrp/web/utils/SearchHelper.java @@ -19,24 +19,35 @@ public class SearchHelper { - public static SearchEntityWrapper childSearchParamProcessor(HttpServletRequest request) throws ParseException { + private static final String ZEIR_ID = "zeir_id"; + private static final String OPENSRP_ID = "opensrp_id"; - ClientSearchBean searchBean = new ClientSearchBean(); + private static final String SIM_PRINT_GUID = "simprints_guid"; + + private static final String FIRST_NAME = "first_name"; + private static final String MIDDLE_NAME = "middle_name"; + private static final String LAST_NAME = "last_name"; + private static final String BIRTH_DATE = "birth_date"; + + //Attributes + private static final String INACTIVE = "inactive"; + private static final String LOST_TO_FOLLOW_UP = "lost_to_follow_up"; + private static final String NFC_CARD_IDENTIFIER = "nfc_card_identifier"; - String ZEIR_ID = "zeir_id"; - String OPENSRP_ID = "opensrp_id"; + // Mother + private static final String MOTHER_GUARDIAN_FIRST_NAME = "mother_first_name"; + private static final String MOTHER_GUARDIAN_LAST_NAME = "mother_last_name"; + private static final String MOTHER_GUARDIAN_NRC_NUMBER = "mother_nrc_number"; + private static final String MOTHER_COMPASS_RELATIONSHIP_ID = "mother_compass_relationship_id"; - String SIM_PRINT_GUID = "simprints_guid"; + private static final String NRC_NUMBER_KEY = "NRC_Number"; + private static final String COMPASS_RELATIONSHIP_ID = "Compass_Relationship_ID"; + + public static SearchEntityWrapper childSearchParamProcessor(HttpServletRequest request) throws ParseException { + + ClientSearchBean searchBean = new ClientSearchBean(); - String FIRST_NAME = "first_name"; - String MIDDLE_NAME = "middle_name"; - String LAST_NAME = "last_name"; - String BIRTH_DATE = "birth_date"; - //Attributes - String INACTIVE = "inactive"; - String LOST_TO_FOLLOW_UP = "lost_to_follow_up"; - String NFC_CARD_IDENTIFIER = "nfc_card_identifier"; Integer limit = RestUtils.getIntegerFilter("limit", request); if (limit == null || limit.intValue() == 0) { @@ -116,11 +127,7 @@ public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest Integer limit = setCoreFilters(request, 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, request); String compassRelationshipId = RestUtils.getStringFilter(MOTHER_COMPASS_RELATIONSHIP_ID, request); @@ -128,8 +135,6 @@ public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest motherSearchBean.setFirstName(RestUtils.getStringFilter(MOTHER_GUARDIAN_FIRST_NAME, request)); motherSearchBean.setLastName(RestUtils.getStringFilter(MOTHER_GUARDIAN_LAST_NAME, request)); - String NRC_NUMBER_KEY = "NRC_Number"; - String COMPASS_RELATIONSHIP_ID = "Compass_Relationship_ID"; Map motherAttributes = new HashMap<>(); if (!StringUtils.isBlank(motherGuardianNrc)) { @@ -161,21 +166,6 @@ public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObjec ClientSearchBean searchBean = new ClientSearchBean(); - String ZEIR_ID = "zeir_id"; - String OPENSRP_ID = "opensrp_id"; - - String SIM_PRINT_GUID = "simprints_guid"; - - String FIRST_NAME = "first_name"; - String MIDDLE_NAME = "middle_name"; - String LAST_NAME = "last_name"; - String BIRTH_DATE = "birth_date"; - - //Attributes - String INACTIVE = "inactive"; - String LOST_TO_FOLLOW_UP = "lost_to_follow_up"; - String NFC_CARD_IDENTIFIER = "nfc_card_identifier"; - Integer limit = jsonObject.optInt("limit"); if (limit == 0) { limit = 100; @@ -254,21 +244,12 @@ public static SearchEntityWrapper motherSearchParamProcessor(JSONObject jsonObje 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 = jsonObject.getString(MOTHER_GUARDIAN_NRC_NUMBER); String compassRelationshipId = jsonObject.getString(MOTHER_COMPASS_RELATIONSHIP_ID); motherSearchBean.setFirstName(jsonObject.getString(MOTHER_GUARDIAN_FIRST_NAME)); motherSearchBean.setLastName(jsonObject.getString(MOTHER_GUARDIAN_LAST_NAME)); - String NRC_NUMBER_KEY = "NRC_Number"; - String COMPASS_RELATIONSHIP_ID = "Compass_Relationship_ID"; - Map motherAttributes = new HashMap<>(); if (!StringUtils.isBlank(motherGuardianNrc)) { motherAttributes.put(NRC_NUMBER_KEY, motherGuardianNrc); From 59060c18e88290ae996ec96b91e9ca112eeaeba5 Mon Sep 17 00:00:00 2001 From: hilpitome Date: Fri, 11 Nov 2022 17:08:51 +0300 Subject: [PATCH 3/9] share common code in SearchHelper --- .../org/opensrp/web/utils/SearchHelper.java | 171 +++++++----------- 1 file changed, 70 insertions(+), 101 deletions(-) diff --git a/src/main/java/org/opensrp/web/utils/SearchHelper.java b/src/main/java/org/opensrp/web/utils/SearchHelper.java index b5e198620..1c12fdfb5 100644 --- a/src/main/java/org/opensrp/web/utils/SearchHelper.java +++ b/src/main/java/org/opensrp/web/utils/SearchHelper.java @@ -60,19 +60,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 @@ -82,39 +74,17 @@ 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); - } - if (!StringUtils.isBlank(simprintsGuid)) { - identifiers.put(SIM_PRINT_GUID, simprintsGuid); - } - Map attributes = new HashMap(); - if (!StringUtils.isBlank(inActive) || !StringUtils.isBlank(lostToFollowUp) - || !StringUtils.isBlank(nfcCardIdentifier)) { + 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)); - 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); + setIdentifiersAndAttributeToChildSearchBean(commonSearchParams, searchBean); boolean isValid = isSearchValid(searchBean); @@ -135,27 +105,7 @@ public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest motherSearchBean.setFirstName(RestUtils.getStringFilter(MOTHER_GUARDIAN_FIRST_NAME, request)); motherSearchBean.setLastName(RestUtils.getStringFilter(MOTHER_GUARDIAN_LAST_NAME, request)); - - Map motherAttributes = new HashMap<>(); - if (!StringUtils.isBlank(motherGuardianNrc)) { - motherAttributes.put(NRC_NUMBER_KEY, motherGuardianNrc); - } - if (!StringUtils.isBlank(compassRelationshipId)) { - motherAttributes.put(COMPASS_RELATIONSHIP_ID, compassRelationshipId); - } - - String nameLike = null; - - if (!StringUtils.isBlank(motherSearchBean.getFirstName()) - && StringUtils.containsWhitespace(motherSearchBean.getFirstName().trim()) - && StringUtils.isBlank(motherSearchBean.getLastName())) { - String[] arr = motherSearchBean.getFirstName().split("\\s+"); - nameLike = arr[0]; - motherSearchBean.setFirstName(null); - } - - motherSearchBean.setNameLike(nameLike); - motherSearchBean.setAttributes(motherAttributes); + setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc,compassRelationshipId, motherSearchBean); boolean isValid = isSearchValid(motherSearchBean); @@ -177,19 +127,11 @@ public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObjec searchBean.setLastEditTo(lastEdit[1]); } - String zeirId = jsonObject.getString(ZEIR_ID); - String opensrpId = jsonObject.getString(OPENSRP_ID); - String simprintsGuid = jsonObject.getString(SIM_PRINT_GUID); - searchBean.setFirstName(jsonObject.getString(FIRST_NAME)); searchBean.setMiddleName(jsonObject.getString(MIDDLE_NAME)); searchBean.setLastName(jsonObject.getString(LAST_NAME)); searchBean.setGender(jsonObject.getString(GENDER)); - String inActive = jsonObject.getString(INACTIVE); - String lostToFollowUp = jsonObject.getString(LOST_TO_FOLLOW_UP); - String nfcCardIdentifier = jsonObject.getString(NFC_CARD_IDENTIFIER); - DateTime[] birthdate = RestUtils .getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html @@ -199,39 +141,16 @@ public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObjec 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); - } - if (!StringUtils.isBlank(simprintsGuid)) { - identifiers.put(SIM_PRINT_GUID, simprintsGuid); - } + Map commonSearchParams = new HashMap<>(); + commonSearchParams.put(ZEIR_ID, jsonObject.getString(ZEIR_ID)); + commonSearchParams.put(OPENSRP_ID, jsonObject.getString(OPENSRP_ID)); + commonSearchParams.put(SIM_PRINT_GUID, jsonObject.getString(SIM_PRINT_GUID)); + commonSearchParams.put(INACTIVE, jsonObject.getString(INACTIVE)); + commonSearchParams.put(LOST_TO_FOLLOW_UP, jsonObject.getString(LOST_TO_FOLLOW_UP)); + commonSearchParams.put(NFC_CARD_IDENTIFIER, jsonObject.getString(NFC_CARD_IDENTIFIER)); - 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); + setIdentifiersAndAttributeToChildSearchBean(commonSearchParams, searchBean); boolean isValid = isSearchValid(searchBean); @@ -250,6 +169,16 @@ public static SearchEntityWrapper motherSearchParamProcessor(JSONObject jsonObje motherSearchBean.setFirstName(jsonObject.getString(MOTHER_GUARDIAN_FIRST_NAME)); motherSearchBean.setLastName(jsonObject.getString(MOTHER_GUARDIAN_LAST_NAME)); + setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc,compassRelationshipId, motherSearchBean); + + 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); @@ -271,11 +200,51 @@ public static SearchEntityWrapper motherSearchParamProcessor(JSONObject jsonObje motherSearchBean.setNameLike(nameLike); motherSearchBean.setAttributes(motherAttributes); - boolean isValid = isSearchValid(motherSearchBean); - - return new SearchEntityWrapper(isValid, motherSearchBean, limit); } + 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); + + } public static Integer setCoreFilters(HttpServletRequest request, ClientSearchBean searchBean) throws ParseException { From 6e79ed2f0d7b0cfc17b4da30c8e957ec5396c06f Mon Sep 17 00:00:00 2001 From: hilpitome Date: Mon, 14 Nov 2022 16:24:36 +0300 Subject: [PATCH 4/9] use opt to get JSONObject fields --- .../org/opensrp/web/utils/SearchHelper.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/opensrp/web/utils/SearchHelper.java b/src/main/java/org/opensrp/web/utils/SearchHelper.java index 1c12fdfb5..81b5ade65 100644 --- a/src/main/java/org/opensrp/web/utils/SearchHelper.java +++ b/src/main/java/org/opensrp/web/utils/SearchHelper.java @@ -127,10 +127,10 @@ public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObjec searchBean.setLastEditTo(lastEdit[1]); } - searchBean.setFirstName(jsonObject.getString(FIRST_NAME)); - searchBean.setMiddleName(jsonObject.getString(MIDDLE_NAME)); - searchBean.setLastName(jsonObject.getString(LAST_NAME)); - searchBean.setGender(jsonObject.getString(GENDER)); + searchBean.setFirstName(jsonObject.optString(FIRST_NAME)); + searchBean.setMiddleName(jsonObject.optString(MIDDLE_NAME)); + searchBean.setLastName(jsonObject.optString(LAST_NAME)); + searchBean.setGender(jsonObject.optString(GENDER)); DateTime[] birthdate = RestUtils .getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html @@ -143,12 +143,12 @@ public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObjec } Map commonSearchParams = new HashMap<>(); - commonSearchParams.put(ZEIR_ID, jsonObject.getString(ZEIR_ID)); - commonSearchParams.put(OPENSRP_ID, jsonObject.getString(OPENSRP_ID)); - commonSearchParams.put(SIM_PRINT_GUID, jsonObject.getString(SIM_PRINT_GUID)); - commonSearchParams.put(INACTIVE, jsonObject.getString(INACTIVE)); - commonSearchParams.put(LOST_TO_FOLLOW_UP, jsonObject.getString(LOST_TO_FOLLOW_UP)); - commonSearchParams.put(NFC_CARD_IDENTIFIER, jsonObject.getString(NFC_CARD_IDENTIFIER)); + commonSearchParams.put(ZEIR_ID, jsonObject.optString(ZEIR_ID)); + commonSearchParams.put(OPENSRP_ID, jsonObject.optString(OPENSRP_ID)); + commonSearchParams.put(SIM_PRINT_GUID, jsonObject.optString(SIM_PRINT_GUID)); + commonSearchParams.put(INACTIVE, jsonObject.optString(INACTIVE)); + commonSearchParams.put(LOST_TO_FOLLOW_UP, jsonObject.optString(LOST_TO_FOLLOW_UP)); + commonSearchParams.put(NFC_CARD_IDENTIFIER, jsonObject.optString(NFC_CARD_IDENTIFIER)); setIdentifiersAndAttributeToChildSearchBean(commonSearchParams, searchBean); @@ -163,11 +163,11 @@ public static SearchEntityWrapper motherSearchParamProcessor(JSONObject jsonObje Integer limit = setCoreFilters(jsonObject, motherSearchBean); - String motherGuardianNrc = jsonObject.getString(MOTHER_GUARDIAN_NRC_NUMBER); - String compassRelationshipId = jsonObject.getString(MOTHER_COMPASS_RELATIONSHIP_ID); + String motherGuardianNrc = jsonObject.optString(MOTHER_GUARDIAN_NRC_NUMBER); + String compassRelationshipId = jsonObject.optString(MOTHER_COMPASS_RELATIONSHIP_ID); - motherSearchBean.setFirstName(jsonObject.getString(MOTHER_GUARDIAN_FIRST_NAME)); - motherSearchBean.setLastName(jsonObject.getString(MOTHER_GUARDIAN_LAST_NAME)); + motherSearchBean.setFirstName(jsonObject.optString(MOTHER_GUARDIAN_FIRST_NAME)); + motherSearchBean.setLastName(jsonObject.optString(MOTHER_GUARDIAN_LAST_NAME)); setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc,compassRelationshipId, motherSearchBean); @@ -264,7 +264,7 @@ public static Integer setCoreFilters(HttpServletRequest request, ClientSearchBea public static Integer setCoreFilters(JSONObject jsonObject, ClientSearchBean searchBean) throws ParseException { - Integer limit = jsonObject.getInt("limit"); + int limit = jsonObject.optInt("limit"); if (limit == 0) { limit = 100; } @@ -381,9 +381,9 @@ 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.getString(MOTHER_GUARDIAN_PHONE_NUMBER); + String motherGuardianPhoneNumber = jsonObject.optString(MOTHER_GUARDIAN_PHONE_NUMBER); motherGuardianPhoneNumber = StringUtils.isBlank(motherGuardianPhoneNumber) - ? jsonObject.getString(CONTACT_PHONE_NUMBER) + ? jsonObject.optString(CONTACT_PHONE_NUMBER) : motherGuardianPhoneNumber; return motherGuardianPhoneNumber; From b128e88e0e5f911dc769d3973a9d1e353955a240 Mon Sep 17 00:00:00 2001 From: hilpitome Date: Tue, 15 Nov 2022 12:36:26 +0300 Subject: [PATCH 5/9] added SearchHelper tests --- .../org/opensrp/web/utils/SearchHelper.java | 38 +++--- .../opensrp/web/utils/SearchHelperTest.java | 111 +++++++++++++++++- 2 files changed, 130 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/opensrp/web/utils/SearchHelper.java b/src/main/java/org/opensrp/web/utils/SearchHelper.java index 81b5ade65..1e2737c15 100644 --- a/src/main/java/org/opensrp/web/utils/SearchHelper.java +++ b/src/main/java/org/opensrp/web/utils/SearchHelper.java @@ -19,29 +19,29 @@ public class SearchHelper { - private static final String ZEIR_ID = "zeir_id"; - private static final String OPENSRP_ID = "opensrp_id"; + public static final String ZEIR_ID = "zeir_id"; + public static final String OPENSRP_ID = "opensrp_id"; - private static final String SIM_PRINT_GUID = "simprints_guid"; + public static final String SIM_PRINT_GUID = "simprints_guid"; - private static final String FIRST_NAME = "first_name"; - private static final String MIDDLE_NAME = "middle_name"; - private static final String LAST_NAME = "last_name"; - private static final String BIRTH_DATE = "birth_date"; + 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 - private static final String INACTIVE = "inactive"; - private static final String LOST_TO_FOLLOW_UP = "lost_to_follow_up"; - private static final String NFC_CARD_IDENTIFIER = "nfc_card_identifier"; + 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"; // Mother - private static final String MOTHER_GUARDIAN_FIRST_NAME = "mother_first_name"; - private static final String MOTHER_GUARDIAN_LAST_NAME = "mother_last_name"; - private static final String MOTHER_GUARDIAN_NRC_NUMBER = "mother_nrc_number"; - private static final String MOTHER_COMPASS_RELATIONSHIP_ID = "mother_compass_relationship_id"; + public static final String MOTHER_GUARDIAN_FIRST_NAME = "mother_first_name"; + public static final String MOTHER_GUARDIAN_LAST_NAME = "mother_last_name"; + public static final String MOTHER_GUARDIAN_NRC_NUMBER = "mother_nrc_number"; + public static final String MOTHER_COMPASS_RELATIONSHIP_ID = "mother_compass_relationship_id"; - private static final String NRC_NUMBER_KEY = "NRC_Number"; - private static final String COMPASS_RELATIONSHIP_ID = "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 { @@ -116,7 +116,8 @@ public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObjec ClientSearchBean searchBean = new ClientSearchBean(); - Integer limit = jsonObject.optInt("limit"); + Integer limit = !jsonObject.optString("limit").equals("") ? Integer.parseInt(jsonObject.optString("limit")) + : jsonObject.optInt("limit"); if (limit == 0) { limit = 100; } @@ -264,7 +265,8 @@ public static Integer setCoreFilters(HttpServletRequest request, ClientSearchBea public static Integer setCoreFilters(JSONObject jsonObject, ClientSearchBean searchBean) throws ParseException { - int limit = jsonObject.optInt("limit"); + Integer limit = !jsonObject.optString("limit").equals("") ? Integer.parseInt(jsonObject.optString("limit")) + : jsonObject.optInt("limit"); if (limit == 0) { limit = 100; } diff --git a/src/test/java/org/opensrp/web/utils/SearchHelperTest.java b/src/test/java/org/opensrp/web/utils/SearchHelperTest.java index d43337dc8..731dc1b97 100644 --- a/src/test/java/org/opensrp/web/utils/SearchHelperTest.java +++ b/src/test/java/org/opensrp/web/utils/SearchHelperTest.java @@ -1,13 +1,16 @@ 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; import javax.servlet.http.HttpServletRequest; +import javax.validation.constraints.AssertTrue; import java.text.ParseException; import java.util.*; @@ -250,7 +253,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"); @@ -266,4 +269,110 @@ public void testMotherSearchParamProcessor() throws ParseException { 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(); + } + } + } From 1e0830b9e1e5af2086659986bc49e74f710582fb Mon Sep 17 00:00:00 2001 From: hilpitome Date: Tue, 15 Nov 2022 17:42:48 +0300 Subject: [PATCH 6/9] search client by post --- .../org/opensrp/web/rest/SearchResource.java | 57 ++++++++++++++++++- .../opensrp/web/rest/SearchResourceTest.java | 12 ++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opensrp/web/rest/SearchResource.java b/src/main/java/org/opensrp/web/rest/SearchResource.java index d5bd765e1..edf3bf3d5 100644 --- a/src/main/java/org/opensrp/web/rest/SearchResource.java +++ b/src/main/java/org/opensrp/web/rest/SearchResource.java @@ -1,5 +1,6 @@ package org.opensrp.web.rest; +import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -29,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import static org.opensrp.common.AllConstants.BaseEntity.LAST_UPDATE; import static org.opensrp.common.AllConstants.Client.ALT_NAME; @@ -120,7 +122,58 @@ public List search(HttpServletRequest request) throws ParseException {// searchBean.setIdentifiers(identifierMap); return searchService.searchClient(searchBean, firstName, middleName, lastName, null); } - + + @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 + JSONObject jsonObject = new JSONObject(jsonRequestBody); + String firstName = jsonObject.optString(FIRST_NAME); + String middleName = jsonObject.optString(MIDDLE_NAME); + String lastName = jsonObject.optString(LAST_NAME); + Optional phoneNumber = Optional.ofNullable(jsonObject.optString(PHONE_NUMBER)); + Optional altPhoneNumber = Optional.ofNullable(jsonObject.optString(ALT_PHONE_NUMBER)); + Optional alternateName = Optional.ofNullable(jsonObject.optString(ALT_NAME)); + ClientSearchBean searchBean = new ClientSearchBean(); + searchBean.setNameLike(jsonObject.optString(NAME)); + + searchBean.setGender(jsonObject.optString(GENDER)); + DateTime[] birthdate = RestUtils.getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html + DateTime[] lastEdit = RestUtils.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 + + 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 = jsonObject.optString(ATTRIBUTE); + 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); + + Map identifierMap = null; + String identifiers = jsonObject.optString(IDENTIFIER); + if (!StringUtils.isBlank(identifiers)) { + String identifierType = StringUtils.isBlank(identifiers) ? null : identifiers.split(":", -1)[0]; + String identifierValue = StringUtils.isBlank(identifiers) ? null : identifiers.split(":", -1)[1]; + + identifierMap = new HashMap(); + identifierMap.put(identifierType, identifierValue); + } + + searchBean.setIdentifiers(identifierMap); + return searchService.searchClient(searchBean, firstName, middleName, lastName, null); + } + @RequestMapping(method = RequestMethod.GET, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) private List searchPathBy(HttpServletRequest request) throws ParseException { @@ -132,7 +185,7 @@ private List searchPathBy(HttpServletRequest request) throws ParseE } @RequestMapping(method = RequestMethod.POST, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) - private List searchPathByPost(@RequestBody String jsonRequestBody) throws ParseException { + private List searchPathBy(@RequestBody String jsonRequestBody) throws ParseException { JSONObject jsonRequestBodyObject = new JSONObject(jsonRequestBody); SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(jsonRequestBodyObject); diff --git a/src/test/java/org/opensrp/web/rest/SearchResourceTest.java b/src/test/java/org/opensrp/web/rest/SearchResourceTest.java index c9dfe147d..715c3a032 100755 --- a/src/test/java/org/opensrp/web/rest/SearchResourceTest.java +++ b/src/test/java/org/opensrp/web/rest/SearchResourceTest.java @@ -3,6 +3,7 @@ import org.joda.time.DateTime; import org.joda.time.DateTimeZone; +import org.json.JSONObject; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -100,4 +101,15 @@ public void shouldSearchClient() throws ParseException { List clients = searchResource.search(mockHttpServletRequest); Assert.assertNotNull(clients); } + + @Test + public void shouldSearchClientPost() 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); + + } } From a8a14164d5d5c3f41654b18402df34943cd0dc9a Mon Sep 17 00:00:00 2001 From: hilpitome Date: Tue, 15 Nov 2022 17:45:43 +0300 Subject: [PATCH 7/9] fix codacy issues --- src/main/java/org/opensrp/web/rest/SearchResource.java | 2 -- src/test/java/org/opensrp/web/rest/SearchResourceTest.java | 1 - src/test/java/org/opensrp/web/utils/SearchHelperTest.java | 1 - 3 files changed, 4 deletions(-) diff --git a/src/main/java/org/opensrp/web/rest/SearchResource.java b/src/main/java/org/opensrp/web/rest/SearchResource.java index edf3bf3d5..fe92887f2 100644 --- a/src/main/java/org/opensrp/web/rest/SearchResource.java +++ b/src/main/java/org/opensrp/web/rest/SearchResource.java @@ -1,6 +1,5 @@ package org.opensrp.web.rest; -import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -30,7 +29,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import static org.opensrp.common.AllConstants.BaseEntity.LAST_UPDATE; import static org.opensrp.common.AllConstants.Client.ALT_NAME; diff --git a/src/test/java/org/opensrp/web/rest/SearchResourceTest.java b/src/test/java/org/opensrp/web/rest/SearchResourceTest.java index 715c3a032..bccefa531 100755 --- a/src/test/java/org/opensrp/web/rest/SearchResourceTest.java +++ b/src/test/java/org/opensrp/web/rest/SearchResourceTest.java @@ -3,7 +3,6 @@ import org.joda.time.DateTime; import org.joda.time.DateTimeZone; -import org.json.JSONObject; import org.junit.Assert; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/org/opensrp/web/utils/SearchHelperTest.java b/src/test/java/org/opensrp/web/utils/SearchHelperTest.java index 731dc1b97..523c6538a 100644 --- a/src/test/java/org/opensrp/web/utils/SearchHelperTest.java +++ b/src/test/java/org/opensrp/web/utils/SearchHelperTest.java @@ -10,7 +10,6 @@ import org.springframework.mock.web.MockHttpServletRequest; import javax.servlet.http.HttpServletRequest; -import javax.validation.constraints.AssertTrue; import java.text.ParseException; import java.util.*; From 06ba41c908cdebd4f75145de80fe5ce647164cd0 Mon Sep 17 00:00:00 2001 From: hilpitome Date: Thu, 17 Nov 2022 16:16:23 +0300 Subject: [PATCH 8/9] apply formating --- .../java/org/opensrp/web/rest/RestUtils.java | 382 +++++----- .../org/opensrp/web/rest/SearchResource.java | 542 +++++++------- .../org/opensrp/web/utils/SearchHelper.java | 682 +++++++++--------- .../opensrp/web/rest/SearchResourceTest.java | 173 ++--- 4 files changed, 882 insertions(+), 897 deletions(-) diff --git a/src/main/java/org/opensrp/web/rest/RestUtils.java b/src/main/java/org/opensrp/web/rest/RestUtils.java index 2b6a3a113..940acfff1 100644 --- a/src/main/java/org/opensrp/web/rest/RestUtils.java +++ b/src/main/java/org/opensrp/web/rest/RestUtils.java @@ -28,121 +28,112 @@ import org.opensrp.domain.Multimedia; import org.opensrp.service.multimedia.MultimediaFileManager; import org.opensrp.service.multimedia.S3MultimediaFileManager; -import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.security.core.Authentication; 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); - } - - @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 Float getFloatFilter(String filter, HttpServletRequest req) - { - String strval = getStringFilter(filter, req); - return strval == null ? null : Float.parseFloat(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 DateTime[] getDateRangeFilter(String filter, HttpServletRequest req) throws ParseException - { - String strval = getStringFilter(filter, req); - if(strval == null){ - return null; - } - if (!strval.contains(":")) { - return new DateTime[] { new DateTime(strval), new DateTime(strval) }; - } - 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 DateTime[] getDateRangeFilter(String filter, JSONObject jsonObject) throws ParseException - { - String strval = jsonObject.optString(filter); - if(strval.equals("")){ - return null; - } - if (!strval.contains(":")) { - return new DateTime[] { new DateTime(strval), new DateTime(strval) }; - } - 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) { - String stringFilter = getStringFilter(filter, 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 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"); - } - } 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; - } + 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); + } + + @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 Float getFloatFilter(String filter, HttpServletRequest req) { + String strval = getStringFilter(filter, req); + return strval == null ? null : Float.parseFloat(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 DateTime[] getDateRangeFilter(String filter, HttpServletRequest req) throws ParseException { + String strval = getStringFilter(filter, req); + if (strval == null) { + return null; + } + if (!strval.contains(":")) { + return new DateTime[]{new DateTime(strval), new DateTime(strval)}; + } + 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 DateTime[] getDateRangeFilter(String filter, JSONObject jsonObject) throws ParseException { + String strval = jsonObject.optString(filter); + if (strval.equals("")) { + return null; + } + if (!strval.contains(":")) { + return new DateTime[]{new DateTime(strval), new DateTime(strval)}; + } + 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) { + String stringFilter = getStringFilter(filter, 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 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"); + } + } 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} @@ -151,91 +142,88 @@ public static HttpHeaders getJSONUTF8Headers() { * @param multimediaFiles * @throws IOException */ - public static void zipFiles(ZipOutputStream zipOutputStream, List multimediaFiles, MultimediaFileManager fileManager) throws IOException { - for (Multimedia multiMedia : multimediaFiles) { - FileInputStream inputStream; - File file = fileManager.retrieveFile(multiMedia.getFilePath()); - if (file != null) { - logger.info("Adding " + file.getName()); - zipOutputStream.putNextEntry(new ZipEntry(file.getName())); - try { - inputStream = new FileInputStream(file); - } catch (FileNotFoundException e) { - logger.warn("Could not find file " + file.getAbsolutePath()); - continue; - } - - // Write the contents of the file - BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); - int data; - while ((data = bufferedInputStream.read()) != -1) { - zipOutputStream.write(data); - } - bufferedInputStream.close(); - zipOutputStream.closeEntry(); - logger.info("Done downloading file " + file.getName()); - - // clean up temp files (may want to cache in future) - if (fileManager instanceof S3MultimediaFileManager) { - file.delete(); - } - } - } - } - - public static User currentUser(Authentication authentication) { - if (authentication != null && authentication.getPrincipal() instanceof KeycloakPrincipal) { - @SuppressWarnings("unchecked") - KeycloakPrincipal kp = (KeycloakPrincipal) authentication - .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()); - user.setAttributes(token.getOtherClaims()); - user.setRoles(authorities); - user.setPermissions(authorities); - return user; - } - return null; - } - - public static void writeToZipFile(String fileName, ZipOutputStream zipStream, String filePath) throws IOException { - File aFile; - FileInputStream fis = null; - ZipEntry zipEntry; - String tempDirectory = System.getProperty("java.io.tmpdir"); - 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 { - fis = new FileInputStream(filePath); - zipEntry = new ZipEntry(filePath); - logger.info("Writing file : '" + filePath + "' to zip file"); - } - zipStream.putNextEntry(zipEntry); - byte[] bytes = new byte[1024]; - int length; - while ((length = fis.read(bytes)) >= 0) { - zipStream.write(bytes, 0, length); - } - - zipStream.closeEntry(); - } - catch (IOException e) { - logger.error("IO Exception occurred: " + e.getMessage()); - } - finally { - if (fis != null) { - fis.close(); - } - } - } + public static void zipFiles(ZipOutputStream zipOutputStream, List multimediaFiles, MultimediaFileManager fileManager) throws IOException { + for (Multimedia multiMedia : multimediaFiles) { + FileInputStream inputStream; + File file = fileManager.retrieveFile(multiMedia.getFilePath()); + if (file != null) { + logger.info("Adding " + file.getName()); + zipOutputStream.putNextEntry(new ZipEntry(file.getName())); + try { + inputStream = new FileInputStream(file); + } catch (FileNotFoundException e) { + logger.warn("Could not find file " + file.getAbsolutePath()); + continue; + } + + // Write the contents of the file + BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); + int data; + while ((data = bufferedInputStream.read()) != -1) { + zipOutputStream.write(data); + } + bufferedInputStream.close(); + zipOutputStream.closeEntry(); + logger.info("Done downloading file " + file.getName()); + + // clean up temp files (may want to cache in future) + if (fileManager instanceof S3MultimediaFileManager) { + file.delete(); + } + } + } + } + + public static User currentUser(Authentication authentication) { + if (authentication != null && authentication.getPrincipal() instanceof KeycloakPrincipal) { + @SuppressWarnings("unchecked") + KeycloakPrincipal kp = (KeycloakPrincipal) authentication + .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()); + user.setAttributes(token.getOtherClaims()); + user.setRoles(authorities); + user.setPermissions(authorities); + return user; + } + return null; + } + + public static void writeToZipFile(String fileName, ZipOutputStream zipStream, String filePath) throws IOException { + File aFile; + FileInputStream fis = null; + ZipEntry zipEntry; + String tempDirectory = System.getProperty("java.io.tmpdir"); + 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 { + fis = new FileInputStream(filePath); + zipEntry = new ZipEntry(filePath); + logger.info("Writing file : '" + filePath + "' to zip file"); + } + zipStream.putNextEntry(zipEntry); + byte[] bytes = new byte[1024]; + int length; + while ((length = fis.read(bytes)) >= 0) { + zipStream.write(bytes, 0, length); + } + + zipStream.closeEntry(); + } catch (IOException e) { + logger.error("IO Exception occurred: " + e.getMessage()); + } finally { + if (fis != null) { + fis.close(); + } + } + } } diff --git a/src/main/java/org/opensrp/web/rest/SearchResource.java b/src/main/java/org/opensrp/web/rest/SearchResource.java index fe92887f2..436ba16a3 100644 --- a/src/main/java/org/opensrp/web/rest/SearchResource.java +++ b/src/main/java/org/opensrp/web/rest/SearchResource.java @@ -47,276 +47,274 @@ @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; - this.clientService = clientService; - this.eventService = eventService; - } - - /** - * @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)); - - 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 - - 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); - - 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]; - - identifierMap = new HashMap(); - identifierMap.put(identifierType, identifierValue); - } - - searchBean.setIdentifiers(identifierMap); - return searchService.searchClient(searchBean, firstName, middleName, lastName, null); - } - - @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 - JSONObject jsonObject = new JSONObject(jsonRequestBody); - String firstName = jsonObject.optString(FIRST_NAME); - String middleName = jsonObject.optString(MIDDLE_NAME); - String lastName = jsonObject.optString(LAST_NAME); - Optional phoneNumber = Optional.ofNullable(jsonObject.optString(PHONE_NUMBER)); - Optional altPhoneNumber = Optional.ofNullable(jsonObject.optString(ALT_PHONE_NUMBER)); - Optional alternateName = Optional.ofNullable(jsonObject.optString(ALT_NAME)); - ClientSearchBean searchBean = new ClientSearchBean(); - searchBean.setNameLike(jsonObject.optString(NAME)); - - searchBean.setGender(jsonObject.optString(GENDER)); - DateTime[] birthdate = RestUtils.getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html - DateTime[] lastEdit = RestUtils.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 - - 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 = jsonObject.optString(ATTRIBUTE); - 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); - - Map identifierMap = null; - String identifiers = jsonObject.optString(IDENTIFIER); - if (!StringUtils.isBlank(identifiers)) { - String identifierType = StringUtils.isBlank(identifiers) ? null : identifiers.split(":", -1)[0]; - String identifierValue = StringUtils.isBlank(identifiers) ? null : identifiers.split(":", -1)[1]; - - identifierMap = new HashMap(); - identifierMap.put(identifierType, identifierValue); - } - - searchBean.setIdentifiers(identifierMap); - return searchService.searchClient(searchBean, firstName, middleName, lastName, null); - } - - @RequestMapping(method = RequestMethod.GET, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) - private List searchPathBy(HttpServletRequest request) throws ParseException { - - String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(request); - SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(request); - SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(request); - - return searchAndProcess(childSearchEntity, motherSearchEntity, contactPhoneNumber); - } - - @RequestMapping(method = RequestMethod.POST, value = "/path", produces = { MediaType.APPLICATION_JSON_VALUE }) - private List searchPathBy(@RequestBody String jsonRequestBody) throws ParseException { - - JSONObject jsonRequestBodyObject = new JSONObject(jsonRequestBody); - SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(jsonRequestBodyObject); - SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(jsonRequestBodyObject); - String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(jsonRequestBodyObject); - - return searchAndProcess(childSearchEntity, motherSearchEntity,contactPhoneNumber); - - } - - private List searchAndProcess(SearchEntityWrapper childSearchEntity, SearchEntityWrapper motherSearchEntity, - String contactPhoneNumber){ - try { - //Process clients search via demographics - - ClientSearchBean searchBean = new ClientSearchBean(); - List children = new ArrayList(); - if (childSearchEntity.isValid()) { - searchBean = childSearchEntity.getClientSearchBean(); - children = searchService.searchClient(searchBean, searchBean.getFirstName(), searchBean.getMiddleName(), - searchBean.getLastName(), childSearchEntity.getLimit()); - } - - //Process mothers search via mother demographics - - ClientSearchBean motherSearchBean = new ClientSearchBean(); - List mothers = new ArrayList(); - - if (motherSearchEntity.isValid()) { - motherSearchBean = motherSearchEntity.getClientSearchBean(); - mothers = searchService.searchClient(motherSearchBean, motherSearchBean.getFirstName(), - motherSearchBean.getMiddleName(), motherSearchBean.getLastName(), motherSearchEntity.getLimit()); - } - - //Process clients search via contact phone number - - - List clientBaseEntityIds = getClientBaseEntityIdsByContactPhoneNumber(contactPhoneNumber); - - List eventChildren = clientService.findByFieldValue(BaseEntity.BASE_ENTITY_ID, clientBaseEntityIds); - - children = SearchHelper.intersection(children, eventChildren);// Search conjunction is "AND" find intersection - - 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.findByFieldValue(BaseEntity.BASE_ENTITY_ID, clientIds); - - } - - List linkedChildren = new ArrayList(); - - if (!mothers.isEmpty()) { - for (Client client : mothers) { - linkedChildren.addAll(clientService.findByRelationship(client.getBaseEntityId())); - } - } - - children = SearchHelper.intersection(children, linkedChildren);// Search conjunction is "AND" find intersection - - for (Client linkedMother : linkedMothers) { - if (!SearchHelper.contains(mothers, linkedMother)) { - mothers.add(linkedMother); - } - } - - return SearchHelper.processSearchResult(children, mothers, RELATIONSHIP_KEY); - - } - catch (Exception e) { - - 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); - if (events != null && !events.isEmpty()) { - for (Event event : events) { - String entityId = event.getBaseEntityId(); - if (entityId != null && !clientBaseEntityIds.contains(entityId)) { - clientBaseEntityIds.add(entityId); - } - } - - } - } - return clientBaseEntityIds; - } - - @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; - } - + + 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; + this.clientService = clientService; + this.eventService = eventService; + } + + /** + * @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)); + + 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 + + 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); + + 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]; + + identifierMap = new HashMap(); + identifierMap.put(identifierType, identifierValue); + } + + searchBean.setIdentifiers(identifierMap); + return searchService.searchClient(searchBean, firstName, middleName, lastName, null); + } + + @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 + JSONObject jsonObject = new JSONObject(jsonRequestBody); + String firstName = jsonObject.optString(FIRST_NAME); + String middleName = jsonObject.optString(MIDDLE_NAME); + String lastName = jsonObject.optString(LAST_NAME); + Optional phoneNumber = Optional.ofNullable(jsonObject.optString(PHONE_NUMBER)); + Optional altPhoneNumber = Optional.ofNullable(jsonObject.optString(ALT_PHONE_NUMBER)); + Optional alternateName = Optional.ofNullable(jsonObject.optString(ALT_NAME)); + ClientSearchBean searchBean = new ClientSearchBean(); + searchBean.setNameLike(jsonObject.optString(NAME)); + + searchBean.setGender(jsonObject.optString(GENDER)); + DateTime[] birthdate = RestUtils.getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html + DateTime[] lastEdit = RestUtils.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 + + 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 = jsonObject.optString(ATTRIBUTE); + 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); + + Map identifierMap = null; + String identifiers = jsonObject.optString(IDENTIFIER); + if (!StringUtils.isBlank(identifiers)) { + String identifierType = StringUtils.isBlank(identifiers) ? null : identifiers.split(":", -1)[0]; + String identifierValue = StringUtils.isBlank(identifiers) ? null : identifiers.split(":", -1)[1]; + + identifierMap = new HashMap(); + identifierMap.put(identifierType, identifierValue); + } + + searchBean.setIdentifiers(identifierMap); + return searchService.searchClient(searchBean, firstName, middleName, lastName, null); + } + + @RequestMapping(method = RequestMethod.GET, value = "/path", produces = {MediaType.APPLICATION_JSON_VALUE}) + private List searchPathBy(HttpServletRequest request) throws ParseException { + + String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(request); + SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(request); + SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(request); + + return searchAndProcess(childSearchEntity, motherSearchEntity, contactPhoneNumber); + } + + @RequestMapping(method = RequestMethod.POST, value = "/path", produces = {MediaType.APPLICATION_JSON_VALUE}) + private List searchPathBy(@RequestBody String jsonRequestBody) throws ParseException { + + JSONObject jsonRequestBodyObject = new JSONObject(jsonRequestBody); + SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(jsonRequestBodyObject); + SearchEntityWrapper motherSearchEntity = SearchHelper.motherSearchParamProcessor(jsonRequestBodyObject); + String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(jsonRequestBodyObject); + + return searchAndProcess(childSearchEntity, motherSearchEntity, contactPhoneNumber); + + } + + private List searchAndProcess(SearchEntityWrapper childSearchEntity, SearchEntityWrapper motherSearchEntity, + String contactPhoneNumber) { + try { + //Process clients search via demographics + + ClientSearchBean searchBean = new ClientSearchBean(); + List children = new ArrayList(); + if (childSearchEntity.isValid()) { + searchBean = childSearchEntity.getClientSearchBean(); + children = searchService.searchClient(searchBean, searchBean.getFirstName(), searchBean.getMiddleName(), + searchBean.getLastName(), childSearchEntity.getLimit()); + } + + //Process mothers search via mother demographics + + ClientSearchBean motherSearchBean = new ClientSearchBean(); + List mothers = new ArrayList(); + + if (motherSearchEntity.isValid()) { + motherSearchBean = motherSearchEntity.getClientSearchBean(); + mothers = searchService.searchClient(motherSearchBean, motherSearchBean.getFirstName(), + motherSearchBean.getMiddleName(), motherSearchBean.getLastName(), motherSearchEntity.getLimit()); + } + + //Process clients search via contact phone number + + + List clientBaseEntityIds = getClientBaseEntityIdsByContactPhoneNumber(contactPhoneNumber); + + List eventChildren = clientService.findByFieldValue(BaseEntity.BASE_ENTITY_ID, clientBaseEntityIds); + + children = SearchHelper.intersection(children, eventChildren);// Search conjunction is "AND" find intersection + + 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.findByFieldValue(BaseEntity.BASE_ENTITY_ID, clientIds); + + } + + List linkedChildren = new ArrayList(); + + if (!mothers.isEmpty()) { + for (Client client : mothers) { + linkedChildren.addAll(clientService.findByRelationship(client.getBaseEntityId())); + } + } + + children = SearchHelper.intersection(children, linkedChildren);// Search conjunction is "AND" find intersection + + for (Client linkedMother : linkedMothers) { + if (!SearchHelper.contains(mothers, linkedMother)) { + mothers.add(linkedMother); + } + } + + return SearchHelper.processSearchResult(children, mothers, RELATIONSHIP_KEY); + + } catch (Exception e) { + + 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); + if (events != null && !events.isEmpty()) { + for (Event event : events) { + String entityId = event.getBaseEntityId(); + if (entityId != null && !clientBaseEntityIds.contains(entityId)) { + clientBaseEntityIds.add(entityId); + } + } + + } + } + return clientBaseEntityIds; + } + + @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/utils/SearchHelper.java b/src/main/java/org/opensrp/web/utils/SearchHelper.java index 1e2737c15..d34930572 100644 --- a/src/main/java/org/opensrp/web/utils/SearchHelper.java +++ b/src/main/java/org/opensrp/web/utils/SearchHelper.java @@ -19,408 +19,406 @@ public class SearchHelper { - public static final String ZEIR_ID = "zeir_id"; - public static final String OPENSRP_ID = "opensrp_id"; + public static final String ZEIR_ID = "zeir_id"; + public static final String OPENSRP_ID = "opensrp_id"; - public static final String SIM_PRINT_GUID = "simprints_guid"; + 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"; + 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"; + //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"; - // Mother - public static final String MOTHER_GUARDIAN_FIRST_NAME = "mother_first_name"; - public static final String MOTHER_GUARDIAN_LAST_NAME = "mother_last_name"; - public static final String MOTHER_GUARDIAN_NRC_NUMBER = "mother_nrc_number"; - public static final String MOTHER_COMPASS_RELATIONSHIP_ID = "mother_compass_relationship_id"; + // Mother + public static final String MOTHER_GUARDIAN_FIRST_NAME = "mother_first_name"; + public static final String MOTHER_GUARDIAN_LAST_NAME = "mother_last_name"; + public static final String MOTHER_GUARDIAN_NRC_NUMBER = "mother_nrc_number"; + 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 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 { + public static SearchEntityWrapper childSearchParamProcessor(HttpServletRequest request) throws ParseException { - ClientSearchBean searchBean = new ClientSearchBean(); + ClientSearchBean searchBean = new ClientSearchBean(); + Integer limit = RestUtils.getIntegerFilter("limit", request); + if (limit == null || limit.intValue() == 0) { + limit = 100; + } - Integer limit = RestUtils.getIntegerFilter("limit", request); - if (limit == null || limit.intValue() == 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]); + } - DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, request);//TODO client by provider id - if (lastEdit != null) { - searchBean.setLastEditFrom(lastEdit[0]); - searchBean.setLastEditTo(lastEdit[1]); - } + 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)); - 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)); + DateTime[] birthdate = RestUtils + .getDateRangeFilter(BIRTH_DATE, request);//TODO add ranges like fhir do http://hl7.org/fhir/search.html - DateTime[] birthdate = RestUtils - .getDateRangeFilter(BIRTH_DATE, request);//TODO add ranges like fhir do http://hl7.org/fhir/search.html + //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a - //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a + if (birthdate != null) { + searchBean.setBirthdateFrom(birthdate[0]); + searchBean.setBirthdateTo(birthdate[1]); + } - if (birthdate != null) { - searchBean.setBirthdateFrom(birthdate[0]); - searchBean.setBirthdateTo(birthdate[1]); - } + 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)); - 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); - setIdentifiersAndAttributeToChildSearchBean(commonSearchParams, searchBean); + boolean isValid = isSearchValid(searchBean); - boolean isValid = isSearchValid(searchBean); + return new SearchEntityWrapper(isValid, searchBean, limit); + } - return new SearchEntityWrapper(isValid, searchBean, limit); - } + public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest request) throws ParseException { - public static SearchEntityWrapper motherSearchParamProcessor(HttpServletRequest request) throws ParseException { + ClientSearchBean motherSearchBean = new ClientSearchBean(); - ClientSearchBean motherSearchBean = new ClientSearchBean(); + Integer limit = setCoreFilters(request, motherSearchBean); - 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)); - String motherGuardianNrc = RestUtils.getStringFilter(MOTHER_GUARDIAN_NRC_NUMBER, request); - String compassRelationshipId = RestUtils.getStringFilter(MOTHER_COMPASS_RELATIONSHIP_ID, request); + setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc, compassRelationshipId, motherSearchBean); - motherSearchBean.setFirstName(RestUtils.getStringFilter(MOTHER_GUARDIAN_FIRST_NAME, request)); - motherSearchBean.setLastName(RestUtils.getStringFilter(MOTHER_GUARDIAN_LAST_NAME, request)); + boolean isValid = isSearchValid(motherSearchBean); - setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc,compassRelationshipId, motherSearchBean); + return new SearchEntityWrapper(isValid, motherSearchBean, limit); + } - boolean isValid = isSearchValid(motherSearchBean); + public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObject) throws ParseException { - return new SearchEntityWrapper(isValid, motherSearchBean, limit); - } + ClientSearchBean searchBean = new ClientSearchBean(); - public static SearchEntityWrapper childSearchParamProcessor(JSONObject jsonObject) throws ParseException { + Integer limit = !jsonObject.optString("limit").equals("") ? Integer.parseInt(jsonObject.optString("limit")) + : jsonObject.optInt("limit"); + if (limit == 0) { + limit = 100; + } - ClientSearchBean searchBean = new ClientSearchBean(); + DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id + if (lastEdit != null) { + searchBean.setLastEditFrom(lastEdit[0]); + searchBean.setLastEditTo(lastEdit[1]); + } - Integer limit = !jsonObject.optString("limit").equals("") ? Integer.parseInt(jsonObject.optString("limit")) - : jsonObject.optInt("limit"); - if (limit == 0) { - limit = 100; - } + searchBean.setFirstName(jsonObject.optString(FIRST_NAME)); + searchBean.setMiddleName(jsonObject.optString(MIDDLE_NAME)); + searchBean.setLastName(jsonObject.optString(LAST_NAME)); + searchBean.setGender(jsonObject.optString(GENDER)); - DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id - if (lastEdit != null) { - searchBean.setLastEditFrom(lastEdit[0]); - searchBean.setLastEditTo(lastEdit[1]); - } + DateTime[] birthdate = RestUtils + .getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html - searchBean.setFirstName(jsonObject.optString(FIRST_NAME)); - searchBean.setMiddleName(jsonObject.optString(MIDDLE_NAME)); - searchBean.setLastName(jsonObject.optString(LAST_NAME)); - searchBean.setGender(jsonObject.optString(GENDER)); + //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a - DateTime[] birthdate = RestUtils - .getDateRangeFilter(BIRTH_DATE, jsonObject);//TODO add ranges like fhir do http://hl7.org/fhir/search.html + if (birthdate != null) { + searchBean.setBirthdateFrom(birthdate[0]); + searchBean.setBirthdateTo(birthdate[1]); + } - //TODO lookinto Swagger https://slack-files.com/files-pri-safe/T0EPSEJE9-F0TBD0N77/integratingswagger.pdf?c=1458211183-179d2bfd2e974585c5038fba15a86bf83097810a + Map commonSearchParams = new HashMap<>(); + commonSearchParams.put(ZEIR_ID, jsonObject.optString(ZEIR_ID)); + commonSearchParams.put(OPENSRP_ID, jsonObject.optString(OPENSRP_ID)); + commonSearchParams.put(SIM_PRINT_GUID, jsonObject.optString(SIM_PRINT_GUID)); + commonSearchParams.put(INACTIVE, jsonObject.optString(INACTIVE)); + commonSearchParams.put(LOST_TO_FOLLOW_UP, jsonObject.optString(LOST_TO_FOLLOW_UP)); + commonSearchParams.put(NFC_CARD_IDENTIFIER, jsonObject.optString(NFC_CARD_IDENTIFIER)); - if (birthdate != null) { - searchBean.setBirthdateFrom(birthdate[0]); - searchBean.setBirthdateTo(birthdate[1]); - } + setIdentifiersAndAttributeToChildSearchBean(commonSearchParams, searchBean); - Map commonSearchParams = new HashMap<>(); - commonSearchParams.put(ZEIR_ID, jsonObject.optString(ZEIR_ID)); - commonSearchParams.put(OPENSRP_ID, jsonObject.optString(OPENSRP_ID)); - commonSearchParams.put(SIM_PRINT_GUID, jsonObject.optString(SIM_PRINT_GUID)); - commonSearchParams.put(INACTIVE, jsonObject.optString(INACTIVE)); - commonSearchParams.put(LOST_TO_FOLLOW_UP, jsonObject.optString(LOST_TO_FOLLOW_UP)); - commonSearchParams.put(NFC_CARD_IDENTIFIER, jsonObject.optString(NFC_CARD_IDENTIFIER)); + boolean isValid = isSearchValid(searchBean); - setIdentifiersAndAttributeToChildSearchBean(commonSearchParams, searchBean); + return new SearchEntityWrapper(isValid, searchBean, limit); + } - boolean isValid = isSearchValid(searchBean); + public static SearchEntityWrapper motherSearchParamProcessor(JSONObject jsonObject) throws ParseException { - return new SearchEntityWrapper(isValid, searchBean, limit); - } + ClientSearchBean motherSearchBean = new ClientSearchBean(); - public static SearchEntityWrapper motherSearchParamProcessor(JSONObject jsonObject) throws ParseException { + Integer limit = setCoreFilters(jsonObject, motherSearchBean); - ClientSearchBean motherSearchBean = new ClientSearchBean(); + String motherGuardianNrc = jsonObject.optString(MOTHER_GUARDIAN_NRC_NUMBER); + String compassRelationshipId = jsonObject.optString(MOTHER_COMPASS_RELATIONSHIP_ID); - Integer limit = setCoreFilters(jsonObject, motherSearchBean); + motherSearchBean.setFirstName(jsonObject.optString(MOTHER_GUARDIAN_FIRST_NAME)); + motherSearchBean.setLastName(jsonObject.optString(MOTHER_GUARDIAN_LAST_NAME)); - String motherGuardianNrc = jsonObject.optString(MOTHER_GUARDIAN_NRC_NUMBER); - String compassRelationshipId = jsonObject.optString(MOTHER_COMPASS_RELATIONSHIP_ID); + setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc, compassRelationshipId, motherSearchBean); - motherSearchBean.setFirstName(jsonObject.optString(MOTHER_GUARDIAN_FIRST_NAME)); - motherSearchBean.setLastName(jsonObject.optString(MOTHER_GUARDIAN_LAST_NAME)); + boolean isValid = isSearchValid(motherSearchBean); - setNameLikeAndAtrributesOnMotherSearchBean(motherGuardianNrc,compassRelationshipId, motherSearchBean); + return new SearchEntityWrapper(isValid, motherSearchBean, limit); + } - boolean isValid = isSearchValid(motherSearchBean); + public static void setNameLikeAndAtrributesOnMotherSearchBean(String motherGuardianNrc, + String compassRelationshipId, + ClientSearchBean motherSearchBean) { + Map motherAttributes = new HashMap<>(); + if (!StringUtils.isBlank(motherGuardianNrc)) { + motherAttributes.put(NRC_NUMBER_KEY, motherGuardianNrc); + } + if (!StringUtils.isBlank(compassRelationshipId)) { + motherAttributes.put(COMPASS_RELATIONSHIP_ID, compassRelationshipId); + } - return new SearchEntityWrapper(isValid, motherSearchBean, limit); - } + String nameLike = null; - public static void setNameLikeAndAtrributesOnMotherSearchBean(String motherGuardianNrc, - String compassRelationshipId, - ClientSearchBean motherSearchBean){ - Map motherAttributes = new HashMap<>(); - if (!StringUtils.isBlank(motherGuardianNrc)) { - motherAttributes.put(NRC_NUMBER_KEY, motherGuardianNrc); - } - if (!StringUtils.isBlank(compassRelationshipId)) { - motherAttributes.put(COMPASS_RELATIONSHIP_ID, compassRelationshipId); - } + if (!StringUtils.isBlank(motherSearchBean.getFirstName()) + && StringUtils.containsWhitespace(motherSearchBean.getFirstName().trim()) + && StringUtils.isBlank(motherSearchBean.getLastName())) { + String[] arr = motherSearchBean.getFirstName().split("\\s+"); + nameLike = arr[0]; + motherSearchBean.setFirstName(null); + } - String nameLike = null; + motherSearchBean.setNameLike(nameLike); + motherSearchBean.setAttributes(motherAttributes); - if (!StringUtils.isBlank(motherSearchBean.getFirstName()) - && StringUtils.containsWhitespace(motherSearchBean.getFirstName().trim()) - && StringUtils.isBlank(motherSearchBean.getLastName())) { - String[] arr = motherSearchBean.getFirstName().split("\\s+"); - nameLike = arr[0]; - motherSearchBean.setFirstName(null); - } + } - motherSearchBean.setNameLike(nameLike); - motherSearchBean.setAttributes(motherAttributes); + 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); + } - public static void setIdentifiersAndAttributeToChildSearchBean(Map commonSearchParams, ClientSearchBean searchBean){ - Map identifiers = new HashMap(); + 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 + } + } - 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); - } + searchBean.setIdentifiers(identifiers); + searchBean.setAttributes(attributes); - 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); + public static Integer setCoreFilters(HttpServletRequest request, ClientSearchBean searchBean) throws ParseException { - } + Integer limit = RestUtils.getIntegerFilter("limit", request); + if (limit == null || limit.intValue() == 0) { + limit = 100; + } - public static Integer setCoreFilters(HttpServletRequest request, ClientSearchBean searchBean) throws ParseException { + DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, request);//TODO client by provider id + if (lastEdit != null) { + searchBean.setLastEditFrom(lastEdit[0]); + searchBean.setLastEditTo(lastEdit[1]); + } - Integer limit = RestUtils.getIntegerFilter("limit", request); - if (limit == null || limit.intValue() == 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; - } - - public static Integer setCoreFilters(JSONObject jsonObject, ClientSearchBean searchBean) throws ParseException { - - Integer limit = !jsonObject.optString("limit").equals("") ? Integer.parseInt(jsonObject.optString("limit")) - : jsonObject.optInt("limit"); - if (limit == 0) { - limit = 100; - } - - DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id - if (lastEdit != null) { - searchBean.setLastEditFrom(lastEdit[0]); - searchBean.setLastEditTo(lastEdit[1]); - } - - return limit; - } - - /** - * Here we check to see if the search entity param is valid for use in child search Some form of - * reflections and custom annotations might have been better - * - * @param searchBean model with search params - * @return boolean whether the search entity is valid - */ - - public static boolean isSearchValid(ClientSearchBean searchBean) { - - return !StringUtils.isBlank(searchBean.getFirstName()) - || !StringUtils.isBlank(searchBean.getMiddleName()) - || !StringUtils.isBlank(searchBean.getLastName()) - || !StringUtils.isBlank(searchBean.getGender()) - || (searchBean.getAttributes() != null && !searchBean.getAttributes().isEmpty()) - || searchBean.getBirthdateFrom() != null || searchBean.getBirthdateTo() != null - || searchBean.getLastEditFrom() != null || searchBean.getLastEditTo() != null - || (searchBean.getIdentifiers() != null && !searchBean.getIdentifiers().isEmpty()) - || !StringUtils.isBlank(searchBean.getNameLike()); - - } - - /** - * // Method returns the intersection of two lists - * - * @param list1_ - * @param list2_ - * @return merged intersection list - */ - public static List intersection(List list1_, List list2_) { - - List list1 = list1_; - List list2 = list2_; - - list1 = createClientListIfEmpty(list1); - - list2 = createClientListIfEmpty(list2); - - if (list1.isEmpty() && list2.isEmpty()) { - return new ArrayList(); - } - - if (list1.isEmpty() && !list2.isEmpty()) { - return list2; - } - - if (list2.isEmpty() && !list1.isEmpty()) { - return list1; - } - - List list = new ArrayList(); - - for (Client t : list1) { - if (contains(list2, t)) { - list.add(t); - } - } - - return list; - } - - public static List createClientListIfEmpty(List list_) { - List list = list_; - - if (list == null) { - list = new ArrayList(); - } - - return list; - } - - public static boolean contains(List clients, Client c) { - if (clients == null || clients.isEmpty() || c == null || c.getBaseEntityId() == null) { - return false; - } - for (Client client : clients) { - - if (client != null && client.getBaseEntityId() != null - && c.getBaseEntityId().equals(client.getBaseEntityId())) { - - return true; - - } - } - return false; - } - - public static String getContactPhoneNumberParam(HttpServletRequest request) { - //Search by mother contact number - String MOTHER_GUARDIAN_PHONE_NUMBER = "mother_contact_phone_number"; - String CONTACT_PHONE_NUMBER = "contact_phone_number"; - String motherGuardianPhoneNumber = RestUtils.getStringFilter(MOTHER_GUARDIAN_PHONE_NUMBER, request); - motherGuardianPhoneNumber = StringUtils.isBlank(motherGuardianPhoneNumber) - ? RestUtils.getStringFilter(CONTACT_PHONE_NUMBER, request) - : motherGuardianPhoneNumber; - - 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(); - for (Client child : children) { - for (Client mother : mothers) { - String relationalId = getRelationalId(child, RELATIONSHIP_KEY); - String motherEntityId = mother.getBaseEntityId(); - if (relationalId != null && relationalId.equalsIgnoreCase(motherEntityId)) { - childMotherList.add(new ChildMother(child, mother)); - } - } - } - - return childMotherList; - } - - public static String getRelationalId(Client c, String relationshipKey) { - Map> relationships = c.getRelationships(); - if (relationships != null) { - for (Map.Entry> entry : relationships.entrySet()) { - String key = entry.getKey(); - if (key.equalsIgnoreCase(relationshipKey)) { - List rList = entry.getValue(); - if (!rList.isEmpty()) { - return rList.get(0); - } - } - } - } - - return null; - } + return limit; + } + + public static Integer setCoreFilters(JSONObject jsonObject, ClientSearchBean searchBean) throws ParseException { + + Integer limit = !jsonObject.optString("limit").equals("") ? Integer.parseInt(jsonObject.optString("limit")) + : jsonObject.optInt("limit"); + if (limit == 0) { + limit = 100; + } + + DateTime[] lastEdit = RestUtils.getDateRangeFilter(LAST_UPDATE, jsonObject);//TODO client by provider id + if (lastEdit != null) { + searchBean.setLastEditFrom(lastEdit[0]); + searchBean.setLastEditTo(lastEdit[1]); + } + + return limit; + } + + /** + * Here we check to see if the search entity param is valid for use in child search Some form of + * reflections and custom annotations might have been better + * + * @param searchBean model with search params + * @return boolean whether the search entity is valid + */ + + public static boolean isSearchValid(ClientSearchBean searchBean) { + + return !StringUtils.isBlank(searchBean.getFirstName()) + || !StringUtils.isBlank(searchBean.getMiddleName()) + || !StringUtils.isBlank(searchBean.getLastName()) + || !StringUtils.isBlank(searchBean.getGender()) + || (searchBean.getAttributes() != null && !searchBean.getAttributes().isEmpty()) + || searchBean.getBirthdateFrom() != null || searchBean.getBirthdateTo() != null + || searchBean.getLastEditFrom() != null || searchBean.getLastEditTo() != null + || (searchBean.getIdentifiers() != null && !searchBean.getIdentifiers().isEmpty()) + || !StringUtils.isBlank(searchBean.getNameLike()); + + } + + /** + * // Method returns the intersection of two lists + * + * @param list1_ + * @param list2_ + * @return merged intersection list + */ + public static List intersection(List list1_, List list2_) { + + List list1 = list1_; + List list2 = list2_; + + list1 = createClientListIfEmpty(list1); + + list2 = createClientListIfEmpty(list2); + + if (list1.isEmpty() && list2.isEmpty()) { + return new ArrayList(); + } + + if (list1.isEmpty() && !list2.isEmpty()) { + return list2; + } + + if (list2.isEmpty() && !list1.isEmpty()) { + return list1; + } + + List list = new ArrayList(); + + for (Client t : list1) { + if (contains(list2, t)) { + list.add(t); + } + } + + return list; + } + + public static List createClientListIfEmpty(List list_) { + List list = list_; + + if (list == null) { + list = new ArrayList(); + } + + return list; + } + + public static boolean contains(List clients, Client c) { + if (clients == null || clients.isEmpty() || c == null || c.getBaseEntityId() == null) { + return false; + } + for (Client client : clients) { + + if (client != null && client.getBaseEntityId() != null + && c.getBaseEntityId().equals(client.getBaseEntityId())) { + + return true; + + } + } + return false; + } + + public static String getContactPhoneNumberParam(HttpServletRequest request) { + //Search by mother contact number + String MOTHER_GUARDIAN_PHONE_NUMBER = "mother_contact_phone_number"; + String CONTACT_PHONE_NUMBER = "contact_phone_number"; + String motherGuardianPhoneNumber = RestUtils.getStringFilter(MOTHER_GUARDIAN_PHONE_NUMBER, request); + motherGuardianPhoneNumber = StringUtils.isBlank(motherGuardianPhoneNumber) + ? RestUtils.getStringFilter(CONTACT_PHONE_NUMBER, request) + : motherGuardianPhoneNumber; + + 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(); + for (Client child : children) { + for (Client mother : mothers) { + String relationalId = getRelationalId(child, RELATIONSHIP_KEY); + String motherEntityId = mother.getBaseEntityId(); + if (relationalId != null && relationalId.equalsIgnoreCase(motherEntityId)) { + childMotherList.add(new ChildMother(child, mother)); + } + } + } + + return childMotherList; + } + + public static String getRelationalId(Client c, String relationshipKey) { + Map> relationships = c.getRelationships(); + if (relationships != null) { + for (Map.Entry> entry : relationships.entrySet()) { + String key = entry.getKey(); + if (key.equalsIgnoreCase(relationshipKey)) { + List rList = entry.getValue(); + if (!rList.isEmpty()) { + return rList.get(0); + } + } + } + } + + return null; + } } diff --git a/src/test/java/org/opensrp/web/rest/SearchResourceTest.java b/src/test/java/org/opensrp/web/rest/SearchResourceTest.java index bccefa531..493dc874b 100755 --- a/src/test/java/org/opensrp/web/rest/SearchResourceTest.java +++ b/src/test/java/org/opensrp/web/rest/SearchResourceTest.java @@ -8,14 +8,18 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; +import org.opensrp.repository.PlanRepository; +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.smartregister.domain.Client; import org.opensrp.repository.ClientsRepository; import org.opensrp.repository.EventsRepository; -import org.opensrp.repository.PlanRepository; import org.opensrp.repository.SearchRepository; -import org.opensrp.service.*; import org.opensrp.web.rest.it.TestWebContextLoader; import org.opensrp.web.utils.SearchHelper; -import org.smartregister.domain.Client; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.test.context.ContextConfiguration; @@ -27,88 +31,85 @@ import java.util.List; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(loader = TestWebContextLoader.class, locations = { "classpath:test-webmvc-config.xml", }) +@ContextConfiguration(loader = TestWebContextLoader.class, locations = {"classpath:test-webmvc-config.xml",}) public class SearchResourceTest { - - @Autowired - protected WebApplicationContext webApplicationContext; - - private SearchService searchService; - - private ClientService clientService; - - private EventService eventService; - - private ExportEventDataMapper exportEventDataMapper; - - - 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); - ClientsRepository clientRepository = Mockito.mock(ClientsRepository.class); - EventsRepository eventsRepository = Mockito.mock(EventsRepository.class); - - searchService = Mockito.spy(new SearchService(searchRepository)); - clientService = Mockito.spy(new ClientService(clientRepository)); - eventService = Mockito.spy(new EventService(eventsRepository, clientService,taskGenerator,planRepository, exportEventDataMapper)); - - } - - @Test - public void testInstantanceCreatesCorrectly() { - - SearchResource searchResource = new SearchResource(searchService, clientService, eventService); - Assert.assertNotNull(searchResource); - - } - - @Test - public void testIntersectionMethodReturnsCorrectResult() throws Exception { - - Client clientA = Mockito.mock(Client.class); - List listA = Arrays.asList(new Client[] { clientA }); - List result = SearchHelper.intersection(null, listA); - - Assert.assertNotNull(result); - Assert.assertEquals(listA, result); - - } - @Test - public void shouldSearchClient() throws ParseException { - mockHttpServletRequest = new MockHttpServletRequest(); - mockHttpServletRequest.addParameter("ff", "ona"); - mockHttpServletRequest.addParameter("phone_number", phoneNumber); - mockHttpServletRequest.addParameter("alt_phone_number", phoneNumber); - 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); - List clients = searchResource.search(mockHttpServletRequest); - Assert.assertNotNull(clients); - } - - @Test - public void shouldSearchClientPost() 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); - - } + + @Autowired + protected WebApplicationContext webApplicationContext; + + private SearchService searchService; + + private ClientService clientService; + + private EventService eventService; + + private ExportEventDataMapper exportEventDataMapper; + + + private TaskGenerator taskGenerator; + + private PlanRepository planRepository; + + MockHttpServletRequest mockHttpServletRequest; + String phoneNumber = "0727000000"; + String firstName = "name"; + DateTime birthDate = new DateTime(0l, DateTimeZone.UTC); + + @Before + public void setUp() { + SearchRepository searchRepository = Mockito.mock(SearchRepository.class); + ClientsRepository clientRepository = Mockito.mock(ClientsRepository.class); + EventsRepository eventsRepository = Mockito.mock(EventsRepository.class); + + searchService = Mockito.spy(new SearchService(searchRepository)); + clientService = Mockito.spy(new ClientService(clientRepository)); + eventService = Mockito.spy(new EventService(eventsRepository, clientService, taskGenerator, planRepository, exportEventDataMapper)); + + } + + @Test + public void testInstantanceCreatesCorrectly() { + + SearchResource searchResource = new SearchResource(searchService, clientService, eventService); + Assert.assertNotNull(searchResource); + + } + + @Test + public void testIntersectionMethodReturnsCorrectResult() throws Exception { + + Client clientA = Mockito.mock(Client.class); + List listA = Arrays.asList(new Client[]{clientA}); + List result = SearchHelper.intersection(null, listA); + + Assert.assertNotNull(result); + Assert.assertEquals(listA, result); + + } + + @Test + public void shouldSearchClientWithGetRequest() throws ParseException { + mockHttpServletRequest = new MockHttpServletRequest(); + mockHttpServletRequest.addParameter("ff", "ona"); + mockHttpServletRequest.addParameter("phone_number", phoneNumber); + mockHttpServletRequest.addParameter("alt_phone_number", phoneNumber); + 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); + 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); + + } } From e59baa5d9df09d8dce43fe94d866db2bfad2e73a Mon Sep 17 00:00:00 2001 From: hilpitome Date: Wed, 23 Nov 2022 09:48:50 +0300 Subject: [PATCH 9/9] rename searchByPath methods --- src/main/java/org/opensrp/web/rest/SearchResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opensrp/web/rest/SearchResource.java b/src/main/java/org/opensrp/web/rest/SearchResource.java index 436ba16a3..713919661 100644 --- a/src/main/java/org/opensrp/web/rest/SearchResource.java +++ b/src/main/java/org/opensrp/web/rest/SearchResource.java @@ -172,7 +172,7 @@ public List searchByPost(@RequestBody String jsonRequestBody) throws Par } @RequestMapping(method = RequestMethod.GET, value = "/path", produces = {MediaType.APPLICATION_JSON_VALUE}) - private List searchPathBy(HttpServletRequest request) throws ParseException { + private List searchPathByGet(HttpServletRequest request) throws ParseException { String contactPhoneNumber = SearchHelper.getContactPhoneNumberParam(request); SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(request); @@ -182,7 +182,7 @@ private List searchPathBy(HttpServletRequest request) throws ParseE } @RequestMapping(method = RequestMethod.POST, value = "/path", produces = {MediaType.APPLICATION_JSON_VALUE}) - private List searchPathBy(@RequestBody String jsonRequestBody) throws ParseException { + private List searchPathByPost(@RequestBody String jsonRequestBody) throws ParseException { JSONObject jsonRequestBodyObject = new JSONObject(jsonRequestBody); SearchEntityWrapper childSearchEntity = SearchHelper.childSearchParamProcessor(jsonRequestBodyObject);