diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java index dcb35b414d8..b543db2985f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java @@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.config; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.i18n.HapiLocalizer; +import ca.uhn.fhir.jpa.dao.DaoRegistry; import ca.uhn.fhir.jpa.model.interceptor.executor.InterceptorService; import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; @@ -72,6 +73,9 @@ public abstract class BaseConfig implements SchedulingConfigurer { @Autowired protected Environment myEnv; + @Autowired + protected DaoRegistry myDaoRegistry; + @Override public void configureTasks(@Nonnull ScheduledTaskRegistrar theTaskRegistrar) { theTaskRegistrar.setTaskScheduler(taskScheduler()); @@ -174,6 +178,13 @@ public abstract class BaseConfig implements SchedulingConfigurer { return new InterceptorService("hapi-fhir-jpa"); } + /** + * Subclasses may override + */ + protected boolean isSupported(String theResourceType) { + return myDaoRegistry.getResourceDao(theResourceType) != null; + } + public static void configureEntityManagerFactory(LocalContainerEntityManagerFactoryBean theFactory, FhirContext theCtx) { theFactory.setJpaDialect(hibernateJpaDialect(theCtx.getLocalizer())); theFactory.setPackagesToScan("ca.uhn.fhir.jpa.model.entity", "ca.uhn.fhir.jpa.entity"); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoRegistry.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoRegistry.java index cdd8b0913f0..5695b16f313 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoRegistry.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoRegistry.java @@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao; * 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. @@ -32,10 +32,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @Component("myDaoRegistry") @@ -47,6 +44,17 @@ public class DaoRegistry implements ApplicationContextAware { private volatile Map> myResourceNameToResourceDao; private volatile IFhirSystemDao mySystemDao; + private Set mySupportedResourceTypes; + + public void setSupportedResourceTypes(Collection theSupportedResourceTypes) { + HashSet supportedResourceTypes = new HashSet<>(); + if (theSupportedResourceTypes != null) { + supportedResourceTypes.addAll(theSupportedResourceTypes); + } + mySupportedResourceTypes = supportedResourceTypes; + myResourceNameToResourceDao = null; + + } @Override public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException { @@ -103,7 +111,9 @@ public class DaoRegistry implements ApplicationContextAware { for (IFhirResourceDao nextResourceDao : theResourceDaos) { RuntimeResourceDefinition nextResourceDef = myContext.getResourceDefinition(nextResourceDao.getResourceType()); - myResourceNameToResourceDao.put(nextResourceDef.getName(), nextResourceDao); + if (mySupportedResourceTypes == null || mySupportedResourceTypes.contains(nextResourceDef.getName())) { + myResourceNameToResourceDao.put(nextResourceDef.getName(), nextResourceDao); + } } } @@ -128,4 +138,16 @@ public class DaoRegistry implements ApplicationContextAware { public IFhirResourceDao getSubscriptionDao() { return getResourceDao(ResourceTypeEnum.SUBSCRIPTION.getCode()); } + + public void setSupportedResourceTypes(String... theResourceTypes) { + setSupportedResourceTypes(toCollection(theResourceTypes)); + } + + private List toCollection(String[] theResourceTypes) { + List retVal = null; + if (theResourceTypes != null && theResourceTypes.length > 0) { + retVal = Arrays.asList(theResourceTypes); + } + return retVal; + } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java index 49e99f77006..9963fdbab00 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java @@ -64,7 +64,7 @@ public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test { protected static ISearchCoordinatorSvc mySearchCoordinatorSvc; private static GenericWebApplicationContext ourWebApplicationContext; private static SubscriptionMatcherInterceptor ourSubscriptionMatcherInterceptor; - private static Server ourServer; + protected static Server ourServer; protected IGenericClient ourClient; ResourceCountCache ourResourceCountsCache; private TerminologyUploaderProviderR4 myTerminologyUploaderProvider; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderOnlySomeResourcesProvidedR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderOnlySomeResourcesProvidedR4Test.java new file mode 100644 index 00000000000..182785f483f --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderOnlySomeResourcesProvidedR4Test.java @@ -0,0 +1,135 @@ +package ca.uhn.fhir.jpa.provider.r4; + +import ca.uhn.fhir.jpa.config.TestR4Config; +import ca.uhn.fhir.jpa.dao.DaoConfig; +import ca.uhn.fhir.jpa.dao.DaoRegistry; +import ca.uhn.fhir.jpa.entity.Search; +import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; +import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; +import ca.uhn.fhir.jpa.util.JpaConstants; +import ca.uhn.fhir.jpa.util.TestUtil; +import ca.uhn.fhir.model.api.TemporalPrecisionEnum; +import ca.uhn.fhir.model.primitive.InstantDt; +import ca.uhn.fhir.model.primitive.UriDt; +import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.parser.StrictErrorHandler; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.api.PreferReturnEnum; +import ca.uhn.fhir.rest.api.SummaryEnum; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.api.IHttpRequest; +import ca.uhn.fhir.rest.client.api.IHttpResponse; +import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor; +import ca.uhn.fhir.rest.gclient.StringClientParam; +import ca.uhn.fhir.rest.param.*; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; +import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; +import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; +import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; +import ca.uhn.fhir.util.StopWatch; +import ca.uhn.fhir.util.UrlUtil; +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.*; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicNameValuePair; +import org.hamcrest.Matchers; +import org.hl7.fhir.instance.model.api.*; +import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator; +import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.Bundle.*; +import org.hl7.fhir.r4.model.Encounter.EncounterLocationComponent; +import org.hl7.fhir.r4.model.Encounter.EncounterStatus; +import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender; +import org.hl7.fhir.r4.model.Narrative.NarrativeStatus; +import org.hl7.fhir.r4.model.Observation.ObservationStatus; +import org.hl7.fhir.r4.model.Questionnaire.QuestionnaireItemType; +import org.hl7.fhir.r4.model.Subscription.SubscriptionChannelType; +import org.hl7.fhir.r4.model.Subscription.SubscriptionStatus; +import org.junit.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.util.AopTestUtils; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.annotation.PostConstruct; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.math.BigDecimal; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.stream.Collectors; + +import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +@SuppressWarnings("Duplicates") +@ContextConfiguration(classes = {ResourceProviderOnlySomeResourcesProvidedR4Test.OnlySomeResourcesProvidedCtxConfig.class}) +public class ResourceProviderOnlySomeResourcesProvidedR4Test extends BaseResourceProviderR4Test { + + @Test + public void testCreateUnsupportedType() { + Patient pt1 = new Patient(); + pt1.addName().setFamily("Elizabeth"); + ourClient.create().resource(pt1).execute(); + + Practitioner pract = new Practitioner(); + pract.setActive(true); + try { + ourClient.create().resource(pract).execute(); + } catch (InvalidRequestException e) { + assertEquals("", e.getMessage()); + } + } + + @org.springframework.context.annotation.Configuration + public static class OnlySomeResourcesProvidedCtxConfig { + + @Autowired + private DaoRegistry myDaoRegistry; + + @Bean + public RegistryConfigurer registryConfigurer() { + return new RegistryConfigurer(myDaoRegistry); + } + + + public static class RegistryConfigurer { + private final DaoRegistry myDaoRegistry; + + public RegistryConfigurer(DaoRegistry theDaoRegistry) { + myDaoRegistry = theDaoRegistry; + } + + @PostConstruct + public void start() { + myDaoRegistry.setSupportedResourceTypes("Patient", "Person", "SearchParameter"); + } + + } + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + +} diff --git a/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans_java.vm b/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans_java.vm index bad24d8db58..cc5d7a443d9 100644 --- a/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans_java.vm +++ b/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans_java.vm @@ -26,13 +26,6 @@ import ca.uhn.fhir.jpa.dao.*; @Configuration public abstract class BaseJavaConfig${versionCapitalized} extends ca.uhn.fhir.jpa.config${package_suffix}.Base${versionCapitalized}Config { - /** - * Subclasses may override - */ - protected boolean isSupported(String theResourceType) { - return true; - } - @Bean(name="myResourceProviders${versionCapitalized}") public List resourceProviders${versionCapitalized}() { List retVal = new ArrayList();