hapifhir / hapi-fhir

🔥 HAPI FHIR - Java API for HL7 FHIR Clients and Servers
http://hapifhir.io
Apache License 2.0
2.04k stars 1.33k forks source link

hapi-fhir-spring-boot-sample-server-jpa does not support Bundle transactions #1256

Open bmh10 opened 5 years ago

bmh10 commented 5 years ago

Issue We are trying to use HAPI FHIR Spring Boot Sample (https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jpa) as a base to work from, however we noticed that it does not seem to support Bundle transactions out of the box. After spinning up the server and trying to POST a Bundle with type set to 'transaction' the server responds with 400 - This is the base URL of FHIR server. Unable to handle this request, as it does not contain a resource type or operation name.

We have looked at some of the other sample JPA servers available and they all seem to support Bundle transactions, however they are using old style Servlets and web.xml rather than Spring Boot which we would like to avoid (most of our projects use Spring Boot and so a lot of our internal tooling depends on it).

Would be great to know if there is a simple fix for this.

Environment

Additional context We noticed when using the HAPI FHIR Spring Boot Sample that the /metadata endpoint does not include:

"interaction": [ { "code": "history-system" }, { "code": "transaction" } which seems to be present for some of the other example servers.

Many Thanks!

jamesagnew commented 5 years ago

@mouellet any thoughts?

c-schuler commented 5 years ago

Any update on this? I am migrating my HAPI JPA server to spring-boot and am blocked by this issue.

KevinMayfield commented 5 years ago

Have you tried modifying the other examples to use spring boot?

In my SpringBootServletInitializer

@Bean public ServletRegistrationBean ServletRegistrationBean() {

    ServletRegistrationBean registration = new ServletRegistrationBean(new JpaRestfulServer(context), "/STU3/*");
    Map<String,String> params = new HashMap<>();
    params.put("FhirVersion","DSTU3");
    params.put("ImplementationDescription","LTHT FHIR CDR");
    registration.setInitParameters(params);
    registration.setName("FhirServlet");
    registration.setLoadOnStartup(1);
    return registration;
}

Modified the JpaRestful server

@WebServlet(urlPatterns = { "/STU3/*" }, displayName = "FHIR CDR Server") public class JpaRestfulServer extends RestfulServer {

private static final long serialVersionUID = 1L;

private ApplicationContext appCtx;

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(JpaRestfulServer.class);

JpaRestfulServer(ApplicationContext context) {

    // This is called from spring boot
    this.appCtx = context;

}

On 27 Mar 2019, at 16:45, Ben notifications@github.com wrote:

Issue We are trying to use HAPI FHIR Spring Boot Sample (https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jpa https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jpa) as a base to work from, however we noticed that it does not seem to support Bundle transactions out of the box. After spinning up the server and trying to POST a Bundle with type set to 'transaction' the server responds with 400 - This is the base URL of FHIR server. Unable to handle this request, as it does not contain a resource type or operation name.

We have looked at some of the other sample JPA servers available and they all seem to support Bundle transactions, however they are using old style Servlets and web.xml rather than Spring Boot which we would like to avoid (most of our projects use Spring Boot and so a lot of our internal tooling depends on it).

Would be great to know if there is a simple fix for this.

Environment

HAPI FHIR Version: 3.7.0 OS: Mac Browser: N/A Additional context We noticed when using the HAPI FHIR Spring Boot Sample that the /metadata endpoint does not include:

"interaction": [ { "code": "history-system" }, { "code": "transaction" } which seems to be present for some of the other example servers.

Many Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/jamesagnew/hapi-fhir/issues/1256, or mute the thread https://github.com/notifications/unsubscribe-auth/AG3Y8kWnK0X3Ro3pz1e27capmtLb3UHqks5va6AxgaJpZM4cOR_-.

jamesagnew commented 5 years ago

Unfortunately I'm not really sure what to do here.

The Spring Boot stuff was a community contribution, which is awesome, but it hasn't been maintained and I don't use Boot so I'm not in a position to do so.

I guess the right thing probably is to put out a call on the mailing list for a new owner and to deprecate if nobody steps up.

carloscaverobarca commented 5 years ago

@jamesagnew we are also migrating from the JPA server to Spring Boot. So we will evaluate internally if we can take over the Spring project and we will let you know.

c-schuler commented 5 years ago

I was able to repro the issue on a working server by using the deprecated setPlainProviders() method. Therefore, I believe the issue is the use of that deprecated method in the FhirAutoConfiguration class (https://github.com/jamesagnew/hapi-fhir/blob/master/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/src/main/java/ca/uhn/fhir/spring/boot/autoconfigure/FhirAutoConfiguration.java#L195). That should be registerProviders(systemProviders), right?

mouellet commented 5 years ago

Hi guys,

@c-schuler, looks like your on the right track!

Sorry for not being more active, I've done that for client a while ago and I fear I don't have the time to support it now...

Anyway, the auto-configuration for this project only picks up the existing spring configurations from the underlying modules based on conditions. Just make sure any changes to those underlying spring configurations are be propagated.

mtyler68 commented 5 years ago

Here's how I got it to work and a suggestion for a patch:

In your Spring configuration class, add the following bean:

    @Autowired
    private FhirContext fhirContext;

    @Bean
    public JpaSystemProviderR4 jpaSystemProviderR4() {
        JpaSystemProviderR4 provider = new JpaSystemProviderR4();
        provider.setContext(fhirContext);
        return provider;
    }

And if you don't have a FhirRestfulServerCustomizer, then add one to your Spring configuration class too in order to register the provider above:

    @Bean
    public FhirRestfulServerCustomizer customize(
        List<IResourceProvider> resourceProviders,
        List<PlainProvider> plainProviders) {
        return (server) -> {

            server.setResourceProviders(resourceProviders);
            server.registerProvider(jpaSystemProviderR4());
            server.registerProviders(plainProviders);
        };
    }

Now, you need to modify JpaSystemProviderR4 in hapi-fhir-jpaserver-base and re-compile for your project (this is where patching the class will come in handy for future generations):

package ca.uhn.fhir.jpa.provider.r4;
...
public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle, Meta> {

    ...

    @PostConstruct
    public void initJpaSystemProviderR4() {
        setDao(mySystemDao);
    }
  ...
}

The code to add is the @PostConstruct method that configures the DAO.

Compile and run your Spring app and you'll have transaction bundles as well as a bunch of other operations supported by HAPI.

Please let me know if you need further help as I may have missed something in my explanation.

--Matt