tapestry-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From P.Stavrini...@albourne.com
Subject Re: T5.2 and Metro / SOAP
Date Wed, 05 Oct 2011 11:03:50 GMT
Hello!

I am using Metro Web Services for near over a year now, and I am pretty happy with it... Integration
with .Net was very trivial , in-fact there is nothing to do on the client except point to
the wsdl file. Having said that though, recently we have created some CXF web services, and
the integration was also very clean, there are only some slight differences btw them. Both
are great, Metro docs are a little thin for my liking, I battled through some edge cases.
The CXF web services we deployed are standalone services, with only the tapestry IoC jar,
whereas I integrated Metro directly into a Tapestry web app. 

This is a basic outline of how I did it, I don't know if its the best approach, but at the
time I found very minimal help / docs, so it was largely my own device. My approach has zero
xml as well, which is what I was after, but be warned you may have problems if you need your
wsdl to be published as an SSL URL, for that Endpoint.publish will not work, you need the
bottom up xml first approach:

1. Create your own filter that will extend Tapestry's
<filter>
	<filter-name>app</filter-name>
	<filter-class>com.web.services.entws.NewWebFilter</filter-class>
</filter>


2. Extend TapestryFilter, Tapestry provides you a convenient extension point out the box:


public class NewWebFilter extends TapestryFilter {

	
	@Override
	protected void init(Registry registry) throws ServletException {
		publishEndpointSingletonServices(registry, HOST_ABSOULTE_URI);
	}

	
// Generic method to my bind Handler chains and EndPoints
	@SuppressWarnings("unchecked")
	private void publishEndpointSingletonServices(Registry registry, String host) {
		for (Class<?> serviceInterface : getSingletonEndPoints()) {
			WebService annotation = serviceInterface
					.getAnnotation(WebService.class);
			if (annotation != null) {
				Endpoint endpoint = Endpoint.create(registry
						.getService(serviceInterface));
			
				
				//eliminates the need to bind using @HandlerChain(file = "handlers.xml")
				List<Handler> chain = endpoint.getBinding().getHandlerChain();
				chain.add(new WsAccessLog());
				chain.add(new WsSoapAccessLog());
				endpoint.getBinding().setHandlerChain(chain);
				
				String fullAddress = host + annotation.serviceName();
				endpoint.publish(fullAddress);
				
			}
		}
	}

	/**
	 * A method to bind enterprise web service endpoints
	 * @return a list of the service endpoint proxies
	 */
	private ArrayList<Class<?>> getSingletonEndPoints() {
		ArrayList<Class<?>> serviceEndpointInterfaces = new ArrayList<Class<?>>();

		// *** Add services here:
		serviceEndpointInterfaces.add(WsFundQueryImpl.class);
		serviceEndpointInterfaces.add(WsAuthenticationImpl.class);
                ...etc
		return serviceEndpointInterfaces;
	}
}

3. Now use regular IoC bindings in your AppModule:
		binder.bind(WsAuthenticationImpl.class).withId(
				"WsAuthentication");
		binder.bind(WsFundQueryImpl.class).withId("WsFundQuery");


4. Then create your web service, it is a regular IoC service, you can use any services via
constructor injection as per normal (even other bound web services work), only difference
being the class is annotated with JAXWS annotations

@WebService(serviceName = "fundquery", targetNamespace="WsClient")
public class WsFundQueryImpl {

	private FundsService fundData_;
	private final SOAPSessionFactory soapSessionFactory_;
	private final WsAuthenticationImpl wsAuthentication_;
	private final FundClassRepository fundClassRepository_;
	private final TimeSeriesRepository timeSeriesRepository_;

	public SOAPSessionFactory getSoapSessionFactory() {
		return soapSessionFactory_;
	}

