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

Refactor for optimization and benchmarking #48

Open
wants to merge 7 commits into
base: 0.1.32-hotfix
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion exec/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>com.google.fhir.gateway</groupId>
<artifactId>fhir-gateway</artifactId>
<version>0.1.39</version>
<version>0.1.41-LT2</version>
</parent>

<artifactId>exec</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion plugins/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
implementations do not have to do this; they can redeclare those deps. -->
<groupId>com.google.fhir.gateway</groupId>
<artifactId>fhir-gateway</artifactId>
<version>0.1.39</version>
<version>0.1.41-LT2</version>
</parent>

<artifactId>plugins</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@
import org.slf4j.Logger;

public class BenchmarkingHelper {

public static void printMessage(String message, Logger logger) {
logger.info(message);
}

public static void printCompletedInDuration(long startTime, String methodDetails, Logger logger) {
long nanoSecondsTaken = System.nanoTime() - startTime;
long millSecondsTaken = nanoSecondsTaken / 1000000;
logger.info(
String.format(
"########## %s : Metric in seconds - %d : Metric in nanoseconds - %d",
methodDetails, millSecondsTaken / 1000, nanoSecondsTaken));
"%s : Metric in seconds - %.1f : Metric in nanoseconds - %d",
methodDetails, millSecondsTaken / 1000.0, nanoSecondsTaken));
}

