Stream: hapi
Topic: hapi-fhir: issue 291: Enhance HAPI RestfulServer to suppo...
Zulip HAPI Bot (Feb 03 2016 at 14:39):
fw060 opened issue 291
We have encountered an issue in RestfulServer.bindMethod when we trying to add a resource provider using CDI in JBoss Wildfly environment (see code below).
In this setup, the resource provider passed in to RestfulServer is not PatientProvider class, but a proxy class generated by JBoss. Then bindMethod would have trouble inspect getPatient method in PatientProvider. After some investigating, we find out that this is caused by the issue that Jboss Proxy loses generic type information (see https://issues.jboss.org/browse/WELD-1539). This will lead to error when bindMethod trying to inspect getPatient method which would return a List of Patient. bindMethod can only see List without any generic type so a null pointer exception would happen.
This is NOT an issue in HAPI, however, maybe solving this issue in HAPI is the cleanest way since other CDI environment might have similar problem.
Our current thought is to create a new method:
public void addResourceProvider(IResourceProvider theResourceProvider, Class theProviderClass)
which would allow designating the Provider class rather than deceiving provider class from the provider instance itself.I will be more than happy to provide any more detailed information. If anyone has a better/cleaner solution, please also let us know. I will provider the pull request hopefully today or tomorrow.
Thanks!
Feipublic class FhirRestfulServlet extends RestfulServer {
@Inject
PatientProvider patientProvider = null;public FhirRestfulServlet() { super(FhirContext.forDstu2()); } @Override protected void initialize() throws ServletException { /* * The servlet defines any number of resource providers, and * configures itself to use them by calling * setResourceProviders() */ List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>(); resourceProviders.add(this.patientProvider); setResourceProviders(resourceProviders); }}
public class PatientProvider implements IResourceProvider {
@Search() public List<Patient> getPatient(@RequiredParam(name = Patient.SP_IDENTIFIER) StringParam identifier) {}
}
Zulip HAPI Bot (Feb 03 2016 at 18:57):
jamesagnew commented on issue 291
Hi Fei,
Interesting problem :)
Is the issue that because of the proxy that Weld creates, the server sees
@Search() public List getPatient(@RequiredParam(name = Patient.SP_IDENTIFIER) StringParam identifier) {instead of
@Search() public List<Patient> getPatient(@RequiredParam(name = Patient.SP_IDENTIFIER) StringParam identifier) {?
I'm actually kind of surprised this would be an issue- The
IResourceProvider
interface has thegetResourceType()
method which the server uses to explicitly find out what resource type is being used. I guess that isn't working for some reason in this case though.Is there any error message or stack trace you see? Could you paste that in here?
Zulip HAPI Bot (Feb 03 2016 at 21:03):
Hi James,
Yes that is the exactly the problem! :)The stack trace is attached. The exact issue is that the line 424 in BaseMethodBinding (with latest snapshot):
returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
would return null for the Proxy class because the line 88 in ReflectionUtil would not return ParameterizedType instance.Thanks,
Fei===============================================
2016-02-03 15:48:57,541 ERROR [io.undertow.request] [LMMFW/ANONYMOUS:NO_HTTP_CONTEXT@default task-1] UT005023: Exception handling request to /gil/fhir/Observation/39624754: javax.servlet.ServletException: Failed to initialize FHIR Restful server
at ca.uhn.fhir.rest.server.RestfulServer.init(RestfulServer.java:747)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:214)
at io.undertow.servlet.core.ManagedServlet.getServlet(ManagedServlet.java:157)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:84)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130)
at org.pcpgm.gis.web.filter.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:29)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at org.pcpgm.gis.web.filter.HttpRequestContextFilter.doFilter(HttpRequestContextFilter.java:38)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at org.pcpgm.gis.web.MDCPopulationFilter.doFilter(MDCPopulationFilter.java:36)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at org.pcpgm.gis.web.filter.TenantStatusAndUserFilter.doFilter(TenantStatusAndUserFilter.java:93)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at org.pcpgm.gis.web.filter.DuplicateRequestFilter.doFilter(DuplicateRequestFilter.java:111)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56)
at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:27)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61)
at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:177)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:727)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at ca.uhn.fhir.rest.method.BaseMethodBinding.isResourceInterface(BaseMethodBinding.java:557)
at ca.uhn.fhir.rest.method.BaseMethodBinding.bindMethod(BaseMethodBinding.java:425)
at ca.uhn.fhir.rest.server.RestfulServer.findResourceMethods(RestfulServer.java:314)
at ca.uhn.fhir.rest.server.RestfulServer.findResourceMethods(RestfulServer.java:303)
at ca.uhn.fhir.rest.server.RestfulServer.registerProviders(RestfulServer.java:1025)
at ca.uhn.fhir.rest.server.RestfulServer.init(RestfulServer.java:729)
... 49 more
Zulip HAPI Bot (Feb 04 2016 at 17:20):
Hi James, I just submitted the pull request. Basically I added a Map from resource type to class and use it later. This is pure optional so the existing functionality should not be impacted. Please let me know what do you think about this.
Thanks!
Fei
Zulip HAPI Bot (Feb 06 2016 at 19:19):
jamesagnew closed issue 291
Zulip HAPI Bot (Feb 06 2016 at 19:21):
jamesagnew commented on issue 291
Hi Fei,
I had a try at creating a unit test to recreate this, and as it turns out I think the issue is really just that we have a check to prevent people returning List<T> of the wrong type, and it was failing if there was no type.
I think that with the fix in https://github.com/jamesagnew/hapi-fhir/commit/0ff111be872a437debff6cfcddaa462c061eb1ad we don't need the extra method from your pull request- are you able to confirm if this fixes things in your setup?
Thanks for all the analysis!
Zulip HAPI Bot (Feb 09 2016 at 14:46):
Hi James,
Yes, your fix works. This was actually the stop gap fix we have been using until we come up with the proposed solution. If the intention of the check is to just to prevent wrong type rather than ensure right type (thus no type is not allowed), then your fix works perfectly. We probably should have checked with you earlier. Thanks again for your time to analyze and fix this!Another question will this fix be in 1.4 or 1.5? It was checked in before version bump but after the 1.4 label was created. Hopefully it is in version 1.4 :)
Thanks!
Fei
Zulip HAPI Bot (Feb 09 2016 at 15:15):
jamesagnew commented on issue 291
Hi Fei,
Yeah, I think just watering the check down is good enough. It's intended to
be a last resort thing, but nothing more. So I think we can call this one
closed :)Unfortunately this fix didn't make it into 1.4. It's already in the most
recent 1.5 snapshot build though, and it'll be a part of the 1.5 release.Cheers,
JamesOn Tue, Feb 9, 2016 at 9:46 AM, fw060 <notifications@github.com> wrote:
Hi James,
Yes, your fix works. This was actually the stop gap fix we have been using
until we come up with the proposed solution. If the intention of the check
is to just to prevent wrong type rather than ensure right type (thus no
type is not allowed), then your fix works perfectly. We probably should
have checked with you earlier. Thanks again for your time to analyze and
fix this!Another question will this fix be in 1.4 or 1.5? It was checked in before
version bump but after the 1.4 label was created. Hopefully it is in
version 1.4 :)Thanks!
Fei—
Reply to this email directly or view it on GitHub
<https://github.com/jamesagnew/hapi-fhir/issues/291#issuecomment-181897662>
.
Zulip HAPI Bot (Feb 09 2016 at 15:25):
Yes, now we can call this closed :)
What is current plan for 1.5 release?
Thanks,
Fei
Zulip HAPI Bot (Feb 09 2016 at 16:17):
jamesagnew commented on issue 291
We don't yet have a release date in mind for 1.5, but snapshots are available now and we have been typically following a 2-3 month release cycle. I would say that at the latest, it will be released before the May HL7 Working Group Meeting.
Zulip HAPI Bot (Feb 10 2016 at 14:53):
Hi James,
May is probably too late for us. So I m exploring other options. We can support our own fork. Another option is to see if 1.4.1 is an option, I m more than willing to help if HAPI team would like to start release maintenance release.Thanks,
Fei
Last updated: Apr 12 2022 at 19:14 UTC