Proxify Web Services in PEtALS with Maven

02/06/2009

This is quite the same thing than the previous post where I introduced how to expose JAXWS service in PEtALS ESB with Maven. This time, let’s proxify a Web service in PEtALS with Maven.

Here is the Maven descriptor snippet :

<build>
	<plugins>
		<plugin>
			<groupId>org.ow2.petals</groupId>
			<artifactId>maven-petals-wsproxy</artifactId>
			<version>1.0-SNAPSHOT</version>
			<executions>
				<execution>
					<id>generate-jbi</id>
					<phase>package</phase>
					<configuration>
						<wsdl>
							http://localhost:8080/Service?wsdl
						</wsdl>
					</configuration>
					<goals>
						<goal>wsproxy</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

This will generate a JBI Service Assembly that you can then deploy intoo PEtALS to proxify the service defined in http://localhost:8080/Service?wsdl

You can give it a try, the snapshot version is available on the OW2 Maven repository

Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

PEtALS , ,

Easily expose JAXWS in PEtALS with Maven

26/05/2009

Since I am always using command line tools such as Maven or Ant to create my project and to package them, I have just created a new Maven plugin to easily and quickly expose a JAXWS service in PEtALS with Maven. This plugin will generate the JBI Service Unit and Service Assembly from a Maven java project with just a few lines of Maven settings…

As an example, the following interface :

package org.ow2.petals;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
@WebService
public interface Service {
 
	@WebMethod
	String ping(String input);
}

and its implementation :

package org.ow2.petals;
 
public class ServiceImpl implements Service {
	public String ping(String input) {
		return input;
	}
}

will generate a Service Assembly idirectly deployable to PEtALS by the help of the Maven plugin :

<build>
	<plugins>
		<plugin>
			<groupId>org.ow2.petals</groupId>
			<artifactId>maven-petals-jaxws2jbi</artifactId>
			<version>1.0-SNAPSHOT</version>
			<executions>
				<execution>
					<id>generate-jbi</id>
					<phase>package</phase>
					<configuration>
						<className>
							org.ow2.petals.ServiceImpl
						</className>
					</configuration>
					<goals>
						<goal>java2jbi</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

The plugin takes the Service class, generates its associated WSDL file and the JBI descriptor and then package all into a Service Assembly.

Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

PEtALS , ,

An operation with name ” already exists in this service

14/05/2009

Here is a tip on how to avoid this type of exception with JAXWS but before let’s try to understand why your Service construciton fails…

This exception occurs when your service definition (the Java interface in our case) have some duplicates methods without the same number of parameters (ie method overloading). This exception is totally normal since it is quite logic that the resulting Web Service can only have unique operation names :

  • Check a WSDL file. Did you ever see the same operation X times?
  • The Web Service Engine generally tries to get the operation context from the operation name. Then it will unmarshall the parameters (it will not have a look to the operation parameters to choose the operation like it should be done in the Java Runtime).

Here is a service definition sample which will be used in this article :

package com.googlecode.chamerling.blog.jaxws.duplicate;
 
/**
 * @author Christophe HAMERLING
 *
 */
public interface Service {
 
	void foo();
 
	void foo(String bar);
}

So let’s implement this interface :

package com.googlecode.chamerling.blog.jaxws.duplicate;
 
import javax.jws.WebService;
 
/**
 * @author Christophe HAMERLING
 *
 */
@WebService
public class ServiceKo implements Service {
 
	public void foo() {
	}
 
	public void foo(String bar) {
	}
}

Let’s use the JaxWsServerFactoryBean CXF factory (other WS stacks should throw the same exception…) to expose this service :

import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
 
/**
 * @author Christophe HAMERLING
 */
public class App {
 
	private static final String URL = "http://localhost:9999/chamerling/services/";
 
	public static void main(String[] args) {
		JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
		Service space = new ServiceKo();
		svrFactory.setAddress(URL + "ServiceKO");
		svrFactory.setServiceBean(space);
 
		org.apache.cxf.endpoint.Server service = svrFactory.create();
 
		System.out.println("Service is available at "
				+ service.getEndpoint().getEndpointInfo().getAddress());
 
	}
}

You should have a beautiful stack trace :

java.lang.IllegalArgumentException: An operation with name [{http://duplicate.jaxws.blog.chamerling.googlecode.com/}foo] already exists in this service
	at org.apache.cxf.service.model.InterfaceInfo.addOperation(InterfaceInfo.java:71)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createOperation(ReflectionServiceFactoryBean.java:774)
	at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.createOperation(JaxWsServiceFactoryBean.java:484)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createInterface(ReflectionServiceFactoryBean.java:766)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:361)
	at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:525)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:422)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:190)
	at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:164)
	at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:100)
	at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:117)
	at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:168)
	at com.googlecode.chamerling.blog.jaxws.duplicate.AppTest.testKoService(AppTest.java:37)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at junit.framework.TestCase.runTest(TestCase.java:154)
	at junit.framework.TestCase.runBare(TestCase.java:127)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:118)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

