Hi All,
I am a little lost with this. I am open to alternative solutions.
I have a problem: We periodically archive issues which have been closed and not updated for one year.
Teams are asking that we enable a solution to allow them to retrieve old issues so that they can search them. The solution is to allow the individual teams to Unarchive all of these issues, until the next archive process will archive them again.
We were thinking of using Fragments for this. But as far as I can tell Fragments can not execute some groovy script? they can only call an end point?
Is this correct?
This is a sample of a script we would want to execute.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.archiving.ArchivedIssueService
def projectManager = ComponentAccessor.getProjectManager()
def issueManager = ComponentAccessor.getIssueManager()
def project = projectManager.getProjectByCurrentKey('TEST')
def issueIds = issueManager.getIssueIdsForProject(project.id)
def issues = issueManager.getIssueObjects(issueIds)
def archivedIssues = issues.findAll { it.isArchived() }
def um = ComponentAccessor.userManager
def archivedIssueService = ComponentAccessor.getComponent(ArchivedIssueService)
def techUser = um.getUserByName("Automation User")
for (item in issues) {
def validationArchive = archivedIssueService.validateRestoreIssue(techUser, item, false)
if (validationArchive.valid) {
archivedIssueService.restoreIssue(validationArchive)
}
}
What is the best way to implement this?
Also, I need to know how I can get the project key.
This is what I thought I could do:
Create Web Panel
This will give me something like a panel below:
Put your script in a Custom Rest Endpoint.
Then add a "Custom Web Item" fragment with "Run Code and DIspaly a flag" option and point the web item to your new endpoint.
Make sure the endpoint returns a flag with something like "Your request to unarchive this project has been received. This may take a while. You will receive an email when it's finished".
Then, of course, add some logic to your script to send that email to the current user.
Here is a sample rest API script (untested) to get you started:
import com.adaptavist.hapi.jira.mail.Mail
import com.adaptavist.hapi.jira.users.Users
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.archiving.ArchivedIssueService
import com.atlassian.jira.util.JiraDurationUtils
import com.atlassian.jira.util.thread.JiraThreadLocalUtil
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
def projectManager = ComponentAccessor.getProjectManager()
def issueManager = ComponentAccessor.getIssueManager()
def archivedIssueService = ComponentAccessor.getComponent(ArchivedIssueService)
def jiraThreadLocalUtil = ComponentAccessor.getComponent(JiraThreadLocalUtil)
def jiraDurationUtils = ComponentAccessor.getComponentOfType(JiraDurationUtils)
@BaseScript CustomEndpointDelegate delegate
def authorizedGroups = []/*put groups here for who is allowed to trigger this*/
unarchiveProject(httpMethod: "POST", groups: authorizedGroups) { MultivaluedMap queryParams->
String projectKey = queryParams.getFirst('pkey')
if(!projectKey){
return Response.status(400).entity(new JsonBuilder([errors: "missing pkey parameter"]).toString()).build()
}
def project = projectManager.getProjectByCurrentKey(projectKey)
if(!project){
return Response.status(400).entity(new JsonBuilder([errors: "$projectKey is not a valid project"]).toString()).build()
}
def issueIds = issueManager.getIssueIdsForProject(project.id)
def currentUser = Users.loggedInUser
def techUser = Users.getByName("Automation User")
//Start a separate thread where the work will get executed. This willallow the flag to be returned immediated back to the user while the task continues in the background.
Thread.start {
jiraThreadLocalUtil.preCall()
def count = 0
def start = System.currentTimeMillis()
try {
ComponentAccessor.jiraAuthenticationContext.loggedInUser = techUser
issueIds.each { issueId ->
def issue = issueManager.getIssueObject(issueId)
count++
def validationArchive = archivedIssueService.validateRestoreIssue(techUser, issue.key, false)
if (validationArchive.valid) {
archivedIssueService.restoreIssue(validationArchive)
}
}
} finally {
jiraThreadLocalUtil.postCall(log)
}
def end = System.currentTimeMillis()
def duration = jiraDurationUtils.getFormattedDuration((end - start) / 1000 as Long)
Mail.send {
setTo(currentUser)
setSubject("Unarchive of $projectKey complete")
setBody("$count issues have been unarchived. This took $duration")
}
}
def flag = [:]
flag.type = 'success'
flag.title = "Unarchive initiated"
flag.close = 'manual'
flag.body = """Your request to unarchive $projectKey been received. <br>This may take a while.<br>You will receive an email when it's finished"""
return Response.ok(new JsonBuilder(flag).toString()).build()
}
Notice how I removed issueManager.getIssueObjects(objectIds) ... this would convert all your issues into issue objects. If you have many issue objects, that might use too much memory on your system. Instead, we iterate over the collection of long issue ids. And only create 1 issue object instance at a time.
Hi @Peter-Dave Sheehan
I Am sorry I did not mark this as Answered. Thank you very much for your solution.
One note. setting the call to POST did not work for me. Only when I made this a get call did it work. Also, I had problems with the validation. I will post the full script soon.
I really like that flag. I did not know one could do this. Amazing
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.