Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Gateway ext. enhancements | Search by REL Sync strategy performance optimizations #79

Merged
merged 10 commits into from
Aug 22, 2024
4 changes: 4 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,7 @@ jobs:

- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

- name: Github Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
14 changes: 0 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,20 +300,6 @@ deprecated in favor of the `mode` query parameter.

#### Mode

##### List Resource

When fetching `List` resources, the endpoint returns a list of references which
can then be used to query for the actual resources. With this query parameter
value configured the response is instead a Bundle that contains all the actual
(referenced) resources. To activate this mode, supply a `mode` query parameter
and give it a value of `list-entries`

Example:

```
/List?mode=list-entries
```

#### Pagination

Pagination is supported in fetching the data from a FHIR server. This can be
Expand Down
4 changes: 2 additions & 2 deletions exec/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.smartregister</groupId>
<artifactId>opensrp-gateway-plugin</artifactId>
<version>2.0.5</version>
<version>2.0.6</version>
</parent>

<artifactId>exec</artifactId>
Expand Down Expand Up @@ -70,7 +70,7 @@
<dependency>
<groupId>org.smartregister</groupId>
<artifactId>plugins</artifactId>
<version>2.0.5</version>
<version>2.0.6</version>
</dependency>

<dependency>
Expand Down
2 changes: 1 addition & 1 deletion plugins/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.smartregister</groupId>
<artifactId>opensrp-gateway-plugin</artifactId>
<version>2.0.5</version>
<version>2.0.6</version>
</parent>

