2 answers
- 10-1
We found that it wasn't a problem of the code, but that in Service now we have a script adding those values a few seconds after the creation.
Add your comment... - 10-1
Can you provide the full code of your incoming sync - Jira side?
- Mihai Arama
Hi,
Sure.
if(firstSync){ issue.projectKey = "ESNIT" // Set type name from source issue, if not found set a default issue.typeName = nodeHelper.getIssueType(replica.type?.name, issue.projectKey)?.name ?: "Task" issue.summary = replica.key + " - " + replica.summary issue.description = nodeHelper.toMarkDownFromHtml(replica.description_html) issue.customFields."URL".value = remoteIssueUrl // Priority sync def priorityMapping = [ // Snow incident priority <-> Jira issue priority "1 - Critical": "Blocker", "2 - High": "Major", "3 - Medium": "Minor", "4 - Low": "Trivial" ] def defaultPriority = "Low" def priorityName = priorityMapping[replica.priority?.name] ?: defaultPriority // set default priority in case the proper urgency could not be found issue.priority = nodeHelper.getPriority(priorityName) // this part will add the hardcoded "PROD" and "CST" values + the values from 4 service-now fields, if they exist, to the jira labels; // also adding the H Software Product and the HSP Categories values to Components def listOfLabels = ['PROD', 'CST'] def listOfComponents = [] if (replica.H_software_product) { def HSoftwareProductValue = replica.H_software_product.display_value def noSpacesHSofwareProductValue = HSoftwareProductValue.replaceAll(" ","_") listOfLabels.add(noSpacesHSofwareProductValue) listOfComponents.add(HSoftwareProductValue) } if (replica.H_spc1) { def HSoftwareProductCategory1Value = replica.H_spc1.display_value def noSpacesHSoftwareProductCategory1Value = HSoftwareProductCategory1Value.replaceAll(" ","_") listOfLabels.add(noSpacesHSoftwareProductCategory1Value) listOfComponents.add(HSoftwareProductCategory1Value) } if (replica.H_spc2) { def HSoftwareProductCategory2Value = replica.H_spc1.display_value def noSpacesHSoftwareProductCategory2Value = HSoftwareProductCategory2Value.replaceAll(" ","_") listOfLabels.add(noSpacesHSoftwareProductCategory2Value) listOfComponents.add(HSoftwareProductCategory2Value) } if (replica.H_spc3) { def HSoftwareProductCategory3Value = replica.H_spc1.display_value def noSpacesHSoftwareProductCategory3Value = HSoftwareProductCategory3Value.replaceAll(" ","_") listOfLabels.add(noSpacesHSoftwareProductCategory3Value) listOfComponents.add(HSoftwareProductCategory3Value) } def project = issue.project ?: nodeHelper.getProject(issue.projectKey) for (eachComponent in listOfComponents){ def component = nodeHelper.getComponent(eachComponent, project) if(!component) {nodeHelper.createComponent( issue, eachComponent, null, null, null ) def newComponent = nodeHelper.getComponent(eachComponent, project) issue.components += newComponent } else {issue.components += component} } for (eachLabel in listOfLabels){ issue.labels += nodeHelper.getLabel(eachLabel) } // this part will create a mapping between the SNOW Country and Jira MO, and add the field value. def CountryToMOMapping = [ // Snow incident country <-> Jira issue MO "BR": "Brazil", "DE": "Germany" ] def defaultMO = "Brazil" def MOName = CountryToMOMapping[replica.country.display_value] ?: defaultMO // set default MO in case the proper MO could not be found issue.customFields."MO".value = MOName //sets the MO in Jira //using the above created MOName, map the MO to a Region, and set it in Jira def MOToRegionMapping = [ "Brazil": "W2", "Germany": "E3" ] def regionName = MOToRegionMapping[MOName] issue.customFields."Region".value = regionName /* def MOToHubLeaderMapping = [ "Brazil": "mihai.arama@externals.H.com", "Germany": "sascha.g@H.com" ] def defaultUser = nodeHelper.getUserByEmail(MOToHubLeaderMapping[MOName]) */ issue.reporter = nodeHelper.getUserByEmail(replica.opened_by) // ?: defaultUser issue.attachments = attachmentHelper.mergeAttachments(issue, replica) issue.customFields."SAP Customer Nr.".value = replica.H_customer.display_value // if(issue.description[-1] != issue.description) { // issue.description = commentHelper.mergeComments(issue, replica) //} } else { def statusMapping = ["Closed (resolved)":"Done"] def remoteStatusName = replica.state if (remoteStatusName == "Closed (resolved)") { issue.setStatus(statusMapping[remoteStatusName] ?: remoteStatusName) } if (!replica.state.equals(previous?.state)) { statusCommentString = "The Service-Now ticket's status is: " + replica.state issue.comments = commentHelper.addComment(statusCommentString, issue.comments) } //issue.attachments = attachmentHelper.mergeAttachments(issue, replica) //issue.description = nodeHelper.toMarkDownFromHtml(replica.description_html) //issue.comments = commentHelper.mergeComments(issue, replica) if (!replica.description_html[0] && !replica.description_html.equals(previous?.description_html)) { descriptionCommentString = "The Service-Now ticket's Description was updated to: " + "\n" + nodeHelper.toMarkDownFromHtml(replica.description_html) issue.comments = commentHelper.addComment(descriptionCommentString, issue.comments) } issue.attachments += replica.addedAttachments //issue.comments += replica.addedinternalworknotes if (!replica.internalworknotes.equals(previous?.internalworknotes)) { fullInternalWorkNotes = nodeHelper.toMarkDownFromHtml(replica.internalworknotes) // each new internal comment in service now starts with a \n\n ... def newRowDouble = fullInternalWorkNotes.indexOf("\n\n") // if \n\n is found, take left side if(newRowDouble != -1) { latestInternalNotes = fullInternalWorkNotes.substring(0, newRowDouble); } else { latestInternalNotes = fullInternalWorkNotes } workNotesCommentString = "New Service-Now Internal Work Notes were added: " + "\n" + latestInternalNotes issue.comments = commentHelper.addComment(workNotesCommentString, issue.comments) } //this next part handles escalation and de-escalation on the service now ticket if (replica.assignment_level > (previous?.assignment_level)){ escalationCommentString = "The Service-Now ticket has been escalated. The new assignment level is: " + replica.assignment_level + " and the assignment group is: " + replica.assignment_group.display_value issue.comments = commentHelper.addComment(escalationCommentString, issue.comments) issue.setStatus("Backlog") } if (replica.assignment_level < (previous?.assignment_level)){ deescalationCommentString = "The Service-Now ticket has been de-escalated. The new assignment level is: " + replica.assignment_level + " and the assignment group is: " + replica.assignment_group.display_value issue.comments = commentHelper.addComment(deescalationCommentString, issue.comments) issue.setStatus("Backlog") } } /* 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 issue.assignee = nodeHelper.getUserByEmail(replica.assignee?.email) ?: defaultUser */ /* 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) } */ /* 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 */ /* 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 */
Thank you for your quick reply!
- Francis Martens (Exalate)
This code segment looks very impressive.
Can you add a debug.error statement to the right block and see why the 'addComment' is being triggered? - Mihai Arama
Hi Francis,
I'm not sure if I added it correctly.
if (replica.description_html.equals(previous?.description_html)) { descriptionCommentString = "The Service-Now ticket's Description was updated to: " + "\n" + nodeHelper.toMarkDownFromHtml(replica.description_html) issue.comments = debug.error(commentHelper.addComment(descriptionCommentString, issue.comments)) }
I now get this:
No signature of method: com.exalate.hubobject.jira.DebugHelper.error() is applicable for argument types: (ArrayList) values: [[BasicHubComment{@body=`The Service-Now ticket's Description was updated to: ---BEGIN--- Short description of problem Attach screenshot of any error messages AT Doc Software version Computer information (operating system, connected to internet, re-installation tried) Attach software log files ---END---`, @id=`null`, @remoteId=`null`, @author=`null`, @created=`null`, @updateAuthor=`null`, @updated=`null`, @group=`null`, @role=`null`, @internal= `true`, @executor= `null`}]] Possible solutions: error(java.lang.String), every(), iterator(), grep(), macro(groovy.lang.Closure), print(java.io.PrintWriter)
But I assume that's not how the debug statement should be used. Any tips there, please?
Thank you!
- Francis Martens (Exalate)
Nope - clearly not
Check details
https://docs.idalko.com/exalate/display/ED/debug.error
Just add it on its own line - Mihai Arama
Hello,
I tried adding it like this:
if (replica.description_html.equals(previous?.description_html)) { descriptionCommentString = "The Service-Now ticket's Description was updated to: " + "\n" + nodeHelper.toMarkDownFromHtml(replica.description_html) issue.comments = commentHelper.addComment(descriptionCommentString, issue.comments) debug.error(commentHelper.addComment(descriptionCommentString, issue.comments)) }
and I get:
No signature of method: com.exalate.hubobject.jira.DebugHelper.error() is applicable for argument types: (ArrayList) values: [[BasicHubComment{@body=`The Service-Now ticket's Description was updated to: ---BEGIN--- Short description of problem Attach screenshot of any error messages AT Doc Software version Computer information (operating system, connected to internet, re-installation tried) Attach software log files ---END---`, @id=`null`, @remoteId=`null`, @author=`null`, @created=`null`, @updateAuthor=`null`, @updated=`null`, @group=`null`, @role=`null`, @internal= `true`, @executor= `null`}, ...]] Possible solutions: error(java.lang.String), every(), iterator(), grep(), macro(groovy.lang.Closure), print(java.io.PrintWriter)
Also, just adding debug.error() does not get me anything.
Also, I do not actually get an error, I just get the value synchronized in a moment when I don't need it synchronized.
Please let me know if you have any suggestions.
Thank you!
- Francis Martens (Exalate)
a) debug.error expects a string. commentHelper.addComment is returning a comment array so that can not work
With debug.error - you can print out the value of certain variables, like
debug.error("The value of firstSync is ${firstSync}")b) try to understand why that section of the code is being executed by looking at the logic and find out why it is getting there.
- Mihai Arama
Hello,
Thank you for the explanation.
I used two statements:
if (!replica.description_html.equals(previous?.description_html)) { descriptionCommentString = "The Service-Now ticket's Description was updated to: " + "\n" + nodeHelper.toMarkDownFromHtml(replica.description_html) issue.comments = commentHelper.addComment(descriptionCommentString, issue.comments) //debug.error("The value of the previous description is ${previous?.description_html}") //debug.error("The value of the current description is ${replica.description_html}") }
This is the output for them:
The value of the previous description is
Details:Username of affected user(s): ex: ukdemo@hilti.biz
Device Manufacturer and Model: ex: Apple iPhone X
Device Operating System: ex: iOS 11.2.6
Affected tools and their Serial Numbers (if applicable): ex: Hilti DX 5 (64632488) , Hilti SD 6H-A22 (15645625)
Mobile Application version: ex: Hilti Connect v1.2.2
Steps to reproduce: ex: Open the mobile application, attempt to login with username ukdemo@hilti.biz - got error message: System is busy
Date & Time when issue occurred: ex: 26-02-2018 - 13:15 CET
Troubleshooting performed: ex: Attempted login on Android phone - login successful; Attempted login with different username on same phone - login failed
Other details: ex: Other colleagues with different iOS phones can login successfully with this username
The value of the current description is
Details:Username of affected user(s): ex: ukdemo@hilti.biz
Device Manufacturer and Model: ex: Apple iPhone X
Device Operating System: ex: iOS 11.2.6
Affected tools and their Serial Numbers (if applicable): ex: Hilti DX 5 (64632488) , Hilti SD 6H-A22 (15645625)
Mobile Application version: ex: Hilti Connect v1.2.2
Steps to reproduce: ex: Open the mobile application, attempt to login with username ukdemo@hilti.biz - got error message: System is busy
Date & Time when issue occurred: ex: 26-02-2018 - 13:15 CET
Troubleshooting performed: ex: Attempted login on Android phone - login successful; Attempted login with different username on same phone - login failed
Other details: ex: Other colleagues with different iOS phones can login successfully with this usernameI compared the texts and they appear to be the same.
However, in service-now, this is a text field for which I can get the HTML source code, which is:
<div style="display: none;">---BEGIN---</div>
<p>Details:</p>
<ol style="list-style-position: inside;">
<li>Username of affected user(s): ex: ukdemo@hilti.biz</li>
<li>Device Manufacturer and Model: ex: Apple iPhone X</li>
<li>Device Operating System: ex: iOS 11.2.6</li>
<li>Affected tools and their Serial Numbers (if applicable): ex: Hilti DX 5 (64632488) , Hilti SD 6H-A22 (15645625)</li>
<li>Mobile Application version: ex: Hilti Connect v1.2.2</li>
<li>Steps to reproduce: ex: Open the mobile application, attempt to login with username <a href="mailto:ukdemo@hilti.biz" rel="nofollow">ukdemo@hilti.biz</a> - got error message: System is busy</li>
<li>Date & Time when issue occurred: ex: 26-02-2018 - 13:15 CET</li>
<li>Troubleshooting performed: ex: Attempted login on Android phone - login successful; Attempted login with different username on same phone - login failed</li>
<li>Other details: ex: Other colleagues with different iOS phones can login successfully with this username</li>
</ol>
<div style="display: none;">---END—Do you think this could be, somehow, the cause?
Thank you!
Add your comment...
Hello,
We have the following use-case:
Jira (cloud) - Service-Now integration.
We have in service now a field called "Assignment level". It can be 1,2,3 or 4.
When this value changes in service-now, we want to add a comment in Jira with the level and the current assignment group. We achieved this by adding the following code: