Regarding Spring and Apache CXF Integration - web-services

Inside the applicationcontext.xml file we have like this
<bean id="vincent" class="com.bayer.vincent.service.vincent"/>
<jaxws:endpoint
id="vincentSOAP"
implementor="#vincent"
implementorClass="com.bayer.vincent.service.vincent"
address="/vincent/soap"
bindingUri="http://schemas.xmlsoap.org/wsdl/soap/" />
what does this mean by this defination ??
My question is how the vincent class is being getting called ??

CXF has provided a custom spring namespace to help easily configure a webservice endpoint here.
If the implementor starts with a #, CXF makes the assumption that the endpoint is a Spring Bean, the way it is in your case.
The endpoint will have to be a normal JAX-WS endpoint, i.e annotated with #Webservice annotation, eg:
#WebService(serviceName="MemberService", endpointInterface="org.bk.memberservice.endpoint.MemberEndpoint", targetNamespace="http://bk.org/memberservice/")
Now any call to your uri-/vincent/soap, will be redirected by the CXF front controller(which you can register in the web.xml file):
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
which maintains an internal registry of payload uri's to handlers(in this case the Spring bean) and dispatches the request appropriately.

As far I understand there created proxy class which forwards all calls to your real class.
See also Configuring an Endpoint where described all jaxws:endpoint attributes.

Related

unable to add additional APIs endpoint classes to GCP endpoints v2