<artifactId>plugins</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class Constants {
public static final String PAGINATION_PAGE_NUMBER = "_page";
public static final int PAGINATION_DEFAULT_PAGE_SIZE = 20;
public static final int PAGINATION_DEFAULT_PAGE_NUMBER = 1;
public static final String SYNC_LOCATIONS = "_syncLocations";
public static final String SYNC_LOCATIONS_SEARCH_PARAM = "_syncLocations";
public static final String RELATED_ENTITY_TAG_URL_ENV = "RELATED_ENTITY_TAG_URL";
public static final String DEFAULT_RELATED_ENTITY_TAG_URL =
"https://smartregister.org/related-entity-location-tag-id";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ public List<LocationHierarchy> getLocationHierarchies(
List<String> locationIds,
List<String> preFetchAdminLevels,
List<String> postFetchAdminLevels) {
List<LocationHierarchy> locationHierarchies = new ArrayList<>();
for (String locationId : locationIds) {
locationHierarchies.add(
getLocationHierarchy(locationId, preFetchAdminLevels, postFetchAdminLevels));
}
return locationHierarchies;
return locationIds.parallelStream()
.map(
locationId ->
getLocationHierarchy(
locationId, preFetchAdminLevels, postFetchAdminLevels))
.collect(Collectors.toList());
Comment on lines +84 to +89
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

}

public LocationHierarchy getLocationHierarchyCore(
Expand All @@ -98,7 +98,7 @@ public LocationHierarchy getLocationHierarchyCore(
LocationHierarchyTree locationHierarchyTree = new LocationHierarchyTree();
LocationHierarchy locationHierarchy = new LocationHierarchy();
if (location != null) {
logger.info("Building Location Hierarchy of Location Id : " + locationId);
logger.info("Building Location Hierarchy of Location Id : {}", locationId);

locationHierarchyTree.buildTreeFromList(
filterLocationsByAdminLevels(
Expand All @@ -110,7 +110,7 @@ public LocationHierarchy getLocationHierarchyCore(

locationHierarchy.setLocationHierarchyTree(locationHierarchyTree);
} else {
logger.error("LocationHierarchy with identifier: " + locationId + " not found");
logger.error("LocationHierarchy with identifier: {} not found", locationId);
locationHierarchy.setId(LOCATION_RESOURCE_NOT_FOUND);
}
return locationHierarchy;
Expand Down Expand Up @@ -160,19 +160,25 @@ public List<Location> getDescendants(
Bundle childLocationBundle =
query.usingStyle(SearchStyleEnum.POST).returnBundle(Bundle.class).execute();

List<Location> allLocations = new ArrayList<>();
List<Location> allLocations = Collections.synchronizedList(new ArrayList<>());
if (parentLocation != null) {
allLocations.add(parentLocation);
}

if (childLocationBundle != null) {
for (Bundle.BundleEntryComponent childLocation : childLocationBundle.getEntry()) {
Location childLocationEntity = (Location) childLocation.getResource();
allLocations.add(childLocationEntity);
allLocations.addAll(
getDescendants(
childLocationEntity.getIdElement().getIdPart(), null, adminLevels));
}

childLocationBundle.getEntry().parallelStream()
.forEach(
childLocation -> {
Location childLocationEntity =
(Location) childLocation.getResource();
allLocations.add(childLocationEntity);
allLocations.addAll(
getDescendants(
childLocationEntity.getIdElement().getIdPart(),
null,
adminLevels));
});
}

return allLocations;
Expand Down Expand Up @@ -214,7 +220,7 @@ public Bundle handleNonIdentifierRequest(
PractitionerDetailsEndpointHelper practitionerDetailsEndpointHelper,
DecodedJWT verifiedJwt) {
String mode = request.getParameter(Constants.MODE);
String syncLocationsParam = request.getParameter(Constants.SYNC_LOCATIONS);
String syncLocationsParam = request.getParameter(Constants.SYNC_LOCATIONS_SEARCH_PARAM);
String administrativeLevelMin = request.getParameter(Constants.MIN_ADMIN_LEVEL);
String administrativeLevelMax = request.getParameter(Constants.MAX_ADMIN_LEVEL);
List<String> preFetchAdminLevels =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -287,7 +288,7 @@ private Map<String, List<String>> collateSyncStrategyIds(
PractitionerDetails practitionerDetails,
RequestDetailsReader requestDetailsReader) {
Map<String, List<String>> resultMap;
List<String> syncStrategyIds;
Set<String> syncStrategyIds;

if (StringUtils.isNotBlank(syncStrategy)) {
if (Constants.SyncStrategy.CARE_TEAM.equalsIgnoreCase(syncStrategy)) {
Expand All @@ -301,7 +302,7 @@ private Map<String, List<String>> collateSyncStrategyIds(
careTeams.stream()
.filter(careTeam -> careTeam.getIdElement() != null)
.map(careTeam -> careTeam.getIdElement().getIdPart())
.collect(Collectors.toList());
.collect(Collectors.toSet());

} else if (Constants.SyncStrategy.ORGANIZATION.equalsIgnoreCase(syncStrategy)) {
List<Organization> organizations =
Expand All @@ -316,7 +317,7 @@ private Map<String, List<String>> collateSyncStrategyIds(
organizations.stream()
.filter(organization -> organization.getIdElement() != null)
.map(organization -> organization.getIdElement().getIdPart())
.collect(Collectors.toList());
.collect(Collectors.toSet());

} else if (Constants.SyncStrategy.LOCATION.equalsIgnoreCase(syncStrategy)) {
syncStrategyIds =
Expand All @@ -326,14 +327,14 @@ private Map<String, List<String>> collateSyncStrategyIds(
practitionerDetails
.getFhirPractitionerDetails()
.getLocationHierarchyList())
: new ArrayList<>();
: new HashSet<>();

} else if (Constants.SyncStrategy.RELATED_ENTITY_LOCATION.equalsIgnoreCase(
syncStrategy)) {

Map<String, String[]> parameters =
new HashMap<>(requestDetailsReader.getParameters());
String[] syncLocations = parameters.get(Constants.SYNC_LOCATIONS);
String[] syncLocations = parameters.get(Constants.SYNC_LOCATIONS_SEARCH_PARAM);

if (this.userRoles.contains(Constants.ROLE_ALL_LOCATIONS)
&& syncLocations != null) {
Expand All @@ -355,14 +356,14 @@ private Map<String, List<String>> collateSyncStrategyIds(
practitionerDetails
.getFhirPractitionerDetails()
.getLocationHierarchyList())
: new ArrayList<>();
: new HashSet<>();
}

} else
throw new IllegalStateException(
"'" + syncStrategy + "' sync strategy NOT supported!!");

resultMap = Map.of(syncStrategy, syncStrategyIds);
resultMap = Map.of(syncStrategy, new ArrayList<>(syncStrategyIds));

} else
throw new IllegalStateException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private Bundle getAttributedPractitionerDetailsByPractitioner(Practitioner pract

List<LocationHierarchy> locationHierarchies =
getLocationsHierarchy(supervisorCareTeamOrganizationLocationIds);
List<String> attributedLocationsList = getAttributedLocations(locationHierarchies);
Set<String> attributedLocationsList = getAttributedLocations(locationHierarchies);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the use of sets here.

List<String> attributedOrganizationIds =
getOrganizationIdsByLocationIds(attributedLocationsList);

Expand Down Expand Up @@ -158,7 +158,7 @@ private Bundle getAttributedPractitionerDetailsByPractitioner(Practitioner pract
}

@NotNull
public static List<String> getAttributedLocations(List<LocationHierarchy> locationHierarchies) {
public static Set<String> getAttributedLocations(List<LocationHierarchy> locationHierarchies) {
List<ParentChildrenMap> parentChildrenList =
locationHierarchies.stream()
.flatMap(
Expand Down Expand Up @@ -186,10 +186,10 @@ public static List<String> getAttributedLocations(List<LocationHierarchy> locati
.map(
locationHierarchy ->
locationHierarchy.getLocationId().getValue()))
.collect(Collectors.toList());
.collect(Collectors.toSet());
}

private List<String> getOrganizationIdsByLocationIds(List<String> attributedLocationsList) {
private List<String> getOrganizationIdsByLocationIds(Set<String> attributedLocationsList) {
if (attributedLocationsList == null || attributedLocationsList.isEmpty()) {
return new ArrayList<>();
}
Expand Down Expand Up @@ -371,7 +371,7 @@ private List<PractitionerRole> getPractitionerRolesByPractitionerId(String pract
private Set<String> getOrganizationIdsByPractitionerRoles(
List<PractitionerRole> practitionerRoles) {
return practitionerRoles.stream()
.filter(practitionerRole -> practitionerRole.hasOrganization())
.filter(PractitionerRole::hasOrganization)
.map(it -> getReferenceIDPart(it.getOrganization().getReference()))
.collect(Collectors.toSet());
}
Expand Down Expand Up @@ -569,18 +569,19 @@ private List<OrganizationAffiliation> mapBundleToOrganizationAffiliation(
}

public static List<LocationHierarchy> getLocationsHierarchy(List<String> locationsIdentifiers) {
List<LocationHierarchy> locationHierarchyList = new ArrayList<>();
LocationHierarchyEndpointHelper locationHierarchyEndpointHelper =
new LocationHierarchyEndpointHelper(r4FHIRClient);
LocationHierarchy locationHierarchy;
for (String locationsIdentifier : locationsIdentifiers) {
locationHierarchy =
locationHierarchyEndpointHelper.getLocationHierarchy(
locationsIdentifier, null, null);
if (!org.smartregister.utils.Constants.LOCATION_RESOURCE_NOT_FOUND.equals(
locationHierarchy.getId())) locationHierarchyList.add(locationHierarchy);
}
return locationHierarchyList;

return locationsIdentifiers.parallelStream()
.map(
locationsIdentifier ->
locationHierarchyEndpointHelper.getLocationHierarchy(
locationsIdentifier, null, null))
.filter(
locationHierarchy ->
!org.smartregister.utils.Constants.LOCATION_RESOURCE_NOT_FOUND
.equals(locationHierarchy.getId()))
.collect(Collectors.toList());
}

public static String createSearchTagValues(Map.Entry<String, String[]> entry) {
Expand Down
Loading
Loading