diff --git a/src/main/java/hudson/plugins/jira/JiraSession.java b/src/main/java/hudson/plugins/jira/JiraSession.java
index 4aa6f0be..580a173e 100644
--- a/src/main/java/hudson/plugins/jira/JiraSession.java
+++ b/src/main/java/hudson/plugins/jira/JiraSession.java
@@ -40,8 +40,6 @@
public class JiraSession {
private static final Logger LOGGER = Logger.getLogger(JiraSession.class.getName());
- public static final Integer MAX_ISSUES = 100;
-
public final JiraRestService service;
/**
@@ -51,9 +49,12 @@ public class JiraSession {
private final String jiraSiteName;
+ private final Integer maxIssuesFromJqlSearch;
+
/* package */ JiraSession(JiraSite site, JiraRestService jiraRestService) {
this.service = jiraRestService;
this.jiraSiteName = site.getName();
+ this.maxIssuesFromJqlSearch = site.getMaxIssuesFromJqlSearch();
}
/**
@@ -132,7 +133,7 @@ public Issue getIssue(String id) {
* @return issues matching the JQL query
*/
public List getIssuesFromJqlSearch(final String jqlSearch) throws TimeoutException {
- return service.getIssuesFromJqlSearch(jqlSearch, MAX_ISSUES);
+ return service.getIssuesFromJqlSearch(jqlSearch, maxIssuesFromJqlSearch);
}
/**
@@ -177,10 +178,10 @@ public List getIssuesWithFixVersion(String projectKey, String version, St
if (isNotEmpty(filter)) {
return service.getIssuesFromJqlSearch(
String.format("project = \"%s\" and fixVersion = \"%s\" and " + filter, projectKey, version),
- MAX_ISSUES);
+ maxIssuesFromJqlSearch);
}
return service.getIssuesFromJqlSearch(
- String.format("project = \"%s\" and fixVersion = \"%s\"", projectKey, version), MAX_ISSUES);
+ String.format("project = \"%s\" and fixVersion = \"%s\"", projectKey, version), maxIssuesFromJqlSearch);
}
/**
@@ -227,7 +228,7 @@ public void migrateIssuesToFixVersion(String projectKey, String version, String
}
LOGGER.fine("Fetching versions with JQL:" + query);
- List issues = service.getIssuesFromJqlSearch(query, MAX_ISSUES);
+ List issues = service.getIssuesFromJqlSearch(query, maxIssuesFromJqlSearch);
if (issues == null || issues.isEmpty()) {
return;
}
@@ -257,7 +258,7 @@ public void replaceFixVersion(String projectKey, String fromVersion, String toVe
}
LOGGER.fine("Fetching versions with JQL:" + query);
- List issues = service.getIssuesFromJqlSearch(query, MAX_ISSUES);
+ List issues = service.getIssuesFromJqlSearch(query, maxIssuesFromJqlSearch);
if (issues == null) {
return;
}
@@ -313,7 +314,7 @@ public void addFixVersion(String projectKey, String version, String query) throw
}
LOGGER.fine("Fetching issues with JQL:" + query);
- List issues = service.getIssuesFromJqlSearch(query, MAX_ISSUES);
+ List issues = service.getIssuesFromJqlSearch(query, maxIssuesFromJqlSearch);
if (issues == null || issues.isEmpty()) {
return;
}
diff --git a/src/main/java/hudson/plugins/jira/JiraSite.java b/src/main/java/hudson/plugins/jira/JiraSite.java
index f5f6db9d..9ac4077a 100644
--- a/src/main/java/hudson/plugins/jira/JiraSite.java
+++ b/src/main/java/hudson/plugins/jira/JiraSite.java
@@ -92,6 +92,7 @@
* needed to access this Jira.
*
* When adding new fields do not miss to look at readResolve method!!
+ *
* @author Kohsuke Kawaguchi
*/
public class JiraSite extends AbstractDescribableImpl {
@@ -117,6 +118,10 @@ public class JiraSite extends AbstractDescribableImpl {
public static final int DEFAULT_THREAD_EXECUTOR_NUMBER = 10;
+ public static final Integer DEFAULT_ISSUES_FROM_JQL = 100;
+
+ public static final Integer MAX_ALLOWED_ISSUES_FROM_JQL = 5000;
+
/**
* URL of Jira for Jenkins access, like {@code http://jira.codehaus.org/}.
* Mandatory. Normalized to end with '/'
@@ -150,6 +155,7 @@ public class JiraSite extends AbstractDescribableImpl {
/**
* User name needed to login. Optional.
+ *
* @deprecated use credentialsId
*/
@Deprecated
@@ -157,6 +163,7 @@ public class JiraSite extends AbstractDescribableImpl {
/**
* Password needed to login. Optional.
+ *
* @deprecated use credentialsId
*/
@Deprecated
@@ -221,12 +228,14 @@ public class JiraSite extends AbstractDescribableImpl {
/**
* response timeout for jira rest call
+ *
* @since 3.0.3
*/
private int readTimeout = DEFAULT_READ_TIMEOUT;
/**
* thread pool number
+ *
* @since 3.0.3
*/
private int threadExecutorNumber = DEFAULT_THREAD_EXECUTOR_NUMBER;
@@ -238,10 +247,14 @@ public class JiraSite extends AbstractDescribableImpl {
/**
* To add scm entry change date and time in jira comments.
- *
*/
private boolean appendChangeTimestamp;
+ /**
+ * To allow configurable value of max issues from jql search via jira site global configuration.
+ */
+ private int maxIssuesFromJqlSearch = DEFAULT_ISSUES_FROM_JQL;
+
private int ioThreadCount = Integer.getInteger(JiraSite.class.getName() + ".httpclient.options.ioThreadCount", 2);
/**
@@ -502,6 +515,7 @@ public boolean getDisableChangelogAnnotations() {
/**
* Sets connect timeout (in seconds).
* If not specified, a default timeout will be used.
+ *
* @param timeoutSec Timeout in seconds
*/
@DataBoundSetter
@@ -516,6 +530,7 @@ public int getTimeout() {
/**
* Sets read timeout (in seconds).
* If not specified, a default timeout will be used.
+ *
* @param readTimeout Timeout in seconds
*/
@DataBoundSetter
@@ -646,6 +661,17 @@ public void setUpdateJiraIssueForAllStatus(boolean updateJiraIssueForAllStatus)
this.updateJiraIssueForAllStatus = updateJiraIssueForAllStatus;
}
+ @DataBoundSetter
+ public void setMaxIssuesFromJqlSearch(int maxIssuesFromJqlSearch) {
+ this.maxIssuesFromJqlSearch = maxIssuesFromJqlSearch > MAX_ALLOWED_ISSUES_FROM_JQL
+ ? MAX_ALLOWED_ISSUES_FROM_JQL
+ : maxIssuesFromJqlSearch;
+ }
+
+ public int getMaxIssuesFromJqlSearch() {
+ return maxIssuesFromJqlSearch;
+ }
+
@SuppressWarnings("unused")
protected Object readResolve() throws FormException {
JiraSite jiraSite;
@@ -683,7 +709,11 @@ protected Object readResolve() throws FormException {
jiraSite.setDisableChangelogAnnotations(disableChangelogAnnotations);
jiraSite.setDateTimePattern(dateTimePattern);
jiraSite.setUseBearerAuth(useBearerAuth);
-
+ if (this.maxIssuesFromJqlSearch <= 0) {
+ jiraSite.setMaxIssuesFromJqlSearch(DEFAULT_ISSUES_FROM_JQL);
+ } else {
+ jiraSite.setMaxIssuesFromJqlSearch(maxIssuesFromJqlSearch);
+ }
return jiraSite;
}
@@ -760,7 +790,8 @@ Lock getProjectUpdateLock() {
/**
* This method only supports credential matching by credentialsId.
* Older methods are not and will not be supported as the credentials should have been migrated already.
- * @param item can be null if top level
+ *
+ * @param item can be null if top level
* @param uiValidation if true and credentials not found at item level will not go up
*/
private StandardUsernamePasswordCredentials resolveCredentials(Item item, boolean uiValidation) {
@@ -1132,9 +1163,10 @@ public boolean existsIssue(String id) {
/**
* Returns all versions for the given project key.
- * @deprecated use {@link JiraSession#getVersions(String)}
+ *
* @param projectKey Project Key
* @return A set of JiraVersions
+ * @deprecated use {@link JiraSession#getVersions(String)}
*/
@Deprecated
public Set getVersions(String projectKey) {
@@ -1148,7 +1180,7 @@ public Set getVersions(String projectKey) {
/**
* Generates release notes for a given version.
*
- * @param projectKey the project key
+ * @param projectKey the project key
* @param versionName the version
* @param filter Additional JQL Filter. Example: status in (Resolved,Closed)
* @return release notes
@@ -1234,9 +1266,9 @@ public void migrateIssuesToFixVersion(String projectKey, String versionName, Str
/**
* Adds new fix version to issues matching the jql.
*
- * @param projectKey the project key
+ * @param projectKey the project key
* @param versionName the version
- * @param query the query
+ * @param query the query
* @throws TimeoutException if too long
*/
public void addFixVersionToIssue(String projectKey, String versionName, String query) throws TimeoutException {
@@ -1251,10 +1283,10 @@ public void addFixVersionToIssue(String projectKey, String versionName, String q
* Progresses all issues matching the JQL search, using the given workflow action. Optionally
* adds a comment to the issue(s) at the same time.
*
- * @param jqlSearch the query
+ * @param jqlSearch the query
* @param workflowActionName the workflowActionName
- * @param comment the comment
- * @param console the console
+ * @param comment the comment
+ * @param console the console
* @throws TimeoutException TimeoutException if too long
*/
public boolean progressMatchingIssues(
@@ -1521,7 +1553,6 @@ public JiraSite build() {
// yes this class hierarchy can be a real big mess...
/**
- *
* @param item the Jenkins {@link Item} can be a {@link Job} or {@link Folder}
* @return the parent as {@link ItemGroup} which can be {@link Jenkins} or {@link Folder}
*/
@@ -1567,6 +1598,7 @@ public static List getSitesFromFolders(ItemGroup itemGroup) {
/**
* Gets the effective {@link JiraSite} associated with the given project
* and creates automatically jiraSession for each jiraSite found
+ *
* @return null if no such was found.
*/
@Nullable
diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly
index 7e939f4e..175369c9 100644
--- a/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly
+++ b/src/main/resources/hudson/plugins/jira/JiraSite/config.jelly
@@ -51,6 +51,9 @@
+
+
+
diff --git a/src/main/resources/hudson/plugins/jira/JiraSite/help-maxIssuesFromJqlSearch.html b/src/main/resources/hudson/plugins/jira/JiraSite/help-maxIssuesFromJqlSearch.html
new file mode 100644
index 00000000..28be7c12
--- /dev/null
+++ b/src/main/resources/hudson/plugins/jira/JiraSite/help-maxIssuesFromJqlSearch.html
@@ -0,0 +1,3 @@
+
+Specifies the maximum number of issues to load from the JQL search query. If this number exceeds the limit configured in Jira, only the maximum allowed by Jira will be retrieved.
+
diff --git a/src/test/java/JiraTester.java b/src/test/java/JiraTester.java
index 7afb65ea..60f4875f 100644
--- a/src/test/java/JiraTester.java
+++ b/src/test/java/JiraTester.java
@@ -5,7 +5,6 @@
import com.atlassian.jira.rest.client.api.domain.Transition;
import com.atlassian.jira.rest.client.api.domain.User;
import hudson.plugins.jira.JiraRestService;
-import hudson.plugins.jira.JiraSession;
import hudson.plugins.jira.JiraSite;
import hudson.plugins.jira.JiraSite.ExtendedAsynchronousJiraRestClientFactory;
import hudson.plugins.jira.extension.ExtendedJiraRestClient;
@@ -57,7 +56,7 @@ public static void main(String[] args) throws Exception {
// restService.createIssue("TESTPROJECT", "This is a test issue created using Jira jenkins plugin. Please
// ignore it.", "TESTUSER", components1, "test issue from Jira jenkins plugin");
- final List searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 3);
+ final List searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 100);
for (Issue searchResult : searchResults) {
System.out.println("JQL search result: " + searchResult);
}
@@ -102,8 +101,8 @@ public static void main(String[] args) throws Exception {
private static void callUniq(final JiraRestService restService) throws Exception {
long start = System.currentTimeMillis();
- List issues =
- restService.getIssuesFromJqlSearch("key in ('JENKINS-53320','JENKINS-51057')", JiraSession.MAX_ISSUES);
+ List issues = restService.getIssuesFromJqlSearch(
+ "key in ('JENKINS-53320','JENKINS-51057')", JiraSite.MAX_ALLOWED_ISSUES_FROM_JQL);
long end = System.currentTimeMillis();
System.out.println("time uniq " + (end - start));
}
@@ -112,7 +111,7 @@ private static void callDuplicate(final JiraRestService restService) throws Exce
long start = System.currentTimeMillis();
List issues = restService.getIssuesFromJqlSearch(
"key in ('JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057')",
- JiraSession.MAX_ISSUES);
+ JiraSite.MAX_ALLOWED_ISSUES_FROM_JQL);
long end = System.currentTimeMillis();
System.out.println("time duplicate " + (end - start));
}
diff --git a/src/test/java/JiraTesterBearerAuth.java b/src/test/java/JiraTesterBearerAuth.java
index bf1f3bbf..646fc317 100644
--- a/src/test/java/JiraTesterBearerAuth.java
+++ b/src/test/java/JiraTesterBearerAuth.java
@@ -5,7 +5,6 @@
import com.atlassian.jira.rest.client.api.domain.Transition;
import com.atlassian.jira.rest.client.api.domain.User;
import hudson.plugins.jira.JiraRestService;
-import hudson.plugins.jira.JiraSession;
import hudson.plugins.jira.JiraSite;
import hudson.plugins.jira.JiraSite.ExtendedAsynchronousJiraRestClientFactory;
import hudson.plugins.jira.auth.BearerHttpAuthenticationHandler;
@@ -59,7 +58,7 @@ public static void main(String[] args) throws Exception {
// restService.createIssue("TESTPROJECT", "This is a test issue created using Jira jenkins plugin. Please
// ignore it.", "TESTUSER", components1, "test issue from Jira jenkins plugin");
- final List searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 3);
+ final List searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 100);
for (Issue searchResult : searchResults) {
System.out.println("JQL search result: " + searchResult);
}
@@ -104,8 +103,7 @@ public static void main(String[] args) throws Exception {
private static void callUniq(final JiraRestService restService) throws Exception {
long start = System.currentTimeMillis();
- List issues =
- restService.getIssuesFromJqlSearch("key in ('JENKINS-53320','JENKINS-51057')", JiraSession.MAX_ISSUES);
+ List issues = restService.getIssuesFromJqlSearch("key in ('JENKINS-53320','JENKINS-51057')", 100);
long end = System.currentTimeMillis();
System.out.println("time uniq " + (end - start));
}
@@ -114,7 +112,7 @@ private static void callDuplicate(final JiraRestService restService) throws Exce
long start = System.currentTimeMillis();
List issues = restService.getIssuesFromJqlSearch(
"key in ('JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057')",
- JiraSession.MAX_ISSUES);
+ 100);
long end = System.currentTimeMillis();
System.out.println("time duplicate " + (end - start));
}
diff --git a/src/test/java/hudson/plugins/jira/JiraSessionTest.java b/src/test/java/hudson/plugins/jira/JiraSessionTest.java
index 367f923a..0b1004e9 100644
--- a/src/test/java/hudson/plugins/jira/JiraSessionTest.java
+++ b/src/test/java/hudson/plugins/jira/JiraSessionTest.java
@@ -60,7 +60,7 @@ void replaceWithFixVersionByRegex() throws URISyntaxException, TimeoutException
ArrayList issues = new ArrayList<>();
issues.add(getIssue(Arrays.asList("v1.0"), 1L));
issues.add(getIssue(Arrays.asList("v1.0", "v2.0", "v2.0.0"), 2L));
- when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(issues);
+ when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(issues);
jiraSession.replaceFixVersion(PROJECT_KEY, "/v1.*/", newVersion.getName(), QUERY);
@@ -99,7 +99,7 @@ void replaceFixVersion() throws URISyntaxException, TimeoutException {
issues.add(getIssue(Arrays.asList("v1.0"), 1L));
issues.add(getIssue(Arrays.asList("v1.0", "v1.0.0", "v2.0.0"), 2L));
issues.add(getIssue(null, 3L));
- when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(issues);
+ when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(issues);
jiraSession.replaceFixVersion(PROJECT_KEY, "v1.0", newVersion.getName(), QUERY);
@@ -183,7 +183,7 @@ void shouldAddVersionToAllIssues() throws Exception {
List issues = new ArrayList<>();
issues.add(getIssue(Arrays.asList("v1.0"), 1L));
issues.add(getIssue(Arrays.asList("v2.0", "v3.0"), 2L));
- when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(issues);
+ when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(issues);
jiraSession.addFixVersion(PROJECT_KEY, newVersion.getName(), QUERY);
@@ -213,7 +213,7 @@ void shouldAddVersionWhenNoFixVersions() throws Exception {
when(jiraSession.getVersions(PROJECT_KEY)).thenReturn(myVersions);
List issues = List.of(getIssue(null, 3L));
- when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(issues);
+ when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(issues);
jiraSession.addFixVersion(PROJECT_KEY, newVersion.getName(), QUERY);
@@ -233,7 +233,7 @@ void shouldNotCallUpdateIfNoIssues() throws Exception {
List myVersions = List.of(newVersion);
when(jiraSession.getVersions(PROJECT_KEY)).thenReturn(myVersions);
- when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(new ArrayList<>());
+ when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(new ArrayList<>());
jiraSession.addFixVersion(PROJECT_KEY, newVersion.getName(), QUERY);
diff --git a/src/test/java/hudson/plugins/jira/JiraSiteTest.java b/src/test/java/hudson/plugins/jira/JiraSiteTest.java
index 65c3272d..4c65e2e1 100644
--- a/src/test/java/hudson/plugins/jira/JiraSiteTest.java
+++ b/src/test/java/hudson/plugins/jira/JiraSiteTest.java
@@ -435,6 +435,14 @@ void getIssueWithoutSession() throws Exception {
assertNull(issue);
}
+ @Test
+ @WithoutJenkins
+ void ensureMaxIssuesFromJqlEndsUpMaxAllowed() throws MalformedURLException {
+ JiraSite jiraSite = new JiraSite(new URL("https://example1.org/").toExternalForm());
+ jiraSite.setMaxIssuesFromJqlSearch(6000);
+ assertEquals(5000, jiraSite.getMaxIssuesFromJqlSearch());
+ }
+
private Folder createFolder(JenkinsRule j, Folder folder) throws IOException {
return folder == null
? j.jenkins.createProject(