	public WsFundQueryImpl(FundsService fundData,
			SOAPSessionFactory soapSessionFactory,
			WsAuthenticationImpl wsAuthentication,
			FundClassRepository fundClassRepository,TimeSeriesRepository timeSeriesRepository) throws
IOException {
		fundData_ = fundData;
		soapSessionFactory_ = soapSessionFactory;
		castleWsAuthentication_ = wsAuthentication;
		fundClassRepository_ = fundClassRepository;
		timeSeriesRepository_ = timeSeriesRepository;
		
	}

	
	
	@WebMethod
	public synchronized List<WsClientFundsContainer> getFundReturnsForClient(
			String username, String password) {

		...

	}

5. You als need Metro of course, I use a profile to include it in my pom:
<profile>
		<id>Metro</id> 
		<properties>
			<metro.version>2.2.1</metro.version> <!-- JAX-WS RI version - see https://jax-ws.dev.java.net/
-->
		</properties>
		<activation>
			<activeByDefault>true</activeByDefault>
		</activation>
		<pluginRepositories>
			<pluginRepository>
				<id>maven2-repository.dev.java.net</id>
				<name>Java.net Maven 2 Repository</name>
				<url>http://download.java.net/maven/2/</url>
			</pluginRepository>
		</pluginRepositories>
		
		<dependencies>
			<dependency>
				<groupId>com.sun.xml.ws</groupId>
				<artifactId>jaxws-rt</artifactId>
				<version>${metro.version}</version>
			</dependency>
			<dependency>
           		<groupId>javax.jws</groupId>
            	<artifactId>jsr181-api</artifactId>
            	<version>1.0-MR1</version>
            </dependency>
			
		</dependencies>
	</profile>

I am running all this on Tomcat 6, I am pretty happy with this solution. One thing I have
noticed though is that deploying a new version requires a restart of Tomcat. Of course if
you wanted more stateful web services I could recommend using glassfish instead of Tomcat,
as it is also an EJB container and has built in support for Metro, and good tools in Netbeans,
(I am using eclipse though).

As you can see integration is trivial in Tapestry, but unfortunately this stuff is not documented...
Hope this helps u out!

Kind regards,
Peter


----- Original Message -----
From: "Lenny Primak" <lprimak@hope.nyc.ny.us>
To: "Tapestry users" <users@tapestry.apache.org>
Sent: Thursday, 22 September, 2011 19:23:52 GMT +02:00 Athens, Bucharest, Istanbul
Subject: Re: T5.2 and Metro / SOAP

I would love to see metro integration. Just because it's the default in glassfish and I am
already using it. Or any thoughts on how to implement it. 



On Sep 22, 2011, at 12:12 PM, Norman Franke <norman@myasd.com> wrote:

> I know Metros quite Windows .NET friendly. Not sure about CXF, but if so, I could go
that way, too. The question would still remain. Can you integrate Tapestry IoC with CXF relatively
easily?
> 
> Norman Franke
> Answering Service for Directors, Inc.
> www.myasd.com
> 
> 
> 
> On Sep 21, 2011, at 6:35 PM, Daniel Honig wrote:
> 
>> Why use metro when you can use CXF?
>> 
>> Metro is good, but I don't think there is as much activity as CXF post the
>> Sun/Oracle merger.
>> 
>> On Wed, Sep 21, 2011 at 6:31 PM, Norman Franke <norman@myasd.com> wrote:
>> 
>>> I have a need to create some web services to provide SOAP access. I'm
>>> already using Tapestry 5.2 for our web applications, so I think it would be
>>> natural to be able to use Tapestry's IoC with Metro, if possible. This would
>>> save me from having to re-implement all the DAO functionality.
>>> 
>>> Has anyone done this? Any thoughts on how to approach this? I'm new to
>>> Metro, but I'm pretty comfortable with Tapestry 5.2.
>>> 
>>> Norman Franke
>>> Answering Service for Directors, Inc.
>>> www.myasd.com
>>> 
>>> 
>>> 
>>> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Mime
View raw message