Confluence Cloud apps with Spring Boot and Atlassian Connect (Part 1)

About Atlassian Connect

To customize OnDemand versions of the Atlassian software products – Confluence Cloud, Jira Cloud & others – Atlassian Connect provides developers with the framework for implementing add-ons (apps) in a variety of programming languages.

An Atlassian Connect app is basically a web application connected via HTTP and can do the following:

  • Insert content into Jira and Confluence via different UI extension points.
  • Fetch data from and push data back to the Atlassian app via standard REST APIs.
  • Listen to connected Atlassian applications for changes in status via WebHooks.

(While Atlassian are reorganizing their websites, here is some introductory information about Atlassian Connect.)

In the following short tutorial, I want to cover these three things in more detail.

What are we implementing?

Our Cloud app is integrated with a Confluence Cloud instance, such that it …

  • listens and responds via a Webhook when a new page is created in Confluence.
  • is integrated in the help menu with a menu item (part 2).
  • displays a Confluence page that was generated in our Cloud instance (part 2).
  • executes OAuth2-authenticated queries on a connected Confluence Cloud system using the REST client (Part 2).

Atlassian Cloud development environment

Atlassian provides free Cloud instances for developers with the following user/agent restrictions:

  • Jira Core: Up to 5 users for free.
  • Jira Software: Five users for free.
  • Confluence: Five users for free.
  • Jira Service Desk: One agent for free.

Read more about the Atlassian Cloud development environment.

Calling home with ngrok

The ngrok tool lets us tunnel connections from our local development machine and make them available on the net – ideal to quickly test WebHooks and Cloud apps.

You can get a command line tool for all common operating systems to build these tunnels from the https://ngrok.com/ website.

For example, to establish a local HTTP connection on port 8080, you can use the following command:

ngrok http 8080

With this, we are assigned a random ID which we can use to access this connection:

Tunnel Status online 
Version 2.0.19/prod 
Web Interface http://127.0.0.1:4040 
Forwarding http://12345678.ngrok.io -> localhost:8080 
Forwarding https://12345678.ngrok.io -> localhost:8080 
 
Connections ttl opn rt1 rt5 p50 p90 
 0 0 0.00 0.00 0.00 0.00

Generate a new project using Maven Archetype

A Maven archetype can be used to quickly generate a new Spring Boot project that includes Atlassian libraries:

mvn archetype:generate -DarchetypeGroupId=com.atlassian.connect -DarchetypeArtifactId=atlassian-connect-spring-boot-archetype -DarchetypeVersion=1.3.5

After entering the GroupID/ArtifactID and version of our application that we want to implement, the project is ready for further development:

.
|-- pom.xml
--- src
    --- main
        |-- java
        |   --- net
        |       --- seibertmedia
        |           --- cloud
        |               --- AddonApplication.java
        --- resources
            |-- application.yml
            --- atlassian-connect.json

In addition to the classic Maven project structure, we will also get access to:

  • App descriptor (atlassian-connect.json)
  • Atlassian libraries: atlassian-connect-spring-boot-starter¬†and atlassian-connect-spring-boot-jpa-starter (including Spring Data JPA and Liquibase database migrations)
  • Spring Boot Application class and Spring configuration in the YAML format

Run the applications

We start our app by using Maven in the command line:

mvn spring-boot:run

After that, we can access our app via http://localhost:8080; and we will be redirected to the app descriptor.

Run the app using ngrok

So that our app also runs via the ngrok tunnel in the network with an appropriate base URL, we have added a parameter with the corresponding ngrok URL:

mvn spring-boot:run -Drun.arguments="--addon.base-url=https://12345678.ngrok.io"

Our app should now be available under HTTPS via ngrok (https://ID.ngrok.io). HTTPS is necessary because Atlassian does not allow apps to communicate via unencrypted HTTP-only connections.

Install the Confluence Cloud app

First of all, we must activate the developer mode for apps in our Confluence Cloud instance, so that we can install the app descriptor from a URL without having to use the Marketplace.

To do this, go to the add-on administration in the Confluence administration area and tick the Developer mode checkbox for the developer mode in the settings.

Now, we can install our app by specifying our ngrok URL, as shown in the following screenshot:

Installing the Cloud add-on

Installing the Cloud add-on

We see that our add-on integration was successful. In future, we will only have to repeat this step if our URL has changed or if we deliver a modified app descriptor (e.g. with WebHooks or extended scopes).

Cloud app installed successfully

Cloud app installed successfully

Watch for system changes with WebHooks

We now want to be notified via the WebHook API when new pages are created in our Confluence Cloud instance.

First, we need to add the following entry in our deployment descriptor:

"modules": {
	"webhooks": [
	  {
		"event": "page_created",
		"url": "/pages/created"
	  }
]

When a new page is created in Confluence Cloud, Confluence calls the specified address on our Cloud app and delivers information about this system event using the JSON format.

We need to define the following POJO to collect this information:

public class PageCreatedEvent {

  private Page page;
  private String user;
  private String userKey;
  private String timestamp;
  private String userName;

  // getter, setter, toString ommitted
}

We will also add a POJO for Confluence page information, called Page:

public class Page {

  private String spaceKey;
  private String modificationDate;
  private String creatorKey;
  private String creatorName;
  private Long id;
  private String title;
  private Long version;

  // getter, setter, tostring ommitted
}

The following listener will now receive the information at the address specified and store it in the log files:

@RestController
public class WebhookListenerResource {
  [..]
  
  @RequestMapping(name = "/pages/create", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
  public void onPageCreate(@RequestBody PageCreatedEvent dto,
      @AuthenticationPrincipal AtlassianHostUser hostUser) {
    log.info("user on host {} with key {} created page: {}", hostUser.getHost().getBaseUrl(),
        hostUser.getUserKey(), dto);

  }
}

Looking forward to part 2

In the second part of this short tutorial, we will implement the integration of Confluence Cloud’s GUI and the server-side rendering of content in Confluence.

Lesen Sie diese Seite auf Deutsch

Further information