ICI/uddi - Is the "country" categoryBag required? Should it be? (CONNECT 4.4.1)

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

ICI/uddi - Is the "country" categoryBag required? Should it be? (CONNECT 4.4.1)

johnhd
This post was updated on .
Hello,

I thought I'd ask a broad question and paste in an email where I described a problem we ran into because of it.

For a given businessEntity...

<businessEntity> 
 ....
     <categoryBag>
          <keyedReference keyName="United States" keyValue="US" tModelKey="uddi:uddi.org:ubr:categorization:iso3166"/>
     </categoryBag> 
</businessEntity>

Is the "categoryBag" attached to each businessEntity in internalConnectionInfo.xml (and uddiConnectionInfo.xml) actually required? Or is it an artifact of the implementation maybe?

It seems informational at best. However, when it's not present, it will cause a nullPointerException for any query at all (EDIT:  not quite... Per my comment below, if the bad entry is "above" the entry you're querying for, then this will occur. Vise versa, it will not. I believe UDDI is checked first, from top to bottom, THEN InternalConnectionInfo is checked, likely also from top to bottom, but haven't confirmed)

(as per my case below).

Full stacktrace:

[#|2015-11-13T14:04:47.383-0800|SEVERE|glassfish3.1.2|gov.hhs.fha.nhinc.patientdiscovery.outbound.StandardOutboundPatientDiscovery|_ThreadID=416;_ThreadName=Thread-2;|Exception occurred while getting responses from communities
java.lang.NullPointerException
	at gov.hhs.fha.nhinc.connectmgr.ConnectionManagerCacheHelper.getStates(ConnectionManagerCacheHelper.java:94)
	at gov.hhs.fha.nhinc.connectmgr.ConnectionManagerCache.filterByRegion(ConnectionManagerCache.java:551)
	at gov.hhs.fha.nhinc.connectmgr.ConnectionManagerCache.getEndpointURLFromNhinTargetCommunities(ConnectionManagerCache.java:904)
	at gov.hhs.fha.nhinc.patientdiscovery.outbound.StandardOutboundPatientDiscovery.getEndpoints(StandardOutboundPatientDiscovery.java:378)
	at gov.hhs.fha.nhinc.patientdiscovery.outbound.StandardOutboundPatientDiscovery.getResponseFromCommunities(StandardOutboundPatientDiscovery.java:167)
	at gov.hhs.fha.nhinc.patientdiscovery.outbound.StandardOutboundPatientDiscovery.respondingGatewayPRPAIN201305UV02(StandardOutboundPatientDiscovery.java:132)
	at gov.hhs.fha.nhinc.patientdiscovery.outbound.StandardOutboundPatientDiscovery$$FastClassByCGLIB$$2a321407.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:50)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
	at gov.hhs.fha.nhinc.patientdiscovery.outbound.StandardOutboundPatientDiscovery$$EnhancerByCGLIB$$78bab07d.respondingGatewayPRPAIN201305UV02(<generated>)
	at gov.hhs.fha.nhinc.patientdiscovery._10.entity.EntityPatientDiscoveryImpl.respondingGatewayPRPAIN201305UV02(EntityPatientDiscoveryImpl.java:49)
	at gov.hhs.fha.nhinc.patientdiscovery._10.gateway.ws.EntityPatientDiscoveryUnsecured.respondingGatewayPRPAIN201305UV02(EntityPatientDiscoveryUnsecured.java:68)
	at gov.hhs.fha.nhinc.patientdiscovery._10.gateway.ws.EntityPatientDiscoveryUnsecured$$FastClassByCGLIB$$a8225b7d.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:50)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
	at gov.hhs.fha.nhinc.patientdiscovery._10.gateway.ws.EntityPatientDiscoveryUnsecured$$EnhancerByCGLIB$$39e5b82f.respondingGatewayPRPAIN201305UV02(<generated>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180)
	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
	at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.invoke(AbstractJAXWSMethodInvoker.java:178)
	at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:68)
	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:75)
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:107)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:239)
	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:218)
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:198)
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:137)
	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:158)
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:243)
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:163)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:688)
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:219)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:745)
|#]

When I reviewed this code with our developer, we noticed that the surrounding code in ConnectionManagerCacheHelper had some null checking, but this particular portion (reading in the country code ~line 94) didn't.

Struck us as an oversight maybe? We patched our local version to swallow the NPE, deployed, and tried again to get around this (worked).

Bottom line I wanted to sort out is:

1) Is this required? If so, I'd suggest some clearer error logging.
2) If not, this missing-state should probably be accounted for?

I'll file a JIRA to this effect after some discussion :)


 Hello,

