Skip to content

Commit

Permalink
Implement List Mode Content Fetch ⚡️
Browse files Browse the repository at this point in the history
- Support returning all List resource References in result
  • Loading branch information
ndegwamartin committed Jul 6, 2023
1 parent 7be1789 commit 3b9aba8
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public boolean canAccess() {
}

@Override
public String postProcess(HttpResponse response) throws IOException {
public String postProcess(ServletRequestDetails request, HttpResponse response) throws IOException {
Preconditions.checkState(HttpUtil.isResponseValid(response));
String content = CharStreams.toString(HttpUtil.readerFromEntity(response.getEntity()));
IParser parser = fhirContext.newJsonParser();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
*/
package com.google.fhir.gateway.plugin;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import com.google.common.annotations.VisibleForTesting;
import com.google.fhir.gateway.ProxyConstants;
Expand All @@ -36,10 +39,16 @@
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.http.HttpResponse;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.util.TextUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.ListResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.fhir.gateway.plugin.PermissionAccessChecker.Factory.PROXY_TO_ENV;

public class OpenSRPSyncAccessDecision implements AccessDecision {
public static final String SYNC_FILTER_IGNORE_RESOURCES_FILE_ENV =
"SYNC_FILTER_IGNORE_RESOURCES_FILE";
Expand All @@ -56,6 +65,9 @@ public class OpenSRPSyncAccessDecision implements AccessDecision {

private final List<String> organizationIds;
private IgnoredResourcesConfig config;
private Gson gson = new Gson();
private FhirContext fhirR4Context = FhirContext.forR4();
private IParser fhirR4JsonParser = fhirR4Context.newJsonParser();

public OpenSRPSyncAccessDecision(
String applicationId,
Expand Down Expand Up @@ -133,8 +145,54 @@ private void addSyncFilters(
}

@Override
public String postProcess(HttpResponse response) throws IOException {
return null;
public String postProcess(ServletRequestDetails request, HttpResponse response) throws IOException {

String resultContent = null;
String listMode = request.getHeader(Constants.FHIR_GATEWAY_MODE);

switch (listMode) {
case Constants.LIST_ENTRIES:
resultContent = postProcessModeListEntries(response);
default:
break;
}
return resultContent;
}

/**
* Generates a Bundle result from making a batch search request with the contained entries in the List as parameters
* @param response HTTPResponse
* @return String content of the result Bundle
*/
private String postProcessModeListEntries(HttpResponse response) throws IOException {

String resultContent = null;
IBaseResource responseResource = fhirR4JsonParser.parseResource((new BasicResponseHandler().handleResponse(response)));

if (responseResource instanceof ListResource && ((ListResource) responseResource).hasEntry()) {

Bundle requestBundle = new Bundle();
requestBundle.setType(Bundle.BundleType.BATCH);
Bundle.BundleEntryComponent bundleEntryComponent;

for (ListResource.ListEntryComponent listEntryComponent : ((ListResource) responseResource).getEntry()) {

bundleEntryComponent = new Bundle.BundleEntryComponent();
bundleEntryComponent.setRequest(new Bundle.BundleEntryRequestComponent()
.setMethod(Bundle.HTTPVerb.GET)
.setUrl(listEntryComponent.getItem().getReference()));

requestBundle.addEntry(bundleEntryComponent);
}

Bundle responseBundle = createFhirClientForR4().transaction()
.withBundle(requestBundle)
.execute();

resultContent = fhirR4JsonParser.encodeResourceToString(responseBundle);

}
return resultContent;
}

/**
Expand Down Expand Up @@ -214,7 +272,6 @@ private boolean isResourceTypeRequest(String requestPath) {
protected IgnoredResourcesConfig getIgnoredResourcesConfigFileConfiguration(String configFile) {
if (configFile != null && !configFile.isEmpty()) {
try {
Gson gson = new Gson();
config = gson.fromJson(new FileReader(configFile), IgnoredResourcesConfig.class);
if (config == null || config.entries == null) {
throw new IllegalArgumentException("A map with a single `entries` array expected!");
Expand Down Expand Up @@ -285,6 +342,9 @@ private boolean shouldSkipDataFiltering(ServletRequestDetails servletRequestDeta
}
return false;
}
private IGenericClient createFhirClientForR4() {;
return fhirR4Context.newRestfulGenericClient(System.getenv(PROXY_TO_ENV));
}

@VisibleForTesting
protected void setSkippedResourcesConfig(IgnoredResourcesConfig config) {
Expand All @@ -308,4 +368,9 @@ public String toString() {
+ '}';
}
}

public static final class Constants {
public static final String FHIR_GATEWAY_MODE = "fhir-gateway-mode";
public static final String LIST_ENTRIES = "list-entries";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.google.fhir.gateway.plugin;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import com.google.common.io.Resources;
import com.google.fhir.gateway.HttpFhirClient;
import java.io.IOException;
Expand All @@ -39,6 +40,10 @@ public class AccessGrantedAndUpdateListTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private HttpResponse responseMock;


@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private ServletRequestDetails requestDetailsMock;

private static final FhirContext fhirContext = FhirContext.forR4();

private AccessGrantedAndUpdateList testInstance;
Expand All @@ -55,14 +60,14 @@ public void postProcessNewPatientPut() throws IOException {
testInstance =
AccessGrantedAndUpdateList.forPatientResource(
TEST_LIST_ID, httpFhirClientMock, fhirContext);
testInstance.postProcess(responseMock);
testInstance.postProcess(requestDetailsMock,responseMock);
}

@Test
public void postProcessNewPatientPost() throws IOException {
testInstance =
AccessGrantedAndUpdateList.forPatientResource(
TEST_LIST_ID, httpFhirClientMock, fhirContext);
testInstance.postProcess(responseMock);
testInstance.postProcess(requestDetailsMock,responseMock);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public boolean authorizeRequest(RequestDetails requestDetails) {
if (HttpUtil.isResponseValid(response)) {
try {
// For post-processing rationale/example see b/207589782#comment3.
content = outcome.postProcess(response);
content = outcome.postProcess(servletDetails, response);
} catch (Exception e) {
// Note this is after a successful fetch/update of the FHIR store. That success must be
// passed to the client even if the access related post-processing fails.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ public boolean canAccess() {
}

@Override
public String postProcess(HttpResponse response) throws IOException {
public String postProcess(ServletRequestDetails requestDetails, HttpResponse response)
throws IOException {
Preconditions.checkState(HttpUtil.isResponseValid(response));
String content = CharStreams.toString(HttpUtil.readerFromEntity(response.getEntity()));
IParser parser = fhirContext.newJsonParser();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ public interface AccessDecision {
* reads the response; otherwise null. Note that we should try to avoid reading the whole
* content in memory whenever it is not needed for post-processing.
*/
String postProcess(HttpResponse response) throws IOException;
String postProcess(ServletRequestDetails request, HttpResponse response) throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public boolean canAccess() {
}

@Override
public String postProcess(HttpResponse response) {
public String postProcess(ServletRequestDetails request, HttpResponse response) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,9 @@ public RequestMutation getRequestMutation(RequestDetailsReader requestDetailsRea
return RequestMutation.builder().queryParams(paramMutations).build();
}

public String postProcess(HttpResponse response) throws IOException {
@Override
public String postProcess(ServletRequestDetails request, HttpResponse response)
throws IOException {
return null;
}
};
Expand Down

0 comments on commit 3b9aba8

Please sign in to comment.