Issue Link Filter for Jira

Freely filter links between issues and fire missing Issue Linked Events



About plugin

Issue Link Filter (aka Issue Linked Event) provide two functionality for Jira.

  • Ability to filter linked issues
  • Fire the custom events when someone created or deleted issue links


Link filter

Go do -> Add-ons -> Issue Link Filter (Other section in left menu)

  1. Call custom Created/Deleted events?

    Available since v. 1.4.0

    You can disable or enable custome events

  2. Call event only for current issue?

    Available since v. 1.3.0

    For example if you checked “only for current issue” option and you try add new issue link, event will be fired only for current issue, but if you checked “current and linked issues” option, event will be fired for current and linked issue.

  3. Validation strategy

    Available since v. 1.4.0

    You can create rules for linked issues how will they be validated, for example: only Bug can be linked into Task with relation “is blocked by”

SUPPORTED JQLDESCRIPTIONEXAMPLE
sourceLinkFilterX(GLOBAL_LINK_NAME)JQL provide information how to validate outward issues

JQL name: sourceLinkFilter1(Relates)
JQL query: issuetyp = Epic and status = “TO DO”

Whats that mean?
All issues in outward “Relates” link relation must be a “Epic” in “TO DO” status

destLinkFilterX(GLOBAL_LINK_NAME)JQL provide information how to validate inward issuesJQL name: destLinkFilter1(Blocks)
JQL query: issuetyp = BugWhats that mean?
All issues in inward “Blocks” link relation must be a “Bug”

errorLinkFilterX(GLOBAL_LINK_NAME)


Only for strategy: All validation must by positive

JQL provide information about error messages when validate not pass.

Default error message when valiadation fail or JQL is not set:
You can’t link this issue/issues due to the link restrictions.

JQL name: errorLinkFilter1(Blocks)



JQL query: summary ~ “Example error message for pair 1”

Whats that mean?



This is message to show, when validation for first pair not pass.

errorLinkFilter(GLOBAL_LINK_NAME)


Only for strategy: Only one validation must by positive

JQL provide information about error message when validate not pass.

Default error message when valiadation fail or JQL is not set:
You can’t link this issue/issues due to the link restrictions.

JQL name: errorLinkFilter(Blocks)



JQL query: summary ~ “Example error message for only one validation must by positive”

Whats that mean?



This is message to show, when validations for linked issues not pass

X – number from 1 to 10
GLOBAL_LINK_NAME – global link name, please see Name on page {JIRA_URL}/secure/admin/ViewLinkTypes!default.jspa


Example:


Events

Plugin add two custom events into Jira (Administration – System – View Events).

  • “Issue Link Created” event
  • “Issue Link Deleted” event

Event Issue Link Created will be fired when you:

  • add new Link (Web, Confluence or Issue) (Issue -> More -> Link)
  • add Linked Issues on transition/edit screen (every transition and edit screen with Linked Issues)
  • Create Linked Issue (More -> Create linked issue)
  • quick Create Issue
  • create new remote link using API

Event Issue Link Deleted will be fired when you:

  • delete any issue links
  • delete remote link using API

You can change template, associated notification schemes, associated workflows and description, but remember … DON’T CHANGE EVENTS NAME.

If you change it, the plugin will create new events!.

The default setting for new events can be seen below.


Event params map

Available since v. 1.3.0

Issue Link Created/Deleted events has information about which links have been added or removed.

You can get it using method getParams form class com.atlassian.jira.event.issue.IssueEvent.

Example data in params

Map<String, Object> params

Add issue/remote link param

Name: addedIssueLink or addedRemoteLink
Type: ArrayList<Long>
Information: ArraList provide links ids (IssueLink ID or RemoteIssueLink ID)

Removed issue link param

Name: removedIssueLink
Type: Map<String, String>
Map Keys: 
 - linkTypeId - link type ID
 - sourceIssueId - source Issue ID
 - destinationIssueId - destination Issue ID

Removed remote link param

Name: removedIssueLink
Type: Map<String, String>
Map Keys:
 - id - link ID
 - title - link title
 - url - link url


How to show it?

I will try to show the plugin in action using script listener and several screenshot from issue actions

 Script Listener Groovy example
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.bc.issue.link.RemoteIssueLinkService;

def eventTypeManager = ComponentAccessor.getEventTypeManager();
def eventType = eventTypeManager.getEventType( event.getEventTypeId() );
def eventTypeName = eventType.getName();
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();
def issueLinkManager = ComponentAccessor.getIssueLinkManager();
def remoteIssueLinkService = ComponentAccessor.getComponent(RemoteIssueLinkService.class);

log.warn (" --- Fire event '"+eventTypeName+"' for issue '"+event.issue.getKey()+"' Params:"+event.getParams().toString() );
//LOG FOR ALL LINKED ISSUES

//GET INFORMATION ABOUT EVENT LINKS
if( eventTypeName == "Issue Link Created" ){
    if( event.getParams()["addedIssueLink"] != null ){
        event.getParams()["addedIssueLink"].each{
            def issueLink = issueLinkManager.getIssueLink(it);
            def linkId = issueLink.getId().toString();
            def sourceId = issueLink.getSourceId().toString();
            def destId = issueLink.getDestinationId().toString();
            //get more -> https://docs.atlassian.com/jira/server/com/atlassian/jira/issue/link/IssueLink.html
            log.warn (" ----- Issue linked ID:$linkId, sourceId:$sourceId destinationId:$destId");
        }
    }else if( event.getParams()["addedRemoteLink"] != null ){
        event.getParams()["addedRemoteLink"].each{
            def remoteLink = remoteIssueLinkService.getRemoteIssueLink(currentUser, it).getRemoteIssueLink();
            def linkId = remoteLink.getId();
            def title = remoteLink.getTitle();
            def url = remoteLink.getUrl();
            //get more -> https://docs.atlassian.com/jira/server/com/atlassian/jira/issue/link/RemoteIssueLink.html
            log.warn (" ----- Issue link ID:$linkId, title:$title, url:$url");
        }
    }
}else{
    if( event.getParams()["removedIssueLink"] != null ){
        def removedLink = event.getParams()["removedIssueLink"];

        log.warn (" ----- Issue link ID:"+removedLink["id"]+" ; linkTypeId:"+removedLink["linkTypeId"]+" ; sourceIssueId:"+removedLink["sourceIssueId"] +" ; destinationIssueId:"+removedLink["destinationIssueId"] );
    }else if( event.getParams()["removedRemoteLink"] != null ){
        def removedLink = event.getParams()["removedRemoteLink"];

        log.warn (" ----- Issue link ID:"+removedLink["id"]+" ; title:"+removedLink["title"]+" ; url:"+removedLink["url"] );
    }
}

and how i set listener in JIRA (using Script Runner)



FAQ

Where in Jira create JQL?

Create JQL in standard JIRA place where you search issue or create JQL’s for filters/gadgets.
Issue (top-menu) -> Current Search or Search for Issues
Now save JQL using specific name for chosen validation strategy.


Saved filter need to be a public?

No


What, if I added several filters with the same name?

If you added several filters with the same name, plugin find first added into JIRA and check only this one, the rest will be ignored (first added into JIRA = lowest id in database)




Support

If you have any questions or suggestions, please don’t hesitate to contact me.

Please feel free to contact us by email support@itlab.net.pl or Jira Service Desk if you require any further information.