So teh solution is to use the @WebParam annotation. Simply use this annotation to specify unique operation names in your service implementation :

package com.googlecode.chamerling.blog.jaxws.duplicate;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
/**
 * @author Christophe HAMERLING
 *
 */
@WebService
public class ServiceOk implements Service {
 
	@WebMethod(operationName = "foo1")
	public void foo() {
	}
 
	@WebMethod(operationName = "foo2")
	public void foo(String bar) {
	}
}

Sources for this example are availble on my google code project (http://code.google.com/p/chamerling/) under http://code.google.com/p/chamerling/source/browse/#svn/trunk/blog/jaxws-duplicate

Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

WebService , ,

SCA and PEtALS ESB, Yes We Can!

07/05/2009

This news has not been published on the PEtALS Web Site (why?) but yes we now have some SCA (Service Component Architecture) tools available with PEtALS ESB!

This work is a result of the ScorWare project in which eBM WebSourcing was involved in.

The SCA feature is provided in PEtALS by the SCA JBI Service Engine (link to the component and link to the documentation)

The main advantage of SCA over other approaches, like BPEL or EIP, is that you can define the composition with Java instead of XML. The SCA composite defines services, which are exposed in the bus. It also defines references, which point to services that might be called or used by the composite at runtime. These references define possible dependencies. And eventually, your composite embeds a Java implementation which allows you to manipulate the references as simple Java objects. This makes the user job easier, in particular to call a service operation or test conditions on a service call result.

For more details on SCA, on tools and more, take a look at the links below :

  • SCA is a specification defined by the Open SOA consortium.
  • SCA is in standardization process by the OASIS Consortium.
  • OW2 FraSCAti is the SCA platform the SCA service engine is based on.
  • Eclipse SCA Tools exist and are hosted by the SOA Tools Platform project. They can be used with the SCA service engine.
  • PEtALS Eclipse tools complete the STP SCA tools for PEtALS specifics (PEtALS Maven plug-in support, packaging for PEtALS…).
Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

PEtALS , ,

Just testing the Google App Engine Java Version

23/04/2009

Just tested the Google App Engine Java version and its Eclipse plugin, really amazing. The sample application is deployed from Eclipse and is running at http://hamerlingchristophe.appspot.com/

I think that I will try to do some things related to SOA and PEtALS on this platform, just need time…

Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

Google ,

Google Data API presentation

23/04/2009

A quick entry on a really good presentation of the Google Data API, simple and interesting…

http://www.infoq.com/presentations/google-data-api-gdata

Frank Mantek discusses the Google Data API (GData) including decisions to use REST rather than SOAP technology, how the API is used, numerous examples of how GData has been used by clients, and future plans for evolving the API. A discussion of how GData facilitates Cloud Computing concludes the presentation.

Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

Google ,

Developing under Mac OS X : The keyboard…

16/04/2009

Mac OS X is cool but where are my special characters I need while developing??? Here are some keys combinations which are (quite) useful :

  • | is under OPTION+SHIFT+L
  • { is under OPTION+( and } is under OPTION+)
  • [ is under OPTION+( and ] is under OPTION+)
  • \ is under OPTION+SHIFT+/
Should be easier now…
Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

Non classé

Apache CXF Clients : null result when using bad client factory

09/04/2009

Just a quick note to show that the client factory choice is important with Apache CXF 2.1.4.

The service interface definition :

package org.ow2.petals.usecase.soapaddressing.server;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
/**
 * @author chamerling - eBM WebSourcing
 *
 */
@WebService
public interface AddressingService {
 
    /**
     * Get the local information
     * 
     * @return
     */
    @WebMethod
    String getInfo();
 
}

The client with the bad client factory :

package org.ow2.petals.usecase.soapaddressing.client;
 
import org.apache.cxf.frontend.ClientProxyFactoryBean;
import org.ow2.petals.usecase.soapaddressing.server.AddressingService;
 
/**
 * @author chamerling - eBM WebSourcing
 *
 */
public class BadFactory {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
        factory.setServiceClass(AddressingService.class);
        factory.setAddress("http://localhost:8084/petals/services/Service01");
        AddressingService client = (AddressingService) factory.create();
        String info = client.getInfo();
        System.out.println(info);
    }
}

With that client code, the Web Service is really invoked, but the result of the getInfo operation is null. So, let’s do it with the right client factory…

The client with the good client factory :

