• [转]User related Groovy script snippets for ScriptRunner for JIRA (Server/Data Center)


    本文转自:https://metamorphant.de/blog/posts/2021-03-20-user-related-groovy-script-snippets-for-scriptrunner-for-jira/

    Why should I use ScriptRunner?

    Using Groovy scripts in Jira Software/Core or Service Management (Server/Data Center) adds a huge amount of new possibilities in customizing workflows, enhancing the user experience and automating processes. The most powerful App in this area is ScriptRunner for Jira. Out of the box it allows you to use Groovy scripts in:

    • Workflow Transitions (Post functions, Conditions, Validators)
    • Custom Script Listeners
    • Custom REST-Endpoints
    • Custom Jobs
    • Behaviours (manipulating field behaviour on create, edit and transition screens)
    • Custom JQL Functions
    • Fragments (manipulating Jira’s user interface)
    • and some useful built-in scripts

    By default Jira’s data model is quite static. Also you need to be Jira Administrator to modify fields. In combination with other apps you are able to provide a completely new Jira experience. For example, using the Jira app Insight - Asset Management you can define asset objects and access them in your scripts. By that you can make Jira behave more dynamic.

    How to use this blog article?

    In this article I will share script snippets for ScriptRunner to handle some common user related use cases I got in touch with. I don’t go into the details of the use cases. The purpose of the snippets is to get you started. Use copy & paste at your own discretion.

    Import packages

    First of all you import all the packages you’ll need in your script context. For debugging it’s helpful to import org.apache.log4j.Logger classes to be able to write into the Jira logs. You will soon recognize that developing in the integrated ScriptRunner script console without custom logging is quite shitty.

    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.issue.Issue
    import com.atlassian.jira.issue.fields.CustomField
    import com.atlassian.jira.user.ApplicationUser
    import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
    import com.atlassian.jira.event.type.EventDispatchOption
    import org.apache.log4j.Logger
    
    def log = Logger.getLogger("com.acme.workflows")
    
    log.info("Script starts...")

    For providing detailed debug information I recommend to use the appropriate log4j log level log.debug(”custom debugging message”). Whether the log.debug statement will appear in the logs, depends on the configured log level of your Jira instance. There is even a webinterface for configuring log levels in Jira Server and Data Center.

    Getting the issue object

    ScriptRunner scripts can be used in different contexts (listeners, postfunctions, …). How to access the issue object depends on the context of your script. Here some common examples.

    Getting the issue object in a listener script

    Issue issue = event.issue

    Getting the issue object in script postfunctions

    In a ScriptRunner script postfunction you don’t need to fetch the issue object of the current issue. It already exists as a prepopulated variable with name issue. You can directly access it to e.g. get the issue key by using issue.getKey().

    Getting the issue object by the issue key

    Independent of the context, you can always get the issue object by the issue key.

    import com.atlassian.jira.component.ComponentAccessor
    
    def issueManager = ComponentAccessor.getIssueManager()
    
    String issueKey = "TEST-1";
    
    issue = issueManager.getIssueObject(issueKey)

    User related script examples

    Now, everything is prepared and you can start using the following script snippets. They’re all tested in Jira 8.5.x (Long Term Support release) with ScriptRunner 6.15.0 and Insight - Asset Management 8.6.15.

    Setting the current user as assignee

    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.event.type.EventDispatchOption
    
    def authContext = ComponentAccessor.getJiraAuthenticationContext()
    
    def currentUser = authContext.getLoggedInUser()
    
    // Example: populate the assignee field using a setter method
    issue.setAssignee(currentUser)
    
    // Example: populate the reporter field using a property accessor
    issue.reporter = currentUser
    
    // More complex example: populate a customfield
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    def myCustomfield = customFieldManager.getCustomFieldObject("customfield_xxxxx")
    issue.setCustomFieldValue(myCustomfield, currentUser)
    
    // Commit changes to issue
    ComponentAccessor.getIssueManager().updateIssue(currentUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false)

    We use several classes from the Jira Java API here:

    In the examples you see two different styles to access a field.

    Performing actions on behalf of another user

    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.event.type.EventDispatchOption
    
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    def authContext = ComponentAccessor.getJiraAuthenticationContext()
    def userManager = ComponentAccessor.getUserUtil()
    
    // Store current user for later reset
    def currentUser = authContext.getLoggedInUser()
    
    // Switch user
    def otherUser =  userManager.getUserByName("SomeUser")
    authContext.setLoggedInUser(otherUser)
    
    // Do something, e.g. manipulate issue
    
    // Commit changes
    ComponentAccessor.getIssueManager().updateIssue(otherUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false)
    
    // Reset user
    authContext.setLoggedInUser(currentUser)

    Make sure you’re reseting the user at the end of your script. Otherwise, the following scripts or postfunctions may use this context, too.

    Adding a user to the request participants in Jira Service Management

    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.event.type.EventDispatchOption
    import com.atlassian.jira.user.ApplicationUser
    
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    def authContext = ComponentAccessor.getJiraAuthenticationContext()
    def userManager = ComponentAccessor.getUserUtil()
    
    def currentUser = authContext.getLoggedInUser()
    
    // Customfield 10001 corresponds to the request participant field in our Jira instance
    def requestParticipantsField = customFieldManager.getCustomFieldObject("customfield_10001")
    
    def user = userManager.getUserByName("username")
    
    // We need an ArrayList because we are going to modify it
    ArrayList<ApplicationUser> requestParticipants = issue.getCustomFieldValue(requestParticipantsField)
    
    requestParticipants.add(user)
    
    issue.setCustomFieldValue(requestParticipantsField, requestParticipants)
    
    ComponentAccessor.getIssueManager().updateIssue(currentUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false)

    ArrayList is an implementation of java.util.List, that supports the .add(...) operation. Other list implementations will throw an UnsupportedOperationException.

    Getting the users from multiple groups

    import com.atlassian.jira.component.ComponentAccessor 
    
    def groupManager = ComponentAccessor.getGroupManager()
    
    def users = []
    def groups =  ["jira-administrators", "jira-service-desk-users"]
    
    // If a user is in both groups, they would be added twice
    for (group in groups) {
        users += groupManager.getUsersInGroup(group)
    }
    
    // Remove duplicate users
    users = users.unique()

    Setting approvers by group membership in Jira Service Management

    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.user.ApplicationUser
    import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
    import com.atlassian.jira.issue.ModifiedValue
    
    def groupManager = ComponentAccessor.getGroupManager()
    def changeHolder = new DefaultIssueChangeHolder
    def userManager = ComponentAccessor.getUserManager()
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    
    def users = []
    def groups =  ["jira-administrators", "jira-service-desk-users"]
    
    // If a user is in both groups, they would be added twice
    for (group in groups) {
        users += groupManager.getUsersInGroup(group)
    }
    
    // Remove duplicate users
    users = users.unique()
    
    def approvers = []
    
    for (user in users) {
        ApplicationUser approver = userManager.getUserByKey(user.getKey())
        approvers.add(approver)
    }
    
    // Customfield 10006 corresponds to a multiple user field which we are using for the approvers
    if (!approvers.isEmpty()) {
        def approverField = customFieldManager.getCustomFieldObject("customfield_10006")
        // Commit changes to field
        approverField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(approverField), approvers), changeHolder)
    }

    Getting Jira groups from Insight object attributes of the type Group

    import com.atlassian.jira.component.ComponentAccessor
    
    // Access Insight Java API
    Class iqlFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade")
    def iqlFacade = ComponentAccessor.getOSGiComponentInstanceOfType(iqlFacadeClass)
    Class objectFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade")
    def objectFacade = ComponentAccessor.getOSGiComponentInstanceOfType(objectFacadeClass)
    
    // Defining the Insight object information
    def objectKey = "ST-12345"
    def objectSchemaID = 1
    def attributeName = "someGroupAttributeName"
    def groups = []
    
    // Get the matching objects from Insight. In this case we are looking for a single object by its unique object key
    def insightObjects = iqlFacade.findObjectsByIQLAndSchema(objectSchemaID, "Key = \"" + objectKey + "\"")
    
    for (object in insightObjects) {
        def groupAttribute = objectFacade.loadObjectAttributeBean(object.getId(), attributeName)
    
        if (groupAttribute != null) {
            def groupAttributeValues = groupAttribute.getObjectAttributeValueBeans()
            if (groupAttributeValues != null) {
                for (group in groupAttributeValues) {
                    groups.add(group.getValue())
                }
            }
        }
    }

    Seting an issue comment with specific user context e.g. a system user

    import com.atlassian.jira.component.ComponentAccessor
    
    def commentManager = ComponentAccessor.getCommentManager()
    def userManager = ComponentAccessor.getUserManager()
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    
    def user =  userManager.getUserByName("username")
    
    // Set comment text e. g. with parsing a customfield value
    def myField = customFieldManager.getCustomFieldObject("customfield_XXXXX")
    
    def commentText = "Text pre " + issue.getCustomFieldValue(myField).toString() + " Text post"
    
    // Commit comment to issue
    commentManager.create(issue, user, commentText, true)

    Further Groovy script use cases within Jira / Jira Service Management

    You can cover quite a distance using this approach. Just to give you some inspiration, here is a couple of other interesting ScriptRunner and Insight Groovy script use cases:

    • Simple password generator within transition post function
    • Access databases to acquire external information and bring them into Jira
    • Call a REST interface from workflow transition post functions and handle its response
    • Using Insight objects linked to an issue or issuetype to:
      • provide texts, comparable to canned responses, in any textfield e.g. resolution text or processing hints without buying another app
      • run validity checks across multiple fields even bundled fields from Dynamic Forms/Extension for Jira Service Management
      • build dynamic forms using ScriptRunner behaviours and accessing Insight object attributes to manipulate the field behaviour on screens
      • control available workflow transitions by linked Insight objects

    If you want more information just leave me a comment or get in touch.

  • 相关阅读:
    C++11 Lambda表达式
    C++ 容器操作
    C/C++ 动态存储分配 malloc calloc realloc函数的用法与区别
    使用visual C++测试
    设计模式有感
    smartProgram学习笔记
    C++析构函数
    C++指针和引用
    Python机器学习笔记:常用评估模型指标的用法
    Python机器学习笔记:不得不了解的机器学习面试知识点(1)
  • 原文地址:https://www.cnblogs.com/freeliver54/p/15885407.html
Copyright © 2020-2023  润新知