I am trying to write a script that will talk to the Autotask API and I'm using the Script Console to test on.
When I run I am hitting this error:
javax.xml.stream.FactoryConfigurationError: Provider for class javax.xml.stream.XMLInputFactory cannot be created and I've tried adding that as an import but it still fails.
Based on some posts online I believe the issue is something to do with the Autotask API messages needing to be in XML but not sure how to get around this.
I'm just doing a very simple call right now to verify the connection will work.
Here is the test code I've written, this is taken from some sample code I was given and also from their documentation:
import javax.xml.ws.BindingProvider
import net.autotask.atws.v1_5.ATWS
import net.autotask.atws.v1_5.ATWSResponse
import net.autotask.atws.v1_5.ATWSSoap
import net.autotask.atws.v1_5.ATWSZoneInfo
import net.autotask.atws.v1_5.GetZoneInfo
import net.autotask.atws.v1_5.Ticket
import net.autotask.atws.v1_5.ArrayOfEntity
import net.autotask.atws.v1_5.Entity
import groovyx.net.http.HTTPBuilder
def ATWS newser = new ATWS()
ATWSSoap port = newser.getPort(ATWSSoap.class)
BindingProvider prov = (BindingProvider) port
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY,"username")
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "userspwd")
prov.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,"https://webservices2.autotask.net/ATServices/1.5/atws.asmx")
def ATWSZoneInfo azi = new ATWSZoneInfo()
azi = port.getZoneInfo("username")
return azi.URL
Hi,
First i think the best option it to communicate about this change and let the owners make the change themselves.
But you can use the API to get all filter
/rest/api/3/filter/search
Then, get the owner to send them a message if the JQL match the customfield or update the filter by your own.
I'm afraid I'll have to agree. It would certainly be nice to have such a feature with Scriptrunner or Jira natively. I'll accept this as an answer, but I won't give up on this script just yet. I'll keep this on my backlog, and hopefully in the future someone can add a comment to this question.
Thanks,
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Did you every get your script to work? I have the exact same use case and have over 600 filters using the team name field I need to change to Team A-1 and changing them all manually is just not a good use of anyone's time just because a team decided to change their name. I am really hoping you got this to work and wouldn't mind sharing your code.
I run Jira Server
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Lopes, Bonnie Unfortunately, I have not found a way. The most I was able to do was find all saved filters that contains the JQL string I want to change. For some reason, I can't seem to get "setQuery" to recognize the "newString". Also, I have not found a way for this to work for Quick Filters on Boards or Structure filters, if you use Structure.
Also I have not found a way through REST API either.
I end up telling the team that they'll have to make new filters with their new team name.
But you or anyone can try to work off what I have. Maybe you'll have better luck than me.
import com.atlassian.jira.bc.JiraServiceContextImpl
import.java.lang.StringBuffer
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.filter.SearchRequestService
import com.atlassian.jira.issue.search.SearchRequest
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.bc.user.search.UserSearchService
import java.lang.StringBuilder
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.bc.issue.search.SearchService
//important variables and components for later
SearchRequestService searchRequestService = ComponentAccessor.getComponent(SearchRequestService.class)
UserSearchService userSearchService = ComponentAccessor.getComponent(UserSearchService)
StringBuilder output = StringBuilder.newInstance()
def sb = new StringBuffer()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService)
//parameters for searching queries
UserSearchParams userSearchParams = new UserSearchParams.Builder()
.allowEmptyQuery(true)
.includeInactive(false)
.ignorePermissionCheck(true)
.maxResults(5000)
.build()
//iterate over each user's filters
userSearchService.findUsers("", userSearchParams).each {ApplicationUser filter_owner ->
try{
searchRequestService.getOwnedFilters(filter_owner).each { SearchRequest filter ->
String jql = filter.getQuery().toString()
def customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(12345)//**CHANGE FIELD ID HERE** to search for the custom field you want
def oldJQL = customField = "Team A" as String// **INPUT OLD VALUE HERE**
def newJQL = customField = "Team A-1" as String// **INPUT NEW VALUE HERE**
def context = new JiraServiceContextImpl(filter_owner)
//First Run = checks each filter, get JQL, and check if it contains out string. Useful for verifying before making changes
//Second Run = comment out sb.append and un-comment the others to perform the bulk editing, but still WIP...
if(jql.contains(oldJQL)) {
//String newString = jql.replace(oldJQL,newJQL)
//def newFilter = searchService.parseQuery(filter_owner,newString).query
//filter.setQuery(newFilter)
//searchRequestService.updateFilter(context,filter)
sb.append("Found: '${filter.name}' owned by ${filter_owner.displayName} - {filter.getPermissions().isPrivate() ? 'Private' : 'Shared'} - JQL: {jql} ||")
}
}
} catch (Exception e) {
//checks if filter is private
sb.append("Unable to get filters for ${filter_owner.displayName} due to ${e}")
}
}
return sb.toString()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you for the reply. I have given your script to my technical folks and hope they can figure out a way to get it to work. If they do. I will surely post it here for all.
BTW, I use a plug-in called Configuration manager for Jira that will allow me to search and retrieve all filters that contain a search string. It is quite useful, as it also tells me where a particular filter is used, on what boards and/or dashboards. Besides filters there are many other configuration items. (Power Admin) is the component within the Configuration Manager for Jira and I believe you can get Power Admin for free.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello @Diana Gorv ,
For updating your Structure Generators, you could use a script like this:
import com.atlassian.jira.component.ComponentAccessor; import org.apache.log4j.Logger import org.apache.log4j.Level def log = Logger.getLogger('script.internal') log.setLevel(Level.DEBUG) def plugin = ComponentAccessor.pluginAccessor.getPlugin("com.almworks.jira.structure") def structureManager = plugin.getModuleDescriptor('structure-manager').module def forestService = plugin.getModuleDescriptor('forest-service').module def rowManager = plugin.getModuleDescriptor('structure-row-manager').module def generatorManager = plugin.getModuleDescriptor('generator-manager').module def loadClass = {name -> plugin.classLoader.loadClass("com.almworks.jira.structure.api.$name")} def PermissionLevel = loadClass('permissions.PermissionLevel') def ForestSpec = loadClass('forest.ForestSpec') def CoreIdentities = loadClass('item.CoreIdentities') def structures = structureManager.getAllStructures(PermissionLevel.ADMIN) /* Get all generator specs */ def generatorIds = new ArrayList(); for (def structure : structures) { def forestSpec = ForestSpec.structure(structure.id) def forest = forestService.getForestSource(forestSpec).latest.forest for (def rowId : forest.rows.toNativeArray()) { def itemId = rowManager.getRow(rowId).itemId if (CoreIdentities.isGenerator(itemId)) { generatorIds.add(itemId.longId) } } } /* Find generators with jql that needed for your case (with old usernames) and replace them to ones with new usernames */ for (def genId : generatorIds) { def spec = generatorManager.getGenerator(genId) def params = spec.parameters if (params.containsKey('jql') && params.containsValue ('project=test') /* replace 'project=test' with your original jql */) { log.debug "old jql: ${params.get('jql')}" def newJql = 'project=demo' /* replace 'project=demo' with your new jql */ def updatedParams = new LinkedHashMap(params); updatedParams.put('jql', newJql); log.debug "new jql: ${updatedParams.get('jql')})" generatorManager.updateGenerator(genId, spec.moduleKey, updatedParams, spec.owningStructure) } }
Unfortunately, it will not work with Transformations. There is not a way to update those in a similar manner.
Hope this helps!
Best,
David
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @David Niro
Thank you for this!
Unfortunately, I got an error "java.lang.ClassNotFoundException: com.almworks.jira.structure.apipermissions.PermissionLevel not found by com.almworks.jira.structure [18]"
Our version is 8.13.8, so if it requires an api, perhaps that is the cause? Since our instance does not have api functionalities yet. (Working on upgrading eventually).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Diana Gorv ,
You are very welcome.
It does require and API, which explains the error received.
Best,
David
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.