I have started an Google cloud endpoints v2 project using the starter code provided by Google which exposes one API named "echo".
My aim is to add another exposed class (one class/api name per business module).
Once deployed, all calls to the new API are not generating a "NOT FOUND" error.
As a solution i have tried to look into the web.xml and did the below changes.
Initial WEB.XML version:
<!-- Route API method requests to the backend. -->
<servlet-mapping>
<servlet-name>EndpointsServlet</servlet-name>
<url-pattern>/_ah/api/*</url-pattern>
</servlet-mapping>
I have added my new servlet and tried to add a new servlet mapping as below:
<servlet-mapping>
<servlet-name>EndpointsServlet</servlet-name>
<url-pattern>/_ah/api/echo/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>UserEndpointsServlet</servlet-name>
<url-pattern>/_ah/api/user/*</url-pattern>
</servlet-mapping>
Now after adding the /echo/* to the initial servlet mapping, the ECHO working services stopped servicing, and the system still cannot invoke the new service.
Does anyone knows what i am doing wrong and what is the solution?
I don't think this feature is not supported by the endpoints v2 framework since it does seem a good design practice to do this separation.
You should use the same servlet, using an init-param with all of the Endpoint classes you need:
<init-param>
<param-name>services</param-name>
<param-value>com.example.echo.Echo,com.example.echo.Echo2</param-value>
</init-param>
You should not use /_ah/api/echo/* or /_ah/api/user/* in your web.xml. Instead, use #Api(name = "echo") or #Api(name = "user") and bind EndpointsServlet to /_ah/api/*.

Duplicating a same SOAP webservice in Camel

A SOAP webservice is been exposed by a system. I have got a wsdl file of the webservice. Im able to send request and get response from soap ui. I want to duplicate this wsdl SOAP webservice in my camel routes deployed in servicemix, thereby making my ESB expose a similar webservice as the system's webservice. THis way many systems access this webservice to contact the system.
How do i duplicate a webservice using wsdl file of the system??
To duplicate webservice, exposed by a system, you can use http proxy route, based on jetty:
<route id="ServiceProxy">
<from uri="jetty:http://0.0.0.0:8186/service/?disableStreamCache=true&matchOnUriPrefix=true&continuationTimeout=900000&httpClient.timeout=120000"/>
<to uri="jetty:http://{{app-server.host}}:{{app-server.http.port}}/service/?bridgeEndpoint=true&throwExceptionOnFailure=false&continuationTimeout=120000&httpClient.timeout=900000"/>
</route>
You can write the same route on JavaDSL.
Found solution - Concept is cxf-proxying
Having a wsdl of the system, create a similar wsdl with the Endpoints defined according to the localhost and port number.
Save the wsdl in your local project,
provide the path to wsdl in pom, for converting wsdl to java by mentioning in the cxf-codegen-plugin.
create cxf consumer bean with details of local wsdl file
<cxf:cxfEndpoint id="consumerProxy" address="http://remote:port/service/"
serviceClass="com.remote.service.RemoteService" endpointName="c:RemoteService"
serviceName="c:RemoteService" xmlns:c="http://remote/namespace/">
<cxf:properties>
<entry key="dataFormat" value="MESSAGE" />
</cxf:properties>
</cxf:cxfEndpoint>
create cxf producer bean with details of remote wsdl file
<cxf:cxfEndpoint id="producerRemote" address="http://localhost:9001/service/"
serviceClass="com.remote.service.RemoteService" endpointName="c:RemoteService"
serviceName="c:RemoteService" xmlns:c="http://remote/namespace/">
<cxf:properties>
<entry key="dataFormat" value="MESSAGE" />
</cxf:properties>
</cxf:cxfEndpoint>
The proxy routes can be like below
from(cxfEndpoint("consumerProxy"))
.to(cxfEndpoint("producerRemote"));
Sending a request to localhost will be consumed by cxf endpoint - consumerProxy and sent to the cxf endpoint - producerRemote.
The response is sent back the reverse way.

Starting JAXWS servlet at root of the web context?

Is it possible to start JAXWS servlet at the roor of the web contex, so that the WSDL will be also accessible?
My context root, defined in application.xml is /myapp/webservice/v1 (the last part should be configurable in the deployment descriptor, and the web service should be available in web context root).
I've tried:
<servlet>
<display-name>WebService</display-name>
<servlet-name>WebService</servlet-name>
<servlet-class>my.package.WebServiceServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WebService</servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
The WebService answers under the address /myapp/webservice/v1, but when I type /myapp/webservice/v1?wsdl, it's converted into /myapp/webservice/v1/?wsdl, which doesn't return WSDL, but it tries to invoke the WebService itself, which answers: "Hello! This is an Axis2 Web Service!" (standard greeting when doing GET to WebService).
I've tried also with url pattern '.'. '' and '/' are not accepted (WebSphere).
When I use
<url-pattern>ws</url-pattern>
and
<welcome-file-list>
<welcome-file>ws</welcome-file>
</welcome-file-list>
the web service works, but the WSDL is available only on /myapp/webservice/v1/ws?wsdl, which makes the solution incompatibile with existing clients.
The reason behind is to create version as separate WARs, which can be then deployed independently or within EAR, and to make WebService address fully configurable, we need to make it accessible under the context root of the Web Module.
I don't know if the problems we are experiencing are WebSphere-specific or Axis-specific...

Spring with Apache Camel and Web services getting started

I am starting to try to figure out how to work with Apache Camel within a Spring framework. The first thing that I want to try to get a grasp on would be running simple web service calls over this but I have no idea where to start.
Right now all I have is a basic HelloWorld Spring project set up and am trying to figure out what needs to be configured Apache Camel wise and where to get started on creating a simple web service.
I have taken a look at the examples on the Apache site but I was hoping maybe someone here knew of a tutorial that was a basic start to finish of something like I am trying to do.
Thanks for any tips or help that you all have!
I really found this one useful once: http://camel.apache.org/spring-ws-example.html (and complete source code in the camel distribution).
There are multiple ways you can deal with web services with Camel. Either use the spring web services as in the example I mention, or use Apache CXF.
Spring Web services are really easy to get started with, compared to CXF. Although CXF is a more complete web service stack.
There are multiple Camel and CXF examples here:
http://camel.apache.org/examples.html
If you go with CXF, you may well benefit from actually learning a few "CXF only" examples before mixing with Camel.
There are essentially two ways to do web services, contract first start with a WSDL, then auto generate classes/interfaces. The other approach is code first - where the you start with java classes and then get an auto generated WSDL.
There are some rather good articles over here: http://cxf.apache.org/resources-and-articles.html
But to answer your question, I don't know of any good step-by-step tutorial on this matter. The examples in the links are really good though.
I had the same question, and I have found this article
Step by step introduction to Web services creation using CXF and Spring:
http://www.ibm.com/developerworks/webservices/library/ws-pojo-springcxf/index.html?ca=drs-
In short, there is four steps to create a web service
1 - Create a service endpoint interface (SEI) and define a method to
be exposed as a Web service.
package demo.order;
import javax.jws.WebService;
#WebService
public interface OrderProcess {
String processOrder(Order order);
}
2 - Create the implementation class and annotate it as a Web service.
package demo.order;
import javax.jws.WebService;
#WebService(endpointInterface = "demo.order.OrderProcess")
public class OrderProcessImpl implements OrderProcess {
public String processOrder(Order order) {
return order.validate();
}
}
3 - Create beans.xml and define the service class as a Spring bean
using a JAX-WS front end.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint
id="orderProcess"
implementor="demo.order.OrderProcessImpl"
address="/OrderProcess" />
</beans>
4 - Create web.xml to integrate Spring and CXF.
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

Spring web-scoped beans and axis2

I want to use spring web-scoped beans in web-service written on AXIS2 framework.
How to configure it?
Axis2 and Spring documentation disagree with each other.
Axis2 documentation says:
For the purpose of this example, we'll configure Spring via a WAR file's web.xml. Let's add a context-param and a listener:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
Spring documentation says:
When using a Servlet 2.4+ web container, with requests processed outside of Spring's DispatcherServlet (e.g. when using JSF or Struts), you need to add the following javax.servlet.ServletRequestListener to the declarations in your web application's 'web.xml' file.
<web-app>
...
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
...
</web-app>
When I use Axis2-recommended ContextLoaderListener with Spring web-scoped beans I got on deploy
java.lang.IllegalStateException: No thread-bound request found: Are
you referring to request attributes outside of an actual web request,
or processing a request outside of the originally receiving thread? If
you are actually operating within a web request and still receive this
message, your code is probably running outside of
DispatcherServlet/DispatcherPortlet: In this case, use
RequestContextListener or RequestContextFilter to expose the current
request.
When I use Spring-recommeded RequestContextListener I got running Web-service with fault on requests:
<faultstring>The SERVICE_OBJECT_SUPPLIER parameter is not specified.</faultstring>
In other words: how to configure AXIS2 with Spring and RequestContextListener?
No such functionality in AXIS2. See request https://issues.apache.org/jira/browse/AXIS2-5467 "Extend Spring support to accept web-scoped beans" for detail.