Thanks Colm. Much appreciated. At least I can now move on from these random problems that have been plaguing me for weeks!
On Wed, 29 Jan 2020 at 23:38, Colm O hEigeartaigh <[email protected]> wrote: > Hi Mark, > > From the spec: > > "A URI that uniquely identifies this message in time and space. No two > messages with a distinct application intent may share a [message id] > property." > > So I think it is a mistake to re-use MessageIds across multiple partners. > > Colm. > > On Tue, Jan 28, 2020 at 11:00 PM Mark Presling <[email protected]> > wrote: > > > I think I *may* have figured it out. I would appreciate the groups > > feedback on whether I should raise a bug report or not... > > > > Our system is reusing the same MessageID across multiple partners. So > > each Exchange is unique by WSA MessageID AND To (or endpoint address) > > when looking at it from the client calls to the partners. > > > > But it looks as though MAPCodec is caching uncorrelatedExchanges based > > on MessageID only. So if/when we deliver a message using the client > > and then receive an asynchronous response on the endpoint with a > > RelatesTo from Partner A while we are *still delivering* a request to > > Partner B (no synchronous response received yet) then > > MAPCodec.restoreExchange() is returning the OUTBOUND exchange. > > MAPCodec appears to be a singleton across the CXF Bus. > > > > Then DocLiteralInInterceptor is seeing the wrong exchange and fails > > the validation: > > > > Exchange exchange = message.getExchange(); > > BindingOperationInfo bop = exchange.getBindingOperationInfo(); > > BindingMessageInfo msgInfo = bop.getInput(); > > MessagePartInfo p = msgInfo.getMessageParts().get(paramNum); > > /* {http://xyz}IdentifyRequest - WRONG */ > > QName elName = xmlReader.getName(); /* > > {http://xyz}IdentifyResponse - CORRECT */ > > validatePart(p, elName, message); > > > > Do you think that MAPCodec should be changed to cache exchanges > > better, taking into account the direction (inbound vs outbound, client > > vs endpoint) and/or the endpoint address and/or the WSA To/From > > properties (if used)? Or do you think this is purely an error on our > > behalf? I have already raised a request to use a unique MessageID > > across all partners, but still think this is something that could be > > improved (at least with a better exception). > > > > Thanks, > > Mark > > > > On Tue, 28 Jan 2020 at 12:59, Mark Presling <[email protected]> > > wrote: > > > > > > Hi All, > > > > > > CXF 3.3.3, Spring Boot 2.1.9, new mailing list user, first post... > > > > > > > > > org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor.validatePart(DocLiteralInInterceptor.java:281) > > > is throwing an exception while receiving an INBOUND message at my > > > endpoint. This only happens occasionally, and only when a JAX-WS > > > client is sending an OUTBOUND message on a different thread at the > > > same time. > > > > > > The Endpoint and Client use the classes that are generated from the > > > same WSDL using cxf-codegen-plugin (we send the same messages in and > > > out, receiving and sending to multiple partners) and the client is set > > > up with client.setThreadLocalRequestContext(true). > > > > > > A pattern is showing in the logs where whilst a Client is sending out > > > a message of type IdentifyRequest on one thread the endpoint receives > > > a message of type IdentifyResponse on a Tomcat handler thread and > > > fails because it expected a IdentifyRequest (this is an asynchronous > > > message pattern, hence the *Request/Response naming). > > > > > > org.apache.cxf.interceptor.Fault: Unexpected element > > > {http://xyz}IdentifyResponse found. Expected > > > {http://xyz}IdentifyRequest > > > > > > This is then immediately backed up by a NPE: > > > > > > java.lang.NullPointerException: null > > > at > > > org.apache.cxf.interceptor.OutFaultChainInitiatorObserver.addToChain(OutFaultChainInitiatorObserver.java:60) > > > at > > > org.apache.cxf.interceptor.OutFaultChainInitiatorObserver.initializeInterceptors(OutFaultChainInitiatorObserver.java:55) > > > at > > > org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:108) > > > at > > > org.apache.cxf.phase.PhaseInterceptorChain.wrapExceptionAsFault(PhaseInterceptorChain.java:374) > > > at > > > org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:332) > > > at > > > org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) > > > at > > > org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267) > > > at > > > org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) > > > at > > > org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) > > > at > > > org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) > > > at > > > org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:216) > > > at > > > org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301) > > > at > > > org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220) > > > at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) > > > > > > I have traced back all the WS-Addressing headers and SOAP actions for > > > both operations, etc and they are correct. > > > > > > So my only guess at this stage is that there is some sort of context > > > or class sharing going on internally with the CXF generated code > > > between the Endpoint and the Client. Is this possible? Even when the > > > client is set up with a thread-local context? > > > > > > My endpoint is created like this: > > > > > > @Bean > > > public Endpoint identifyEndpoint() { > > > Identify identifyPort = new IdentifyPortImpl(); > > > > > > EndpointImpl endpoint = new EndpointImpl(bus, identifyPort, > > > javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING); > > > endpoint.setWsdlLocation("classpath:/IdentifyService.wsdl"); > > > endpoint.setServiceName(IdentifyService.SERVICE); > > > endpoint.setEndpointName(IdentifyService.IdentifyPort); > > > > > > endpoint.getFeatures().add(new LoggingFeature()); > > > endpoint.getFeatures().add(new WSAddressingFeature()); > > > endpoint.getProperties().put(Message.SCHEMA_VALIDATION_ENABLED, > > true); > > > endpoint.publish("/v1/identify"); > > > > > > return endpoint; > > > } > > > > > > This didn't occur (as far as I know) until we upgraded from 3.1.10 to > > > 3.3.3. Are there any other properties I should be setting? > > > > > > NOTE: As usual, this is only happening in Production whilst under > > > load. As such I cannot simply upgrade to 3.3.5 and/or reproduce it in > > > test at this stage. I'm looking for a "configuration" change that I > > > could sneak through as a hotfix if it's a known issue. > > > > > > Thanks, > > > Mark > > > > > > > >
