Details
-
Bug
-
Resolution: Unresolved
-
Low
-
None
-
9.12.5
-
9.12
-
2
-
Severity 3 - Minor
-
13
-
Description
Issue Summary
The Bulk Edit step 3 screen (BulkEditDetails.jspa) is very slow to load when many issues have security levels set.
In some cases, a 504 (Gateway timeout) error might be displayed in the browser.
This issue gets proportionately worse with these numbers:
- Number of issues selected for bulk edit which have issue security set
- Number of custom fields available for the issue, either due to field context or global fields
- Database latency
Steps to Reproduce
- Create 1000 issues in a project
- Optionally, create hundreds of custom fields
- Associate them with an issue security level
- Try to bulk edit the issues
Expected Results
- Bulk editing works normally.
Actual Results
When loading the "step 3" page, the response takes a long time.
In some of our tests, we found that:
- Bulk editing 1000 issues in an environment before creating extra custom fields, but with issue security level set took 26s
- Doing the same after creating 400 custom fields took 6 minutes
- Removing the issue security level dropped the time to 7s
During the time the page is processed (with security and custom fields), we can see the stack trace is always getting the issue security scheme:
java.net.SocketInputStream.socketRead0(java.base@11.0.22/Native Method) java.net.SocketInputStream.socketRead(java.base@11.0.22/SocketInputStream.java:115) java.net.SocketInputStream.read(java.base@11.0.22/SocketInputStream.java:168) java.net.SocketInputStream.read(java.base@11.0.22/SocketInputStream.java:140) sun.security.ssl.SSLSocketInputRecord.read(java.base@11.0.22/SSLSocketInputRecord.java:484) sun.security.ssl.SSLSocketInputRecord.readHeader(java.base@11.0.22/SSLSocketInputRecord.java:478) sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(java.base@11.0.22/SSLSocketInputRecord.java:70) sun.security.ssl.SSLSocketImpl.readApplicationRecord(java.base@11.0.22/SSLSocketImpl.java:1459) sun.security.ssl.SSLSocketImpl$AppInputStream.read(java.base@11.0.22/SSLSocketImpl.java:1070) org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:161) org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:128) org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:113) org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73) org.postgresql.core.PGStream.receiveChar(PGStream.java:465) org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2155) org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:368) org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:327) org.postgresql.jdbc.PgPreparedStatement.getParameterMetaData(PgPreparedStatement.java:1706) org.apache.commons.dbcp2.DelegatingPreparedStatement.getParameterMetaData(DelegatingPreparedStatement.java:162) org.apache.commons.dbcp2.DelegatingPreparedStatement.getParameterMetaData(DelegatingPreparedStatement.java:162) com.atlassian.jira.ofbiz.sql.PreparedStatementWrapper.getParameterMetaData(PreparedStatementWrapper.java:218) org.ofbiz.core.entity.jdbc.SQLProcessor.prepareStatement(SQLProcessor.java:488) org.ofbiz.core.entity.GenericDAO.select(GenericDAO.java:625) org.ofbiz.core.entity.GenericDAO.select(GenericDAO.java:596) org.ofbiz.core.entity.GenericHelperDAO.findByPrimaryKey(GenericHelperDAO.java:105) org.ofbiz.core.entity.GenericDelegator.findByPrimaryKey(GenericDelegator.java:621) org.ofbiz.core.entity.GenericDelegator.findByPrimaryKey(GenericDelegator.java:659) com.atlassian.jira.ofbiz.DefaultOfBizDelegator.findByPrimaryKey(DefaultOfBizDelegator.java:341) com.atlassian.jira.ofbiz.DefaultOfBizDelegator.findByPrimaryKey(DefaultOfBizDelegator.java:335) com.atlassian.jira.ofbiz.DefaultOfBizDelegator.findById(DefaultOfBizDelegator.java:327) com.atlassian.jira.ofbiz.WrappingOfBizDelegator.findById(WrappingOfBizDelegator.java:192) com.atlassian.jira.scheme.AbstractSchemeManager.getScheme(AbstractSchemeManager.java:135) com.atlassian.jira.issue.security.IssueSecuritySchemeManagerImpl.hasSecurityLevelAccess(IssueSecuritySchemeManagerImpl.java:396) com.atlassian.jira.security.DefaultPermissionManager.doIssuePermissionCheck(DefaultPermissionManager.java:237) com.atlassian.jira.security.DefaultPermissionManager.doIssuePermissionCheck(DefaultPermissionManager.java:212) com.atlassian.jira.security.DefaultPermissionManager.hasPermission(DefaultPermissionManager.java:163) com.atlassian.jira.security.WorkflowBasedPermissionManager.hasPermission(WorkflowBasedPermissionManager.java:86) com.atlassian.jira.security.DefaultPermissionManager.hasPermission(DefaultPermissionManager.java:180) com.atlassian.jira.security.WorkflowBasedPermissionManager.hasPermission(WorkflowBasedPermissionManager.java:80) com.atlassian.jira.security.ApplicationRequiredPermissionManager.lambda$hasPermission$0(ApplicationRequiredPermissionManager.java:80) com.atlassian.jira.security.ApplicationRequiredPermissionManager$$Lambda$9559/0x00007f1c134e9108.getAsBoolean(Unknown Source) com.atlassian.jira.security.ApplicationRequiredPermissionManager.checkUserHasApplicationOrFalse(ApplicationRequiredPermissionManager.java:202) com.atlassian.jira.security.ApplicationRequiredPermissionManager.checkUserHasApplicationOrFalse(ApplicationRequiredPermissionManager.java:195) com.atlassian.jira.security.ApplicationRequiredPermissionManager.hasPermission(ApplicationRequiredPermissionManager.java:80) com.atlassian.jira.security.PublicAccessPermissionManager.lambda$hasPermission$0(PublicAccessPermissionManager.java:75) com.atlassian.jira.security.PublicAccessPermissionManager$$Lambda$6961/0x00007f1c29eea108.getAsBoolean(Unknown Source) com.atlassian.jira.security.PublicAccessPermissionManager.checkPublicAccessEnabledOrDelegate(PublicAccessPermissionManager.java:193) com.atlassian.jira.security.PublicAccessPermissionManager.hasPermission(PublicAccessPermissionManager.java:75) jdk.internal.reflect.GeneratedMethodAccessor1635.invoke(Unknown Source) jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.22/DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(java.base@11.0.22/Method.java:566) com.atlassian.jira.config.component.SwitchingInvocationHandler.invoke(SwitchingInvocationHandler.java:38) com.sun.proxy.$Proxy106.hasPermission(Unknown Source) com.atlassian.jira.issue.fields.ImmutableCustomField.hasBulkUpdatePermission(ImmutableCustomField.java:1411) com.atlassian.jira.issue.fields.ImmutableCustomField.availableForBulkEdit(ImmutableCustomField.java:1346) com.atlassian.jira.bulkedit.operation.BulkEditActionImpl.isAvailable(BulkEditActionImpl.java:28) com.atlassian.jira.web.action.issue.bulkedit.BulkEdit.setFieldDefaults(BulkEdit.java:237) com.atlassian.jira.web.action.issue.bulkedit.BulkEdit.doDetails(BulkEdit.java:219) ...
What happens is that Jira is getting the issue security scheme from the database for each custom field, for each issue.
This means that even though the query response is quick, it is run a large number of times. In our example, it is run 400 * 1000 times, so even if the queries take 1ms each, we'd still get over 6 minutes delay just from this behavior.
Workaround
Avoid using issue security levels by default. Prefer to set more restrictive project permissions instead and set the security level only for the ones that need stricter visibility.
Attachments
Issue Links
- mentioned in
-
Page Loading...