On Sep 9, 2013, at 6:57 PM, Jesse Pangburn <jesse.pangb...@infor.com> wrote:

> Hi Dan,
> I can submit a patch to make this change if necessary?  Just hoping for some 
> feedback if this is a bad idea for some reason?

Sure.  Feel free to submit a patch for it.   I cannot imagine it would be a 
problem, but I could then run a series of extra tests and such for it.

Dan


> 
> Thanks,
> Jesse
> 
> -----Original Message-----
> From: Jesse Pangburn 
> Sent: Friday, June 28, 2013 3:05 PM
> To: users@cxf.apache.org; Daniel Kulp
> Subject: RE: how to determine/debug effective ws policy used?
> 
> Hi Dan,
> Just wonder if you've had a chance to see if this code should be changed as I 
> suggested, or if it is incorrect and will cause some other problem?
> 
> Thanks,
> Jesse
> 
> -----Original Message-----
> From: Jesse Pangburn [mailto:jesse.pangb...@infor.com] 
> Sent: Wednesday, June 05, 2013 3:36 PM
> To: Daniel Kulp; users@cxf.apache.org
> Subject: RE: how to determine/debug effective ws policy used?
> 
> Hi Dan,
> As always, thanks for your excellent help!  That did work.  However, there's 
> a setting that I thought was supposed to take care of this issue in Dispatch:
> disp.getRequestContext().put("find.dispatch.operation", Boolean.TRUE);
> 
> This was the fix I used to make it properly set the SOAPAction header based 
> on the payload name when WS-Addressing is not enabled.  Previously (you may 
> recall), I found that SOAPAction was only set when WS-Addressing was not 
> enabled.  This resolved that issue.  What I'm wondering is how come this same 
> setting doesn't already take care of this WSDL operation issue too?  If it's 
> set true then it's already going in and locating the "dispatchedOpName".  
> This is the relevant code:
> 
> <String, QName> payloadOPMap = 
>        
> createPayloadEleOpNameMap(client.getEndpoint().getBinding().getBindingInfo());
>    if (findDispatchOp && !payloadOPMap.isEmpty()) {
>        String payloadElementName = null;              
>        if (obj instanceof javax.xml.transform.Source) {
>            XMLStreamReader reader = null;
>            try {
>                reader = 
> StaxUtils.createXMLStreamReader((javax.xml.transform.Source)obj);
>                Document document = StaxUtils.read(reader);
>                createdSource = new 
> StaxSource(StaxUtils.createXMLStreamReader(document));
>                payloadElementName = 
> getPayloadElementName(document.getDocumentElement());
>            } catch (Exception e) {                        
>                // ignore, we are trying to get the operation name
>            } finally {
>                StaxUtils.close(reader);
>            }
>        }
>        if (obj instanceof SOAPMessage) {
>            payloadElementName = getPayloadElementName((SOAPMessage)obj);
> 
>        }
> 
>        if (this.context != null) {
>            payloadElementName = getPayloadElementName(obj);
>        }
> 
>        if (payloadElementName != null) {
>            QName dispatchedOpName = payloadOPMap.get(payloadElementName);
>            if (null != dispatchedOpName) {
>                BindingOperationInfo bop = 
> client.getEndpoint().getBinding().getBindingInfo()
>                  .getOperation(opName);
>                BindingOperationInfo dbop = 
> client.getEndpoint().getBinding().getBindingInfo()
>                  .getOperation(dispatchedOpName);
>                if (bop != null) {
>                    // set the actual binding operation object to this 
> dispatch operation
>                    bop.setProperty("dispatchToOperation", dbop);
>                }
>            }
>        }
>    }
> 
> I see it just sets this "dispatchToOperation" property on the 
> BindingOperationInfo object for the default "Invoke" placeholder opName.  Why 
> not just set the opName to the newly determined dispatchedOpName at this 
> point?  Then all subsequent code will execute with the opName set to the 
> correct one from the WSDL instead of the default "Invoke".  I changed that 
> section to:
>                if (bop != null) {
>                    // set the actual binding operation object to this 
> dispatch operation
>                    bop.setProperty("dispatchToOperation", dbop);
>                    //  update the opName while we're at it
>                    opName = dispatchedOpName;
>                }
> 
> This solved the problem without manually setting the 
> MessageContext.WSDL_OPERATION, probably because it gets set correctly on down 
> the line from this updated opName.  I assume there must be something wrong 
> with doing this, which is why that property was set instead of just updating 
> the opName in the first place?
> 
> Thanks,
> Jesse
> 
> -----Original Message-----
> From: Daniel Kulp [mailto:dk...@apache.org] 
> Sent: Wednesday, June 05, 2013 1:55 PM
> To: users@cxf.apache.org; Jesse Pangburn
> Subject: Re: how to determine/debug effective ws policy used?
> 
> 
> On Jun 5, 2013, at 4:46 PM, Jesse Pangburn <jesse.pangb...@infor.com> wrote:
> 
>> This appears to be a bug.  I stepped through the debugger into the 
>> PolicyOutInterceptor's handle method and found the following in the 
>> BindingOperationInfo object:
>> [BindingOperationInfo: {http://cxf.apache.org/jaxws/dispatch}Invoke]
>> 
>> This is the default value which gets overridden at some point with the 
>> actual operation.  I'm not sure why this is, but my guess is that this 
>> PolicyOutInterceptor is running before the code that looks at the message 
>> content and computes the operation from the WSDL.
>> 
>> The result is that the effective policy is incorrectly calculated because 
>> the operation is unknown at that point, so it's only using the policy for 
>> the service's binding and not merging in the policy for the operation's 
>> output message.  Does anyone know how to fix this correctly?
> 
> In general, with a Dispatch client, you may need to tell the client which 
> operation you are invoking. 
> 
> dispatch.getRequestContext().put(MessageContext.WSDL_OPERATION,
>         new QName("http://cxf.apache.org/greeter_control";, "greetMeOneWay"));
> 
> or similar.  That will allow the client to not process the body contents at 
> all to try and determine the operation.
> 
> Dan
> 
> 
> 
>> 
>> BTW, in case anyone else is reading this looking for how to print out the 
>> effective policy, the answer is to turn on logging for the 
>> PolicyOutInterceptor class at FINEST level.
>> 
>> Thanks,
>> Jesse
>> 
>> -----Original Message-----
>> From: Jesse Pangburn [mailto:jesse.pangb...@infor.com]
>> Sent: Tuesday, June 04, 2013 4:22 PM
>> To: users@cxf.apache.org
>> Subject: how to determine/debug effective ws policy used?
>> 
>> Hi,
>> I'm trying to learn how to correctly use WS-Policy with CXF (using version 
>> 2.7.2) and would like to know if there's a way to log the effective policy 
>> calculated for both consumer and provider?
>> 
>> The problem is that I have a wsdl with 3 policies attached to different 
>> points.  The first policy contains an asymmetric binding to provide the X509 
>> keys for signing/encryption.  The second two policies just have the places I 
>> want signed/encrypted, like this:
>>   <wsp:Policy wsu:Id="Output_Policy">
>>       <wsp:ExactlyOne>
>>           <wsp:All>
>>               <sp:EncryptedParts>
>>                   <sp:Body/>
>>               </sp:EncryptedParts>
>>               <sp:SignedParts>
>>                   <sp:Body/>
>> ...
>> 
>> In the WSDL, I have the following binding which references the first policy:
>> <wsdl:binding name="Binding_MyService" type="tns:MyService">
>>   <wsp:PolicyReference URI="#main_policy"/>
>> 
>> The operations reference the second two policies to say what to sign/encrypt 
>> in each direction:
>>   <wsdl:operation name="PatientRequests">
>>     <soap12:operation 
>> soapAction="http://example.com/schemas/'myService/PatientRequests" 
>> style="document"/>
>>     <wsdl:input>
>>       <wsp:PolicyReference URI="#Input_policy"/>
>>       <soap12:body use="literal"/>
>>     </wsdl:input>
>>     <wsdl:output>
>>       <wsp:PolicyReference URI="#Output_Policy"/>
>>       <soap12:body use="literal"/>
>>     </wsdl:output>
>>   </wsdl:operation>
>> 
>> I've setup a client (using CXF Dispatch) and a server (using CXF Provider).  
>> If I make a bad URI in the policy reference for the operation, the client 
>> does not complain but the server does throw an exception saying it can't 
>> find policy "xyz" (or whatever I rename the PolicyReference to).  Whether 
>> the URI is right or not, the client doesn't do the signing/encryption but 
>> the server errors out complaining that the Body is not signed or encrypted 
>> (correctly, since the client failed to sign/encrypt).
>> 
>> So it appears to me that the client is not properly calculating the 
>> effective policy as the merge of the main policy and either the input/output 
>> policy (depending on direction), but the server does correctly calculate the 
>> effective policy.  In the main policy, I also have WS-Addressing engaged and 
>> when I trace the messages I see that the client is sending the right Action 
>> header so it's correctly determining the operation from the message I'm 
>> sending, so it should be able to determine the right policy (just as the 
>> server does when it receives the message and calculates the policy based on 
>> the Action header).
>> 
>> Thanks,
>> Jesse
> 
> --
> Daniel Kulp
> dk...@apache.org - http://dankulp.com/blog Talend Community Coder - 
> http://coders.talend.com
> 

-- 
Daniel Kulp
dk...@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

Reply via email to