I thought I would attack this topic next given its growing popularity in the forums !. So why is this so popular? The context is pretty much given in the earlier tutorial for creating a SOAP client. There are at least a couple of ways for extending the given, out of the box SOAP capabilities of JIRA. Those will be writing an RPC plugin (thanks to JIRA for giving that option) and re-building the RPC plugin. I prefer writing a new RPC Plugin. The one problem I see with it is that it introduces a new web service. So you end up connecting to the JIRA native one for the all the methods JIRA already exposes and to the new custom one for the new methods that is written. But re-building RPC plugin appears more painful for me because
So, let me assume that you are with me on writing a new RPC plugin. Here is how you write your descriptor to define the new RPC module. I am writing a v1 plugin here as I haven't worked on a v2 rpc plugin yet! As the JIRA rpc plugin is a v1 plugin, I guess it makes sense to keep this one also as v1.
<rpc-soap key="jtricks-soap-service" name="JTricks SOAP Service" class="com.jtricks.JTricksSoapServiceImpl">
<description>JTricks SOAP service.</description> <service-path>jtricksservice</service-path> <published-interface>com.jtricks.JTricksSoapService</published-interface> </rpc-soap> Let us have a look in detail. You need a new interface for your SOAP module and an implementation class for this. In our case we have JTricksSoapService and JTricksSoapServiceImpl. Now we need to define both of these in the rpc-soap module. As usual, the module should have a unique key along with the other details. Now define the method you want to expose, inside the interface.
public interface JTricksSoapService {
String login(String username, String password); // Method to return Project Categories RemoteCategory[] getProjectCategories(String token) throws RemoteException; } Before we move on to the Implementation, we need to define what is a RemoteCategory. Let us assume we need only the name for now. RemoteCategory will then look like this:
public class RemoteCategory extends AbstractNamedRemoteEntity {
private String name; public RemoteCategory(GenericValue value) { super(value); this.name = value.getString("name"); } public String getName() { return this.name; } public void setName(String name) { this.name = name; } } It should extend AbstractNamedRemoteEntity class. Make sure you add the following dependency in the pom.xml for that:
<dependency>
<groupId>atlassian-jira-rpc-plugin</groupId> <artifactId>atlassian-jira-rpc-plugin</artifactId> <version>3.13-1</version> <scope>provided</scope> </dependency> Use the appropriate version. You will find the jars in your jira distribution or in the maven repository. Now we create the implementation. Here is how the getProjectCategories look like in the implementation class:
public RemoteCategory[] getProjectCategories(String token) throws RemoteException {
validateToken(token); Collection<GenericValue> categories = projectManager.getProjectCategories(); RemoteCategory[] remoteCategories = new RemoteCategory[categories.size()]; int i = 0; for (GenericValue category : categories) { remoteCategories[i++] = new RemoteCategory(category); } return remoteCategories; } Make sure you validate the token first using the tokenManager. You can inject the manager in the constructor.
private void validateToken(String token) {
try { User user = tokenManager.retrieveUser(token); } catch (RemoteAuthenticationException e) { throw new RuntimeException("Error Authenticating!,"+e.toString()); } catch (RemotePermissionException e) { throw new RuntimeException("User does not have permission for this operation,"+e.toString()); } } You create the token using the initial method in the SOAP module which will look like this:
public String login(String username, String password) {
try { return tokenManager.login(username, password); } catch (RemoteAuthenticationException e) { throw new RuntimeException("Error Authenticating!,"+e.toString()); } catch (com.atlassian.jira.rpc.exception.RemoteException e) { throw new RuntimeException("Couldn't login,"+e.toString()); } } Coming back to the getProjectCategories method, Once the token is validated, just retrieve all the categories using ProjectManager, populate the array of RemoteCategory and return it! Simple, isn't it? All you need now is to build the plugin and put it under WEB-INF/lib. You can reach your new awesome webservice at {your_jira_url}/rpc/soap/jtricksservice?WSDL . You can similarly extend the XPM-RPC methods as well. Read more about all these in the Atlassian docs . And find the source code for this tutorial below. Let us know how it went! And feel free to add any comments / feedbacks.
13 Comments
"The system RPC plugin is still version one? No way!" I thought so I checked the source and you're right. Then I filed a bug with Atlassian: http://jira.atlassian.com/browse/JRA-22596
Reply
J-Tricks
10/25/2010 07:10:16 am
Thanks Matt. Very valid points.
Reply
Raj
1/24/2011 05:53:40 pm
Hi,
Reply
J-Tricks
1/24/2011 06:16:22 pm
Raj,
Reply
Raj
1/24/2011 06:33:31 pm
Reply
J-Tricks
1/24/2011 06:48:52 pm
Raj,
Reply
Christina
6/16/2011 01:34:15 pm
Hi,
Reply
J-Tricks
6/16/2011 07:23:10 pm
Christina,
Reply
Christina
6/17/2011 06:25:30 am
Hi again!
Reply
J-Tricks
6/17/2011 07:52:05 am
Christina,
Reply
Christina
6/20/2011 06:56:08 am
Hi,
Reply
J-Tricks
6/20/2011 09:18:22 pm
Christina, Seems the SOAP Header is not constructed properly. You might be encountering something specific to .NET invocation.
Reply
6/26/2013 12:56:25 am
Awesome post! This is an informative article for all the SOAP clients. This can really make them confident in building an RPC plug in. These instructions can speed up the implementation of SOAP module. I will continue looking after your blog for more such instructions. Thank you!
Reply
Your comment will be posted after it is approved.
Leave a Reply. |
AuthorJobin Kuruvilla - Works in Adaptavist as Head of DevOps Professional Services. Categories
All
Archives
October 2016
|