One of the issue here is the version of the Atlassian libraries you will use for your development. Reason is obvious, compatibility and another repositories. So let's take a look on maven descriptor file pom.xml.
...The nice thing on the plugin development is testing of all parts during the process. Atlassian provides some testing libraries (ex. jira-tests or jira-func-tests) in additions with others (harmcrest matcher, mockito, junit etc...)... jfrog http://repo.jfrog.org/artifactory/libs-releases atlassian-public https://maven.atlassian.com/repository/public true never warn true warn ... 5.0.4 6.1.7 2.5.0 3.0.0-m24 2.7.1 2.18 1.3.14.3.5 2.1 1.0-SNAPSHOT 4.11 1.8.5
Img.1.: heart of the plugin -> descriptor file -> atlasssian-plugin.xml |
It shows which technologies (Soy ~ Google Closure, Blue-prints, Velocity ...) we use inside the plugin and which parts of jira core services we employ to make the plugin work according what we are expecting from it:${project.description} ${project.version} images/pluginIcon.png images/pluginLogo.png The LEGO CRUD Issue Plugin /issuecrud Lego CRUD Resources com.atlassian.auiplugin:ajs com.atlassian.auiplugin:jquery atl.general com.example.plugins.tutorial.servlet.LegoBrickService Provides Lego Brick services.
Img.2. - add1.: Lego Project Template is INSIDE like Intel |
2. Lego Issue tracker
3. Lego REST API
Img.3. - add1.: Lego Template is there with Customised workflows and Issues |
{namespace JIRA.Templates.ProjectLegoTemplates.Lego} ... {template .renderLegoProjectTemplateExplanation} {getText('lego.project.template.info.page.description')} ...
- {getText('lego.project.template.reason.1')}
- {getText('lego.project.template.reason.2')}
- {getText('lego.project.template.reason.3')}
{ "issue-type-scheme": { "name": "lego.project.template.issuetype.scheme.name", "description": "lego.project.template.issuetype.scheme.description", "issue-types": [ { "key": "issueType1", "name": "New Lego Feature", "description": "A new Lego JSON feature of the product, which has yet to be developed.", "icon": "/images/icons/newfeature.png", "workflow": "wf1" }, ... }, "workflow-scheme": { "name": "lego.project.template.workflow.scheme.name", "description": "lego.project.template.workflow.scheme.description", "default-workflow": "wf1", "workflows": [ { "key": "wf1", "name": "lego.project.template.workflow.wf1.name", "workflow-bundle": "/wfb/Issue-Tracking-Workflow.jwb" }, ... ...and the project is hooked with the JIRA system by using Blueprints API. Specifically implementing the interface AddProjectHook with @Overriden methods validate and configure .
... public class LegoProjectHook implements AddProjectHook { ... @Override public ValidateResponse validate(final ValidateData validateData) { ... } @Override public ConfigureResponse configure(final ConfigureData configureData) { ... } ...
The result looks pretty cool because now we have inside the JIRA official Lego Project with its own issues and flows how to solve them. We can also track whole development.
Img.4.: Lego Project inside the JIRA |
For those who has experiences with Lego MindStorm EV3 Java/Scala development it's nothing new to get an issue. The tracker is represented by the simple servlet that handles
Img.5.:: Lego Issue Tracker |
Img.6.: Velocity templates for LegoIssueTracker |
In side every template file (edit.vm, list.vm or new.vm) is possible to employ JavaScript to make for example cross-domain JSONP calls and get information from another resources (in my case RaspberryPi powered by Netty)
example: new.vm or edit.vm
... function getRaspData(){ jQuery.ajax({ url: 'IP_ADDRESS', dataType: 'JSONP', jsonpCallback: 'callback', type: 'GET', success: function (data) { ... jQuery('input[name="ip"]').val(data.ip); } }); } ... AJS.$(document).ready(function() { jQuery('.button-rasp').click(function() { console.log('RASP PI'); ... getRaspData(); }); }); ... ... ...edit.vm - Velocity template language ... ...Now we are ready, according to the atlassian descriptor file, to create the Servlet implementaiton:<h1> Edit Lego issue $issue.getKey()</h1> #if ($errors.size()>0) ...
public class IssueCRUD extends HttpServlet { ... private static final String PLUGIN_STORAGE_KEY = "com.example.plugins.tutorial.servlet.lego"; private static final String NO_IP_MESSAGE = "No IP Setup"; ... private IssueService issueService; private ProjectService projectService; private SearchService searchService; private UserManager userManager; private TemplateRenderer renderer; private LegoBrickService legoBrickService; private static final String LIST_BROWSER_TEMPLATE = "/templates/list.vm"; private static final String NEW_BROWSER_TEMPLATE = "/templates/new.vm"; ... @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ... } ... @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ... User user = getCurrentUser(req); ... } ...After short coding session we have prepared also LegoIssue sending functionality
Img.7.:: send the 1st Lego Issue to the LEGO project |
@Path("/") @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public class RestLegoService { … public RestLegoService(PluginSettingsFactory pluginSettingsFactory) { this.pluginSettingsFactory = pluginSettingsFactory; } @GET @Path("brick") public Response getLegoBrick() { …In the end we get appropriate JSON response by accessing the defined path.
I hope this blog post helps in way to get a basic idea how to deal with Atlassian plugin development. In my case I don't want to use it as the reminder what I have done :)
Enjoy!
PS: I've used IntelliJ IDEA 13.x and SourceTree
No comments:
Post a Comment