Java and Metadata Exchange MEX - java

I'm trying to generate classes using an MEX endpoint unfortunately doesn't seems to be possible, because it won't find the WSDL.
I also want create a client for that web services using spring and Apache CXF but I don't know if I'm in the right path. I tried declaring the following on my spring-config:
<jaxws:client name="{http://payments.com:8080/}IOriginatorPaymentsService"
createdFromAPI="true">
<jaxws:properties>
<entry key="ws-security.username" value="Username"/>
<entry key="ws-security.password" value="Password"/>
</jaxws:properties>
</jaxws:client>
My questions are:
1. It's possible to generate the classes using only the following MEX endpoint http://payments.com:8080/OriginatorPaymentsHNL/Service/OriginatorPaymentsService.svc/mex the WSDL appears to be unexposed.
Could you provide an example of how to use spring and Apache CXF to create a client for the MEX endpoint.
As far I understand I can't unless the web service has enable the httpGetEnabled flag to expose the WSDL.
Thank you

Enable httpGetEnabled flag to expose the WSDL

Related

Consuming a webservice with CXF in Mule 3.5

I am trying to consume web service using CXF component in mule(Anypoint Studio).
So I tried genrating the WSDL file from URL but I was getting this errror: Rpc/encoded wsdls are not supported in CXF so I followed this answer.
It worked and it generated client stubs, then copied the files into my mule project.
but I am getting this error:
Service.SomeService.<init>(java.net.URL, javax.xml.namespace.QName) (java.lang.NoSuchMethodException)
This is my flow:
<flow name="WebServiceTest">
<cxf:jaxws-client
clientClass="service.SomeService"
wsdlLocation="http://127.0.0.1:8000/api/v2_soap/?wsdl"
operation="test"/>
<outbound-endpoint address="http://127.0.0.1:8000/api.php/?type=v2_soap"/>
</flow>
Any ideas?
Your configuration is not correct specially your outbound endpoint url.
You can try configuring a CXF client as per Mule documentation.
You can also build a client for your JAX-WS services without generating a client from WSDL. Here you need a copy of your service interface and all your data objects locally to use something like this :-
<flow name="csvPublisher">
...
<cxf:jaxws-client serviceClass="org.example.HelloService" operation="sayHi"/>
<outbound-endpoint address="http://localhost:63081/services/greeter"/>
</flow>
Another approach is you can use a CXF-generated client as an outbound endpoint. First, you need to generate a CXF client using the WSDL to Java tool from CXF or the Maven plugin.
Then you need to configure something like the following :-
<flow name="csvPublisher">
...
<cxf:jaxws-client
clientClass="org.apache.hello_world_soap_http.SOAPService"
port="SoapPort"
wsdlLocation="classpath:/wsdl/hello_world.wsdl"
operation="greetMe"/>
<outbound-endpoint address="http://localhost:63081/services/greeter"/>
</flow>
It is better to put the wsdl in your local classpath.
Please checkout the full documentation here as reference to get it configured :-
https://docs.mulesoft.com/mule-user-guide/v/3.7/consuming-web-services-with-cxf
and
Consuming a Webservice Using Mule 3.4

SOAP UI doesnt generate wsdl-interface

I am trying to test my soap web service by SOAP-UI, Also I use Spring-ws and Java.
I point to my wsdl file in spring configuration like this:
<bean id="myservice" class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
<constructor-arg value="/WEB-INF/wsdl/myservice.wsdl"/>
</bean>
Then in the SOAP UI I locate this wsdl file, but it does not create and WSDL-interface that I can work with to create requests.
But If I use the exactly same xsd but dynamically create the wsdl file than SOAP UI creates the wsdl interface fine:
<sws:dynamic-wsdl id="myservice"
portTypeName="MyService"
locationUri="/myService"
targetNamespace="http://mypath">
<sws:xsd location="/mypath.xsd"/>
</sws:dynamic-wsdl>
What am I missing? I need modify my wsdl file and not work directly with spring auto generated wsdl.

SignedSupportingTokens wssecurity policy cxf client

