diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImpl.java index 1012e52c02a..c82d3576430 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImpl.java @@ -177,6 +177,9 @@ public class ResourceReindexingSvcImpl implements IResourceReindexingSvc { @Transactional(Transactional.TxType.NEVER) @Scheduled(fixedDelay = 10 * DateUtils.MILLIS_PER_SECOND) public Integer runReindexingPass() { + if (myDaoConfig.isSchedulingDisabled()) { + return null; + } if (myIndexingLock.tryLock()) { try { return doReindexingPassInsideLock(); diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptor.java index ace45066ee5..68aca58273c 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptor.java @@ -9,9 +9,9 @@ package ca.uhn.fhir.rest.server.interceptor.auth; * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -87,7 +87,7 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter return; } - handleDeny(decision); + handleDeny(theRequestDetails, decision); } @Override @@ -219,6 +219,19 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter return Collections.unmodifiableSet(myFlags); } + /** + * This property configures any flags affecting how authorization is + * applied. By default no flags are applied. + * + * @param theFlags The flags (must not be null) + * @see #setFlags(AuthorizationFlagsEnum...) + */ + public AuthorizationInterceptor setFlags(Collection theFlags) { + Validate.notNull(theFlags, "theFlags must not be null"); + myFlags = new HashSet<>(theFlags); + return this; + } + /** * This property configures any flags affecting how authorization is * applied. By default no flags are applied. @@ -238,6 +251,17 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter * throw {@link ForbiddenOperationException} (HTTP 403) with error message citing the * rule name which trigered failure *

+ * + * @since HAPI FHIR 3.6.0 + */ + protected void handleDeny(RequestDetails theRequestDetails, Verdict decision) { + handleDeny(decision); + } + + /** + * This method should not be overridden. As of HAPI FHIR 3.6.0, you + * should override {@link #handleDeny(RequestDetails, Verdict)} instead. This + * method will be removed in the future. */ protected void handleDeny(Verdict decision) { if (decision.getDecidingRule() != null) { @@ -350,51 +374,6 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter handleUserOperation(theRequest, theNewResource, RestOperationTypeEnum.UPDATE); } - /** - * This property configures any flags affecting how authorization is - * applied. By default no flags are applied. - * - * @param theFlags The flags (must not be null) - * @see #setFlags(AuthorizationFlagsEnum...) - */ - public AuthorizationInterceptor setFlags(Collection theFlags) { - Validate.notNull(theFlags, "theFlags must not be null"); - myFlags = new HashSet<>(theFlags); - return this; - } - - private static UnsupportedOperationException failForDstu1() { - return new UnsupportedOperationException("Use of this interceptor on DSTU1 servers is not supportd"); - } - - static List toListOfResourcesAndExcludeContainer(IBaseResource theResponseObject, FhirContext fhirContext) { - if (theResponseObject == null) { - return Collections.emptyList(); - } - - List retVal; - - boolean isContainer = false; - if (theResponseObject instanceof IBaseBundle) { - isContainer = true; - } else if (theResponseObject instanceof IBaseParameters) { - isContainer = true; - } - - if (!isContainer) { - return Collections.singletonList(theResponseObject); - } - - retVal = fhirContext.newTerser().getAllPopulatedChildElementsOfType(theResponseObject, IBaseResource.class); - - // Exclude the container - if (retVal.size() > 0 && retVal.get(0) == theResponseObject) { - retVal = retVal.subList(1, retVal.size()); - } - - return retVal; - } - private enum OperationExamineDirection { BOTH, IN, @@ -432,4 +411,36 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter } + private static UnsupportedOperationException failForDstu1() { + return new UnsupportedOperationException("Use of this interceptor on DSTU1 servers is not supportd"); + } + + static List toListOfResourcesAndExcludeContainer(IBaseResource theResponseObject, FhirContext fhirContext) { + if (theResponseObject == null) { + return Collections.emptyList(); + } + + List retVal; + + boolean isContainer = false; + if (theResponseObject instanceof IBaseBundle) { + isContainer = true; + } else if (theResponseObject instanceof IBaseParameters) { + isContainer = true; + } + + if (!isContainer) { + return Collections.singletonList(theResponseObject); + } + + retVal = fhirContext.newTerser().getAllPopulatedChildElementsOfType(theResponseObject, IBaseResource.class); + + // Exclude the container + if (retVal.size() > 0 && retVal.get(0) == theResponseObject) { + retVal = retVal.subList(1, retVal.size()); + } + + return retVal; + } + } diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/server/ServerExceptionDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/server/ServerExceptionDstu3Test.java index 70c3f0e4e9b..0612076e290 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/server/ServerExceptionDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/server/ServerExceptionDstu3Test.java @@ -1,13 +1,14 @@ package ca.uhn.fhir.rest.server; -import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; - -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.concurrent.TimeUnit; - +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; +import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; +import com.google.common.base.Charsets; import org.apache.commons.io.IOUtils; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -25,32 +26,32 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.rest.annotation.Search; -import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; -import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; -import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; -import ca.uhn.fhir.util.PortUtil; -import ca.uhn.fhir.util.TestUtil; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; public class ServerExceptionDstu3Test { + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerExceptionDstu3Test.class); + public static BaseServerResponseException ourException; private static CloseableHttpClient ourClient; private static FhirContext ourCtx = FhirContext.forDstu3(); - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerExceptionDstu3Test.class); private static int ourPort; private static Server ourServer; - public static BaseServerResponseException ourException; @Test public void testAddHeadersNotFound() throws Exception { - + OperationOutcome operationOutcome = new OperationOutcome(); operationOutcome.addIssue().setCode(IssueType.BUSINESSRULE); - + ourException = new ResourceNotFoundException("SOME MESSAGE"); ourException.addResponseHeader("X-Foo", "BAR BAR"); - + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient"); CloseableHttpResponse status = ourClient.execute(httpGet); @@ -58,7 +59,7 @@ public class ServerExceptionDstu3Test { String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info(status.getStatusLine().toString()); ourLog.info(responseContent); - + assertEquals(404, status.getStatusLine().getStatusCode()); assertEquals("BAR BAR", status.getFirstHeader("X-Foo").getValue()); assertThat(status.getFirstHeader("X-Powered-By").getValue(), containsString("HAPI FHIR")); @@ -68,21 +69,50 @@ public class ServerExceptionDstu3Test { } + @Test + public void testResponseUsesCorrectEncoding() throws Exception { + + OperationOutcome operationOutcome = new OperationOutcome(); + operationOutcome + .addIssue() + .setCode(IssueType.PROCESSING) + .setSeverity(OperationOutcome.IssueSeverity.ERROR) + .setDiagnostics("El nombre está vacío"); + + ourException = new InternalErrorException("Error", operationOutcome); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=json"); + CloseableHttpResponse status = ourClient.execute(httpGet); + try { + byte[] responseContentBytes = IOUtils.toByteArray(status.getEntity().getContent()); + String responseContent = new String(responseContentBytes, Charsets.UTF_8); + ourLog.info(status.getStatusLine().toString()); + ourLog.info(responseContent); + + assertEquals(400, status.getStatusLine().getStatusCode()); + assertEquals("BAR BAR", status.getFirstHeader("X-Foo").getValue()); + assertThat(status.getFirstHeader("X-Powered-By").getValue(), containsString("HAPI FHIR")); + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + + } + @Test public void testAuthorize() throws Exception { - + OperationOutcome operationOutcome = new OperationOutcome(); operationOutcome.addIssue().setCode(IssueType.BUSINESSRULE); - + ourException = new AuthenticationException().addAuthenticateHeaderForRealm("REALM"); - + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient"); CloseableHttpResponse status = ourClient.execute(httpGet); try { String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info(status.getStatusLine().toString()); ourLog.info(responseContent); - + assertEquals(401, status.getStatusLine().getStatusCode()); assertEquals("Basic realm=\"REALM\"", status.getFirstHeader("WWW-Authenticate").getValue()); } finally { @@ -91,6 +121,20 @@ public class ServerExceptionDstu3Test { } + public static class DummyPatientResourceProvider implements IResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Search() + public List search() { + throw ourException; + } + + } + @AfterClass public static void afterClassClearContext() throws Exception { ourServer.stop(); @@ -121,18 +165,4 @@ public class ServerExceptionDstu3Test { } - public static class DummyPatientResourceProvider implements IResourceProvider { - - @Override - public Class getResourceType() { - return Patient.class; - } - - @Search() - public List search() { - throw ourException; - } - - } - }