REST call from within Macro Plugin throws error w. RestClientFactory or refused with Jersey client

Hauke Hörhold
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 6, 2020

I try to make a REST call from within an Confluence Macro Java Plugin to my own Confluence page (for Confluence version 7.5.2), to get JSON content from a page. I use Jersey for it.
I tried to save and load content properties from pages via functions calls from the API like using the ContentPropertyService, but I got stuck with it somehow and now I want to try it with REST calls, which will do the same thing in the end.

The problem:
When I'm using the com.sun.jersey.api.client.Client the plugin works, but I get an error saying the connection is refused. It seems I can't make a REST call from within my own plugin to my own Confluence page where it is installed on. From a website or a REST tool it's possible to get information from the domain with a get call on https://DOMAIN/rest/api/content/PAGENR/property. And when I load some JSON from external sources it's working fine.

So I found RestClientFactory from Atlassian (https://mvnrepository.com/artifact/com.atlassian.confluence/confluence-rest-client/7.3.3) which seems to create a Jersey client with correct default Atlassian configuration. But when I'm using it, the plugin throws an error on the page which says "Error rendering macro 'macro-name' com/atlassian/confluence/rest/client/RestClientFactory", in the logs there is this error message: "Caused by: java.lang.ClassNotFoundException: com.atlassian.confluence.rest.client.RestClientFactory not found by com.testtesttest.wiki.theme-testtesttest [303]". So after some searching I thought it's the scope, which is on "provided".

Then I tried to set the scope to "compile", but then I can install the plugin, but it takes long and is greyed out after installation so that I can't use it and 0 modules are enabled. I don't know how to get more information on that error. In the logs it just says it takes too long and it will try again.

So, the question:
Must I use the RestClientFactory to create a Jersey client, which will handle the authentification? Or how is authentification handled when using the normal Jersey client with Confluence?
Or in general, how do you do a REST call to Conflunce from a Confluence macro plugin?

This is my macro plugin code:

package com.testtesttest.wiki.macro;

import org.springframework.beans.factory.annotation.Autowired;
import java.util.Map;
import com.atlassian.confluence.content.render.xhtml.ConversionContext;
import com.atlassian.confluence.macro.Macro;
import com.atlassian.confluence.macro.MacroExecutionException;
import com.atlassian.confluence.rest.client.RestClientFactory;
import com.atlassian.confluence.setup.settings.SettingsManager;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.webresource.api.assembler.PageBuilderService;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

@Scanned
public class MacroSetPropertiesDoku implements Macro {
private final PageBuilderService pageBuilderService;
private final SettingsManager settingsManager;

@Autowired
public MacroSetPropertiesDoku(
@ComponentImport PageBuilderService pageBuilderService,
@ComponentImport SettingsManager settingsManager
) {
this.pageBuilderService = pageBuilderService;
this.settingsManager = settingsManager;
}

public String execute(Map<String, String> map, String s, ConversionContext conversionContext) throws MacroExecutionException {
final long pageID = conversionContext.getEntity().getId();
final String url = settingsManager.getGlobalSettings().getBaseUrl() + "/rest/api/content/" + pageID + "/property";

pageBuilderService.assembler().resources().requireWebResource("com.testtesttest.wiki.theme-testtesttest:theme-testtesttest-resources");

String output = "";

try {
Client client = RestClientFactory.newClient();

WebResource webResource = client.resource(url);
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);

if (response.getStatus() != 200) {
output = "Failed with error code: " + response.getEntity(String.class);
}

output = "did it!: " + response.getEntity(String.class);
}
catch (Exception e) {
output = "CATCHED: " + e.toString();
}

return output;
}

public BodyType getBodyType() { return BodyType.NONE; }
public OutputType getOutputType() { return OutputType.BLOCK; }
}

In "pom.xml" I added the following dependencies:

<dependency>
<groupId>com.atlassian.confluence</groupId>
<artifactId>confluence-rest-client</artifactId>
<version>7.3.3</version>
<scope>provided</scope> <!-- I also tried "compile" -->
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.8-atlassian-16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.8-atlassian-16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.8-atlassian-16</version>
<scope>provided</scope>
</dependency>

Thank you for any insights!

0 answers

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events