Skip to content

Commit

Permalink
Handle secondary terminology server errors properly
Browse files Browse the repository at this point in the history
  • Loading branch information
Grahame Grieve committed Nov 25, 2024
1 parent b519517 commit f41adb9
Show file tree
Hide file tree
Showing 16 changed files with 186 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ public Bundle fetchFeed(String url) {
try {
feed = utils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve history since last update", e);
handleException("An error has occurred while trying to read a bundle", e);
}
return feed;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ public Bundle fetchFeed(String url) {
try {
feed = utils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve history since last update", e);
handleException("An error has occurred while trying to read a bundle", e);
}
return feed;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ public Bundle fetchFeed(String url) {
try {
feed = client.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve history since last update", e);
handleException("An error has occurred while trying to read a bundle", e);
}
return feed;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ public Bundle fetchFeed(String url) {
try {
feed = client.issueGetFeedRequest(new URI(url), withVer(getPreferredResourceFormat(), "4.0"), timeoutLong);
} catch (Exception e) {
handleException(0, "An error has occurred while trying to retrieve history since last update", e);
handleException(0, "An error has occurred while trying to read a bundle", e);
}
return feed;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.hl7.fhir.r4.utils.client.ResourceFormat;
import org.hl7.fhir.utilities.MimeType;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.http.*;
import org.hl7.fhir.utilities.xhtml.XhtmlUtils;

Expand Down Expand Up @@ -179,7 +180,11 @@ protected <T extends Resource> T unmarshalReference(HTTPResult response, String
boolean ok = code >= 200 && code < 300;
if (response.getContent() == null) {
if (!ok) {
throw new EFhirClientException(response.getMessage());
if (Utilities.noString(response.getMessage())) {
throw new EFhirClientException(response.getMessagefromCode());
} else {
throw new EFhirClientException(response.getMessage());
}
} else {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ public Bundle fetchFeed(String url) {
try {
feed = client.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve history since last update", e);
handleException("An error has occurred while trying to read a bundle", e);
}
return feed;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.hl7.fhir.r4b.utils.client.EFhirClientException;
import org.hl7.fhir.r4b.utils.client.ResourceFormat;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.http.*;
import org.hl7.fhir.utilities.xhtml.XhtmlUtils;

Expand Down Expand Up @@ -174,7 +175,11 @@ protected <T extends Resource> T unmarshalReference(HTTPResult response, String
boolean ok = code >= 200 && code < 300;
if (response.getContent() == null) {
if (!ok) {
throw new EFhirClientException(response.getMessage());
if (Utilities.noString(response.getMessage())) {
throw new EFhirClientException(response.getMessagefromCode());
} else {
throw new EFhirClientException(response.getMessage());
}
} else {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,19 @@ public void generateSnapshot(StructureDefinition base, StructureDefinition deriv
}
}

for (int i = 0; i < derived.getSnapshot().getElement().size(); i++) {
ElementDefinition ed = derived.getSnapshot().getElement().get(i);
if (ed.getType().size() > 1) {
List<TypeRefComponent> toRemove = new ArrayList<ElementDefinition.TypeRefComponent>();
for (TypeRefComponent tr : ed.getType()) {
ElementDefinition typeSlice = findTypeSlice(derived.getSnapshot().getElement(), i, ed.getPath(), tr.getWorkingCode());
if (typeSlice != null && typeSlice.prohibited()) {
toRemove.add(tr);
}
}
ed.getType().removeAll(toRemove);
}
}
if (derived.getKind() != StructureDefinitionKind.LOGICAL && !derived.getSnapshot().getElementFirstRep().getType().isEmpty())
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl()));
mappingDetails.update();
Expand Down Expand Up @@ -992,6 +1005,34 @@ public void generateSnapshot(StructureDefinition base, StructureDefinition deriv
}


private ElementDefinition findTypeSlice(List<ElementDefinition> list, int i, String path, String typeCode) {
for (int j = i+1; j < list.size(); j++) {
ElementDefinition ed = list.get(j);
if (pathMatches(path, ed) && typeMatches(ed, typeCode)) {
return ed;
}
}
return null;
}

private boolean pathMatches(String path, ElementDefinition ed) {
String p = ed.getPath();
if (path.equals(p)) {
return true;
}
if (path.endsWith("[x]")) { // it should
path = path.substring(0, path.length()-3);
if (p.startsWith(path) && p.length() > path.length() && !p.substring(path.length()).contains(".")) {
return true;
}
}
return false;
}

private boolean typeMatches(ElementDefinition ed, String typeCode) {
return ed.getType().size() == 1 && typeCode.equals(ed.getTypeFirstRep().getWorkingCode());
}

private void checkTypeParameters(StructureDefinition base, StructureDefinition derived) {
String bt = ToolingExtensions.readStringExtension(base, ToolingExtensions.EXT_TYPE_PARAMETER);
if (!derived.hasExtension(ToolingExtensions.EXT_TYPE_PARAMETER)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ public int compare(T arg1, T arg2) {
private Object lock = new Object(); // used as a lock for the data that follows
protected String version; // although the internal resources are all R5, the version of FHIR they describe may not be

protected final TerminologyClientManager terminologyClientManager = new TerminologyClientManager(new TerminologyClientR5.TerminologyClientR5Factory(), UUID.randomUUID().toString());
private boolean minimalMemory = false;

private Map<String, Map<String, ResourceProxy>> allResourcesById = new HashMap<String, Map<String, ResourceProxy>>();
Expand Down Expand Up @@ -279,6 +278,7 @@ public int compare(T arg1, T arg2) {
protected boolean noTerminologyServer;
private int expandCodesLimit = 1000;
protected org.hl7.fhir.r5.context.ILoggingService logger = new SystemOutLoggingService();
protected final TerminologyClientManager terminologyClientManager = new TerminologyClientManager(new TerminologyClientR5.TerminologyClientR5Factory(), UUID.randomUUID().toString(), logger);
protected Parameters expParameters;
private Map<String, PackageInformation> packages = new HashMap<>();

Expand Down Expand Up @@ -2031,6 +2031,7 @@ public void setCanRunWithoutTerminology(boolean canRunWithoutTerminology) {

public void setLogger(@Nonnull org.hl7.fhir.r5.context.ILoggingService logger) {
this.logger = logger;
getTxClientManager().setLogger(logger);
}

public Parameters getExpansionParameters() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.r5.context.CanonicalResourceManager;
import org.hl7.fhir.r5.context.ILoggingService;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.CodeSystem;
Expand All @@ -27,6 +28,7 @@
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
import org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.TerminologyClientContextUseType;
import org.hl7.fhir.r5.terminologies.client.TerminologyClientManager.ServerOptionList;
import org.hl7.fhir.r5.terminologies.client.TerminologyClientR5.TerminologyClientR5Factory;
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache;
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedCodeSystem;
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedValueSet;
Expand Down Expand Up @@ -86,11 +88,14 @@ public interface ITerminologyClientFactory {
}

public class InternalLogEvent {
private boolean error;
private String message;
private String server;
private String vs;
private String systems;
private String choices;
private String context;
private String request;
protected InternalLogEvent(String message, String server, String vs, String systems, String choices) {
super();
this.message = message;
Expand All @@ -99,9 +104,12 @@ protected InternalLogEvent(String message, String server, String vs, String syst
this.systems = systems;
this.choices = choices;
}
protected InternalLogEvent(String message) {
protected InternalLogEvent(String message, String ctxt, String request) {
super();
error = true;
this.message = message;
this.context = ctxt;
this.request = request;
}
public String getMessage() {
return message;
Expand All @@ -118,7 +126,15 @@ public String getChoices() {
public String getServer() {
return server;
}

public boolean isError() {
return error;
}
public String getContext() {
return context;
}
public String getRequest() {
return request;
}
}

public static final String UNRESOLVED_VALUESET = "--unknown--";
Expand All @@ -142,10 +158,13 @@ public String getServer() {

private boolean useEcosystem;

public TerminologyClientManager(ITerminologyClientFactory factory, String cacheId) {
private ILoggingService logger;

public TerminologyClientManager(ITerminologyClientFactory factory, String cacheId, ILoggingService logger) {
super();
this.factory = factory;
this.cacheId = cacheId;
this.logger = logger;
}

public String getCacheId() {
Expand Down Expand Up @@ -346,11 +365,11 @@ private ServerOptionList decideWhichServer(String url) {
}
return ret;
} catch (Exception e) {
String msg = "Error resolving system "+url+": "+e.getMessage()+" ("+request+")";
String msg = "Error resolving system "+url+": "+e.getMessage();
if (!hasMessage(msg)) {
internalLog.add(new InternalLogEvent(msg));
internalLog.add(new InternalLogEvent(msg, url, request));
}
if (!monitorServiceURL.contains("tx.fhir.org")) {
if (logger.isDebugLogging()) {
e.printStackTrace();
}
}
Expand Down Expand Up @@ -571,12 +590,13 @@ public SourcedValueSet findValueSetOnServer(String canonical) {
ValueSet vs = (ValueSet) client.getClient().read("ValueSet", rid);
return new SourcedValueSet(server, vs);
} catch (Exception e) {
e.printStackTrace();
String msg = "Error resolving valueSet "+canonical+": "+e.getMessage()+" ("+request+")";
String msg = "Error resolving valueSet "+canonical+": "+e.getMessage();
if (!hasMessage(msg)) {
internalLog.add(new InternalLogEvent(msg));
internalLog.add(new InternalLogEvent(msg, canonical, request));
}
if (logger.isDebugLogging()) {
e.printStackTrace();
}
e.printStackTrace();
return null;
}
}
Expand Down Expand Up @@ -651,12 +671,13 @@ public SourcedCodeSystem findCodeSystemOnServer(String canonical) {
CodeSystem vs = (CodeSystem) client.getClient().read("CodeSystem", rid);
return new SourcedCodeSystem(server, vs);
} catch (Exception e) {
e.printStackTrace();
String msg = "Error resolving valueSet "+canonical+": "+e.getMessage()+" ("+request+")";
String msg = "Error resolving CodeSystem "+canonical+": "+e.getMessage();
if (!hasMessage(msg)) {
internalLog.add(new InternalLogEvent(msg));
internalLog.add(new InternalLogEvent(msg, canonical, request));
}
if (logger.isDebugLogging()) {
e.printStackTrace();
}
e.printStackTrace();
return null;
}
}
Expand All @@ -673,4 +694,14 @@ public boolean supportsSystem(String system) throws IOException {
public List<InternalLogEvent> getInternalLog() {
return internalLog;
}

public ILoggingService getLogger() {
return logger;
}

public void setLogger(ILoggingService logger) {
this.logger = logger;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ private String presentExpected(String expected) {
case "$url$": return "\"A URL\"";
case "$token$": return "\"A Token\"";
case "$version$": return variables.containsKey("version") ? variables.get("version") : "(anything)";
case "$semver$": return "A semver";
default: return "Unhandled template: "+expected;
}
}
Expand Down Expand Up @@ -558,6 +559,7 @@ private boolean matches(String actualJsonString, String expectedJsonString) {
case "$id$": return actualJsonString.matches("[A-Za-z0-9\\-\\.]{1,64}");
case "$url$": return actualJsonString.matches("(https?://|www\\.)[-a-zA-Z0-9+&@#/%?=~_|!:.;]*[-a-zA-Z0-9+&@#/%=~_|]");
case "$token$": return actualJsonString.matches("[0-9a-zA-Z_][0-9a-zA-Z_\\.\\-]*");
case "$semver$": return actualJsonString.matches("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
case "$version$": return matchesVariable(actualJsonString, "version");
default:
throw new Error("Unhandled template: "+expectedJsonString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ public Bundle fetchFeed(String url) {
try {
feed = client.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
} catch (Exception e) {
handleException(0, "An error has occurred while trying to retrieve history since last update", e);
handleException(0, "An error has occurred while trying to read a bundle", e);
}
return feed;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.hl7.fhir.r5.utils.client.ResourceFormat;
import org.hl7.fhir.utilities.MimeType;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.http.*;
import org.hl7.fhir.utilities.xhtml.XhtmlUtils;

Expand Down Expand Up @@ -162,7 +163,11 @@ protected <T extends Resource> T unmarshalReference(HTTPResult response, String
boolean ok = code >= 200 && code < 300;
if (response.getContent() == null) {
if (!ok) {
throw new EFhirClientException(code, response.getMessage());
if (Utilities.noString(response.getMessage())) {
throw new EFhirClientException(code, response.getMessagefromCode());
} else {
throw new EFhirClientException(code, response.getMessage());
}
} else {
return null;
}
Expand Down
Loading

0 comments on commit f41adb9

Please sign in to comment.