Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
25 changes: 25 additions & 0 deletions fhir/fhir_connector.bal
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,31 @@ public isolated client class FHIRConnector {
return error(string `${FHIR_CONNECTOR_ERROR}: ${e.message()}`, errorDetails = e);
}
}

# Proxies an incoming HTTP request to the FHIR server and returns the upstream response as-is.
#
# + requestUrl - Relative request URL to be forwarded to the configured FHIR server
# + request - Incoming HTTP request to be forwarded as-is
# + return - The upstream HTTP response, with URL rewriting applied when enabled.
@display {label: "Proxy request to FHIR server"}
remote isolated function proxy(@display {label: "Request URL"} string requestUrl,
@display {label: "Incoming Request"} http:Request request)
returns http:Response|FHIRError {
do {
log:printDebug(string `Request URL: ${requestUrl}`);
http:Response result = check self.httpClient->forward(requestUrl, check enrichRequest(request, self.pkjwtHanlder));
if self.urlRewrite {
return generalRewriteServerUrl(result, self.baseUrl, self.replacementURL);
}
return result;
} on fail error e {
log:printDebug(string `${FHIR_CONNECTOR_ERROR}: ${e.message()}`, e);
if e is FHIRError {
return e;
}
return error(string `${FHIR_CONNECTOR_ERROR}: ${e.message()}`, errorDetails = e);
}
}
}

# Waits for the completion of a bulk export file download.
Expand Down
65 changes: 64 additions & 1 deletion fhir/utils.bal
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ isolated function getBundleResponse(http:Response response) returns FHIRResponse
int statusCode = response.statusCode;
json|xml responseBody = check extractResponseBody(response);
map<string> responseHeaders = extractHeadersFromResponse(response);
if (is2xx(statusCode)) {
if (is2xx(statusCode)) {
FHIRResponse fhirResponse = {httpStatusCode: statusCode, 'resource: responseBody, serverResponseHeaders: responseHeaders};
return fhirResponse;
} else {
Expand Down Expand Up @@ -598,6 +598,69 @@ isolated function rewriteServerUrl(FHIRResponse response, string baseUrl, string
}
}

// Replaces base url in all headers and payload content of a generic http:Response.
isolated function generalRewriteServerUrl(http:Response response, string baseUrl, string? replacementUrl = ()) returns http:Response|FHIRError {
if replacementUrl is () {
return response;
}

do {
var rewrite = isolated function(string inputString) returns string {
return re `${baseUrl}`.replaceAll(inputString, <string>replacementUrl);
};

// Rewrite all header values (including multi-value headers)
foreach string headerName in response.getHeaderNames() {
string[] values = check response.getHeaders(headerName);
if values.length() > 0 {
response.removeHeader(headerName);
foreach string value in values {
response.addHeader(headerName, rewrite(value));
}
}
}

string contentType = "";
string contentTypeCheck = "";
string|error contentTypeResult = response.getHeader(http:CONTENT_TYPE);
if contentTypeResult is string {
contentType = contentTypeResult;
contentTypeCheck = contentType.toLowerAscii();
}

// Rewrite payload based on type; fallback to text when possible.
if contentTypeCheck.includes("json") {
json payload = check response.getJsonPayload();
string rewritten = rewrite(payload.toJsonString());
json rewrittenJson = check rewritten.fromJsonString();
response.setPayload(rewrittenJson);
return response;
}

if contentTypeCheck.includes("xml") {
xml payload = check response.getXmlPayload();
string rewritten = rewrite(payload.toString());
xml rewrittenXml = check xml:fromString(rewritten);
response.setPayload(rewrittenXml);
return response;
}

string|error textPayload = response.getTextPayload();
if textPayload is string {
string rewrittenText = rewrite(textPayload);
if contentType == "" {
response.setTextPayload(rewrittenText);
} else {
response.setTextPayload(rewrittenText, contentType = contentType);
}
}

return response;
} on fail var e {
return error FHIRConnectorError(string `${FHIR_CONNECTOR_ERROR}: ${e.message()}`, errorDetails = e);
}
}

isolated function constructHttpConfigs(FHIRConnectorConfig|BulkExportConfig config) returns http:ClientConfiguration {
http:ClientConfiguration httpConfig = {
httpVersion: config.httpVersion,
Expand Down
Loading