Плагин для Jira Cloud: Hello World

В этой статье мы создадим плагин для Jira Cloud, используя atlassian-connect-spring-boot.

Для того, чтобы повторить все действия из этой статьи, Вам понадобятся maven, ngrok и IntelliJ Idea.

Вы можете посмотреть окончательный код плагина вот здесь.

Создаем проект для atlassian-connect-spring-boot

Для того, чтобы создать проект для atlassian-connect-spring-boot, Вам необходимо выполнить вот такую команду в терминале:

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

Вас попросят ввести значения для параметров. Я задал вот такие значения:

Define value for property 'groupId': ru.matveev.alexey.atlassian.cloud.tutorial
Define value for property 'artifactId': hello-world
Define value for property 'version' 1.0-SNAPSHOT: : 
Define value for property 'package' ru.matveev.alexey.atlassian.cloud.tutorial: : 

Подвердите значения параметров:

Confirm properties configuration:
groupId: ru.matveev.alexey.atlassian.cloud.tutorial
artifactId: hello-world
version: 1.0-SNAPSHOT
package: ru.matveev.alexey.atlassian.cloud.tutorial
 Y: : Y

В результате будет создана новая папка hello-world. Перейдите в эту папку:

cd hello-world

Добавляем новую точку входа в плагин

Jira Cloud при установке плагина считывает файл src/main/resources/atlassian-connect.json. В настоящее время этот файл в нашем плагине не содержит каких-либо пользовательских точек входа.

Вот содержимое этого файла:

{
  "key": "${addon.key}",
  "baseUrl": "${addon.base-url}",
  "name": "Hello World",
  "authentication": {
    "type": "jwt"
  },
  "lifecycle": {
    "installed": "/installed",
    "uninstalled": "/uninstalled"
  },
  "scopes": ["READ"]
}

Мы добавим пользовательскую точку входа. Сделаем так, что у пользователя появится пункт меню, на который он может нажать, и будет загружена страница с текстом Hello World.

Добавим соответствующую конфигурацию в файл atlassian-connect.json:

"modules": {
    "generalPages": [
      {
        "key": "helloworld-page-jira",
        "location": "system.top.navigation.bar",
        "name": {
          "value": "Hello World"
        },
        "url": "/helloworld"
      }
    ]
  }

Здесь мы добавляем новый пункт меню в system.top.navigation.bar, который назвается Hello World. Если Вы выберете этот пункт меню, то будет вызван метод /helloworld из нашего плагина. Этот метод вернет html страницу с текстом Hello World.

Добавляем helloworld метод

Создадим файл src/main/java/ru/matveev/alexey/atlassian/cloud/tutorial/controller/HelloWorldController.java:

package ru.matveev.alexey.atlassian.cloud.tutorial.controller;

import com.atlassian.connect.spring.IgnoreJwt;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class HelloWorldController {

        @GetMapping("/helloworld")
        @IgnoreJwt
        public String helloworld() {
            return "helloworld";
        }
}

Здесь мы создаем контролер с методом helloworld. Мы используем аннотацию @IgnoreJwt для того, чтобы отключить проверку JWT нашим плагином. Atlassian использует JWT аутентификацию (можете подробнее почитать здесь). Мы отключаем проверку JWT для того, чтобы протестировать наш плагин на локальном хосте. Потом мы закомментируем эту аннотацию. Наш метод helloworld возвращает html страницу c именем helloworld.

Создаем страницу helloworld

Мы будем вызывать страницу helloworld с помощью thymeleaf. Поэтому в файл pom.xml нам нужно добавить зависимость:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Вот полный pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
    </parent>

    <groupId>ru.matveev.alexey.atlassian.cloud.tutorial</groupId>
    <artifactId>hello-world</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
        <atlassian-connect-spring-boot.version>2.1.1</atlassian-connect-spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.atlassian.connect</groupId>
            <artifactId>atlassian-connect-spring-boot-starter</artifactId>
            <version>${atlassian-connect-spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>com.atlassian.connect</groupId>
            <artifactId>atlassian-connect-spring-boot-jpa-starter</artifactId>
            <version>${atlassian-connect-spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>spring-boot:run</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>versions-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>display-spring-boot-dependency-updates</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>display-parent-updates</goal>
                            <goal>display-property-updates</goal>
                        </goals>
                        <configuration>
                            <includeProperties>atlassian-connect-spring-boot.version</includeProperties>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>default</id>
            <activation>
                <property>
                    <name>!spring.profiles.active</name>
                </property>
            </activation>
            <dependencies>
                <dependency>
                    <groupId>org.hsqldb</groupId>
                    <artifactId>hsqldb</artifactId>
                    <scope>runtime</scope>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-devtools</artifactId>
                    <optional>true</optional>
                </dependency>
            </dependencies>
        </profile>
    </profiles>
</project>

Теперь создадим саму страницу src/main/resources/templates/helloworld.htm:

<!DOCTYPE html>
<html lang="en">
<body>
<section id="content" class="ac-content">
    <h1>Hello World</h1>
</section>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="https://unpkg.com/@atlaskit/css-reset@2.0.0/dist/bundle.css" media="all">
    <script src="https://connect-cdn.atl-paas.net/all.js" async></script>
</head>
<body>
<section id="content" class="ac-content">
    <h1>Hello World</h1>
</section>
</body>
</html>

Запускаем наш плагин на локальном хосте

Я запускаю плагин через IntelliJ Idea вот так:

После того, как плагин запустится, зайдите в браузер по адресу localhost:8080. Если все прошло успешно, то Вы увидите содержимое файла atlassian-connect.json:

Теперь в браузере вызовем наш helloworld метод по адресу localhost:8080/helloworld. Вы должны увидеть Hello World:

Запускаем плагин в Jira Cloud

Закомментируйте @IgnoreJWT в контролере helloworld.

Создайте свой инстанс Jira Cloud. Вот здесь можно почитать, как это сделать.

У меня нет статического ip адреса, поэтому для того, что из интернета вызвать мой запущенный на локальном хосте плагин, я воспользуюсь утилитой ngrok, которая создаст туннель к моему локальному хосту. Наш плагин запускается на порту 8080, поэтому мы запустим ngrok вот так:

./ngrok http 8080

Скопируйте https линк на Ваш плагин (Ваш линк будет отличаться от моего):

Теперь присвойте параметру base-url в файле src/main/resources/application.yml значение линка, которое Вы скопировали:

spring.jpa.hibernate.ddl-auto: none
spring.datasource.url: jdbc:hsqldb:file:addon-db # Use a file-based backing store for HSQL

addon:
  key: hello-world
  base-url: https://f42659855a77.ngrok.io

logging.level.com.atlassian.connect.spring: DEBUG

Опять запустите плагин через IntelliJ Idea.

Линкуем наш плагин с Jira Cloud

Откройте Ваш инстанс Jira Cloud, перейдите в Manage Apps и нажмите на кнопку Settings:

Вы увидите вот такое окно:

Установите флажок в поле Enable development mode и нажмите на кнопку Apply.

Затем нажмите на кнопку Upload App и введите туда значение https линка, который Вы скопировали из ngrok:

Нажмите на кнопку Upload. После того, как Ваше приложение установилось, Вы увидите окно подтверждения:

Теперь выберите Apps -> Hello World:

И Вы должны увидеть Hello World:

Отлично! Плагин работает.

If you have found a spelling error, please, notify us by selecting that text and pressing Ctrl+Enter.

Leave a Reply

%d bloggers like this:

Spelling error report

The following text will be sent to our editors: