Hi,
I'm working on JIRA 4.4.4 & Confluence 3.5.13
Until now, I used to make an RPC call to Confluence from my JIRA plugin using TrustedApps (with TrustedApplicationsManager) in order to retrieve a Confluence spaces list (the JIRA application was trusted from Confluence), like this :
XmlRpcHandler rpcClient = remoteQueryFactory.getXmlRpcHandler(xmlrpcUrl, user, trustedApplicationsManager); result = rpcClient.execute(service + "." + method, parameters);
I'm currently trying to update this one in order to use Application Links, but I can't find out how to do it, and none documentation I found is helping me.
Does anyone could help me on this ?
Thank you in advance,
Regards,
--
Clément Capiaux
Community moderators have prevented the ability to post new answers.
I found the problem !
I was creating the ApplicationLinkRequest object omitting the base URL before "/rpc/xmlrpc/" and adding the service path. That's not correct, it has to be done as below :
ApplicationLinkRequest request = requestFactory.createRequest(MethodType.POST, aAppLink.getRpcUrl() + "/rpc/xmlrpc");
The method/parameters call are written in a XML message computed in the requestBody attribute of the ApplicationLinkRequest object (I give the complete class code at the bottom of this comment)
Besides, I managed to make my RPC call through ApplicationLinks, without no effort because the "execute" method of ApplicationLinkRequest object is returning a String, and through this, my Vector object returned from my Confluence RPC service is serialized in a XML String.
So I had to develop some bean classes in order to unmarshall the serialized XML in an appropriate object, in order to rewrite it as a Vector like the output of my RPC service method.
All these informations could be very helpful for anyone who would make a RPC call through ApplicationLinks in the future !
This is the code of my Java class realizing all this mechanism (the bean classes for XML unmarshalling are not shown but if needed, simply ask me :
package com.valiantys.jira.plugins.confluence.entitypicker.trustedapps; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import org.apache.log4j.Logger; import com.atlassian.applinks.api.ApplicationLink; import com.atlassian.applinks.api.ApplicationLinkRequest; import com.atlassian.applinks.api.ApplicationLinkRequestFactory; import com.atlassian.applinks.api.ApplicationLinkService; import com.atlassian.sal.api.net.Request.MethodType; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.Dom4JDriver; public class RemoteQueryLauncher { /** * class Logger. */ private static final Logger LOG = Logger.getLogger(RemoteQueryLauncher.class); private final ApplicationLinkService appLinkService; private static XStream xstream; public RemoteQueryLauncher(final ApplicationLinkService aAppLinkService) { this.appLinkService = aAppLinkService; } public Object doLaunchQuery(final String service, final String method, final Vector parameters) throws Exception { Object result = null; if (this.xstream == null) { xstreamInit(); } Iterable<ApplicationLink> appLinks = appLinkService.getApplicationLinks(); if (appLinks != null) { for (Iterator<ApplicationLink> it = appLinks.iterator(); it.hasNext();) { ApplicationLink aAppLink = it.next(); LOG.debug("Application link found : " + aAppLink.getName()); ApplicationLinkRequestFactory requestFactory = aAppLink.createAuthenticatedRequestFactory(); String url = aAppLink.getRpcUrl() + "/rpc/xmlrpc"; LOG.debug("RPC service about to be called : " + url); // building Application Link request ApplicationLinkRequest request = requestFactory.createRequest(MethodType.POST, url); // setting request headers (as it was done before by XmlRpcHandler class, with call method through the TrustedAppsManager) request.addHeader("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"); request.setRequestContentType("text/xml"); request.addHeader("Pragma", "no-cache"); request.addHeader("Cache-Control", "no-cache"); // building XML RPC message from the service path, the method name, and parameters values request.setRequestBody(computeRequestBody(service, method, parameters)); String xml = request.execute(); ConfluenceRpcResponse unmarshalledResponse = (ConfluenceRpcResponse) xstream.fromXML(xml, new ConfluenceRpcResponse()); result = computeObjectFromResponse(unmarshalledResponse); } } else { LOG.debug("None application link has been found"); } return result; } private String computeRequestBody(final String aService, final String aMethod, final Vector aParameters) { StringBuilder strBuilder = new StringBuilder(); strBuilder.append("<?xml version=\"1.0\"?>"); strBuilder.append("<methodCall>"); strBuilder.append("<methodName>"); strBuilder.append(aService + "." + aMethod); strBuilder.append("</methodName>"); strBuilder.append("<params>"); for (int i = 0; i < aParameters.size(); i++) { strBuilder.append("<param><value>"); strBuilder.append(aParameters.get(i)); strBuilder.append("</value></param>"); } strBuilder.append("</params>"); strBuilder.append("</methodCall>"); return strBuilder.toString(); } private Object computeObjectFromResponse(final ConfluenceRpcResponse unmarshalledResponse) { if (unmarshalledResponse != null && unmarshalledResponse.getParams() != null) { ResponseValue responseValue = unmarshalledResponse.getParams().get(0).getValue(); if (responseValue.getArray() != null) { Vector<Hashtable<String, String>> vectorResponse = new Vector<Hashtable<String, String>>(); for (DataValue aDataValue : responseValue.getArray().getData()) { Hashtable<String, String> aComputedValue = new Hashtable<String, String>(); for (ResponseMember aMember : aDataValue.getStruct()) { aComputedValue.put(aMember.getName(), aMember.getValue()); } vectorResponse.add(aComputedValue); } return vectorResponse; } else if (responseValue.getStruct() != null) { Hashtable<String, String> hashtableResponse = new Hashtable<String, String>(); for (ResponseMember aMember : responseValue.getStruct()) { hashtableResponse.put(aMember.getName(), aMember.getValue()); } return hashtableResponse; } } return null; } private static void xstreamInit() { xstream = new XStream(new Dom4JDriver()); xstream = new XStream(new Dom4JDriver()); xstream.autodetectAnnotations(true); xstream.alias("methodResponse", ConfluenceRpcResponse.class); xstream.alias("param", ResponseParam.class); xstream.alias("value", ResponseValue.class); xstream.alias("member", ResponseMember.class); } }
Regards, and thank you Joseph for your help :)
Great work solving the problem! :-)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This tutorial provides an example of how to Application Links to connection to Confluence from JIRA: https://developer.atlassian.com/display/JIRADEV/Plugin+Tutorial+-+Application+Links+in+JIRA
is it helpful?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I managed to prepare objects for my call, but I can't find how to build the URL (POST or GET), in order to make the RPC call I used to do like this :
XmlRpcHandler rpcClient = RemoteQueryFactory.getXmlRpcHandler(xmlrpcUrl, user, trustedApplicationsManager); result = rpcClient.execute(service + "." + method, parameters);
Is there anyone who have done this yet ? Any help on how to build the Application Links query ?
For now, I tried to do it as below (I put the XML message built as it was done when I used the RPC client) :
ApplicationLinkRequest request = requestFactory.createRequest(MethodType.POST, "/rpc/xmlrpc/" + myRpcServicePath); request.setRequestBody("<methodCall><methodName>myRpcServicePath.aMethodName</methodName><params><param><value>param1</value></param><param><value>param2</value></param></params></methodCall>"); result = request.execute();
, and I get a ResponseException like this :
com.atlassian.sal.api.net.ResponseException: Unexpected response received. Status code: 404
Any help will be appreciated :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Does the ApplicationLinkRequest type provide a way to see the full URL that will be used? The fact that the response you are getting is a 404 means that maybe the URL is not being constructed correctly?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
hi joseph;
https://developer.atlassian.com/display/JIRADEV/Plugin+Tutorial+-+Application+Links+in+JIRA
with this link i am able to get url of confluence page
i want to display whole page data instead of just url on jira issue tab panel
is this possible?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.