cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Aki Yoshida <elak...@googlemail.com>
Subject Re: Coloc feature and dispatch clients
Date Wed, 01 Jun 2011 22:08:49 GMT
Hi Dan,
yes, it sounds definitely more user-friendly to hide the code within
DispatchImpl.

Another thing that I experimented was to provide more usefulness in
this dispatch<Source> based coloc feature. The current limitation is
that you need to have the compatible operations at the consumer and
the provider side. This limitation seems natural for POJO services,
but not for those Source based clients, as the approach will only work
if the provider service is also implemented as an argument-Source
operation. This is not a typical case. Thus, it seems a serious
limitation for this feature to become useful.

So what we can do is to remove this limitation by dynamically
converting the coloc content from Source to POJO or the other way
around if necessary. This can be done at ColocMessageObserver if the
two operations do not match exactly. The idea is analogue to adding
the DocLitInInterceptor's xmlreader->pojo mapping. The response
message must be converted in the other direction as well. To
demonstrate this approach, I added a dispatch<Source> based coloc
client in the in_jvm_transport sample that calls its POJO coloc
target. It seems to be working fine. I can also add this to a jira
ticket.

regards, aki

2011/6/1 Daniel Kulp <dkulp@apache.org>:
> On Monday, May 30, 2011 4:22:36 PM Aki Yoshida wrote:
>> It came to my mind that we could simplify the client code by just
>> reusing the dispatch's operations that are already available in the
>> dispatch object.
>>
>>         Client client = ((DispatchImpl)dispatch).getClient();
>>         InterfaceInfo iinfo =
>> client.getEndpoint().getEndpointInfo().getService().getInterface();
>>
>>         OperationInfo dpOpInfo =
>>             iinfo.getOperation(oneWay ? INVOKE_ONEWAY_OPERATION_NAME :
>> INVOKE_OPERATION_NAME);
>>
>>         // add the desired operation name having the dispatch's invoke op
>>         OperationInfo opInfo = iinfo.addOperation(operationName);
>>
>>         opInfo.setInput(dpOpInfo.getInputName(), dpOpInfo.getInput());
>>         if (!oneWay) {
>>             opInfo.setOutput(dpOpInfo.getOutputName(),
>> dpOpInfo.getOutput()); }
>>
>>         for (BindingInfo bind :
>> client.getEndpoint().getEndpointInfo().getService().getBindings()) {
>>             BindingOperationInfo bo = new BindingOperationInfo(bind,
>> opInfo); bind.addOperation(bo);
>>         }
>>
>>         dispatch.getRequestContext().put(MessageContext.WSDL_OPERATION,
>> operationName);
>
> I was thinking something similar along this, but having it "automatic" inside
> of DispatchImpl.   In the DispatchImpl.invoke, if the operation name is
> specified but not found, create it instead of falling back to the invoke
> operation.     Thus, the user wouldn't really need to do anything except set
> the WSDL_OPERATION.   All the rest of the above code we be part of
> DispatchImpl.
>
> Feel free to add a JIRA and give it a try.  :-)
>
> Dan
>
>
>
>>
>> 2011/5/30 Aki Yoshida <elakito@googlemail.com>:
>> > Hi Dan,
>> > Thanks for your explanation. I was looking at the dispatcher in a
>> > narrow scope. It makes sense to use a specific operation in general
>> > cases.
>> >
>> > It looks like Gunnar can programmatically add the right operation to
>> > the binding associated with the service at his client program. In this
>> > case,  the dispatch mechanism can find the correct operation using the
>> > correct operation name and he can just use the generic disptach client
>> > without  any WSDL by simply setting the appropriate operation for each
>> > scenario.
>> >
>> > This looks like:
>> > // dispatch = the dispatch instance created for Source.class
>> > // operationName = the operaiton qname
>> >
>> >        Client client = ((DispatchImpl)dispatch).getClient();
>> >        ServiceInfo info =
>> > client.getEndpoint().getEndpointInfo().getService();
>> >
>> >        OperationInfo opInfo =
>> > info.getInterface().addOperation(operationName); MessageInfo mInfo =
>> > opInfo.createMessage(new
>> > QName(operationName.getNamespaceURI(), operationName.getLocalPart() +
>> > "Request"),
>> >                                                 Type.INPUT);
>> >        opInfo.setInput(operationName.getLocalPart() + "Request", mInfo);
>> >
>> >        MessagePartInfo mpi = mInfo.addMessagePart("parameters");
>> >        mpi.setElement(true);
>> >        mpi.setTypeClass(Source.class);
>> >
>> >        // do the same for the output/response if not oneway
>> >        ...
>> >
>> >        // add the operation to the bindings
>> >        for (BindingInfo bind :
>> > client.getEndpoint().getEndpointInfo().getService().getBindings()) {
>> >            BindingOperationInfo bo = new BindingOperationInfo(bind,
>> > opInfo); bind.addOperation(bo);
>> >        }
>> >
>> >        // set the operation for this dispatch call
>> >        dispatch.getRequestContext().put(MessageContext.WSDL_OPERATION,
>> > operationName);
>> >
>> > I think this is probably the right way for his use case.
>> > .
>> >
>> > Regards, aki
>> >
>> > 2011/5/27 Daniel Kulp <dkulp@apache.org>:
>> >> On Friday, May 27, 2011 1:58:17 PM Aki Yoshida wrote:
>> >>> Hi Dan,
>> >>> I don't think replacing the generic operation name with the user
>> >>> defined operation name so early in the phase helps because the
>> >>> operation name must match within ClientImpl to find one of the
>> >>> "dispatching operations".
>> >>
>> >> Actually, it doesn't.  If the Dispatch is created via a Service object
>> >> that was created with the WSDL URL, it should be able to find a valid
>> >> operation for it.    This is also needed to be able to do things like
>> >> WS-SecurityPolicy and such with the Dispatch clients.   To get the
>> >> correct policies for the operation, we need to know the operation,
>> >> match it based on the WSDL, and get the policies from there.    The
>> >> SecurityPolicyTest.testDispatchClient() test case (in the ws-security
>> >> systests) shows this, although this actually goes a different route.
>> >> If the operation is not specified on the RequestContext, it will use
>> >> the qname on the root of the Source passed into the dispatch.invoke to
>> >> try and match the operation.
>> >>
>> >> Again, this ONLY works if the Service is constructed with a WSDL.   If
>> >> you try with a generic Service object, it won't.
>> >>
>> >> Dan
>> >>
>> >>> I also gave up on trying to use the annotations to make the matching
>> >>> work because there seems to be no way to construct a matching pair
>> >>> when you want to have the service name of your provider to be
>> >>> something different from the dispatch invoker’s generic service name.
>> >>>
>> >>> If we can set the namespace of the provider’s operation to the
>> >>> dispatch invoker's generic namespace while setting the namespace of
>> >>> the provider's service to the user defined one, that would work. In
>> >>> this case, the endpoint references will match with the user defined
>> >>> name and the binding operations will match with the invoker's generic
>> >>> operation name. But I couldn't find a way to do this.
>> >>>
>> >>> So I just went the other way and modifed a couple of lines in several
>> >>> Coloc classes to make it work. I don't know whether there is an easier
>> >>> approach.
>> >>>
>> >>> regards, aki
>> >>>
>> >>> 2011/5/27 Daniel Kulp <dkulp@apache.org>:
>> >>> > One thing you can try:
>> >>> >
>> >>> > If you do a
>> >>> > dispatch.getRequestContext().put(MessageContext.WSDL_OPERATION,
new
>> >>> > QName("http://my.namespace", "myOperation"));
>> >>> >
>> >>> > before calling the invoke, it MAY be able to properly match the
>> >>> > operation name and thus not use the generic "invoke" operation.
>> >>> > That said, you MAY need to create the Dispatch client from a Service
>> >>> > that was created with a WSDL URL.
>> >>> >
>> >>> > Dan
>> >>> >
>> >>> > On Thursday, May 26, 2011 1:02:56 PM Gunnar Morling wrote:
>> >>> >> Hi,
>> >>> >>
>> >>> >> I'm trying to use CXF's coloc feature
>> >>> >> (http://cxf.apache.org/docs/coloc-feature.html). Things work
fine
>> >>> >> when using a "real" client for accessing the service (meaning
the
>> >>> >> generated service/port classes for my service).
>> >>> >>
>> >>> >> But I'm running into trouble when using a dynamic client, namely
a
>> >>> >> JAX-WS dispatch client. The cause seems to be that in
>> >>> >> org.apache.cxf.binding.coloc.ColocOutInterceptor#isColocated()
the
>> >>> >> name of the invoked operation is compared against the names
hosted
>> >>> >> by the co-located server port. As the invoked method name is
a
>> >>> >> generic one in the dispatch scenario ("invoke" actually) this
>> >>> >> comparison fails and instead of the coloc transport the standard
>> >>> >> transport using HTTP is performed.
>> >>> >>
>> >>> >> Is there anything I could do about this? If JAX-WS dispatch
based
>> >>> >> clients are generally not supported, is there any other way
to use
>> >>> >> the coloc transport in a generic manner? Or is this just an
issue,
>> >>> >> for which I should open up a feature request in JIRA?
>> >>> >>
>> >>> >> Thanks in advance,
>> >>> >>
>> >>> >> Gunnar
>> >>> >
>> >>> > --
>> >>> > Daniel Kulp
>> >>> > dkulp@apache.org
>> >>> > http://dankulp.com/blog
>> >>> > Talend - http://www.talend.com
>> >>
>> >> --
>> >> Daniel Kulp
>> >> dkulp@apache.org
>> >> http://dankulp.com/blog
>> >> Talend - http://www.talend.com
>
> --
> Daniel Kulp
> dkulp@apache.org
> http://dankulp.com/blog
> Talend - http://www.talend.com
>

Mime
View raw message