Answer by Jiri Kanicky on 04 August 2020
Hi.
Incoming sync quite long (I had to reduct it a bit). It all works, just the permission is the issue.
if(firstSync){
// issue.projectKey = "GCD"
// Set type name from source issue, if not found set a default
// issue.typeName = nodeHelper.getIssueType(replica.typeName)?.name ?: "Task"
if(replica.type.name == "Admin Reporting") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "COB") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Data Upload") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Decommission Server") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Delivery Admin") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Dev/Test Setup") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Documentation") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "DR Setup") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "ETL") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "File Request") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Go-Live Checklist") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Incident") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Integration") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "License Update") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Network Request") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Non-Prod Setup") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Presales") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Prod Setup") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Restart Services") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Risk") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Security Task") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Server Spec") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Task") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Tuning") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Upgrades / Monthly Builds") {
issue.projectKey = "GCD"
issue.typeName = "Task"
}
else if (replica.type.name == "Environment Refresh") {
issue.projectKey = "GCD"
issue.typeName = "Environment Refresh"
}
else if (replica.type.name == "Backup â Appl. & DB") {
issue.projectKey = "GCD"
issue.typeName = "Backup - Appl. & DB Data"
}
else if (replica.type.name == "Release") {
issue.projectKey = "GCD"
issue.typeName = "Release"
}
else if (replica.type.name == "Sub-task") {
issue.projectKey = "GCD"
issue.typeName = "Sub-task"
}
else if (replica.type.name == "User Access") {
issue.projectKey = "GCD"
issue.typeName = "User Access"
}
else if (replica.type.name == "Change Request") {
issue.projectKey = "GCD"
issue.typeName = "Change Request"
}
// set date when the issue is created during sync
// issue.customFields."Migration Date".value = "Date"
}
if(firstSync && replica.parentId){
issue.typeName = "Sub-task" //Make sure to use the right subtask type here.
def localParent = nodeHelper.getLocalIssueFromRemoteId(replica.parentId.toLong())
if(localParent){
issue.parentId = localParent.id
} else {
throw new com.exalate.api.exception.IssueTrackerException("Subtask cannot be created: parent issue with remote id " + replica.parentId + " was not found. Please make sure the parent issue is synchronized before resolving this error" )
}
}
// Organizations sync
//add organization names into the Text Field
issue.customFields."Migration Details".value = issue.customFields."Migration Details".value +"\n"+ "Organizations: " + replica.customKeys."Organization Names"?.join(",")
// Assing Organization to variable that it can be processed in if else list later. Assuming that only 1 organization exists per ticket
def orgName = replica.customKeys."Organization Names"?.join(",")
if (orgName == "BNE"){
issue.customFields.Organizations.value = "GCD-Alex Technologies Pty Ltd"
}
//CRM Company assign based on Customer (Cloud Imp)
if (orgName.isEmpty()) {
def customerCloud1 = replica.customFields."Customer (Cloud Imp)".value.value
def customerCloud = customerCloud1?.join("")
issue.customFields."Migration Details".value = issue.customFields."Migration Details".value +"\n" + "orgName is emty"
issue.customFields."Migration Details".value = issue.customFields."Migration Details".value +"\n" + "Customer (Cloud Imp): " + customerCloud?.join("")
if (customerCloud == "BNE"){
issue.customFields."Migration Details".value = issue.customFields."Migration Details".value +"\n" + "if condition for BNE executed"
issue.customFields."CRM Company".value = "XXX"
}
}
// Customer Request type
//if (replica.key == "CD-9160"){
// def customerRequestType = replica.customFields."Customer Request Type".value
//}
def issueType = replica.type.name
if (issueType == "Release"){
issue.customFields."Customer Request Type".value = "Release/Change"
}
else if (issueType == "Documentation"){
issue.customFields."Customer Request Type".value = "Documentation"
}
else if (issueType == "Incident"){
issue.customFields."Customer Request Type".value = "Incident"
}
else if (issueType == "User Access"){
issue.customFields."Customer Request Type".value = "User Access"
}
else if (issueType == "Restart Services"){
issue.customFields."Customer Request Type".value = "Restart Services"
}
else if (issueType == "Integration"){
issue.customFields."Customer Request Type".value = "Integration"
}
else if (issueType == "File Request"){
issue.customFields."Customer Request Type".value = "Data Extract - Files / Logs"
}
else if (issueType == "Data Upload"){
issue.customFields."Customer Request Type".value = "Data Upload"
}
else if (issueType == "Environment Refresh"){
issue.customFields."Customer Request Type".value = "Environment Refresh"
}
else if (issueType == "Backup - Appl. & DB Data"){
issue.customFields."Customer Request Type".value = "Backup - Appl. & DB Data"
}
else if (issueType == "COB"){
issue.customFields."Customer Request Type".value = "COB"
}
else if (issueType == "ETL"){
issue.customFields."Customer Request Type".value = "ETL"
}
else if (issueType == "Network Reqeust"){
issue.customFields."Customer Request Type".value = "Network Changes"
}
else if (issueType == "Change Request"){
issue.customFields."Customer Request Type".value = "Change Request (CR)"
}
else if (issueType == "Tuning"){
issue.customFields."Customer Request Type".value = "Tuning"
}
else if (issueType == "Decomission Server"){
issue.customFields."Customer Request Type".value = "Decomission Server"
}
else if (issueType == "Admin Reporting"){
issue.customFields."Customer Request Type".value = "Delivery Reporting"
}
else if (issueType == "Risk"){
issue.customFields."Customer Request Type".value = "Risk"
}
else if (issueType == "Dev/Test Setup"){
issue.customFields."Customer Request Type".value = "Dev Test Setup"
}
else if (issueType == "Task"){
issue.customFields."Customer Request Type".value = "Miscellaneous Request"
}
else if (issueType == "Prod Setup"){
issue.customFields."Customer Request Type".value = "Prod Setup"
}
else if (issueType == "DR Setup"){
issue.customFields."Customer Request Type".value = "DR Setup"
}
else if (issueType == "Delivery Admin"){
issue.customFields."Customer Request Type".value = "Delivery Admin Setup"
}
else if (issueType == "Non-Prod Setup"){
issue.customFields."Customer Request Type".value = "Non-Prod Setup"
}
else if (issueType == "License Update"){
issue.customFields."Customer Request Type".value = "License Update"
}
else if (issueType == "Upgrades / Monthly Builds"){
issue.customFields."Customer Request Type".value = "Upgrades / Monthly Builds"
}
else if (issueType == "Presales"){
issue.customFields."Customer Request Type".value = "Presales"
}
else if (issueType == "Go-Live Checklist"){
issue.customFields."Customer Request Type".value = "Go-Live Checklist"
}
//issue.customFields."Migration Details".value = issue.customFields."Migration Details".value +"\n"+ "Customer Request Type: " + customerRequestType
issue.customFields."Migration Details".value = issue.customFields."Migration Details".value +"\n"+ "Issue Type: " + issueType
//issue.customFields."Customer Request Type".value = replica.customFields."Customer Request Type"
// System fields
issue.summary = replica.summary
issue.description = replica.description
issue.labels = replica.labels
issue.created = replica.created
issue.resolutiondate = replica.resolutiondate
issue.attachments = attachmentHelper.mergeAttachments(issue, replica)
// User Synchronization (Assignee/Reporter)
// Set a Reporter/Assignee from the source side, if the user can't be found set a default user
// You can use this approach for custom fields of type User
//def defaultUser = nodeHelper.getUserByEmail("jirabot_service@temenos.com")
issue.creator = nodeHelper.getUserByUsername(replica.creator?.username)
issue.assignee = nodeHelper.getUserByUsername(replica.assignee?.username)
issue.reporter = nodeHelper.getUserByUsername(replica.reporter?.username)
// Requested Participants
issue.customFields."Request participants"?.value = replica.customFields."Request participants"?.value?.collect { it ->
nodeHelper.getUserByEmail(it?.email)
}
/*
Comment Synchronization
Sync comments with the original author if the user exists in the local instance
Remove original Comments sync line if you are using this approach
*/
issue.comments = commentHelper.mergeComments(issue, replica){ it.executor = nodeHelper.getUserByEmail(it.author?.email) }
//issue.comments = commentHelper.mergeComments(issue, replica)
/*
Status Synchronization
Sync status according to the mapping [remote issue status: local issue status]
If statuses are the same on both sides don't include them in the mapping
def statusMapping = ["Open":"New", "To Do":"Backlog"]
def remoteStatusName = replica.status.name
issue.setStatus(statusMapping[remoteStatusName] ?: remoteStatusName)
*/
def statusMap = [
// "remote status name": "local status name"
"Closed" : "Closed",
"Paused" : "Paused",
"Triage" : "Triage",
"Waiting for Customer" : "Waiting for Customer",
"In Progress" : "In Progress",
"Waiting for Internal 3rd Party" : "Waiting for Internal 3rd Party",
"Pending" : "Pending",
"Awaiting approval" : "Awaiting Approval",
"Estimation" : "Estimate",
"Remediating" : "In Progress",
"Scoping" : "Scoping"
]
def remoteStatusName = replica.status.name
issue.setStatus(statusMap[remoteStatusName] ?: remoteStatusName)
// Priority Mapping
def priorityMapping = [
// remote side priority <-> local side priority
"Blocker" : "Blocker",
"Critical" : "Critical",
"Major" : "Medium",
"Minor" : "Low",
"Trivial" : "Minor"
]
def priorityName = priorityMapping[replica.priority?.name] ?: "Low" // set default priority in case the proper urgency could not be found
issue.priority = nodeHelper.getPriority(priorityName)
// Resolution Mapping
if (replica.resolution == null && issue.resolution != null) {
// if the remote issue is not resolved, but the local issue is set, then clear the local issue resolution
issue.resolution = null
}
if (replica.resolution != null) {
// the remote issue is resolved, but the local isn't - look up the correct local resolution object.
def resolutionMap = [
"Cannot Reproduce" : "Cannot Reproduce",
"Current Production Issue" : "Known Error",
"Data Integrity" : "Code Fix",
"Duplicate" : "Duplicate",
"Fixed" : "Resolved",
"Incomplete" : "Incomplete",
"Infrastructure/Environmental" : "Cannot Reproduce",
"Knowledge/Training" : "Working as Expected",
"Out of Scope Requirement" : "Feature Request",
"Raised in Error" : "Declined",
"Request Completed" : "Resolved",
"Will not be actioned" : "Won't Do",
"Done" : "Done",
"Won't Do" : "Won't Do",
"Declined" : "Declined"
]
// use 'done' as resolution if the remote resolution is not found
def targetResolutionName = resolutionMap[replica.resolution.name] ?: "Done"
// nodeHelper.getResolution looks up the local resolution object based on the provided name
issue.resolution = nodeHelper.getResolution(targetResolutionName)
}
/*
Custom Fields
This line will sync Text, Option(s), Number, Date, Organization, and Labels CFs
For other types of CF check documentation
issue.customFields."CF Name".value = replica.customFields."CF Name".value
*/
issue.customFields."Migration Ticket".value = replica.key
issue.customFields."Migration Ticket URL".value = "https://client.rubik.com.au/support/browse/" + replica.key
issue.customFields."Migration Instance".value = "Rubik"
// single selects
if(replica.customFields."Request Type"?.value){
issue.customFields."User Access Request Type".value = replica.customFields."Request Type".value.value
}
if(replica.customFields."Team Responsible"?.value){
issue.customFields."Team Responsible".value = replica.customFields."Team Responsible".value.value
}
if(replica.customFields."Cloud Infrastructure"?.value){
issue.customFields."Cloud Infrastructure".value = replica.customFields."Cloud Infrastructure".value.value
}
if(replica.customFields."User Access Type"?.value){
issue.customFields."User Access Type".value = replica.customFields."User Access Type".value.value
}
if(replica.customFields."Hosting Solution"?.value){
issue.customFields."Hosting Solution".value = replica.customFields."Hosting Solution".value.value
}
if(replica.customFields."CR Classification"?.value){
issue.customFields."CR Classification".value = replica.customFields."CR Classification".value.value
}
if(replica.customFields."CR Type"?.value){
issue.customFields."CR Type" = replica.customFields."CR Type"
}
// radio
if(replica.customFields."Cloud Security Policy Acknowledgement"?.value){
issue.customFields."Cloud Security Policy Acknowledgement".value = replica.customFields."Cloud Security Policy Acknowledgement".value.value
}
if(replica.customFields."CR Outcome"?.value){
issue.customFields."CR Outcome" = replica.customFields."CR Outcome"
}
//dates
issue.due = replica.due
issue.customFields."Rollback Date".value = replica.customFields."Rollback Date".value
// Checkboxes
def checkboxCollection1 = replica.customFields."Env Deployment Checklist".
value?.
collect{
a->
nodeHelper.getOption (issue, "Env Deployment Checklist", a.value)
}
issue.customFields."Env Deployment Checklist".value = checkboxCollection1
def checkboxCollection2 = replica.customFields."Env Refresh Checklist".
value?.
collect{
a->
nodeHelper.getOption (issue, "Env Refresh Checklist", a.value)
}
issue.customFields."Env Refresh Checklist".value = checkboxCollection2
def checkboxCollection3 = replica.customFields."Env Verification Checklist".
value?.
collect{
a->
nodeHelper.getOption (issue, "Env Verification Checklist", a.value)
}
issue.customFields."Env Verification Checklist".value = checkboxCollection3
def checkboxCollection4 = replica.customFields."Environment".
value?.
collect{
a->
nodeHelper.getOption (issue, "Cloud Environment", a.value)
}
issue.customFields."Cloud Environment".value = checkboxCollection4
// issue.customFields."Migration Details".value = issue.customFields."Migration Details".value +"\n" + checkboxCollection4?.join(",")
def checkboxCollection5 = replica.customFields."Product/s".
value?.
collect{
a->
nodeHelper.getOption (issue, "Migration Products", a.value)
}
issue.customFields."Migration Products".value = checkboxCollection5
//Text single (ensure that field names are correct. Its case sensitive.)
if(replica.customFields."Contact Email"?.value){
issue.customFields."Contact Email".value = replica.customFields."Contact Email".value
}
if(replica.customFields."Contact Person"?.value){
issue.customFields."Contact Person".value = replica.customFields."Contact Person".value
}
if(replica.customFields."Job Title"?.value){
issue.customFields."Job Title".value = replica.customFields."Job Title".value
}
if(replica.customFields."Pack Location"?.value){
issue.customFields."Pack Location".value = replica.customFields."Pack Location".value
}
if(replica.customFields."Refresh From"?.value){
issue.customFields."Refresh From".value = replica.customFields."Refresh From".value
}
if(replica.customFields."Refresh To"?.value){
issue.customFields."Refresh To".value = replica.customFields."Refresh To".value
}
if(replica.customFields."Team Name"?.value){
issue.customFields."Team Name".value = replica.customFields."Team Name".value
}
//Text field to Number field (text field must have a digit)
if(replica.customFields."Estimate - High Level (days)"?.value){
def valueStr = replica.customFields."Estimate - High Level (days)".value
double valueNum = Double.valueOf(valueStr)
issue.customFields."Est. (Days)".value = valueNum
}
//Test multiline
if(replica.customFields."Server IPs"?.value){
issue.customFields."Server IPs".value = replica.customFields."Server IPs".value
}
// Radion to Cascading field
if(replica.customFields."Release Window"?.value){
def radioValue = replica.customFields."Release Window".value.value
issue.customFields."Release Window".value = nodeHelper.getCascadingSelect(
nodeHelper.getOption(issue, "Release Window", "APAC"), // hardcoded value
nodeHelper.getOption(issue, "Release Window", radioValue )
)
}
//other
// issue.customFields."Approvers" = replica.customFields."Approvers"
Comments:
Francis Martens (Exalate) commented on 04 August 2020
It is indeed long. You might have a look at the switch statement in groovy which would help compress the incoming sync.
Could you please remove the line
issue.creator = nodeHelper.getUserByUsername(replica.creator?.username)
From the incoming sync script and try again.
Also as a suggestion you can also ensure that the reporter and assignee are always set with following code
def defaultUser = nodeHelper.getUserByEmail("jirabot_service@temenos.com")
issue.assignee = nodeHelper.getUserByUsername(replica.assignee?.username) ?: defaultUser
issue.reporter = nodeHelper.getUserByUsername(replica.reporter?.username) ?: defaultUser