comment inline

Ron Gavlin wrote:
I was able to workaround this problem by explicitly setting the operation on the eip:pipeline transformer's exchange-target. However, if I use a servicemix-http soap-provider as the transformer instead of a cxfbc:provider, the transformer's exchange-target operation need not be set.
Is there a reason why the cxfbc:provider requires the operation and the 
servicemix-http does not?

I guess the servicemix-http soap-provider here didn't use the jbi wrapper, right, iirc, we've discussed similar issue in [1], the main reason for cxf component didn't extract operation from the message is that in case of using rpc mode, there is no operation info in the JBI wrapper message, also extract operation from the message we need read message content which we avoid for higher performance. Any way, if there is only one operation in the interface, we should support it in the CxfBcProviderMessageObserver.
[1]https://issues.apache.org/activemq/browse/SM-1279
Also, during my research, I noticed that there is some operation-handling code in CxfBcProvider to derive the operation if the interface has only one of them. It appears this logic should also be either included in CxfBcProviderMessageObserver (as listed below) or the calculated BindingOperationInfo in CxfBcProvider should be passed in the constructor into CxfBcProviderMessageObserver.
Let me know if I should open a JIRA for this issue.

Yeah, open jira in case the interface only have one operation
Thanks,

- Ron

CxfBcProviderMessageObserver.java
...
    public void onMessage(Message message) {
        try {
            if (messageExchange.getStatus() != ExchangeStatus.ACTIVE) {
                return;
            }

            contentType = (String) message.get(Message.CONTENT_TYPE);
SoapMessage soapMessage = (SoapMessage) this.providerEndpoint.getCxfEndpoint().getBinding().createMessage(message);

            EndpointInfo ei = providerEndpoint.getEndpointInfo();

            QName opeName = messageExchange.getOperation();
            BindingOperationInfo boi = null;
            if (opeName == null) {
                // if interface only have one operation, may not specify the 
opeName in MessageExchange
                boi = ei.getBinding().getOperations().iterator().next();
            } else {
boi = ei.getBinding().getOperation(opeName); } // create XmlStreamReader
            if (boi.getOperationInfo().isOneWay()) {
                return;
            }
...

----- Original Message ----
From: Ron Gavlin <[EMAIL PROTECTED]>
To: [email protected]
Sent: Wednesday, May 14, 2008 2:25:11 AM
Subject: servicemix-cxf-bc provider NPE invoking cxf-wsdl-first sample

Using the current 3.2 branch, I have hot deployed the cxf-wsdl-first sample. In a 
separate flow, I have a file:poller -> eip:pipeline(transformer = cxfbc:provider) 
-> file:sender. My input file for this flow contains:

<jbi:message xmlns:jbi="http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper"; 
version="1.0">
<jbi:part>
<tns:GetPerson 
xmlns:tns="http://servicemix.apache.org/samples/wsdl-first/types";>
      <tns:personId>world</tns:personId>
</tns:GetPerson>
</jbi:part>
</jbi:message>

When this flow is processed, the cxfbc:provider throws the following NPE:

May 14, 2008 1:59:44 AM org.apache.cxf.transport.jbi.JBITransportFactory 
setDeliveryChannel
INFO: configuring DeliveryChannel:      [EMAIL PROTECTED]
May 14, 2008 1:59:45 AM org.apache.cxf.transport.jbi.JBITransportFactory 
setDeliveryChannel
INFO: configuring DeliveryChannel:      [EMAIL PROTECTED]
java.lang.NullPointerException
        at 
java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:157)
        at 
java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:730)
        at 
org.apache.cxf.service.model.BindingInfo.getOperation(BindingInfo.java:126)
        at 
org.apache.servicemix.cxfbc.CxfBcProviderMessageObserver.onMessage(CxfBcProviderMessageObserver.java:93)
        at 
org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1988)
        at 
org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1824)
        at 
org.apache.servicemix.cxfbc.CxfBcProvider.process(CxfBcProvider.java:201)
        at 
org.apache.servicemix.common.AsyncBaseLifeCycle.doProcess(AsyncBaseLifeCycle.java:538)
        at 
org.apache.servicemix.common.AsyncBaseLifeCycle.processExchange(AsyncBaseLifeCycle.java:490)
        at 
org.apache.servicemix.common.BaseLifeCycle.onMessageExchange(BaseLifeCycle.java:46)
        at 
org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.processInBound(DeliveryChannelImpl.java:610)
        at 
org.apache.servicemix.jbi.nmr.flow.AbstractFlow.doRouting(AbstractFlow.java:172)
        at 
org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow.doRouting(SedaFlow.java:167)
        at 
org.apache.servicemix.jbi.nmr.flow.seda.SedaQueue$1.run(SedaQueue.java:134)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
        at java.lang.Thread.run(Thread.java:595)

The problem is that the CxfBcProviderMessageObserver's messageExchange has a 
null operation. On the cxfbc:provider, how is the operation supposed to be set? 
I do not see it as a configurable property on the cxfbc:provider.

Thanks in advance for your assistance.

- Ron


Reply via email to