Skip to content

Commit ac75c47

Browse files
Hardikrathod01Hardik Rathod
andauthored
Add Jira site property to configure max number of returned Jira issues (#665)
* Update for adding jira site config parameter maxIssuesFromJqlSearch * Update for replacing hard coded value in DescriptorImplTest with Default max value parameter * Fix testcase replaceWithFixVersionByRegex * Update for fixing format violations * - Update for adding maximum allowed value check - Removing constructor param from JiraSession - Add and fix test cases * Use validation message from messages * Remove check method for form field validation * Apply spotless fix * Fix test case * Fix test case and a validation message grammar * Fix test case because old config will not have maxIssuesFromJqlSearch * Remove parameter maxIssuesFromJqlSearch from doValidate and related places * Implement maximum param value check in setter method * Use variable for comparison of max allowed value * Use ternary operator in setter method * Remove parameter from old jira configuration * Resolve conflicts * Fix jira session tests * Fix test cases because of stubbing problem * Fix indentation * Use Integer instead of int * Fix default value not being used when migrating from old config --------- Co-authored-by: Hardik Rathod <hardik.rathod@fruitcore.de>
1 parent 1583eda commit ac75c47

File tree

8 files changed

+78
-34
lines changed

8 files changed

+78
-34
lines changed

src/main/java/hudson/plugins/jira/JiraSession.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
public class JiraSession {
4141
private static final Logger LOGGER = Logger.getLogger(JiraSession.class.getName());
4242

43-
public static final Integer MAX_ISSUES = 100;
44-
4543
public final JiraRestService service;
4644

4745
/**
@@ -51,9 +49,12 @@ public class JiraSession {
5149

5250
private final String jiraSiteName;
5351

52+
private final Integer maxIssuesFromJqlSearch;
53+
5454
/* package */ JiraSession(JiraSite site, JiraRestService jiraRestService) {
5555
this.service = jiraRestService;
5656
this.jiraSiteName = site.getName();
57+
this.maxIssuesFromJqlSearch = site.getMaxIssuesFromJqlSearch();
5758
}
5859

5960
/**
@@ -132,7 +133,7 @@ public Issue getIssue(String id) {
132133
* @return issues matching the JQL query
133134
*/
134135
public List<Issue> getIssuesFromJqlSearch(final String jqlSearch) throws TimeoutException {
135-
return service.getIssuesFromJqlSearch(jqlSearch, MAX_ISSUES);
136+
return service.getIssuesFromJqlSearch(jqlSearch, maxIssuesFromJqlSearch);
136137
}
137138

138139
/**
@@ -177,10 +178,10 @@ public List<Issue> getIssuesWithFixVersion(String projectKey, String version, St
177178
if (isNotEmpty(filter)) {
178179
return service.getIssuesFromJqlSearch(
179180
String.format("project = \"%s\" and fixVersion = \"%s\" and " + filter, projectKey, version),
180-
MAX_ISSUES);
181+
maxIssuesFromJqlSearch);
181182
}
182183
return service.getIssuesFromJqlSearch(
183-
String.format("project = \"%s\" and fixVersion = \"%s\"", projectKey, version), MAX_ISSUES);
184+
String.format("project = \"%s\" and fixVersion = \"%s\"", projectKey, version), maxIssuesFromJqlSearch);
184185
}
185186

186187
/**
@@ -227,7 +228,7 @@ public void migrateIssuesToFixVersion(String projectKey, String version, String
227228
}
228229

229230
LOGGER.fine("Fetching versions with JQL:" + query);
230-
List<Issue> issues = service.getIssuesFromJqlSearch(query, MAX_ISSUES);
231+
List<Issue> issues = service.getIssuesFromJqlSearch(query, maxIssuesFromJqlSearch);
231232
if (issues == null || issues.isEmpty()) {
232233
return;
233234
}
@@ -257,7 +258,7 @@ public void replaceFixVersion(String projectKey, String fromVersion, String toVe
257258
}
258259

259260
LOGGER.fine("Fetching versions with JQL:" + query);
260-
List<Issue> issues = service.getIssuesFromJqlSearch(query, MAX_ISSUES);
261+
List<Issue> issues = service.getIssuesFromJqlSearch(query, maxIssuesFromJqlSearch);
261262
if (issues == null) {
262263
return;
263264
}
@@ -313,7 +314,7 @@ public void addFixVersion(String projectKey, String version, String query) throw
313314
}
314315

315316
LOGGER.fine("Fetching issues with JQL:" + query);
316-
List<Issue> issues = service.getIssuesFromJqlSearch(query, MAX_ISSUES);
317+
List<Issue> issues = service.getIssuesFromJqlSearch(query, maxIssuesFromJqlSearch);
317318
if (issues == null || issues.isEmpty()) {
318319
return;
319320
}

src/main/java/hudson/plugins/jira/JiraSite.java

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
* needed to access this Jira.
9393
* </p>
9494
* <b>When adding new fields do not miss to look at readResolve method!!</b>
95+
*
9596
* @author Kohsuke Kawaguchi
9697
*/
9798
public class JiraSite extends AbstractDescribableImpl<JiraSite> {
@@ -117,6 +118,10 @@ public class JiraSite extends AbstractDescribableImpl<JiraSite> {
117118

118119
public static final int DEFAULT_THREAD_EXECUTOR_NUMBER = 10;
119120

121+
public static final Integer DEFAULT_ISSUES_FROM_JQL = 100;
122+
123+
public static final Integer MAX_ALLOWED_ISSUES_FROM_JQL = 5000;
124+
120125
/**
121126
* URL of Jira for Jenkins access, like {@code http://jira.codehaus.org/}.
122127
* Mandatory. Normalized to end with '/'
@@ -150,13 +155,15 @@ public class JiraSite extends AbstractDescribableImpl<JiraSite> {
150155

151156
/**
152157
* User name needed to login. Optional.
158+
*
153159
* @deprecated use credentialsId
154160
*/
155161
@Deprecated
156162
private transient String userName;
157163

158164
/**
159165
* Password needed to login. Optional.
166+
*
160167
* @deprecated use credentialsId
161168
*/
162169
@Deprecated
@@ -221,12 +228,14 @@ public class JiraSite extends AbstractDescribableImpl<JiraSite> {
221228

222229
/**
223230
* response timeout for jira rest call
231+
*
224232
* @since 3.0.3
225233
*/
226234
private int readTimeout = DEFAULT_READ_TIMEOUT;
227235

228236
/**
229237
* thread pool number
238+
*
230239
* @since 3.0.3
231240
*/
232241
private int threadExecutorNumber = DEFAULT_THREAD_EXECUTOR_NUMBER;
@@ -238,10 +247,14 @@ public class JiraSite extends AbstractDescribableImpl<JiraSite> {
238247

239248
/**
240249
* To add scm entry change date and time in jira comments.
241-
*
242250
*/
243251
private boolean appendChangeTimestamp;
244252

253+
/**
254+
* To allow configurable value of max issues from jql search via jira site global configuration.
255+
*/
256+
private int maxIssuesFromJqlSearch = DEFAULT_ISSUES_FROM_JQL;
257+
245258
private int ioThreadCount = Integer.getInteger(JiraSite.class.getName() + ".httpclient.options.ioThreadCount", 2);
246259

247260
/**
@@ -502,6 +515,7 @@ public boolean getDisableChangelogAnnotations() {
502515
/**
503516
* Sets connect timeout (in seconds).
504517
* If not specified, a default timeout will be used.
518+
*
505519
* @param timeoutSec Timeout in seconds
506520
*/
507521
@DataBoundSetter
@@ -516,6 +530,7 @@ public int getTimeout() {
516530
/**
517531
* Sets read timeout (in seconds).
518532
* If not specified, a default timeout will be used.
533+
*
519534
* @param readTimeout Timeout in seconds
520535
*/
521536
@DataBoundSetter
@@ -646,6 +661,17 @@ public void setUpdateJiraIssueForAllStatus(boolean updateJiraIssueForAllStatus)
646661
this.updateJiraIssueForAllStatus = updateJiraIssueForAllStatus;
647662
}
648663

664+
@DataBoundSetter
665+
public void setMaxIssuesFromJqlSearch(int maxIssuesFromJqlSearch) {
666+
this.maxIssuesFromJqlSearch = maxIssuesFromJqlSearch > MAX_ALLOWED_ISSUES_FROM_JQL
667+
? MAX_ALLOWED_ISSUES_FROM_JQL
668+
: maxIssuesFromJqlSearch;
669+
}
670+
671+
public int getMaxIssuesFromJqlSearch() {
672+
return maxIssuesFromJqlSearch;
673+
}
674+
649675
@SuppressWarnings("unused")
650676
protected Object readResolve() throws FormException {
651677
JiraSite jiraSite;
@@ -683,7 +709,11 @@ protected Object readResolve() throws FormException {
683709
jiraSite.setDisableChangelogAnnotations(disableChangelogAnnotations);
684710
jiraSite.setDateTimePattern(dateTimePattern);
685711
jiraSite.setUseBearerAuth(useBearerAuth);
686-
712+
if (this.maxIssuesFromJqlSearch <= 0) {
713+
jiraSite.setMaxIssuesFromJqlSearch(DEFAULT_ISSUES_FROM_JQL);
714+
} else {
715+
jiraSite.setMaxIssuesFromJqlSearch(maxIssuesFromJqlSearch);
716+
}
687717
return jiraSite;
688718
}
689719

@@ -760,7 +790,8 @@ Lock getProjectUpdateLock() {
760790
/**
761791
* This method only supports credential matching by credentialsId.
762792
* Older methods are not and will not be supported as the credentials should have been migrated already.
763-
* @param item can be <code>null</code> if top level
793+
*
794+
* @param item can be <code>null</code> if top level
764795
* @param uiValidation if <code>true</code> and credentials not found at item level will not go up
765796
*/
766797
private StandardUsernamePasswordCredentials resolveCredentials(Item item, boolean uiValidation) {
@@ -1132,9 +1163,10 @@ public boolean existsIssue(String id) {
11321163

11331164
/**
11341165
* Returns all versions for the given project key.
1135-
* @deprecated use {@link JiraSession#getVersions(String)}
1166+
*
11361167
* @param projectKey Project Key
11371168
* @return A set of JiraVersions
1169+
* @deprecated use {@link JiraSession#getVersions(String)}
11381170
*/
11391171
@Deprecated
11401172
public Set<ExtendedVersion> getVersions(String projectKey) {
@@ -1148,7 +1180,7 @@ public Set<ExtendedVersion> getVersions(String projectKey) {
11481180
/**
11491181
* Generates release notes for a given version.
11501182
*
1151-
* @param projectKey the project key
1183+
* @param projectKey the project key
11521184
* @param versionName the version
11531185
* @param filter Additional JQL Filter. Example: status in (Resolved,Closed)
11541186
* @return release notes
@@ -1234,9 +1266,9 @@ public void migrateIssuesToFixVersion(String projectKey, String versionName, Str
12341266
/**
12351267
* Adds new fix version to issues matching the jql.
12361268
*
1237-
* @param projectKey the project key
1269+
* @param projectKey the project key
12381270
* @param versionName the version
1239-
* @param query the query
1271+
* @param query the query
12401272
* @throws TimeoutException if too long
12411273
*/
12421274
public void addFixVersionToIssue(String projectKey, String versionName, String query) throws TimeoutException {
@@ -1251,10 +1283,10 @@ public void addFixVersionToIssue(String projectKey, String versionName, String q
12511283
* Progresses all issues matching the JQL search, using the given workflow action. Optionally
12521284
* adds a comment to the issue(s) at the same time.
12531285
*
1254-
* @param jqlSearch the query
1286+
* @param jqlSearch the query
12551287
* @param workflowActionName the workflowActionName
1256-
* @param comment the comment
1257-
* @param console the console
1288+
* @param comment the comment
1289+
* @param console the console
12581290
* @throws TimeoutException TimeoutException if too long
12591291
*/
12601292
public boolean progressMatchingIssues(
@@ -1521,7 +1553,6 @@ public JiraSite build() {
15211553
// yes this class hierarchy can be a real big mess...
15221554

15231555
/**
1524-
*
15251556
* @param item the Jenkins {@link Item} can be a {@link Job} or {@link Folder}
15261557
* @return the parent as {@link ItemGroup} which can be {@link Jenkins} or {@link Folder}
15271558
*/
@@ -1567,6 +1598,7 @@ public static List<JiraSite> getSitesFromFolders(ItemGroup itemGroup) {
15671598
/**
15681599
* Gets the effective {@link JiraSite} associated with the given project
15691600
* and creates automatically jiraSession for each jiraSite found
1601+
*
15701602
* @return <code>null</code> if no such was found.
15711603
*/
15721604
@Nullable

src/main/resources/hudson/plugins/jira/JiraSite/config.jelly

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
<f:entry title="${%Jira comments timestamp format}" field="dateTimePattern">
5252
<f:textbox />
5353
</f:entry>
54+
<f:entry title="${%Max Issues From Jql Search}" field="maxIssuesFromJqlSearch">
55+
<f:number default="100" max="5000" clazz="positive-number-required" />
56+
</f:entry>
5457
<f:entry>
5558
<f:validateButton title="${%Validate Settings}"
5659
method="validate" with="url,credentialsId,groupVisibility,roleVisibility,useHTTPAuth,alternativeUrl,timeout,readTimeout,threadExecutorNumber,useBearerAuth" />
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
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.
3+
</div>

src/test/java/JiraTester.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.atlassian.jira.rest.client.api.domain.Transition;
66
import com.atlassian.jira.rest.client.api.domain.User;
77
import hudson.plugins.jira.JiraRestService;
8-
import hudson.plugins.jira.JiraSession;
98
import hudson.plugins.jira.JiraSite;
109
import hudson.plugins.jira.JiraSite.ExtendedAsynchronousJiraRestClientFactory;
1110
import hudson.plugins.jira.extension.ExtendedJiraRestClient;
@@ -57,7 +56,7 @@ public static void main(String[] args) throws Exception {
5756
// restService.createIssue("TESTPROJECT", "This is a test issue created using Jira jenkins plugin. Please
5857
// ignore it.", "TESTUSER", components1, "test issue from Jira jenkins plugin");
5958

60-
final List<Issue> searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 3);
59+
final List<Issue> searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 100);
6160
for (Issue searchResult : searchResults) {
6261
System.out.println("JQL search result: " + searchResult);
6362
}
@@ -102,8 +101,8 @@ public static void main(String[] args) throws Exception {
102101

103102
private static void callUniq(final JiraRestService restService) throws Exception {
104103
long start = System.currentTimeMillis();
105-
List<Issue> issues =
106-
restService.getIssuesFromJqlSearch("key in ('JENKINS-53320','JENKINS-51057')", JiraSession.MAX_ISSUES);
104+
List<Issue> issues = restService.getIssuesFromJqlSearch(
105+
"key in ('JENKINS-53320','JENKINS-51057')", JiraSite.MAX_ALLOWED_ISSUES_FROM_JQL);
107106
long end = System.currentTimeMillis();
108107
System.out.println("time uniq " + (end - start));
109108
}
@@ -112,7 +111,7 @@ private static void callDuplicate(final JiraRestService restService) throws Exce
112111
long start = System.currentTimeMillis();
113112
List<Issue> issues = restService.getIssuesFromJqlSearch(
114113
"key in ('JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057')",
115-
JiraSession.MAX_ISSUES);
114+
JiraSite.MAX_ALLOWED_ISSUES_FROM_JQL);
116115
long end = System.currentTimeMillis();
117116
System.out.println("time duplicate " + (end - start));
118117
}

src/test/java/JiraTesterBearerAuth.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.atlassian.jira.rest.client.api.domain.Transition;
66
import com.atlassian.jira.rest.client.api.domain.User;
77
import hudson.plugins.jira.JiraRestService;
8-
import hudson.plugins.jira.JiraSession;
98
import hudson.plugins.jira.JiraSite;
109
import hudson.plugins.jira.JiraSite.ExtendedAsynchronousJiraRestClientFactory;
1110
import hudson.plugins.jira.auth.BearerHttpAuthenticationHandler;
@@ -59,7 +58,7 @@ public static void main(String[] args) throws Exception {
5958
// restService.createIssue("TESTPROJECT", "This is a test issue created using Jira jenkins plugin. Please
6059
// ignore it.", "TESTUSER", components1, "test issue from Jira jenkins plugin");
6160

62-
final List<Issue> searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 3);
61+
final List<Issue> searchResults = restService.getIssuesFromJqlSearch("project = \"TESTPROJECT\"", 100);
6362
for (Issue searchResult : searchResults) {
6463
System.out.println("JQL search result: " + searchResult);
6564
}
@@ -104,8 +103,7 @@ public static void main(String[] args) throws Exception {
104103

105104
private static void callUniq(final JiraRestService restService) throws Exception {
106105
long start = System.currentTimeMillis();
107-
List<Issue> issues =
108-
restService.getIssuesFromJqlSearch("key in ('JENKINS-53320','JENKINS-51057')", JiraSession.MAX_ISSUES);
106+
List<Issue> issues = restService.getIssuesFromJqlSearch("key in ('JENKINS-53320','JENKINS-51057')", 100);
109107
long end = System.currentTimeMillis();
110108
System.out.println("time uniq " + (end - start));
111109
}
@@ -114,7 +112,7 @@ private static void callDuplicate(final JiraRestService restService) throws Exce
114112
long start = System.currentTimeMillis();
115113
List<Issue> issues = restService.getIssuesFromJqlSearch(
116114
"key in ('JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-53320','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057','JENKINS-51057')",
117-
JiraSession.MAX_ISSUES);
115+
100);
118116
long end = System.currentTimeMillis();
119117
System.out.println("time duplicate " + (end - start));
120118
}

src/test/java/hudson/plugins/jira/JiraSessionTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void replaceWithFixVersionByRegex() throws URISyntaxException, TimeoutException
6060
ArrayList<Issue> issues = new ArrayList<>();
6161
issues.add(getIssue(Arrays.asList("v1.0"), 1L));
6262
issues.add(getIssue(Arrays.asList("v1.0", "v2.0", "v2.0.0"), 2L));
63-
when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(issues);
63+
when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(issues);
6464

6565
jiraSession.replaceFixVersion(PROJECT_KEY, "/v1.*/", newVersion.getName(), QUERY);
6666

@@ -99,7 +99,7 @@ void replaceFixVersion() throws URISyntaxException, TimeoutException {
9999
issues.add(getIssue(Arrays.asList("v1.0"), 1L));
100100
issues.add(getIssue(Arrays.asList("v1.0", "v1.0.0", "v2.0.0"), 2L));
101101
issues.add(getIssue(null, 3L));
102-
when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(issues);
102+
when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(issues);
103103

104104
jiraSession.replaceFixVersion(PROJECT_KEY, "v1.0", newVersion.getName(), QUERY);
105105

@@ -183,7 +183,7 @@ void shouldAddVersionToAllIssues() throws Exception {
183183
List<Issue> issues = new ArrayList<>();
184184
issues.add(getIssue(Arrays.asList("v1.0"), 1L));
185185
issues.add(getIssue(Arrays.asList("v2.0", "v3.0"), 2L));
186-
when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(issues);
186+
when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(issues);
187187

188188
jiraSession.addFixVersion(PROJECT_KEY, newVersion.getName(), QUERY);
189189

@@ -213,7 +213,7 @@ void shouldAddVersionWhenNoFixVersions() throws Exception {
213213
when(jiraSession.getVersions(PROJECT_KEY)).thenReturn(myVersions);
214214

215215
List<Issue> issues = List.of(getIssue(null, 3L));
216-
when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(issues);
216+
when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(issues);
217217

218218
jiraSession.addFixVersion(PROJECT_KEY, newVersion.getName(), QUERY);
219219

@@ -233,7 +233,7 @@ void shouldNotCallUpdateIfNoIssues() throws Exception {
233233
List<ExtendedVersion> myVersions = List.of(newVersion);
234234
when(jiraSession.getVersions(PROJECT_KEY)).thenReturn(myVersions);
235235

236-
when(service.getIssuesFromJqlSearch(QUERY, JiraSession.MAX_ISSUES)).thenReturn(new ArrayList<>());
236+
when(service.getIssuesFromJqlSearch(QUERY, 0)).thenReturn(new ArrayList<>());
237237

238238
jiraSession.addFixVersion(PROJECT_KEY, newVersion.getName(), QUERY);
239239

0 commit comments

Comments
 (0)