Merge pull request #1408 from hapifhir/do-20230824-add-version-to-agent-header

Adds core version to agent string for TerminologyClient headers
This commit is contained in:
Grahame Grieve 2023-08-28 19:48:16 +02:00 committed by GitHub
commit f868e86608
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 23 deletions

View File

@ -200,6 +200,11 @@ public class TerminologyClientR2 implements ITerminologyClient {
return this; return this;
} }
@Override
public String getUserAgent() {
return client.getUserAgent();
}
@Override @Override
public String getServerVersion() { public String getServerVersion() {
return client.getServerVersion(); return client.getServerVersion();

View File

@ -202,6 +202,11 @@ public class TerminologyClientR3 implements ITerminologyClient {
return this; return this;
} }
@Override
public String getUserAgent() {
return client.getUserAgent();
}
@Override @Override
public String getServerVersion() { public String getServerVersion() {
return client.getServerVersion(); return client.getServerVersion();

View File

@ -210,6 +210,11 @@ public class TerminologyClientR4 implements ITerminologyClient {
return this; return this;
} }
@Override
public String getUserAgent() {
return client.getUserAgent();
}
@Override @Override
public String getServerVersion() { public String getServerVersion() {
return client.getServerVersion(); return client.getServerVersion();

View File

@ -190,6 +190,11 @@ public class TerminologyClientR5 implements ITerminologyClient {
return this; return this;
} }
@Override
public String getUserAgent() {
return client.getUserAgent();
}
@Override @Override
public String getServerVersion() { public String getServerVersion() {
return client.getServerVersion(); return client.getServerVersion();

View File

@ -65,4 +65,5 @@ public interface ITerminologyClient {
ClientHeaders getClientHeaders(); ClientHeaders getClientHeaders();
ITerminologyClient setClientHeaders(ClientHeaders clientHeaders); ITerminologyClient setClientHeaders(ClientHeaders clientHeaders);
ITerminologyClient setUserAgent(String userAgent); ITerminologyClient setUserAgent(String userAgent);
String getUserAgent();
} }

View File

@ -34,6 +34,9 @@ import org.hl7.fhir.utilities.json.model.JsonObject;
import org.hl7.fhir.utilities.json.parser.JsonParser; import org.hl7.fhir.utilities.json.parser.JsonParser;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.validation.cli.utils.Common;
import javax.annotation.Nonnull;
public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IValidationPolicyAdvisor, IWorkerContextManager.ICanonicalResourceLocator { public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IValidationPolicyAdvisor, IWorkerContextManager.ICanonicalResourceLocator {
@ -258,14 +261,18 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IV
String root = getRoot(p, url); String root = getRoot(p, url);
if (root != null) { if (root != null) {
ITerminologyClient c; ITerminologyClient terminologyClient = getTerminologyClient(root);
c = TerminologyClientFactory.makeClient("source", root, "fhir/validator", context.getVersion()); return terminologyClient.read(p[p.length - 2], p[p.length - 1]);
return c.read(p[p.length - 2], p[p.length - 1]);
} else { } else {
throw new FHIRException("The URL '" + url + "' is not known to the FHIR validator, and has not been provided as part of the setup / parameters"); throw new FHIRException("The URL '" + url + "' is not known to the FHIR validator, and has not been provided as part of the setup / parameters");
} }
} }
@Nonnull
protected ITerminologyClient getTerminologyClient(String root) throws URISyntaxException {
return TerminologyClientFactory.makeClient("source", root, Common.getValidatorUserAgent(), context.getVersion());
}
private String getRoot(String[] p, String url) { private String getRoot(String[] p, String url) {
if (p.length > 3 && Utilities.isValidId(p[p.length - 1]) && context.getResourceNames().contains(p[p.length - 2])) { if (p.length > 3 && Utilities.isValidId(p[p.length - 1]) && context.getResourceNames().contains(p[p.length - 2])) {
url = url.substring(0, url.lastIndexOf("/")); url = url.substring(0, url.lastIndexOf("/"));

View File

@ -77,6 +77,7 @@ import org.hl7.fhir.validation.cli.renderers.DefaultRenderer;
import org.hl7.fhir.validation.cli.renderers.ESLintCompactRenderer; import org.hl7.fhir.validation.cli.renderers.ESLintCompactRenderer;
import org.hl7.fhir.validation.cli.renderers.NativeRenderer; import org.hl7.fhir.validation.cli.renderers.NativeRenderer;
import org.hl7.fhir.validation.cli.renderers.ValidationOutputRenderer; import org.hl7.fhir.validation.cli.renderers.ValidationOutputRenderer;
import org.hl7.fhir.validation.cli.utils.Common;
import org.hl7.fhir.validation.cli.utils.EngineMode; import org.hl7.fhir.validation.cli.utils.EngineMode;
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation; import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
@ -441,7 +442,7 @@ public class ValidationService {
@Nonnull @Nonnull
protected ValidationEngine buildValidationEngine( CliContext cliContext, String definitions, TimeTracker timeTracker) throws IOException, URISyntaxException { protected ValidationEngine buildValidationEngine( CliContext cliContext, String definitions, TimeTracker timeTracker) throws IOException, URISyntaxException {
System.out.print(" Load FHIR v" + cliContext.getSv() + " from " + definitions); System.out.print(" Load FHIR v" + cliContext.getSv() + " from " + definitions);
ValidationEngine validationEngine = getValidationEngineBuilder().withTHO(false).withVersion(cliContext.getSv()).withTimeTracker(timeTracker).withUserAgent("fhir/validator").fromSource(definitions); ValidationEngine validationEngine = getValidationEngineBuilder().withTHO(false).withVersion(cliContext.getSv()).withTimeTracker(timeTracker).withUserAgent(Common.getValidatorUserAgent()).fromSource(definitions);
System.out.println(" - " + validationEngine.getContext().countAllCaches() + " resources (" + timeTracker.milestone() + ")"); System.out.println(" - " + validationEngine.getContext().countAllCaches() + " resources (" + timeTracker.milestone() + ")");

View File

@ -6,6 +6,8 @@ import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.settings.FhirSettings; import org.hl7.fhir.utilities.settings.FhirSettings;
import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.ValidationEngine;
import javax.annotation.Nonnull;
public class Common { public class Common {
public static String getVersion(String[] args) { public static String getVersion(String[] args) {
@ -70,18 +72,9 @@ public class Common {
return defaultValue; return defaultValue;
} }
/** @Nonnull
* Default validation engine will point to "http://tx.fhir.org" terminology server. public static String getValidatorUserAgent() {
*/ return "fhir/validator/" + VersionUtil.getVersion();
public static ValidationEngine getValidationEngine(String version, String definitions, String txLog, TimeTracker tt) throws Exception {
return getValidationEngine(version, FhirSettings.getTxFhirProduction(), definitions, txLog, tt);
}
public static ValidationEngine getValidationEngine(String version, String txServer, String definitions, String txLog, TimeTracker tt) throws Exception {
System.out.println("Loading (v = " + version + ", tx server -> " + txServer + ")");
ValidationEngine ve = new ValidationEngine.ValidationEngineBuilder().withVersion(version).withTimeTracker(tt).withUserAgent("fhir/validator").fromSource(definitions);
ve.connectToTSServer(txServer, txLog, FhirPublication.fromCode(version));
return ve;
} }
public static boolean isNetworkPath(String path) { public static boolean isNetworkPath(String path) {

View File

@ -0,0 +1,23 @@
package org.hl7.fhir.validation.cli.services;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.terminologies.client.ITerminologyClient;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.validation.cli.utils.VersionUtil;
import org.junit.Test;
import java.net.URISyntaxException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
public class StandAloneValidatorFetcherTests
{
@Test
public void testGetTerminologyClient() throws URISyntaxException {
StandAloneValidatorFetcher standAloneValidatorFetcher = new StandAloneValidatorFetcher(mock(FilesystemPackageCacheManager.class), mock(IWorkerContext.class), mock(IPackageInstaller.class));
ITerminologyClient client = standAloneValidatorFetcher.getTerminologyClient("http://dummyserver/fhir");
assertEquals("fhir/validator/" + VersionUtil.getVersion(), client.getUserAgent());
}
}

View File

@ -35,6 +35,7 @@ import org.hl7.fhir.validation.ValidationEngine;
import org.hl7.fhir.validation.cli.model.CliContext; import org.hl7.fhir.validation.cli.model.CliContext;
import org.hl7.fhir.validation.cli.model.FileInfo; import org.hl7.fhir.validation.cli.model.FileInfo;
import org.hl7.fhir.validation.cli.model.ValidationRequest; import org.hl7.fhir.validation.cli.model.ValidationRequest;
import org.hl7.fhir.validation.cli.utils.VersionUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -228,8 +229,10 @@ class ValidationServiceTest {
return cliContext; return cliContext;
} }
/* This is a particularly long way to test that a single field in ValidationEngine was set. /* This is a particularly long way to test that fields in ValidationEngine are
However, it does provide example code to test other parts of the buildValidationEngine method as well. set to expected default values.
It also provides example code to test other parts of the buildValidationEngine method as well.
*/ */
@Test @Test
public void buildValidationEngineTest() throws IOException, URISyntaxException { public void buildValidationEngineTest() throws IOException, URISyntaxException {
@ -241,12 +244,11 @@ class ValidationServiceTest {
final ValidationEngine validationEngine = mock(ValidationEngine.class); final ValidationEngine validationEngine = mock(ValidationEngine.class);
when(validationEngine.getContext()).thenReturn(workerContext); when(validationEngine.getContext()).thenReturn(workerContext);
final ValidationEngine.ValidationEngineBuilder validationEngineBuilder = mock(ValidationEngine.ValidationEngineBuilder.class);;
final ValidationService validationService = new ValidationService() { final ValidationService validationService = new ValidationService() {
@Override @Override
protected ValidationEngine.ValidationEngineBuilder getValidationEngineBuilder() { protected ValidationEngine.ValidationEngineBuilder getValidationEngineBuilder() {
ValidationEngine.ValidationEngineBuilder validationEngineBuilder = mock(ValidationEngine.ValidationEngineBuilder.class);
when(validationEngineBuilder.withTHO(anyBoolean())).thenReturn(validationEngineBuilder); when(validationEngineBuilder.withTHO(anyBoolean())).thenReturn(validationEngineBuilder);
when(validationEngineBuilder.withVersion(isNull())).thenReturn(validationEngineBuilder); when(validationEngineBuilder.withVersion(isNull())).thenReturn(validationEngineBuilder);
when(validationEngineBuilder.withTimeTracker(any())).thenReturn(validationEngineBuilder); when(validationEngineBuilder.withTimeTracker(any())).thenReturn(validationEngineBuilder);
@ -267,10 +269,10 @@ class ValidationServiceTest {
} }
}; };
CliContext cliContext = new CliContext(); CliContext cliContext = new CliContext();
validationService.buildValidationEngine(cliContext, null, timeTracker); validationService.buildValidationEngine(cliContext, null, timeTracker);
verify(validationEngineBuilder).withUserAgent(eq("fhir/validator/" + VersionUtil.getVersion()));
} }
} }