Don't crash when a multitenant server has a request for /
This commit is contained in:
parent
fb327c60cd
commit
a395e48cd4
|
@ -49,6 +49,7 @@ ca.uhn.fhir.parser.ParserState.wrongResourceTypeFound=Incorrect resource type fo
|
|||
ca.uhn.fhir.rest.server.RestfulServer.getPagesNonHttpGet=Requests for _getpages must use HTTP GET
|
||||
ca.uhn.fhir.rest.server.RestfulServer.unknownMethod=Invalid request: The FHIR endpoint on this server does not know how to handle {0} operation[{1}] with parameters [{2}]
|
||||
ca.uhn.fhir.rest.server.RestfulServer.rootRequest=This is the base URL of FHIR server. Unable to handle this request, as it does not contain a resource type or operation name.
|
||||
ca.uhn.fhir.rest.server.RestfulServer.rootRequest.multitenant=This is the base URL of a multitenant FHIR server. Unable to handle this request, as it does not contain a tenant ID.
|
||||
ca.uhn.fhir.validation.ValidationContext.unableToDetermineEncoding=Unable to determine encoding (e.g. XML / JSON) on validation input. Is this a valid FHIR resource body?
|
||||
ca.uhn.fhir.validation.FhirValidator.noPhlocWarningOnStartup=Phloc-schematron library not found on classpath, will not attempt to perform schematron validation
|
||||
ca.uhn.fhir.validation.FhirValidator.noPhlocError=Phloc-schematron library not found on classpath, can not enable perform schematron validation
|
||||
|
@ -94,4 +95,3 @@ ca.uhn.fhir.jpa.term.BaseHapiTerminologySvc.cannotCreateDuplicateCodeSystemUri=C
|
|||
ca.uhn.fhir.jpa.term.BaseHapiTerminologySvc.expansionTooLarge=Expansion of ValueSet produced too many codes (maximum {0}) - Operation aborted!
|
||||
ca.uhn.fhir.jpa.term.BaseHapiTerminologySvc.expansionTooLarge=Expansion of ValueSet produced too many codes (maximum {0}) - Operation aborted!
|
||||
|
||||
|
|
@ -250,9 +250,14 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
String linkSelf;
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(serverBase);
|
||||
|
||||
if (isNotBlank(theRequest.getRequestPath())) {
|
||||
b.append('/');
|
||||
b.append(theRequest.getRequestPath());
|
||||
if (isNotBlank(theRequest.getTenantId()) && theRequest.getRequestPath().startsWith(theRequest.getTenantId() + "/")) {
|
||||
b.append(theRequest.getRequestPath().substring(theRequest.getTenantId().length() + 1));
|
||||
} else {
|
||||
b.append(theRequest.getRequestPath());
|
||||
}
|
||||
}
|
||||
// For POST the URL parameters get jumbled with the post body parameters so don't include them, they might be huge
|
||||
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
|
||||
|
|
|
@ -20,12 +20,17 @@ package ca.uhn.fhir.rest.server.tenant;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.i18n.HapiLocalizer;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.UrlPathTokenizer;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
|
||||
|
||||
/**
|
||||
* This class is a tenant identification strategy which assumes that a single path
|
||||
* element will be present between the server base URL and the beginning
|
||||
|
@ -36,11 +41,17 @@ public class UrlBaseTenantIdentificationStrategy implements ITenantIdentificatio
|
|||
|
||||
@Override
|
||||
public void extractTenant(UrlPathTokenizer theUrlPathTokenizer, RequestDetails theRequestDetails) {
|
||||
String tenantId = null;
|
||||
if (theUrlPathTokenizer.hasMoreTokens()) {
|
||||
String tenantId = theUrlPathTokenizer.nextToken();
|
||||
tenantId = defaultIfBlank(theUrlPathTokenizer.nextToken(), null);
|
||||
ourLog.trace("Found tenant ID {} in request string", tenantId);
|
||||
theRequestDetails.setTenantId(tenantId);
|
||||
}
|
||||
|
||||
if (tenantId == null) {
|
||||
HapiLocalizer localizer = theRequestDetails.getServer().getFhirContext().getLocalizer();
|
||||
throw new InvalidRequestException(localizer.getMessage(RestfulServer.class, "rootRequest.multitenant"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
@ -83,8 +84,9 @@ public class MultitenancyR4Test {
|
|||
assertEquals("bar", ourIdentifiers.getValuesAsQueryTokens().get(0).getValuesAsQueryTokens().get(0).getValue());
|
||||
|
||||
Bundle resp = ourCtx.newJsonParser().parseResource(Bundle.class, responseContent);
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
ourLog.debug(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
|
||||
assertEquals("http://localhost:" + ourPort + "/TENANT2/Patient?identifier=foo%7Cbar", resp.getLink("self").getUrl());
|
||||
assertEquals("http://localhost:" + ourPort + "/TENANT2/Patient/0", resp.getEntry().get(0).getFullUrl());
|
||||
assertEquals("http://localhost:"+ourPort+"/TENANT2/Patient/0", resp.getEntry().get(0).getResource().getId());
|
||||
assertThat(resp.getLink("next").getUrl(), startsWith("http://localhost:"+ourPort+"/TENANT2?_getpages="));
|
||||
|
@ -93,6 +95,16 @@ public class MultitenancyR4Test {
|
|||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
}
|
||||
|
||||
// GET the root
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/");
|
||||
status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
assertEquals(400, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, containsString("\"diagnostics\":\"This is the base URL of a multitenant FHIR server. Unable to handle this request, as it does not contain a tenant ID.\""));
|
||||
} finally {
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
Loading…
Reference in New Issue