Uploaded image for project: 'Jira Software Data Center'
  1. Jira Software Data Center
  2. JSWSERVER-17685

Lexorank management does not display table data and Rebalance is not visible

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Low
    • None
    • 7.6.3, 7.13.18, 8.5.13, 8.13.5, 9.12.2
    • Lexorank

    Description

      Summary

      Viewing the Lexorank management console there is no option to rebalance and the *Balance All fields option is missing.

      Steps to Reproduce

      1. This Occurs when there are NULL associations left over from a Delete action exact steps to reproduce are unknown at this time, but has been seen on a Bulk delete that encounter a page timeout during the deletion action:
      2. The Lexorank management page looks like this when it occurs:

      Actual Results

      The below exception is thrown in the atlassian-jira.log file when accessing the LexoRank management page:

      2018-09-28 18:29:26,081 http-nio-8080-exec-17 ERROR Test_User 1109x1267x2 15hfiw5 192.0.0.82 /rest/greenhopper/1.0/lexorank/balance [c.a.p.r.c.error.jersey.ThrowableExceptionMapper] Uncaught exception thrown by REST service: null
      java.lang.NullPointerException
      	at com.atlassian.greenhopper.service.lexorank.balance.LexoRankBalanceRankInfoService.getIssueKey(LexoRankBalanceRankInfoService.java:45)
      	at com.atlassian.greenhopper.service.lexorank.balance.LexoRankBalanceRankInfoService.getMaxRank(LexoRankBalanceRankInfoService.java:64)
      	at com.atlassian.greenhopper.service.lexorank.balance.LexoRankBalancer.getBalanceStatus(LexoRankBalancer.java:207)
      	at com.atlassian.greenhopper.web.configuration.LexoRankHelper.getBalanceStatus(LexoRankHelper.java:38)
      	at com.atlassian.greenhopper.web.configuration.LexoRankResource$1.call(LexoRankResource.java:86)
      	at com.atlassian.greenhopper.web.configuration.LexoRankResource$1.call(LexoRankResource.java:82)
      	at com.atlassian.greenhopper.web.util.RestCall.response(RestCall.java:42)
      	at com.atlassian.greenhopper.web.AbstractResource.createResponse(AbstractResource.java:111)
      	at com.atlassian.greenhopper.web.AbstractResource.responseWithoutAccessCheck(AbstractResource.java:105)
      	at com.atlassian.greenhopper.web.configuration.LexoRankResource.balanceStatus(LexoRankResource.java:81)
      	... 3 filtered
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	... 19 filtered
      	at com.atlassian.plugins.rest.module.RestDelegatingServletFilter$JerseyOsgiServletContainer.doFilter(RestDelegatingServletFilter.java:154)
      	... 1 filtered
      	at com.atlassian.plugins.rest.module.RestDelegatingServletFilter.doFilter(RestDelegatingServletFilter.java:68)
      	... 41 filtered
      	at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
      	... 53 filtered
      	at com.atlassian.jira.security.JiraSecurityFilter.lambda$doFilter$0(JiraSecurityFilter.java:66)
      	... 1 filtered
      	at com.atlassian.jira.security.JiraSecurityFilter.doFilter(JiraSecurityFilter.java:64)
      	... 16 filtered
      	at com.atlassian.plugins.rest.module.servlet.RestSeraphFilter.doFilter(RestSeraphFilter.java:37)
      	... 19 filtered
      	at com.atlassian.jira.servermetrics.CorrelationIdPopulatorFilter.doFilter(CorrelationIdPopulatorFilter.java:30)
      	... 5 filtered
      	at com.atlassian.jwt.internal.servlet.JwtAuthFilter.doFilter(JwtAuthFilter.java:32)
      	... 8 filtered
      	at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
      	... 4 filtered
      	at com.atlassian.web.servlet.plugin.LocationCleanerFilter.doFilter(LocationCleanerFilter.java:36)
      	... 26 filtered
      	at com.atlassian.jira.servermetrics.MetricsCollectorFilter.doFilter(MetricsCollectorFilter.java:25)
      	... 23 filtered
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      	at java.lang.Thread.run(Thread.java:748)
      

      The Following Exception is caught in the Javascript console of the Browser developer tools:

      Uncaught TypeError: Cannot read property 'balancingSuspended' of undefined
          at Object.GH.tpl.lexorankmanagement.renderBalanceStatus (com.pyxis.greenhopper.jira:gh-admin-lexorank-manage-app.js:24)
          at child.render (com.pyxis.greenhopper.jira:gh-admin-lexorank-manage-app.js:325)
          at triggerEvents (batch.js:47978)
          at child.trigger (batch.js:47918)
          at child.set (batch.js:48132)
          at Object.<anonymous> (com.pyxis.greenhopper.jira:gh-admin-lexorank-manage-app.js:164)
          at fire (batch.js:2824)
          at Object.fireWith (batch.js:2942)
          at Object.fire (batch.js:2949)
          at fire (batch.js:2824)
      
      plugin-icon:1 Failed to load resource: the server responded with a status of 404 ()
      

      Notes

      Triggering a rebalance from the API POST /rest/greenhopper/1.0/lexorank/balance will fail on balance interrupted error.

      The Following Select will identify rank values in the bad state:

      SELECT * FROM "AO_60DB71_LEXORANK" left join jiraissue j on j.id = "AO_60DB71_LEXORANK"."ISSUE_ID" where j.id is NULL and "FIELD_ID" = <Lexorank_Field>;
      

      Workaround

      Please take AO_60DB71_LEXORANK table back up before performing delete operation
      Please adjust your FIELD_ID value per your environment that corresponds to RANK custom field.
      Make the note of limit clause we are using to determine which rank from the top has proper issue_id associated.
      Queries below are Postgres complaint. Please tweak it according to DB being used.

      Notice the stack trace above, we are trying to get the max rank and then issue key from issue that we retrieved as having max rank from AO_60DB71_LEXORANK table. Below is the translated query used behind the scene to fetch that info:

      select "LEXORANK"."FIELD_ID", "LEXORANK"."ID", "LEXORANK"."ISSUE_ID", "LEXORANK"."RANK", "LEXORANK"."TYPE", "LEXORANK"."BUCKET" from "AO_60DB71_LEXORANK" "LEXORANK"  where "LEXORANK"."FIELD_ID" = <your_Rank_FIELD_ID> and "LEXORANK"."TYPE" = 1 order by length("LEXORANK"."RANK") desc, "LEXORANK"."RANK" desc limit 1
      

      Run following query to figure if the issue_id we retrieved from above is present in the jiraissue table or not

      select * from jiraissue j2 where j2.id in (select adl."ISSUE_ID" from "AO_60DB71_LEXORANK" adl where 
      adl."FIELD_ID"=<your_Rank_FIELD_ID> and adl."TYPE"=1 order by length(adl."RANK") desc, adl."RANK" desc limit 1)
      

      With stack failure like above we can only get NPE if the issue_id retrieved from first query is not present in jiraissue table and hence we could not form issue object to get the issue key from. We need to keep increasing the limit in first query and correspondingly in the second query or just in the second query itself to determine which one of these descending max rank does have a valid issue_id associated(the one that exist in the jira issue table).

      Let's say we got 13th record from the top that gave us the issue_id which exist in the jira issue table, this determines the fact that earlier 12 records were stale and is not needed. In other words you got result for this query, while you kept on increasing the limit each time:

      select * from jiraissue j2 where j2.id in (select adl."ISSUE_ID" from "AO_60DB71_LEXORANK" adl where 
      adl."FIELD_ID"=<your_Rank_FIELD_ID> and adl."TYPE"=1 order by length(adl."RANK") desc, adl."RANK" desc limit 13)
      

      We need to clean up records from AO_60DB71_LEXORANK table where ISSUE_ID is not in jiraissue table(in our example it is 12 such rows from top that we need to clean up). Since we have the table back up, it is safe to run below query to clean up the records:

      • Stop the Servers.
      • Run the delete command
        delete from "AO_60DB71_LEXORANK" "lr" where "lr"."ID" in ( select "LEXORANK"."ID" from "AO_60DB71_LEXORANK" "LEXORANK"
        where "LEXORANK"."FIELD_ID" = <your_Rank_FIELD_ID> and "LEXORANK"."TYPE" = 1 order by length("LEXORANK"."RANK") desc, "LEXORANK"."RANK" desc limit 12)
        

        // NOTE: limit 12 is just an example here. We need to determine specifically for each environment facing this issue, what that value would be, using the second join query. Every time we do not get the result we keep increasing the limit.

      • Start the servers and try access the lexorank management page. The balancing section(that internally makes a call to /rest/greenhopper/1.0/lexorank/balance) should be showing up on the page.

      Attachments

        Activity

          People

            Unassigned Unassigned
            emccutcheon Earl McCutcheon
            Votes:
            10 Vote for this issue
            Watchers:
            15 Start watching this issue

            Dates

              Created:
              Updated: