Don't crash when a multitenant server has a request for /

This commit is contained in:
jamesagnew 2018-02-04 18:44:37 -05:00
parent fb327c60cd
commit a395e48cd4
4 changed files with 32 additions and 4 deletions

View File

@ -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!

View File

@ -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) {

View File

@ -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

View File

@ -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