Thanks a lot. Implementing Provider interface resolved this problem.

Now I've got 2 minor issues in 2.2.4:
- method "invoke" shows up in Services List for this portType, but it
shouldn't (how to deal with it?)

- operation is not mapped as javax.xml.ws.wsdl.operation property
inside WebServiceContext, so I need to cast to CXF internal or use
reflection to actually get it.

I've got following service's impl (deployed as WAR in Tomcat, endpoint
spring config is like in previous mail):

package pl.touk.humantask.ws;
import javax.annotation.Resource;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.Endpoint;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.MessageContext;

@WebServiceProvider
@ServiceMode(value=Service.Mode.MESSAGE)
public class JaxWSService implements Provider<SOAPMessage> {
    private WebServiceContext context;

    public WebServiceContext getContext() {
        return context;
    }

    @Resource
    public void setContext(WebServiceContext context) {
        this.context = context;
    }

    public SOAPMessage invoke(SOAPMessage request) {
        try {
            MessageContext c = context.getMessageContext();
            Object operationInfo =
c.get("org.apache.cxf.service.model.OperationInfo");
            QName operation = (QName)
operationInfo.getClass().getMethod("getName").invoke(operationInfo);
            QName portType = (QName) c.get("javax.xml.ws.wsdl.interface");

            System.err.println("invoked " + request + " endpoint " +
endpoint + " operation:" + operation + " portType:" + portType);

            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}



Those are properties set while executing invoke (note lacking
javax.xml.ws.wsdl.operation, but existing
org.apache.cxf.service.model.OperationInfo):
org.apache.cxf.binding.binding=org.apache.cxf.binding.soap.soapbind...@da7b85
org.apache.cxf.bus=org.apache.cxf.bus.cxfbusi...@1e373de
javax.xml.ws.wsdl.description=http://localhost:8080/x/ClaimsHandlingService/?wsdl
org.apache.cxf.service.model.BindingOperationInfo=[BindingOperationInfo:
{http://www.insurance.example.com/claims}approve]
org.apache.cxf.jaxws.handler.handlerchaininvoker=org.apache.cxf.jaxws.handler.handlerchaininvo...@1cc2f42
org.apache.cxf.service.model.OperationInfo=[OperationInfo:
{http://www.insurance.example.com/claims}approve]
org.apache.cxf.service.Service=[ServiceImpl
{http://www.insurance.example.com/claims}ClaimsHandlingService]
javax.xml.ws.wsdl.service={http://www.insurance.example.com/claims}ClaimsHandlingService
javax.xml.ws.wsdl.interface={http://www.insurance.example.com/claims}ClaimsHandlingPT
javax.xml.ws.wsdl.port={http://www.insurance.example.com/claims}ClaimsHandlingPort
java.util.concurrent.executor=org.apache.cxf.workqueue.synchronousexecu...@1f844f7
org.apache.cxf.interceptor.LoggingMessage.ID=1
org.apache.cxf.endpoint.Endpoint={}

I saw that 
rt/core/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java
copies some properties, which don't include operation. But it isn't
staightforwad to fix, because I wasn't able to find OperationInfo
during runtime. So I suppose operation is available later in
interceptor chain.



2009/10/9 Daniel Kulp <[email protected]>:
>
> I THINK the provider impl  is wrong:
>>
>> @WebServiceProvider
>> public class JaxWSService {
>
> This should be
>
> @WebServiceProvider
> public class JaxWSService implements Provider<Source> {
>
> That MAY be the issue.    If it doesn't implement Provider, it may not be
> treating it as a provider and thus may be the issue.   Definitely should
> provide a better error message though.
>
> If the above doesn't fix the issue, can you package it in a war or similar and
> attach it to a jira as a bug?
>
> Thanks!
> Dan
>
>
>
>
> On Thu October 8 2009 5:16:14 pm Rafal Rusin wrote:
>> Hello,
>>
>> I'd like to expose some consumer services from xml defined file in
>> cxf. All such services have corresponding wsdls.
>> So I thought the best way is to create generic @WebServiceProvider
>> class and expose services via javax.xml.ws.Endpoint.publish() in loop.
>> Then I would be able to anwer exchanges for various operations inside
>> invoke method.
>>
>> But I saw that exposing a single endpoint in spring config, using such
>> generic implementor causes problems - in services list I see only a
>> portType without any operation inside.
>> And I get failures during recognizing message on soap calls.
>>
>> Here's my spring config:
>>
>>   <bean id="impl2" class="pl.touk.humantask.ws.JaxWSService">
>>     <property name="services" ref="humanTaskServices"/>
>>     <property name="endpoint" ref="testHtd1"></property>
>>   </bean>
>>
>>   <jaxws:endpoint id="testHtd1"
>>     address="/ClaimsHandlingService/"
>>     implementor="#impl2"
>>     serviceName="ins:ClaimsHandlingService"
>>     endpointName="ins:ClaimsHandlingPort"
>>     publish="true"
>>     wsdlLocation="classpath:ExampleTasks.wsdl"
>>
>>
>> Attached is wsdl (but I think wsdl doesn't really matters, because I
>> tested it on different ones - including those working on
>> code-generated services).
>>
>> Here's my generic implementor class:
>>
>> package pl.touk.humantask.ws;
>>
>> import javax.xml.transform.Source;
>> import javax.xml.ws.Endpoint;
>> import javax.xml.ws.WebServiceProvider;
>>
>> import pl.touk.humantask.HumanTaskServices;
>>
>> @WebServiceProvider
>> public class JaxWSService {
>>     public Source invoke(Source request) {
>>         System.err.println("invoked " + request + " endpoint " + endpoint);
>>         return request;
>>     }
>> }
>>
>> And here's log which I got after soap call:
>> ----------------------------
>> ID: 2
>> Address: /x/ClaimsHandlingService29/
>> Encoding: UTF-8
>> Content-Type: text/xml;charset=UTF-8
>> Headers: {content-length=[653], accept-encoding=[gzip,deflate],
>> host=[localhost:8080], user-agent=[Jakarta Commons-HttpClient/3.1],
>> SOAPAction=["http://www.insurance.example.com/claims/approve";],
>> content-type=[text/xml;charset=UTF-8]}
>> Payload: <soapenv:Envelope
>> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";
>> xmlns:cla="http://www.insurance.example.com/claims";>
>>    <soapenv:Header/>
>>    <soapenv:Body>
>>       <cla:approve>
>>          <ClaimApprovalRequest>
>>          <cla:cust>
>>             <cla:id>123</cla:id>
>>             <cla:firstname>Edmund</cla:firstname>
>>             <cla:lastname>Zorn</cla:lastname>
>>          </cla:cust>
>>          <cla:amount>1234</cla:amount>
>>          <cla:region>usa</cla:region>
>>          <cla:prio>2</cla:prio>
>>          <cla:activateAt>2009-01-02T12:00:00</cla:activateAt>
>>          </ClaimApprovalRequest>
>>       </cla:approve>
>>    </soapenv:Body>
>> </soapenv:Envelope>
>> --------------------------------------
>> 2009-10-08 20:43:37 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
>> INFO: Interceptor has thrown exception, unwinding now
>> org.apache.cxf.interceptor.Fault: Message part
>> {http://www.insurance.example.com/claims}approve was not recognized.
>> (Does it exist in service WSDL?)
>>       at
>>  org.apache.cxf.interceptor.BareInInterceptor.handleMessage(BareInIntercept
>> or.java:133) at
>>  org.apache.cxf.binding.soap.interceptor.RPCInInterceptor.handleMessage(RPC
>> InInterceptor.java:111) at
>>  org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorCha
>> in.java:236) at
>>  org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiation
>> Observer.java:89) at
>>  org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestinat
>> ion.java:99) at
>>  org.apache.cxf.transport.servlet.ServletController.invokeDestination(Servl
>> etController.java:357) at
>>  org.apache.cxf.transport.servlet.ServletController.invoke(ServletControlle
>> r.java:183) at
>>  org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServ
>> let.java:163) at
>>  org.apache.cxf.transport.servlet.AbstractCXFServlet.doPost(AbstractCXFServ
>> let.java:141) at
>>  javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
>>       at
>>  org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicati
>> onFilterChain.java:290) at
>>  org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilter
>> Chain.java:206) at
>>  org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilter
>> Internal(OpenEntityManagerInViewFilter.java:112) at
>>  org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerReques
>> tFilter.java:76) at
>>  org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicati
>> onFilterChain.java:235) at
>>  org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilter
>> Chain.java:206) at
>>  org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.
>> java:233) at
>>  org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.
>> java:175) at
>>  org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:1
>> 28) at
>>  org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:1
>> 02) at
>>  org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.ja
>> va:109) at
>>  org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286
>> ) at
>>  org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
>>  at
>>  org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Ht
>> tp11Protocol.java:583) at
>>  org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at
>>  java.lang.Thread.run(Thread.java:595)
>> 2009-10-08 20:43:37
>> org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback
>> onClose
>>
>>
>>
>> So is there any fix for it? Or maybe there's more elegant way to
>> expose dynamic web services in cxf?
>> Axis2 supports such things, so there needs to be a way in cxf.
>>
>> Regards,
>>
>
> --
> Daniel Kulp
> [email protected]
> http://www.dankulp.com/blog
>


Regards,
-- 
Rafał Rusin
http://www.touk.pl
http://top.touk.pl
http://people.apache.org/~rr/

Reply via email to