I'm trying to put together a small CXF client for a soap service which is having SignedSupportingTokens ws-security policy in its wsdl. I have configured CXF client as follows
<jaxws:client id="secretService" name="{http:/mySecretServiceEndpoint//}Service" createdFromAPI="true">
<jaxws:properties>
<entry key="ws-security.signature.properties" value="keystore/secret.properties" />
<entry key="ws-security.encryption.properties" value="keystore/secret.properties" />
<entry key="ws-security.timestamp.timeToLive" value="600" />
</jaxws:properties>
</jaxws:client>
Unfortunately it fails to send out messages with following error.
Caused by: org.apache.cxf.ws.policy.PolicyException: None of the policy alternatives can be satisfied.
at org.apache.cxf.ws.policy.EffectivePolicyImpl.chooseAlternative(EffectivePolicyImpl.java:199)
at org.apache.cxf.ws.policy.EffectivePolicyImpl.chooseAlternative(EffectivePolicyImpl.java:192)
at org.apache.cxf.ws.policy.EffectivePolicyImpl.initialise(EffectivePolicyImpl.java:96)
at org.apache.cxf.ws.policy.PolicyEngineImpl.getEffectiveClientRequestPolicy(PolicyEngineImpl.java:205)
at org.apache.cxf.ws.policy.PolicyOutInterceptor.handle(PolicyOutInterceptor.java:98)
at org.apache.cxf.ws.policy.AbstractPolicyInterceptor.handleMessage(AbstractPolicyInterceptor.java:44)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:138)
I was wondering if CXF supports SignedSupportingTokens policy by default? Do I need to register some handlers or am I missing something else? I don't have much experience with WS-Security and WS-SecurityPolicy, any response will be highly appreciated.
Answering my own question as it might help somebody someday! CXF does supports SignedSupportingTokens and a lot more, In my case, service WSDL was having a different namespace for SignedSupportingTokens which CXF client dint understand (couldn't match up).
I was able to fix the issue by using ws-security interceptors to configure the client.

Migration to Spring WS 2.0 failed due to lack of bean endpoint mapping?

We used the PayloadRootQNameEndpointMapping to map endpoint scripts (based on a scripting language like groovy or something else) to a given root QName. We recently tried to migrate spring ws to version 2.0. The javadoc of the PayloadRootQNameEndpointMapping shows that the class is marked as deprecated.
PayloadRootQNameEndpointMapping Deprecated as of Spring Web Services 2.0, in favor of PayloadRootAnnotationMethodEndpointMapping
Since annotations are static we can't provide a dynamic concept for scripting endpoints. Until now we could generically map the Bean which is handling a script endpoint (provided with a script file and some contexts) to the root QName.
Short: How can we achieve the good old bean endpoint to Root QName mapping without using the deprecated API? Any ideas?
Thank you in advance.
Can you use something like the SimpleMethodEndpointMapping to write your own dispatcher? Check the link for the source
You can use more general XPathPayloadEndpointMapping where xpath will point to root element.
<bean id="endpointMapping" class="org.springframework.ws.server.endpoint.mapping.XPathPayloadEndpointMapping">
<property name="expression" value="local-name(//*[1])" />
<property name="endpointMap">
<map>
<entry key="rootElement" value="endpointRef" />
</map>
</property>
</bean>

passwordCallback in CXF

I develop a webservice client for an existing webservice. I am using Apache CXF 2.2. The service requires security with Username and plain text password, which I configured like this:
<bean id="myPasswordCallback"
class="com.kraemer_imd.mobilized.m2m_adapter.ClientPasswordCallback"/>
<jaxws:client id="m2mClientService"
serviceClass="de.vodafone.easypu.ws.EasyPUOrderServicePortType"
address="http://m2m.vodafone.de/speasy/services/EasyPUOrderService"
bindingId="http://www.w3.org/2003/05/soap/bindings/HTTP/">
<jaxws:outInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken Timestamp"/>
<entry key="passwordType" value="PasswordText"/>
<entry key="user" value="myusername"/>
<entry key="passwordCallbackRef">
<ref bean="myPasswordCallback"/>
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
That works quite well. But I did not understand why I have to provide the password via a callback handler instead of just providing it via configuration. The documentation says it is for security reasons, but I donĀ“t see why this should be more secure to have a callback handler that reads it from a property file (or worse has it hard coded in the callback).
So, could somebody explain this to me? Maybe the callback is intended for some magic stuff that I missed..
Thanks
Michel
The password callback is provided by Apache CXF as a mechanism for the client application to retrieve the credentials for the targeted webservice, which at runtime is likely to be stored in the database, configuration fiels, LDAP or some other store. This callback hook provides the flexibility to the application to retrieve the credentials from application specific configuration.
If password is stored in clear text in the configuration then this approach may not give you any extra security.
However having password stored as clear text in some configuration may have some security issues as there can be folks that may need access to this configuration and will be able to hold of password although it may not have been intended to.
Better is to store the encrypted password in the configuration. In this case, you need some code that will decrypt this password before it's use. Password callback will come to rescue in this scenario.

Categories