I ran into some issues this past week that cost me a ton of time and I wanted to share my observations with Sequioa to help others avoid the same fate.

I'm using CONNECT 4.4.1, and I hooked up a test environment to the validation UDDI successfully on Wednesday & Friday (I watched the UDDI download & update no problem).

However, when I fired off a query to an endpoint in my internalConnectionInfo.xml configuration file (unrelated!) I wound up getting a very vague NullPointerException and my request never even made it out of my server (FULL stacktrace attached for readability).

[#|2015-11-13T14:04:47.383-0800|SEVERE|glassfish3.1.2|gov.hhs.fha.nhinc.patientdiscovery.outbound.StandardOutboundPatientDiscovery|_ThreadID=416;_ThreadName=Thread-2;|Exception occurred while getting responses from communities
java.lang.NullPointerException
        at gov.hhs.fha.nhinc.connectmgr.ConnectionManagerCacheHelper.getStates(ConnectionManagerCacheHelper.java:94)
        at gov.hhs.fha.nhinc.connectmgr.ConnectionManagerCache.filterByRegion(ConnectionManagerCache.java:551)
        ...
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
        at java.lang.Thread.run(Thread.java:745)
|#]

After floundering for a while I dragged in a developer to help me debug the CONNECT code itself to find out what was null.

Line 94 of ConnectionManagerCacheHelper, as it turns out, is looking for an categoryBag node on a given businessEnitity. I've gathered that this is run against *each* endpoint in uddiConnectionInfo for every outbound query (and, I presume, internalConnectionInfo too).

If this (required?) field doesn't appear, it attempts to iterate through a null list and throws an unhandled NPE and fails out at that point (despite the fact that my endpoint was in internalConnectionInfo!!!).

TL;DR: if any businessEntity is missing this categoryBag node (which identifies the state/region represented), it breaks outbound queries from CONNECT 4.4.1 (and maybe other versions).

The two endpoints that were missing this field were:

uddi:OrionHealthGWVAL01:2.16.840.1.113883.3.89.200.6.3.1.0
uddi:IODIncorporatedGWVAL01:2.16.840.1.113883.3.914

I was able to work around this by deleting the entire businessEntity in the UDDI (and disabling refresh). (Although I suspect adding a generic one would have worked as well:)

<businessEntity> 
 ....
     <categoryBag>
          <keyedReference keyName="United States" keyValue="US" tModelKey="uddi:uddi.org:ubr:categorization:iso3166"/>
     </categoryBag> 
</businessEntity>

Glancing at the surrounding code, it looks like this probably was an oversight in CONNECT itself not to include NPE handling (no idea if newer versions addressed this), but I wanted to reach out and see if these entries could be corrected to help others avoid this....

Well... I just checked again and the freshest UDDI seems to have the identifierBag for my two offending organizations above, so maybe this has been corrected?

Oh well...
Reply | Threaded
Open this post in threaded view
|

Re: ICI/uddi - Is the "country" categoryBag required? Should it be? (CONNECT 4.4.1)

drodrigues
Administrator
Thank you for the question John and for your review of the CONNECT code as well. We have created a ticket(CONN-1628) to research this. I looked at the specs some and from the underlying UDDI specification - https://www.oasis-open.org/committees/uddi-spec/doc/spec/v3/uddi-v3.0.2-20041019.htm, it seems that the categoryBag for the BusinessEntity is optional. However in the NwHIN specs utilized by the eHealth Exchange i.e., NwHIN Web Service Registry Specification v3.0, indicate that this information is provided by the NHIO. It however does not say SHALL Vs SHOULD Vs MAY. The samples in the web service registry specification show the CategoryBag populated with the geographic location. This would be a good question for the spec factory to validate spec interpretation as well as understanding what is the current practice and/or requirements at the eHealth Exchange for populating the UDDI.
We will be looking at the code from an internal connection info NPE handling perspective and will keep you posted.

Thanks,
Deepthi
CONNECT Product Team
Reply | Threaded
Open this post in threaded view
|

Re: ICI/uddi - Is the "country" categoryBag required? Should it be? (CONNECT 4.4.1)

johnhd
For reference, here's the code post-modification that we changed in ConnectionManagerCacheHelper:

public List<String> getStates(BusinessEntity businessEntity) {
		List<String> result = new ArrayList<String>();

		if (businessEntity.getCategoryBag() != null) {
			for (KeyedReference reference : businessEntity.getCategoryBag().getKeyedReference()) {
				String key = reference.getTModelKey();
				String value = reference.getKeyValue();
				if (UDDI_STATE_KEY.equals(key)) {
					result.add(value);
				}
			}
		}
		if (result.size() <= 0) {
			result = null;
		}
		return result;
	}

Although I'd like to point out a larger issue here- the endpoints that were missing this categoryBag were not the endpoints I was querying, which implies that CONNECT is going through every single businessEntity on a pretty granular level in some kind of sequential scan, for every query. Seems inefficient, and it creates a fairly wide point of failure in cases like this.

Not sure if it's feasible to modify this, but just wanted to bring it up.
Reply | Threaded
Open this post in threaded view
|

Re: ICI/uddi - Is the "country" categoryBag required? Should it be? (CONNECT 4.4.1)

johnhd
In reply to this post by johnhd
Slight update after running into this again (on a different instance of CONNECT 4.4.1 where we didn't have the patch I mentioned above in-place)

We were pointed to the Sequoia Validation UDDI. Turns out that one of the nodes was missing the categoryBag altogether.

This one:

    <businessEntity businessKey="uddi:OrionHealthGWVAL01:2.16.840.1.113883.3.89.200.6.3.1.0">
        <name xml:lang="en">Orion Health GWVAL01</name>
        <description xml:lang="en">OID:2.16.840.1.113883.3.89.200.6.3.1.0 HIE Vendor</description>
        <contacts>
            <contact useType="">

At the end, it skips straight from identifierBag to the closing \businessEntity tag.:

        <identifierBag>
            <keyedReference tModelKey="uddi:nhin:nhie:homecommunityid" keyName="" keyValue="2.16.840.1.113883.3.89.200.6.3.1.0"/>
        </identifierBag>
    </businessEntity>

Adding an arbitrarily filled out categoryBag like so got me past this issue:

</identifierBag>
        <categoryBag>
            <keyedReference tModelKey="uddi:uddi.org:ubr:categorization:iso3166" keyName="Texas" keyValue="US-TX"/>
        </categoryBag>
    </businessEntity>

A few more points of clarification:

I wanted to specify that this occurs when I'm pointed to the Sequoia VALIDATION environment: registry-vs.nhinonline.net/uddi/inqury

I'm able to reproduce this by removing any businessEntity's categoryBag (with state information in it) that is closer to the top of the UDDI than the endpoint I'm trying to query, suggesting it fails out in a linear search from top-to-bottom.

I'd like to point out that even "bad" information "works", though, such as these examples I found along the way:

<categoryBag>
   <keyedReference tModelKey="uddi:uddi.org:ubr:categorization:iso3166" keyName="Maryland" keyValue="US-MD"/>
   <keyedReference tModelKey="uddi:nhin:nhie:publickey" keyName="" keyValue="Available via download from Entrust site"/>
</categoryBag>
 
<categoryBag>
   <keyedReference tModelKey="uddi:nhin:standard-servicenames" keyName="HIEM" keyValue="HIEM"/>
   <keyedReference tModelKey="uddi:nhin:standard-servicenames" keyName="notificationproducer" keyValue="notificationproducer"/>
</categoryBag>
 
<categoryBag>            
            <keyedReference tModelKey="uddi:nhin:nhie:publickey" keyName="" keyValue="Not Published"/>
            <keyedReference tModelKey="uddi:uddi.org:ubr:categorization:iso3166" keyName="Ohio" keyValue="US-OH"/>
</categoryBag>
Reply | Threaded
Open this post in threaded view
|

Re: ICI/uddi - Is the "country" categoryBag required? Should it be? (CONNECT 4.4.1)

Sovann Huynh
Administrator
In reply to this post by johnhd
Hi John, I've posed this question to the Exchange spec factory. Here's the link so you can follow along:

http://exchange-specifications.wikispaces.com/share/view/77125321
Sovann
CONNECT Product Team Member
Reply | Threaded
Open this post in threaded view
|

Re: ICI/uddi - Is the "country" categoryBag required? Should it be? (CONNECT 4.4.1)

Sovann Huynh
Administrator
In reply to this post by johnhd
John, I'm unable to reproduce this issue with the latest CONNECT ear. About to to set up 4.4.1 and give it a go.
Sovann
CONNECT Product Team Member
Reply | Threaded
Open this post in threaded view
|

Re: ICI/uddi - Is the "country" categoryBag required? Should it be? (CONNECT 4.4.1)

Sovann Huynh
Administrator
This issue was discussed during the Feb 3, 2016 eHEX spec factory call and the forum post has been udpated - see http://exchange-specifications.wikispaces.com/share/view/77125321

Although not clearly stated in the specifications, the categoryBag node SHOULD be present and will be for all entries in both the validation and production UDDI going forward. I was also not able to reproduce this issue with CONNECT 4.4.1 and our latest version of CONNECT.

CONN-1628 has been closed
Sovann
CONNECT Product Team Member