public static long startBenchmarking() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2021-2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.fhir.gateway.plugin;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public enum CacheHelper {
INSTANCE;
Cache<String, Map<String, List<String>>> cache;

public CacheHelper getInstance() {
return INSTANCE;
}

CacheHelper() {
cache = Caffeine.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).maximumSize(1_000).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2021-2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.fhir.gateway.plugin;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

public enum HttpHelper {
INSTANCE;

public static HttpHelper getInstance() {
return INSTANCE;
}

HttpHelper() {

PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
new PoolingHttpClientConnectionManager();

if (StringUtils.isNotBlank(System.getenv(MAX_CONNECTION_TOTAL))) {
poolingHttpClientConnectionManager.setMaxTotal(
Integer.valueOf(System.getenv(MAX_CONNECTION_TOTAL)));
}

if (StringUtils.isNotBlank(System.getenv(MAX_CONNECTION_PER_ROUTE))) {
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(
Integer.valueOf(System.getenv(MAX_CONNECTION_PER_ROUTE)));
}

if (StringUtils.isNotBlank(System.getenv(SOCKET_TIMEOUT))) {
SocketConfig socketConfig =
SocketConfig.custom()
.setSoTimeout(Integer.valueOf(System.getenv(SOCKET_TIMEOUT)) * 1000)
.build();
poolingHttpClientConnectionManager.setDefaultSocketConfig(socketConfig);
}

httpClient =
HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build();

genericClient = createFhirClientForR4(FhirContext.forR4());
}

private final CloseableHttpClient httpClient;

public CloseableHttpClient getHttpClient() {
return httpClient;
}

private final IGenericClient genericClient;

public IGenericClient getGenericClient() {
return genericClient;
}

private IGenericClient createFhirClientForR4(FhirContext fhirContext) {
long start = BenchmarkingHelper.startBenchmarking();
String fhirServer = System.getenv(PROXY_TO_ENV);
IGenericClient client = fhirContext.newRestfulGenericClient(fhirServer);
System.out.println(
String.format(
"########## createFhirClientForR4 created in %.1f seconds",
((System.nanoTime() - start) / 1000)));
return client;
}

public static final String SOCKET_TIMEOUT = "GATEWAY_SOCKET_TIMEOUT";
public static final String CONNECTION_REQUEST_TIMEOUT = "GATEWAY_CONNECTION_REQUEST_TIMEOUT";
public static final String CONNECT_TIMEOUT = "GATEWAY_CONNECT_TIMEOUT";
public static final String MAX_CONNECTION_TOTAL = "GATEWAY_MAX_CONNECTION_TOTAL";
public static final String MAX_CONNECTION_PER_ROUTE = "GATEWAY_MAX_CONNECTION_PER_ROUTE";

public static final String PROXY_TO_ENV = "PROXY_TO";
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smartregister.model.location.LocationHierarchy;
import org.smartregister.model.location.ParentChildrenMap;
import org.smartregister.model.practitioner.FhirPractitionerDetails;
import org.smartregister.model.practitioner.PractitionerDetails;
import org.smartregister.utils.Constants;
Expand Down Expand Up @@ -138,9 +137,9 @@ private Bundle getAttributedPractitionerDetailsByPractitioner(Practitioner pract

careTeamList.addAll(attributedCareTeams);

logger.error(
"##### OpenSRPHelper.getAttributedPractitionerDetailsByPractitioner() -> CareTeam List"
+ attributedCareTeams);
BenchmarkingHelper.printMessage(
"getAttributedPractitionerDetailsByPractitioner() -> CareTeam List" + attributedCareTeams,
logger);

for (CareTeam careTeam : careTeamList) {
// Add current supervisor practitioners
Expand Down Expand Up @@ -181,7 +180,7 @@ public static List<String> getAttributedLocations(List<LocationHierarchy> locati

long start = BenchmarkingHelper.startBenchmarking();

List<ParentChildrenMap> parentChildrenList =
List<String> attributedLocationsList =
locationHierarchies.stream()
.flatMap(
locationHierarchy ->
Expand All @@ -190,15 +189,12 @@ public static List<String> getAttributedLocations(List<LocationHierarchy> locati
.getLocationsHierarchy()
.getParentChildren()
.stream())
.collect(Collectors.toList());
List<String> attributedLocationsList =
parentChildrenList.stream()
.flatMap(parentChildren -> parentChildren.getChildIdentifiers().stream())
.map(it -> getReferenceIDPart(it.toString()))
.collect(Collectors.toList());

BenchmarkingHelper.printCompletedInDuration(
start, "getAttributedLocations " + locationHierarchies, logger);
start, "getAttributedLocations " + attributedLocationsList, logger);

return attributedLocationsList;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ public class OpenSRPSyncAccessDecision implements AccessDecision {
private final String syncStrategy;
private final String applicationId;
private final boolean accessGranted;
private final List<String> careTeamIds;
private final List<String> locationIds;
private final List<String> organizationIds;
private final Map<String, List<String>> syncStrategyIds;
private final List<String> roles;
private IgnoredResourcesConfig config;
private String keycloakUUID;
Expand All @@ -74,27 +72,26 @@ public OpenSRPSyncAccessDecision(
String keycloakUUID,
String applicationId,
boolean accessGranted,
List<String> locationIds,
List<String> careTeamIds,
List<String> organizationIds,
Map<String, List<String>> syncStrategyIds,
String syncStrategy,
List<String> roles) {
this.fhirR4Context = fhirContext;
this.keycloakUUID = keycloakUUID;
this.applicationId = applicationId;
this.accessGranted = accessGranted;
this.careTeamIds = careTeamIds;
this.locationIds = locationIds;
this.organizationIds = organizationIds;
this.syncStrategyIds = syncStrategyIds;
this.syncStrategy = syncStrategy;
this.config = getSkippedResourcesConfigs();
this.roles = roles;
long start = BenchmarkingHelper.startBenchmarking();
try {
setFhirR4Client(
fhirR4Context.newRestfulGenericClient(
System.getenv(PermissionAccessChecker.Factory.PROXY_TO_ENV)));
} catch (NullPointerException e) {
logger.error(e.getMessage());
} finally {
BenchmarkingHelper.printCompletedInDuration(start, "constructor setFhirR4Client", logger);
}

this.openSRPHelper = new OpenSRPHelper(fhirR4Client);
Expand All @@ -112,7 +109,7 @@ public RequestMutation getRequestMutation(RequestDetailsReader requestDetailsRea

RequestMutation requestMutation = null;
if (isSyncUrl(requestDetailsReader)) {
if (locationIds.isEmpty() && careTeamIds.isEmpty() && organizationIds.isEmpty()) {
if (syncStrategyIds.isEmpty()) {

ForbiddenOperationException forbiddenOperationException =
new ForbiddenOperationException(
Expand All @@ -128,7 +125,7 @@ public RequestMutation getRequestMutation(RequestDetailsReader requestDetailsRea
// Skip app-wide global resource requests
if (!shouldSkipDataFiltering(requestDetailsReader)) {
List<String> syncFilterParameterValues =
addSyncFilters(getSyncTags(locationIds, careTeamIds, organizationIds));
addSyncFilters(getSyncTags(this.syncStrategy, this.syncStrategyIds));
requestMutation =
RequestMutation.builder()
.queryParams(
Expand Down Expand Up @@ -211,7 +208,7 @@ public String postProcess(RequestDetailsReader request, HttpResponse response)

BenchmarkingHelper.printCompletedInDuration(
start,
"postProcess : params include Gateway mode "
"postProcess : params include Gateway Mode "
+ (gatewayMode != null ? gatewayMode : "Default"),
logger);

Expand Down Expand Up @@ -271,7 +268,7 @@ private Bundle processListEntriesGatewayModeByBundle(IBaseResource responseResou
}

@NotNull
private static Bundle.BundleEntryComponent createBundleEntryComponent(
public static Bundle.BundleEntryComponent createBundleEntryComponent(
Bundle.HTTPVerb method, String requestPath, @Nullable String condition) {

Bundle.BundleEntryComponent bundleEntryComponent = new Bundle.BundleEntryComponent();
Expand Down Expand Up @@ -311,22 +308,25 @@ private Bundle postProcessModeListEntries(IBaseResource responseResource) {
* Generates a map of Code.url to multiple Code.Value which contains all the possible filters that
* will be used in syncing
*
* @param locationIds
* @param careTeamIds
* @param organizationIds
* @param syncStrategy
* @param syncStrategyIds
* @return Pair of URL to [Code.url, [Code.Value]] map. The URL is complete url
*/
private Map<String, String[]> getSyncTags(
List<String> locationIds, List<String> careTeamIds, List<String> organizationIds) {
String syncStrategy, Map<String, List<String>> syncStrategyIds) {
StringBuilder sb = new StringBuilder();
Map<String, String[]> map = new HashMap<>();

sb.append(ProxyConstants.TAG_SEARCH_PARAM);
sb.append(ProxyConstants.Literals.EQUALS);

addTags(ProxyConstants.LOCATION_TAG_URL, locationIds, map, sb);
addTags(ProxyConstants.ORGANISATION_TAG_URL, organizationIds, map, sb);
addTags(ProxyConstants.CARE_TEAM_TAG_URL, careTeamIds, map, sb);
if (ProxyConstants.LOCATION.equals(syncStrategy)) {
addTags(ProxyConstants.LOCATION_TAG_URL, syncStrategyIds.get(syncStrategy), map, sb);
} else if (ProxyConstants.ORGANIZATION.equals(syncStrategy)) {
addTags(ProxyConstants.ORGANISATION_TAG_URL, syncStrategyIds.get(syncStrategy), map, sb);
} else if (ProxyConstants.CARE_TEAM.equals(syncStrategy)) {
addTags(ProxyConstants.CARE_TEAM_TAG_URL, syncStrategyIds.get(syncStrategy), map, sb);
}

return map;
}
Expand Down
Loading