JIRA 5.x Development
Cookbook
This book is your one-stop resource for mastering JIRA
extensions and customizations
JIRA 5.x Development Cookbook
Copyright © 2013 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: April 2013
Production Reference: 1180413
Published by Packt Publishing Ltd. Livery Place
35 Livery Street
Birmingham B3 2PB, UK. ISBN 978-1-78216-908-6
www.packtpub.com
Credits
Author
Jobin Kuruvilla
Reviewers Felix Martineau
Mizan Ali Sayed
Acquisition Editor Kevin Colaco
Lead Technical Editor Sruthi Kutty
Technical Editors Dominic Pereira
Kirti Pujari
Mameet Singh Vasir
Hardik B. Soni
Project Coordinator Hardik Patel
Proofreaders Maria Gould
Paul Hindle
Aaron Nash
Indexer Rekha Nair
Graphics Abhinash Sahu
Production Coordinator Arvindkumar Gupta
Cover Work
About the Author
Jobin Kuruvilla
is an Atlassian Consultant with experience in customizing JIRA and writing JIRA plugins for various customers. He is currently working with Go2Group as an Atlassian platinum expert, and is involved in managing Atlassian products for big enterprises as well as small starter license installations.Jobin is the author of JIRA Development Cookbook, Packt Publishing, released in 2011, which is a well-received book in the JIRA community. He also runs a website named J-Tricks (http://www.j-tricks.com), using which he shares numerous tutorials to help the developer community, who he believes have contributed immensely to his personal development. It is indeed those tutorials that sowed the first seeds of JIRA Development Cookbook.
Acknowledgement
No book is the product of just the author; he just happens to be the one with his name on the cover.
A number of people contributed to the success of this book, and it would take more space than I have to thank each one individually.
First of all, thanks to the Almighty God for helping me to sail through the difficulties in this short life and for making my life as wonderful as it is now.
The next biggest thanks goes to Project Coordinator, Hardik Patel, and Lead Technical Editor, Sruthi Kutty, both of whom went through the pain of making me write another book. Also, thanks to the entire Packt Publishing team for working so diligently to help bring out another high quality product.
It is amazing to work with a team of talented developers and technical geeks. Thank you STORM team, PD&B team, and RAMP team. Your encouragement and support were invaluable to me; you guys rock!
I must also thank the talented JIRA community who are instrumental in helping each other, sharing solutions, being active in the forums, running user groups, and what not? I am just one of the many who have benefited.
Before I wind up, thank you Atlassian for giving us JIRA and a set of other wonderful products. You don't realize how much you are making our lives easier!
About the Reviewers
Felix Martineau
runs the Atlassian practice at TechSolCom (http://www.techsolcom.ca) and has been working as a professional JIRA consultant since 2008. Having started with JIRA in 2007, over the years he has worked with the entire Atlassian portfolio. Felix has a rare blend of technical expertise, people skills, and business acumen. For Felix, the people are always more important than the tools.I want to thank the people at Packt Publishing for giving me this opportunity to review the book. Jobin Kuruvilla is one of the top people in the JIRA community, so it's an honor for me to be involved.
I would also like to thank my girlfriend Genevieve for her continuous support, as well as Paul Gamache and Jean Perron at TechSolCom, to whom I owe a lot professionally.
Mizan Ali Sayed
is a Master in Computer Science from Pune university, India. Mizan currently works as an Atlassian tools specialist and has experience with implementing, customizing, and supporting large scale enterprise JIRA. He is active within the Atlassian forum "Answers" and has published open source add-ons on the Atlassian Marketplace.www.PacktPub.com
Support files, eBooks, discount offers and more
You might want to visit www.PacktPub.com for support files and downloads related to your book. Did you know that Packt offers eBook versions of every book published, with PDF and ePub files
available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at service@ packtpub.com for more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
http://PacktLib.PacktPub.com
Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library. Here, you can access, read and search across Packt's entire library of books.
Why Subscribe?
f Fully searchable across every book published by Packt
f Copy and paste, print and bookmark content
f On demand and accessible via web browser
Free Access for Packt account holders
If you have an account with Packt at www.PacktPub.com, you can use this to access PacktLib today and view nine entirely free books. Simply use your login credentials for immediate access.
Instant Updates on New Packt Books
friends from TKM and JNV Kottayam.
This book would not have been possible without you, one way or the other!
Table of Contents
Preface 1
Chapter 1: Plugin Development Process
7
Introduction 7
Setting up the development environment 10
Creating a skeleton plugin 13
Adding plugin modules 17
Deploying a JIRA plugin 19
Making changes to and redeploying a plugin 23
Using FastDev for plugin development 24
Testing and debugging 28
Chapter 2: Understanding the Plugin Framework
31
Introduction 31
Architecture explained 34
Types of plugin modules 39
Working with the Plugins1 and Plugins2 versions 44
JIRA system plugins 46
Stable and core APIs 49
Modifying Atlassian bundled plugins 50
Converting plugins from v1 to v2 51
Adding resources into plugins 54
Adding web resources into plugins 56
Building JIRA from source 59
Adding new webwork actions to JIRA 63
Extending a webwork action in JIRA 68
Table of Contents
Chapter 3: Working with Custom Fields
77
Introduction 78
Writing a simple custom field 78
Custom field searchers 83
Dealing with custom fields on an issue 88
Programming custom field options 90
Overriding validation of custom fields 93
Customizing the change log value 94
Migrating from one custom field type to another 96
Making custom fields sortable 99
Displaying custom fields on subtask columns 100
User and date fields 102
Adding custom fields to notification mails 103
Adding help text for a custom field 105
Removing the "none" option from a select field 107 Making the custom field project importable 108 Changing the size of a text area custom field 109
Chapter 4: Programming Workflows
113
Introduction 114
Writing a workflow condition 115
Writing a workflow validator 122
Writing a workflow post function 129
Editing an active workflow 136
Making an issue editable/non-editable based on workflow status 138 Including/excluding resolutions for specific transitions 139
Permissions based on workflow status 140
Internationalization in workflow transitions 142 Obtaining available workflow actions programmatically 144 Programmatically progressing on workflows 146 Obtaining workflow history from the database 148
Reordering workflow actions in JIRA 151
Creating common transitions in workflows 153 Creating global transitions in workflows 158
Jelly escalation 160
Chapter 5: Gadgets and Reporting in JIRA
165
Introduction 166
Writing a JIRA report 167
Reports in an Excel format 174
Table of Contents
Object-configurable parameters for reports 181
Creating a pie chart in JIRA 189
Writing JIRA 4 gadgets 194
Invoking REST services from gadgets 202
Configuring user preferences in gadgets 206
Accessing gadgets outside of JIRA 214
Chapter 6: The Power of JIRA Searching
219
Introduction 219
Writing a JQL function 220
Sanitizing JQL functions 226
Adding a search request view 229
Smart querying using quick search 235
Searching in plugins 239
Parsing JQL queries in plugins 242
Linking directly to search queries 243
Index and de-index programmatically 244
Managing filters programmatically 246
Subscribing to a filter 249
Chapter 7: Programming Issues
253
Introduction 253
Creating an issue from a plugin 254
Creating subtasks on an issue 257
Updating an issue 258
Deleting an issue 259
Adding new issue operations 260
Conditions on issue operations 263
Working with attachments 265
Time tracking and worklog management 267
Working with comments on issues 275
Programming change logs 277
Programming issue links 279
Discarding fields while cloning 282
JavaScript tricks on issue fields 284
Creating issues and comments from an e-mail 287
Chapter 8: Customizing the UI
291
Introduction 292
Changing the basic look and feel 292
Adding new web sections in the UI 295
Table of Contents
Adding conditions for web fragments 305
Creating new Velocity context for web fragments 308
Adding a new drop-down menu on the top navigation bar 310
Dynamic creation of web items 311
Adding new tabs in the View Issue screen 315
Adding new tabs in the Browse Project screen 319
Creating the project tab panel using fragments 321
Adding new tabs in the Browse Version screen 325
Adding new tabs in the Browse Component screen 328
Adding issue link renderers 330
Extending a webwork action to add UI elements 338
Displaying dynamic notifications/warnings on issues 342
Re-ordering issue operations in the View Issue page 346
Re-ordering fields in the View Issue page 348
Chapter 9: Remote Access to JIRA
353
Introduction 354
Writing a Java client for the REST API 354
Creating a SOAP client 356
Writing a Java XML-RPC client 358
Working with issues 360
Working with attachments 364
Remote time tracking 366
Working with comments 368
Remote user and group management 369
Progressing an issue in a workflow 370
Managing versions 371
Managing components 373
Remote administration methods 374
Exposing services and data entities as REST APIs 378
Deploying a SOAP service in JIRA 384
Deploying an XML-RPC service within JIRA 388
Chapter 10: Dealing with the JIRA Database
393
Introduction 394
Extending the JIRA database with a custom schema 395
Accessing database entities from plugins 399
Persisting plugin information in the JIRA database 401
Using Active Objects to store data 405
Accessing the JIRA configuration properties 408
Table of Contents
Retrieving issue information from a database 411
Retrieving custom field details from a database 414
Retrieving permissions on issues from a database 416
Retrieving workflow details from a database 419
Updating the issue status in a database 421
Retrieving users and groups from a database 422
Dealing with change history in a database 424
Chapter 11: Useful Recipes
427
Introduction 428
Writing a service in JIRA 428
Adding configurable parameters to a service 430
Writing scheduled tasks in JIRA 433
Writing listeners in JIRA 435
Customizing e-mail content 442
Redirecting to a different page in webwork actions 444
Adding custom behavior for user details 445
Deploying a servlet in JIRA 450
Adding shared parameters to the servlet context 453
Writing a servlet context listener 455
Using filters to intercept queries in JIRA 456
Adding and importing components in JIRA 459
Adding new module types to JIRA 463
Enabling access logs in JIRA 467
Enabling SQL logging in JIRA 470
Overriding JIRA's default components in plugins 471
Internationalization in webwork plugins 474
Sharing common libraries across v2 plugins 476
Operations using direct HTML links 478
Preface
This book is your one-stop resource for mastering JIRA extension and customization. You will learn how to create your own JIRA plugins, customize the look and feel of your JIRA UI, work with workflows, issues, custom fields, and much more.The book starts with recipes on simplifying the plugin development process followed by a complete chapter dedicated to the plugin framework for mastering plugins in JIRA. Then we will move on to writing custom field plugins to create new field types or custom searchers. We then learn how to program and customize workflows to transform JIRA into a user-friendly system.
We will then look at customizing the various searching aspects of JIRA such as JQL, searching in plugins, managing filters, and so on.
Then the book steers towards programming issues, that is, creating/editing/deleting issues, creating new issue operations, managing the various other operations available on issues using the JIRA APIs, and so on.
In the latter half of the book, you will learn how to customize JIRA by adding new tabs, menus, and web items, and communicate with JIRA using the REST, SOAP, or XML/RPC interfaces, as well as working with the JIRA database.
The book ends with a chapter on useful and general JIRA recipes.
What this book covers
Chapter 1, Plugin Development Process, covers the fundamentals of the JIRA plugin development process. It covers, in detail, the setting up of a development environment, creating a plugin, deploying it, and testing it.
Chapter 3, Working with Custom Fields, looks at programmatically creating custom fields in JIRA, writing custom field searchers, and various other useful recipes related to custom fields.
Chapter 4, Programming Workflows, looks at the various ways of programming the JIRA workflows. It includes writing new conditions, validators, post functions, and so on, and contains related recipes that are useful in extending the workflows.
Chapter 5, Gadgets and Reporting in JIRA, covers the reporting capabilities of JIRA. It looks at writing reports, dashboard gadgets, and much more in detail.
Chapter 6, The Power of JIRA Searching, covers the searching capabilities of JIRA and how it can be extended using the JIRA APIs.
Chapter 7, Programming Issues, looks at the various APIs and methods used for managing issues programmatically. It covers the CRUD operations, working with attachments, programming the change logs and issue links, time tracking, and much more.
Chapter 8, Customizing the UI, looks at the various ways of extending and modifying the JIRA user interface.
Chapter 9, Remote Access to JIRA, looks at the remote capabilities of JIRA—REST, SOAP, and XML/RPC—and the ways of extending them.
Chapter 10, Dealing with the JIRA Database, looks at the database architecture of JIRA and covers the major tables in detail. It also covers the different ways to extend the storage and access or modify the data from plugins.
Chapter 11, Useful Recipes, covers a selected list of useful recipes, which do not belong in the preceding categories, but are powerful enough to get your attention. Read away!
What you need for this book
This book focuses on JIRA development. You need the following software as a bare minimum:
f JIRA 5.x+
f JAVA 1.6+
f Maven 2.x
f Atlassian Plugin SDK
Who this book is for
If you are a JIRA developer or a project manager who wants to fully exploit the exciting capabilities of JIRA, then this is the perfect book for you.
Conventions
In this book, you will find a number of styles of text that distinguish between different kinds of information. Here are some examples of these styles, and an explanation of their meaning. Code words in text, database table names, folder names, filenames, file extensions,
pathnames, dummy URLs, user input, and Twitter handles are shown as follows: " To use this, edit the settings.xml file under M2_HOME/conf/ by modifying the localRepository attribute to point to the embedded repository folder."
A block of code is set as follows:
<settings> .
<proxies> <proxy>
<active>true</active> <protocol>http</protocol> <host>proxy.demo.com</host> <port>8080</port>
<username>demouser</username> <password>demopassword</password>
<nonProxyHosts>localhost|*.demosite.com</nonProxyHosts> </proxy>
</proxies> .
</settings>
Any command-line input or output is written as follows:
select id from changegroup where issueid = '10010'
Warnings or important notes appear in a box like this.
Tips and tricks appear like this.
Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of.
To send us general feedback, simply send an e-mail to feedback@packtpub.com, and mention the book title via the subject of your message.
If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide on www.packtpub.com/authors.
Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
Errata
Piracy
Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works, in any form, on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at copyright@packtpub.com with a link to the suspected pirated material.
We appreciate your help in protecting our authors, and our ability to bring you valuable content.
Questions
1
Plugin Development
Process
In this chapter, we will cover:
f Setting up the development environment
f Creating a skeleton plugin
f Adding plugin modules
f Deploying a JIRA plugin
f Making changes to and redeploying a plugin
f Using FastDev for plugin development
f Testing and debugging
Introduction
Atlassian JIRA, as we all know, is primarily an issue tracking and project tracking
system. What many people do not know, though, is the power of its numerous customization capabilities, using which we can turn it into a different system altogether! Maybe a help desk system, a user story management system, an online approval process, and a lot more. This is in addition to the issue tracking and project tracking capabilities for which JIRA, arguably, is the best player in the market.
So what are these customizations? How can we convert the JIRA we know into a product we want? Or maybe just add extra functionalities that are specific to our organization?
But is that the only way? Definitely not! JIRA itself provides a lot of customization options through its user interface, and in more demanding cases, using property files such as jira-config.properties. In some cases, you will also find yourself modifying some of the JIRA core files to tweak functionality or to work around a problem. We will see more of that in the chapters to come, but the best entry point to JIRA customizations is through plugins, and that is where we start our cookbook before we move on to the in-depth details.
What is a JIRA plugin?
So, what is a JIRA plugin? JIRA itself is a web application written in Java. That doesn't mean you need to know Java to write a plugin, though in most cases you will need to. You might end up writing a simple descriptor file to add a few links here and there. If that makes the "non-Java" developer in you happy, watch out for the different plugin modules JIRA supports. A JIRA plugin is a JAR file that has a mandatory plugin descriptor and some optional Java classes and Velocity templates. The Velocity templates are used to render the HTML pages associated with your plugin, but in some cases, you might also want to introduce JSPs to make use of some pre-existing templates in JIRA. JSPs, as opposed to Velocity templates, cannot be embedded in the plugin, but instead they should be dropped into the appropriate folders in the JIRA web application. Using Velocity templates is therefore recommended over JSPs.
You can find more details on writing Velocity templates at http://velocity.apache.org/engine/releases/ velocity-1.5/user-guide.html#velocity_ template_language_vtl:_an_introduction.
The plugin descriptor, the only mandatory part of a plugin, is an XML file that must be named atlassian-plugin.xml. This file is located at the root of the plugin. The atlassian-plugin.xml file defines the various modules in a plugin. The different types of available plugin modules include reports, custom field types, and so on. These are discussed in detail in the next chapter.
The plugin development process
The process of developing a JIRA plugin can be of varying complexity depending on the functionality we are trying to achieve. The plugin development process essentially is a four-step process:
f Developing the plugin
f Deploying it into local JIRA
f Testing the plugin functionality
JIRA, on start up, identifies all the plugins that are deployed in the current installation. You can deploy multiple plugins, but there are some things you need to keep an eye on!
The atlassian-plugin.xml file has aplugin key, which should be unique across all the plugins. It is much similar to a Java package. Each module in the plugin also has a key that is unique within the plugin. The plugin key combined with the module key, separated by a colon (:), forms the complete key of a plugin module.
Following is a sample atlassian-plugin.xml file without any plugin modules in it:
<!-- the unique plugin key -->
<atlassian-plugin key="com.jtricks.demo" name="Demo Plugin" plugins-version="2">
<!-- Plugin Info --> <plugin-info>
<description>This is a Demo Description</description> <version>1.0</version>
<!-- optional vendor details -->
<vendor name="J-Tricks" url="http://www.j-tricks.com"/> </plugin-info>
. . . 1 or more plugin modules . . . </atlassian-plugin>
The plugin, as you can see from the preceding sample, has details such as description, version, vendor details, and so on.
When a plugin is loaded, all the unique modules in it are also loaded. The plugin classes override the system classes, and so if there is an action that has the same alias name as that of a JIRA action, it is the plugin action class that will be loaded. We will see more about extending actions in the coming chapters.
Suppose you have a report module in your plugin. It will look as follows:
<report key="demo-report" name="My Demo Report" ....> ..
</report>
The plugin key in the preceding case will be com.jtricks.demo, and the complete module key will be com.jtricks.demo:demo-report. Hang on, before you start writing your little plugin for a much wanted feature, have a look at the Atlassian Marketplace to see if someone else has already done the dirty work for you!
Atlassian Marketplace
Atlassian Marketplace is a one-stop shop where you can find the entire list of commercial and open source plugins that people around the world have written.
Troubleshooting
A common scenario that people encounter while deploying a plugin is when the plugin fails to load even though everything looks fine. Make sure your plugin's key is unique and is not duplicated in one of your or another third-party's plugin! The same applies to individual plugin modules.
Setting up the development environment
Now that we know what a plugin is, let's aim at writing one! The first step in writing a JIRA plugin is to set up your environment—if you haven't done that already. In this recipe, we will see how to set up a local environment.
To make our plugin development easier, Atlassian provides the Atlassian plugin software development kit (SDK). It comes along with Maven and a preconfigured settings.xml file to make things easier.
The Atlassian plugin SDK can be used to develop plugins for other Atlassian products, including Confluence, Crowd, and so on, but we are concentrating only on JIRA.
Getting ready
Following are the prerequisites for running the Atlassian plugin SDK:
f The default port 2990 for the SDK should be available. This is important because different ports are reserved for different Atlassian products.
f JDK should be installed and Java version 1.6.x is required.
The SDK is not yet compatible with Java 1.7.
f Make sure the JAVA_HOME environment variable is set properly and the java -version command outputs the correct Java version details.
How to do it…
Following are the steps to set up our development environment:
2. Install the SDK by following the instructions provided on the Atlassian Developer Documentation page, depending upon the operating system. Let's call this directory SDK_HOME.
3. Add the SDK's bin directory into the environment Path variable.
4. Create a new environment variable, M2_HOME, pointing to the apache-maven directory in your /SDK_HOME/atlassian-plugin-sdk directory.
SDK version 4.x and above doesn't need this step.
5. A lot of commonly used dependencies are already available in the repository folder embedded in the SDK. To use this, edit the settings.xml file under M2_HOME/conf/ by modifying the localRepository attribute to point to the embedded repository folder. By default, it will use the USER_HOME/.m2/ repository directory.
6. Install the IDE of your choice. Atlassian recommends Eclipse, IntelliJ IDEA, or NetBeans, as they all support Maven.
With the preceding steps executed properly, we have a development environment for JIRA plugins. The next step is to create a skeleton plugin, import it in to your IDE, and start writing some code! Creating the skeleton plugin, deploying it, and so on, is explained in detail in the forthcoming recipes of this chapter. So, ready, set, go…
There's more…
If you are facing issues while downloading the dependencies using Maven, just read on.
Proxy settings for Maven
If you are executing behind a firewall, make sure you have configured proxy settings in Maven's settings.xml file. A proxy can be configured as follows:
<settings> .
<proxies> <proxy>
<active>true</active> <protocol>http</protocol> <host>proxy.demo.com</host> <port>8080</port>
<password>demopassword</password>
<nonProxyHosts>localhost|*.demosite.com</nonProxyHosts> </proxy>
</proxies> .
</settings>
To find out more about proxy settings for Maven and other aspects of it,
go to http://maven.apache.org/index.html.
Using local Maven
If you are a developer, in many cases you will have Maven already installed in your local machine. In that case, point the M2_HOME environment variable to your local Maven, and update the respective settings.xml file with the repository details in the default settings.xml file that ships with the Atlassian plugin SDK. Or, you can simply add the following lines to the existing settings.xml file:
<pluginRepository>
<id>atlassian-plugin-sdk</id>
<url>file://${env.ATLAS_HOME}/repository</url> <releases>
<enabled>true</enabled>
<checksumPolicy>warn</checksumPolicy> </releases>
<snapshots>
<enabled>false</enabled> </snapshots>
</pluginRepository>
Configuring IDEs to use the SDK
If you are using IntelliJ IDEA, configuring it to use the SDK is an easy job because IDEA integrates Maven out of the box. Just load the project by selecting the pom.xml file! See https://developer.atlassian.com/display/DOCS/ Configure+IDEA+to+use+the+SDK for more details.
If you are using Netbeans, check out https://developer.atlassian.com/display/ DOCS/Configure+NetBeans+to+use+the+SDK on how to configure it to use the SDK.
Troubleshooting
If you see Maven download errors such as "Could not resolve artifact", make sure you verify the following:
f Entry in Maven's settings.xml file is correct. That is, it points to the correct repositories.
f Proxy configuration is done if required.
f Antivirus in the local machine is disabled and/or firewall restrictions removed if none
of the above works! Seriously, it makes a difference.
See also
f The Creating a skeleton plugin recipe
Creating a skeleton plugin
In this recipe, we will look at creating a skeleton plugin. We will use the Atlassian plugin SDK to create the skeleton!
Getting ready
Before beginning this recipe, make sure you have the Atlassian plugin SDK installed.
How to do it…
Following are the steps to create a skeleton plugin:
1. Open a command window and go to the folder where you want to create the plugin.
2. Type atlas-create-jira-plugin and press Enter.
3. Press 1 if you want to create a JIRA 5 plugin or 2 if you want to create a plugin for JIRA 4 or earlier versions.
This step can be avoided if you use the atlas-create-jira5-plugin
command instead of atlas-create-jira-plugin. Note the use of
jira5 instead of jira!
4. Enter the group-id information when prompted. group-id would normally be coming from your organization name and mostly resembles the Java package. Of course, you can enter a different package name as we move forward if you want to keep it separate. group-id will be used to identify your plugin along with artifact-id, for example, com.jtricks.demo.
5. Enter the artifact-id information (the identifier for this artifact) when prompted. Do not use spaces here, for example, demoplugin.
6. Enter the version information when prompted. The default version is 1.0-SNAPSHOT. Enter a new version if you want to change it or press Enter to keep the default version, for example, 1.0.
7. Enter the package information when prompted. Press Enter if the package value is the same as the group-id value. If not, enter the new value here and press Enter, for example, com.jtricks.mypackage.
8. Confirm the selection when prompted. If you want to change any of the entered values, type N and press Enter.
9. Wait for the BUILD SUCCESSFUL message to appear.
Downloading the example code
You can download the example code files for all Packt books you have
purchased from your account at http://www.packtpub.com . If you purchased this book elsewhere, you can visit http://www. packtpub.com/support and register to have the files e-mailed
directly to you.
How it works…
Following is a snapshot of how the project will look like in Eclipse. It also shows the design view of the default atlassian-plugin.xml file:
As you can see, there is a pom.xml file at the root level and a src folder. A sample LICENSE file and a README file are also created for you at the root level.
Under the src folder, you will find two folders—main and test—with an identical folder structure. All your main Java code goes under the main folder. Any JUnit tests you write will go into the same location under the test folder. There is an additional folder—it—under the test folder, where all the integration tests will go!
You will find the plugin descriptor, that is atlassian-plugin.xml, under src/main/ resources with sample values already populated in it. The values shown in the previous screenshot are populated from the pom.xml file. In our case, the plugin key will be populated as com.jtricks.demo:demoplugin when the plugin is built.
There are two more folders under the src/test tree. The src/test/resources folder, which will hold any resources required for unit tests or integration tests, and the src/test/ xml folder, which can hold the XML data from any other JIRA instance. If the XML is supplied, the SDK will use it to configure the JIRA instance before running the integration tests.
Remember, the first Maven run is going to take some time, as it
downloads all the dependencies into your local repository. A coffee break might not be enough! If you have a choice, plan your meals.
There's more…
Sometimes, for the geeks, it is much easier to run a single command to create a project, without bothering about the step-by-step creation. In the next section, we will quickly see how to do it. We will also have a look at how to create an Eclipse project if you opt out of installing m2eclipse.
One step to your skeleton plugin
You can ignore the interactive mode by passing the parameters such as group-id, artifact-id, and so on, as arguments to the atlas-create-jira-plugin command:
atlas-create-jira5-plugin -g my_groupID -a my_artefactId -v my_version -p my_package ---non-interactive
For the example values we saw earlier, the single line command will be as follows:
atlas-create-jira5-plugin -g com.jtricks.demo -a demoplugin -v 1.0 -p com.jtricks.mypackage --non-interactive
You can pick and choose the parameters and provide the rest in an interactive mode too!
Creating an Eclipse project
If you are not using m2eclipse, just run the following command from the folder that contains the pom.xml file:
atlas-mvneclipse:eclipse
This will generate the plugin project for Eclipse and you can then import this project into the IDE. Execute atlas-mvn eclipse:clean eclipse:eclipse if you want to clean the old project and create again!
With IDEA or m2eclipse, just opening a file will do. That is, you can just import the project using the File | Import | Existing Maven Projects option, and select the relevant project.
See also
f The Adding plugin modules recipe
Adding plugin modules
In this recipe, we will look at adding plugin modules into an existing plugin project.
Getting ready
Make sure the plugin project already exists, or create a new skeleton project as explained in the previous recipe.
How to do it…
Following are the steps to add plugin modules into an existing plugin project:
1. Open a command window and go to the plugin project folder where pom.xml resides. 2. Type atlas-create-jira-plugin-module and press Enter. This will show all the
3. Select the number against the module that you are planning to add. For example, type 25 and press Enter if you want to add a simple Web Item module to the plugin. 4. Follow the instructions to provide details required for the selected module. Some of
the options may have default values.
Some modules might also have an advanced setup. Type Y and press
Enter when prompted if you want to go to Advanced Setup. If not, type N and press Enter.
5. Once the module is completed, type Y or N and press Enter when prompted, depending on whether you want to add another module or not.
6. Repeat the steps for every module you want to add.
7. Wait for the BUILD SUCCESSFUL message to appear when no more modules are there to be added.
How it works…
Similar to the skeleton plugin creation, a set of directories and subdirectories are created during the process of adding plugin modules, along with a number of Java files or Velocity templates required for the selected plugin module.
It also adds the plugin module definition in the atlassian-plugin.xml file based on our inputs in step 4. A sample plugin descriptor, after adding the Web Item module, is shown as follows:
<?xml version="1.0" encoding="UTF-8"?>
<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description> <version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project. organization.url}"/>
</plugin-info>
<resource type="i18n" name="i18n" location="com.jtricks.demo. demoplugin"/>
<web-item name="My Web Item" i18n-name-key="my-web-item. name" key="my-web-item" section="system.user.options/personal" weight="1000">
<description key="my-web-item.description">The My Web Item Plugin</description>
<label key="my-web-item.label"></label>
As you can see, a web-item module is added. You can also see a resource module, which is added automatically the first time a plugin module is created. This will be the i18n resource file for the plugin, and more key-value pairs will be added into this file when more modules
are added. The file has the name {plugin-artifact-name}.properties and is created under the src/main/resources{plugin-group-folder} folder. In our example, a demo. properties file is created under the src/main/resources/com/jtricks/demo folder. A sample property file is shown as follows:
my-web-item.label=J-Tricks my-web-item.name=My Web Item
my-web-item.description=The My Web Item Plugin
See also
f The Creating a skeleton plugin recipe
f The Deploying a JIRA plugin recipe
f The Making changes to and redeploying a plugin recipe
Deploying a JIRA plugin
In this recipe, we will see how to deploy a plugin into JIRA. We will see both the automated deployment using the Atlassian plugin SDK and the manual deployment.
Getting ready
Make sure you have the development environment set up as we discussed earlier. Also, the skeleton plugin should now have the plugin logic implemented in it.
How to do it…
Installing a JIRA plugin using the Atlassian plugin SDK is a cakewalk. The following steps show how it is done:
2. Type atlas-run and press Enter. It is possible to pass more options as arguments to this command. The details regarding this can be found at https://developer. atlassian.com/display/DOCS/atlas-run.
You will see a lot of things happening as Maven downloads all the dependent libraries into your local repository. As usual, it is going to take a lot of time when you run it for the first time.
3. If you are on Windows, and if you see a security alert popping up, click on Unblock to allow incoming network connections.
4. When the installation is complete, you will see the following message:
[WARNING] [talledLocalContainer] INFO: Server startup in 123558 ms [INFO] [talledLocalContainer] Tomcat 6.x started on port [2990] [INFO] jira started successfully and available at http:// localhost:2990/jira
[INFO] Type CTRL-C to exit
5. Open http://localhost:2990/jira in your browser. 6. Log in using the username as admin and password as admin.
7. Test your plugin! You can always go to Administration | Plugins | Manage Add-ons
to confirm that the plugin is deployed properly.
8. If you already have a local JIRA installed, or if you want to manually install your plugin, all you need to do is to package the plugin JAR and install it via the Universal Plugin Manager (UPM), as described in detail at https://confluence.
atlassian.com/display/UPM/Installing+Add-ons#InstallingAdd-ons-Installingbyfileupload. Or, you can copy it across to the JIRA_Home/plugins/ installed-plugins directory and restart JIRA.
You can package the plugin using the following command:
atlas-mvn clean package
Use atlas-mvn clean install if you also want to install the packaged plugin into your local repository.
How it works…
There is only one single command that does the whole thing: atlas-run. When you execute this command, it does the following tasks:
f Builds your plugin JAR file
f Downloads the latest/specified version of JIRA to your local machine if it is the first
f Creates a virtual JIRA installation under your plugin's /target folder
f Copies the JAR file into the /target/jira/home/plugins/installed-plugins directory
f Starts JIRA in the Tomcat container
Now, if you look at your target folder, you will see a lot of new folders that were created for the virtual JIRA installation! The two main folders are the container folder, which has the Tomcat container setup, and the jira folder, which has the JIRA WAR along with the JIRA home setup!
You will find the database (HSQLDB), indexes, backups, and attachments under /target/ jira/home. You can also see your jira-webapp at /target/container/tomcat6x/ cargo-jira-home/webapps/jira.
If you have any JSPs that need to be put under the webapp, you will have to copy it to the appropriate folder under the aforementioned path!
There's more…
It is also possible to use a specific version of JIRA or to re-use the data that we have used for testing. To find out how, just read on.
Using a specific version of JIRA
As mentioned earlier, atlas-run deploys the latest version of JIRA. But what if you want to deploy the plugin into an earlier version of JIRA and test it? There are two ways to do this:
f Mention the JIRA version as an argument to atlas-run. Make sure you run atlas-clean if you already have the latest version deployed.
1. Run atlas-clean (if required).
2. Run atlas-run -v 5.0 or atlas-run -version 5.0 if you are developing for JIRA version 5.0. Replace the version number with a version of your choice.
f Permanently change the JIRA version in your plugin's pom.xml file. 1. Go to your pom.xml file.
2. Modify the jira.version property value to the desired version. 3. Modify the jira.data.version property value to a matching version.
Following is how it will look for JIRA 5.0:
<properties>
<jira.version>5.0</jira.version>
Re-using the configurations in each run
Suppose you have added some data onto virtual JIRA; how do you retain it when you clean startup JIRA next time? This is where a new SDK command comes to our rescue. After the atlas-run command has finished its execution, that is, after you have pressed Ctrl + C, execute the following command:
atlas-create-home-zip
This will generate a file named generated-test-resources.zip under the target folder. Copy this file to the /src/test/resources folder or any other known locations. Now modify the pom.xml file to add the following entry under configurations in the maven-jira-plugin plugin section:
<productDataPath>${basedir}/src/test/resources/generated-test-resources.zip</productDataPath>
Modify the path accordingly. This will re-use the configurations the next time you run atlas-run.
Troubleshooting
Following are some points to remember:
f Missing a JAR file exception? Make sure the local-repository attribute in the settings.xml file points to the embedded Maven repository that comes with the SDK. If the problem still persists, manually download the missing JAR files and use atlas-mvn install to install them into the local repository.
Watch out for the proxy settings or antivirus settings that can potentially block the download in some cases!
f Getting a BeanCreationException error? Make sure your plugin is of version 2. Check your atlassian-plugin.xml file to see if the plugins-version="2" entry is there or not. If not, add the entry shown as follows:
<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.artifactId}" plugins-version="2">
Making changes to and redeploying a plugin
Now that we have deployed the test plugin, it is time to add some proper logic, redeploy the plugin, and test it. Making the changes and redeploying a plugin is pretty easy. In this recipe, we will quickly look at how to do this.
How to do it…
You can make changes to the plugin and redeploy it while the JIRA application is still running. Following is how we do it:
1. Keep the JIRA application running in the window where we executed atlas-run. 2. Open a new command window and go to the root plugin folder where your pom.xml
file resides. 3. Run atlas-cli.
4. Wait for the Waiting for commands message to appear.
5. Run the pi. pi stands for plugin install and this will compile your changes, package the plugin JAR, and install it into the installed-plugins folder.
As of JIRA 4.4, all the modules are reloadable and hence can be redeployed using this technique.
There's more…
It is also possible to run the plugin in debug mode and point your IDE's remote debugger to it.
Debugging in Eclipse
Following are the steps to debug your plugin in Eclipse:
1. Use atlas-debug instead of atlas-run.
2. Once the virtual JIRA is up and running with your plugin deployed in it, go to Run |
Debug Configurations in Eclipse. 3. Create a new remote Java application.
See also
f The Setting up the development environment recipe
f The Creating a skeleton plugin recipe
f The Using FastDev for plugin development recipe
Using FastDev for plugin development
We have seen how to use atlas-cli to reload a plugin without having to restart atlas-run. It is a pretty good way to save time, but Atlassian have walked the extra mile to develop a plugin named FastDev, which can be used to reload plugin changes during development to all Atlassian applications including JIRA. And that, from the browser itself!
Getting ready
Create a plugin and use atlas-run to run the plugin as discussed in the aforementioned recipe. Let us assume we are doing it on the plugin we created in the previous recipe—the one with the sample Web Item. If we run this sample Web Item plugin, using atlas-run, we can access JIRA at port 2990 as mentioned earlier, and the Web Item will look as highlighted in the following screenshot:
As you can see, the J-Tricks link appears along with the Profile link under the personal section. But what if you wanted the link at the jira-help section, along with Online Help,
How to do it…
Following are the simple steps to make the aforementioned change to the plugin and reload it using FastDev:
1. Access the FastDev servlet on the browser using the following path: http://localhost:2990/jira/plugins/servlet/fastdev You will find the servlet as shown in the following screenshot:
2. Make the change to your plugin. In this example, the change is pretty small. All we do is modify the atlassian-plugin.xml file to change the section attribute in the web-item module from section="system.user.options/personal" to section="system.user.options/jira-help".
3. Click on the Scan and Reload button on the servlet (shown in the previous
4. Once the plugin is successfully reloaded, you will see the following screenshot with a success message:
5. Reload the JIRA page to see if the change is effective. In our example, the new screen will be as follows:
As you can see, the J-Tricks link has moved to the help section.
Using FastDev is very effective while building a plugin from scratch and testing it, as the pieces fall into the right places gradually.
How it works...
More information on FastDev can be found at https://developer. atlassian.com/display/DOCS/Automatic+Plugin+Reinst allation+with+FastDev.
There's more…
There is more to FastDev than the default configurations. They can be set in your plugin's pom.xml file by adding the required property to the systemPropertyVariables node. You will find the details in the Atlassian documentation (see the previous note box), but the most useful ones are mentioned later.
Adding ignored files
While looking for changes, FastDev ignores certain files such as .js or .css files that don't need a reinstall of the plugin. The following table shows the full list of files/directories that are ignored:
Type Property name Default(s)
Directory fastdev.no.reload.directories .svn
Extension fastdev.no.reload.extensions .js, .vm, .vmd, .fm, .ftl,
.html, .png, .jpeg, .gif, .css
File fastdev.no.reload.files –
If you want to ignore additional files or directories, you can add them using the preceding properties, shown as follows:
<systemPropertyVariables> ...
<fastdev.no.reload.directories> images
</fastdev.no.reload.directories> <fastdev.no.reload.extensions> classpath
</fastdev.no.reload.extensions> <fastdev.no.reload.files>
${basedir}/src/main/resources/LICENSE.txt </fastdev.no.reload.files>
Changing admin credentials
FastDev uses the default admin/admin credential to reinstall the plugin. But if the username or password is different, use the fastdev.install.username and fastdev.install. password properties, shown as follows:
<systemPropertyVariables> ...
<fastdev.install.username>myusername</fastdev.install.username> <fastdev.install.password>mypassword</fastdev.install.password> </systemPropertyVariables>
See also
f The Setting up the development environment recipe
f The Creating a skeleton plugin recipe
f The Making changes to and redeploying a plugin recipe
Testing and debugging
In the world of test-driven development (TDD), writing tests is a part and parcel of the development process. I don't want to bore you with why testing is important! Let us just assume that this holds true for a JIRA plugin development as well. In this recipe, we will see the various commands for running unit tests and integration tests in JIRA plugins.
If you are wondering what exactly TDD is, just go to
http://en.wikipedia.org/wiki/Test-driven_development.
Getting ready
How to do it...
Without further delay, lets perform the following steps:
1. The first step is to write some tests! We recommend you use some powerful testing frameworks such as JUnit, in collaboration with mocking frameworks such as PowerMock or Mockito. Make sure you have the valid dependencies added onto your pom.xml file.
2. Let us now make a huge assumption that you have written a few tests! Following is the command to run your unit tests from the command line:
atlas-unit-test
The normal Maven command, atlas-mvn clean test, also does the same thing.
3. If you are running the integration tests, the command to use is:
atlas-integration-test
Or, the Maven command to use is:
atlas-mvn clean integration-test
4. Once we are onto the stage of running tests, we will see them failing at times. Here comes the need for debugging. Checkout the *.txt and *.xml files created under target/ surefire-reports/, which have all the required information on the various tests that are executed.
5. Now, if you want to skip the tests at the various stages, use -skip-tests. For example, atlas-unit-test --skip-tests will skip the unit tests.
6. You can also use the Maven options directly to skip the unit/integrations tests or both together:
-Dmaven.test.skip=true: Skips both unit and integration tests -Dmaven.test.unit.skip=true: Skips unit tests
-Dmaven.test.it.skip=true: Skips integration tests
How it works…
The atlas-unit-test command merely runs the related Maven command, atlas-mvn clean test, in the backend to execute the various unit tests. It also generates the outputs into the surefire-reports directory for reference or debugging.
But how does JIRA differentiate between the unit tests and integration tests? This is where the folder structure plays an important role. Anything under the src/test/java/it/ folder will be treated as integration tests and everything else will be treated as unit tests!
There's more…
It is also possible to use custom data for integration tests and to test it against different JIRA versions.
Using custom data for integration/functional tests
While atlas-integration-test makes our life easier by setting up a JIRA instance with some default data in it, we might need some custom data as well to successfully run a few functional tests.
We can do this in a few simple steps:
1. Export the data from a preconfigured JIRA instance into XML. 2. Save it under the src/test/xml/ directory.
3. Provide this path as the value for the jira.xml.data.location property in the localtest.properties file under src/main/resources.
The XML resource will then be imported to JIRA before the tests are executed.
Testing against different versions of JIRA/Tomcat
Just like the atlas-run command, you can use the -v option to test your plugin against a different version of JIRA. Just like before, make sure you run atlas-clean before executing the tests if you had tested it against another version earlier.
You can also use the -c option to test it against a different version of the Tomcat container. For example, atlas-clean && atlas-integration-test -v 3.0.1 -c tomcat5x will test your plugin against JIRA version 3.0.1 using Tomcat container 5.
See also
f The Setting up the development environment recipe
2
Understanding the
Plugin Framework
In this chapter, we will cover more details on the JIRA architecture and the plugin framework. We will also cover the following recipes:
f Modifying Atlassian bundled plugins
f Converting plugins from v1 to v2
f Adding resources into plugins
f Adding web resources into plugins
f Building JIRA from source
f Adding new webwork actions to JIRA
f Extending a webwork action in JIRA
f Capturing plugin installation/uninstallation events
Introduction
As we saw in the previous chapter, the JIRA plugin development process is probably an easier task than we expected it to be. With the help of Atlassian Plugin SDK, developers can spend more time worrying about the plugin logic than on the troublesome deployment activities. And yes, after all, it is the plugin logic that is going to make an impact!
JIRA architecture
We will quickly see how the various components within JIRA fit in to form the JIRA we know. It is best described in a diagram, and Atlassian has a neat one along with a detailed explanation at https://developer.atlassian.com/display/JIRADEV/ JIRA+Architectural+Overview. We will redraw the diagram a little bit to explain it in a brief but useful way.
Third-party components
Before we dig deeper into the JIRA architecture, it is probably helpful to understand a few key components and familiarize yourself with them. JIRA's major third-party dependencies are outlined next.
It is not mandatory to know all about these frameworks, but it will be very helpful during plugin development if you have an understanding of these.
Webwork
Webwork is nothing but a Java web application development framework. The following is a quick overview of webwork as described in the OpenSymphony documentation:
"It is built specifically with developer productivity and code simplicity in mind, providing robust support for building reusable UI templates, such as form controls, UI themes, internationalization, dynamic form parameter mapping to JavaBeans, robust client- and server-side validation, and much more."
Note that JIRA uses webwork1 and not 2. In this book, all instances of webwork refer to the webwork1 version. JIRA itself refers to the technology as webwork, but you will notice that the files, plugin modules, and so on, use webwork1 just to emphasize the version.
Seraph
Seraph is Atlassian's open source web authentication framework. It provides a simple, extensible authentication system that JIRA uses for all authentication purposes.
Read more about Seraph at http://docs.atlassian.com/atlassian-seraph/ latest/.
OSUser
Embedded Crowd
JIRA 4.3+ uses Crowd, which is Atlassian's Identity management and Single Sign-on tool, for user management. JIRA embeds a subset of Crowd's core modules, which provides the user with management capabilities.
More information on Crowd can be found at http://www.atlassian.com/software/ crowd/overview.
PropertySet
PropertySet is again another open source framework from OpenSymphony that helps you to store a set of properties against any ''entity" with a unique ID. The properties will be key/value pairs and can only be associated with a single entity at a time.
Active Objects
Active Objects is a new Object Relational Mapping (ORM) layer into Atlassian products. It is implemented as a plugin and provides data storage that can be used by plugins to persist their private data. It enables easier, faster, and scalable data access compared to PropertySet.
More details on Active Objects can be found at https://developer.atlassian.com/ display/AO/Active+Objects. We have also discussed about Active Objects in Chapter 10, Dealing with JIRA Database.
OSWorkflow
OSWorkflow is yet another open source framework from the OpenSymphony group. It is an extremely flexible workflow implementation that is capable of driving complex conditions, validators, post functions, and so on, along with many other features.
OFBiz Entity Engine
OFBiz stands for "Open For Business", and the OFBiz Entity Engine is a set of tools and patterns used to model and manage entity-specific data.
As per the definition from the standard Entity-Relation modeling concepts of Relational Database Management Systems:
An Entity is a piece of data defined by a set of fields and a set of relations to other entities.
Apache Lucene
The following is a simple definition of Apache Lucene that you can find in its documentation:
Apache Lucene(TM) is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform.
More about Lucene and its potential can be found at http://lucene.apache.org/core/ index.html.
Atlassian Gadget JavaScript Framework
JIRA 4 introduces a powerful gadget framework. Atlassian has gone OpenSocial with gadgets and in order to help developers in creating gadgets, Atlassian has introduced a Gadget JavaScript Framework that encapsulates a lot of common requirements and functionalities used between gadgets.
More about gadget development can be read at https://developer.atlassian.com/ display/GADGETS/Using+the+Atlassian+Gadgets+JavaScript+Framework. Quartz
Quartz is an open source job scheduling service. It can be used to create jobs that can be scheduled within any Java EE and SE applications. The tasks are defined as standard Java components and scheduler includes many enterprise-class features, such as JTA transactions and clustering.
Read more at http://www.quartz-scheduler.org/.
Architecture explained
User/Browser
Plugins
RDBMS
Scheduler
Apache Lucene RPC Jelly
Quartz
OFBiz Entity Engine OSWorkflow
Active Objects
Embedded Crowd PropertySet
Lucene indexes JIRA core utility
and Manager classes
Webworks
Seraph JSP/Velocity
JIRA is a web application built using the MVC architecture. It is fully written in Java and is deployed as a WAR file into a Java Servlet Container such as Tomcat.
The majority of the JIRA core functionality revolves around the JIRA Utility and Manager Classes, which thus becomes the heart of JIRA. It also interacts with a lot of third-party components, which we saw earlier, to deliver powerful functionalities such as workflows, permissions, user management, and searching.
Authentication and user management
The user authentication, whichever way the request comes, is done in JIRA using Seraph, Atlassian's open source web authentication framework. Seraph is implemented as a servlet filter, and it intercepts each and every incoming request and associates them with a specific user. It supports various authentication mechanisms such as HTTP Basic Authentication, form-based authentication, and it even looks up already stored credentials in a user session when implemented with SSO (Single Sign On).
However, Seraph doesn't do any user management itself. It delegates this to the Embedded Crowd framework (OSUser in JIRA versions prior to 4.3). One additional thing that Seraph does in JIRA is to intercept URLs starting with /admin/ and allow users access only if they have the "Global Admin" permission.
Coming back to authentication and other user management functions, it is OSUser that does the work for JIRA in versions prior to 4.3. It does the following activities:
f User management: Creates/updates/deletes users and stores the details in the JIRA database. It also stores user preferences.
f Group management: Creates/updates/deletes groups and stores the details in the JIRA database. It also manages group memberships.
f Authentication: Password matching.
From JIRA 4.3 onward, user management in JIRA is done using Crowd. Crowd is a single sign-on and identity management system from Atlassian, which is now embedded in JIRA 4.3+. Plugin developers can now use CrowdService to manage users and groups, for which more information can be found at http://docs.atlassian.com/crowd/current/com/ atlassian/crowd/embedded/api/CrowdService.html.
The following are the core Crowd functionalities:
f User, Group, and Membership management—stores all details in JIRA DB
f Authentication—password matching
f Allows connection to external user directories such as LDAP, AD, and Crowd.
Property management
JIRA lets you add key/value pairs as properties on any available entity such as User, Group, Project, and Issue. It uses OpenSymphony's PropertySet to do this. Three major cases where PropertySet is used internally in JIRA are as follows:
f To store user preferences by the OSUser framework like e-mail, full name, and so on
f To store application properties
f To store chosen preferences of Portlets/Gadgets on user dashboards
We can also use the PropertySet in our plugins to store custom data as key/value pairs.
In earlier versions of JIRA, PropertySet was the only technology used to store plugin information and other data related to plugins. But JIRA now supports a new technology called Active Objects, which can be used to store plugin data. This is explained in detail in Chapter 10, Dealing with the JIRA Database.
Presentation
The presentation layer in JIRA is built using JSPs and Velocity templates. Another experimental component available in JIRA 5 for the presentation layer is soy templates.
The web requests coming on to JIRA are processed by OpenSymphony's webwork1 framework. The requests are handled by webwork actions that internally use the JIRA Service layer. The service classes expose the core utility and Manager classes that perform the tasks behind the scenes!
Database
JIRA talks to its database using the OFBiz Entity Engine module. Its database schema is defined in the entitmodel.xml and entitygroup.xml files residing in the WEB-INF/ classes/entitydefs folder. The entity configuration details goes in to entityengine. xml under WEB-INF/classes, whereas the DB connectivity details are stored in
dbconfig.xml residing in the JIRA Home directory.
Workflows
Workflows are one of the most important features in JIRA. They provide us with a highly configurable workflow engine that uses OpenSymphony's OSWorkflow behind the scenes. It lets us customize the workflows by adding new steps and transitions, and for each transition we can add conditions, validators, or post functions. We can even write plugins to add more of these, in addition to the ones that ship with JIRA. We will see all that in detail in the coming chapters.
Searching
JIRA uses Apache Lucene to perform indexing in JIRA. Whenever an issue is changed in JIRA, it performs a partial re-indexing to update the related indexes. JIRA also lets us do a full re-index at any time manually from the Administration screen.
Searching in JIRA is done using these indexes, which are stored in the local drive. We can even store search queries as filters whose results get updated as the indexes changes.
Scheduled jobs
JIRA uses the Quartz API to schedule jobs. These jobs, including the subscriptions to the filters and the custom ones we add, are stored in the JIRA database, and are executed by the Quartz job scheduling service.
JIRA's built-in scheduled job details can be found at scheduler-config.xml. It is possible to schedule new events in JIRA using the SAL services implementation. As Atlassian puts it:
The Shared Access Layer, or SAL inshort, provides a consistent, cohesive API to common plugin tasks, regardless of the Atlassian application into which your plugin is deployed.
More information on scheduling events in JIRA using SAL can be found at
https://developer.atlassian.com/display/DOCS/Plugin+Tutorial+-+Scheduling+Events+via+SAL.
Plugins
Last but not least, plugins fit into the JIRA architecture to provide extra functionalities or to alter some of the existing ones. The plugins mostly use the same JIRA core utility classes and Manager classes as webwork actions do, but in some cases also add to the list.
This, I hope, gives you a brief introduction to the JIRA architecture and the major components used in it. We will see most of these in detail in the coming chapters, and we will cover how to customize them by writing plugins. Off you go!
Types of plugin modules
Let us briefly see the different types of plugin modules supported in JIRA5. All these modules are various extension points, using which we can not only add new functionalities in to JIRA, but also extend some of the existing functionalities.
Let us group them based on functionality instead of seeing them all together!
Reporting
Module type Description
Gadget Adds new Gadgets into the user's dashboard. These gadgets can also be accessed from other applications.
Report Adds new reports in to JIRA.
Workflows
Module type Description
workflow-condition Adds new workflow conditions to the JIRA workflow. It can then be used to limit the workflow actions to users, based on pre-defined conditions.
workflow-validator Adds new workflow validations to the JIRA workflow. Validations can be used to prevent certain workflow actions when certain criteria are not met.
workflow-function Adds new workflow post functions to the JIRA workflow. These can be used to perform custom actions after a workflow action is executed.
Custom fields
Module type Description
customfield-type Adds new custom field types to JIRA. We can customize the look and feel of the fields in addition to creating custom logic. See also
Searching
Module type Description
customfield-searcher Adds new field searchers in to JIRA. The searcher needs to be mapped with the relevant custom fields.
jql-function Adds new JQL Functions to be used with JIRA's advanced searching.
search-request-view Adds a new view in the Issue Navigator. They can be used to sh