package org.ow2.petals.usecase.soapaddressing.client;
 
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.ow2.petals.usecase.soapaddressing.server.AddressingService;
 
/**
 * @author chamerling - eBM WebSourcing
 *
 */
public class GoodFactory {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(AddressingService.class);
        factory.setAddress("http://localhost:8084/petals/services/Service01");
        AddressingService client = (AddressingService) factory.create();
        String info = client.getInfo();
        System.out.println(info);
    }
}

This time the result is not null and is really the one expected…

Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

WebService , ,

JSR181 Servive Engine sample : Talk to Twitter

01/04/2009

Just for fun…

The current article will show you that the JSR181 Service Engine really provides an easy way to create JBI services. Since creating simple HelloWorld service is quite boring, let’s talk to twitter micro blogging site.

I will use the Twitter4J API () to talk to Twitter (right all the Twitter job is done here… The current article is not a Twitter tutorial but just a small PEtALS one…).

Interface definition

package net.chamerling.petals.twitter;
 
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
 
/**
 * @author chamerling
 *
 */
@WebService
public interface TwitterService {
 
	@WebMethod
	public String update(@WebParam(name = "id") String login,
			@WebParam(name = "password") String password,
			@WebParam(name = "status") String status) throws TwitterServiceException;
 
	@WebMethod
	public String[] getTimeLine(@WebParam(name = "id") String login,
			@WebParam(name = "password") String password,
			@WebParam(name = "user") String user) throws TwitterServiceException;
}

Implementation (quick)

package net.chamerling.petals.twitter;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
 
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
 
/**
 * @author chamerling
 *
 */
@WebService(serviceName = "TwitterService", name = "TwitterService", targetNamespace = "http://twitter.chamerling.net/petals")
public class TwitterServiceImpl implements TwitterService {
 
	/*
	 * (non-Javadoc)
	 * @see net.chamerling.petals.twitter.TwitterService#update(java.lang.String, java.lang.String, java.lang.String)
	 */
	@WebMethod
	public String update(@WebParam(name = "id") String login,
			@WebParam(name = "password") String password,
			@WebParam(name = "status") String status) throws TwitterServiceException {
		String result = null;
		try {
			Status s = getTwitter(login, password).update(status);
			result = s.getText();
		} catch (twitter4j.TwitterException e) {
			throw new TwitterServiceException(e.getMessage());
		}
		return result;
	}
 
	/*
	 * (non-Javadoc)
	 * @see net.chamerling.petals.twitter.TwitterService#getTimeLine(java.lang.String, java.lang.String, java.lang.String)
	 */
	@WebMethod
	public String[] getTimeLine(@WebParam(name = "id") String login,
			@WebParam(name = "password") String password,
			@WebParam(name = "user") String user) throws TwitterServiceException {
		Twitter twitter = getTwitter(login, password);
		List result = new ArrayList();
		List status = null;
		try {
			if (user == null) {
				status = twitter.getUserTimeline();
			} else {
				status = twitter.getUserTimeline(user);
			}
		} catch (TwitterException e) {
			throw new TwitterServiceException(e.getMessage());
		}
 
		for (Status status2 : status) {
			result.add(status2.getText());
		}
 
		return result.toArray(new String[0]);
	}
 
	/**
	 * TODO : Some work to do for caching...
	 * 
	 * @param login
	 * @param password
	 * @return
	 */
	private Twitter getTwitter(String login, String password) {
		return new Twitter(login, password);
	}
}

Put all of this in a JSR181 Service Unit, ie create the good Service Unit descriptor (cf to source attchment), package it (use PEtALS Maven plugin) and that’s all. JSR181 makes it easy ;o)

So now you can publish some status to Twitter with PEtALS.
I have created a test acount here http://twitter.com/chamerlingtest on which I have published messages with PEtALS.

Service Unit sources are available here : http://dl.getdropbox.com/u/73785/blog/twitter-jsr181.zip

Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

PEtALS, SOCIAL , ,

Going to SOA4All project first year review

27/03/2009

Next week at the SOA4All project first year review (Brussels NESSI office), I will show a prototype of the SOA4All Distributed Service Bus based on PEtALS ESB and on a P2P based library.
Like in every middleware demo, it is always difficult to show something ’sexy’ since exchanging XML messages is not… This time I have a web portal based on GWT which is connected to the Bus which is more funky. The main point is how message are exchanged between PEtALS nodes with P2P and semantic techniques. I think this feature will be available in PEtALS before the end of the project (year 2011), so stay tuned.

Share and Enjoy:
  • Digg
  • Google
  • del.icio.us
  • Facebook
  • StumbleUpon
  • E-mail this story to a friend!

PEtALS, soa4all , ,