Uploaded image for project: 'Jira Data Center'
  1. Jira Data Center
  2. JRASERVER-76240

Applying a Jira product license might break the whole instance with duplicate license keys in the database

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • High
    • 9.12.0, 8.20.28, 9.4.12
    • 8.0.0, 8.5.0, 8.13.0, 8.20.0, 9.4.0, 9.11.0, 9.4.9
    • Licensing
    • None
    • 8
    • 21
    • Severity 1 - Critical
    • 154
    • Hide
      Atlassian Update – 06.10.2023

      Dear Customers,

      We're happy to announce that this issue will be fixed in 8.20.28, 9.4.12 and 9.12.0 releases. Learn more about the release

      The bug was caused by the race condition occurring when updating licenses concurrently.

      The cluster lock has been added around the license update logic so no duplicate licenses should be added during concurrent updates.

      Best regards

      Filip Nowak

      Jira DC Software Engineer

      Show
      Atlassian Update – 06.10.2023 Dear Customers, We're happy to announce that this issue will be fixed in 8.20.28, 9.4.12 and 9.12.0 releases. Learn more about the release The bug was caused by the race condition occurring when updating licenses concurrently. The cluster lock has been added around the license update logic so no duplicate licenses should be added during concurrent updates. Best regards Filip Nowak Jira DC Software Engineer

    Description

      Issue Summary

      Applying a Jira product license (Core, Software or Service Management) is a common task for an administrator that may occur at least once a year on an instance.

      The product license key is stored in the productlicense database table and there must be only one key for each licensed product.
      If there are multiple keys decoded to the same product, such as two keys for Jira Software, the whole application breaks, making the instance unaccessible to end-users.

      There could be specific conditions on which simply applying a new license from the Versions & licenses admin page would create duplicate license keys in the database, rendering the instance unusable.

      Steps to Reproduce

      The procedure described below is just an example of how to consistently cause the problem.
      On a production instance, with several users accessing the environment, the actions may be different (and even more simple), but will lead to the same problem.

      1. Instal a vanilla instance of Jira Software (JSW) Data Center.
        • This was validated on a 3 node DC instance on versions 9.4.9 and 9.11.0.
        • This is certainly an issue happening prior to Jira 8.
      2. Apply a valid JSW license key.
      3. Confirm only one license key is available in the database.
        select * from productlicense;
        
      4. Open a terminal window and start running consecutive requests to apply a new valid license key (say valid-license-key-1).
        • You may create a shell script similar to the below.
          for i in $(seq 1 100); do
            curl -v '<jira-base-url>/rest/plugins/applications/1.0/installed/jira-software/license' -X POST \
              -H 'Content-Type: application/vnd.atl.plugins+json' \
              -H 'X-Requested-With: XMLHttpRequest' \
              -H 'Connection: keep-alive' \
              -H 'Cookie: atlassian.xsrf.token=<atlassian.xsrf.token>; JSESSIONID=<JSESSIONID>' \
              -H 'Sec-Fetch-Dest: empty' \
              -H 'Sec-Fetch-Mode: cors' \
              -H 'Sec-Fetch-Site: same-origin' \
              -H 'Pragma: no-cache' \
              -H 'Cache-Control: no-cache' \
              --data-raw '{"licenseKey":"<valid-license-key-1>"}'
            sleep 3
          done
          
      5. Open a terminal window and start running consecutive requests to apply another valid license key (say valid-license-key-2).
      6. Note that at this point there's no problem and Jira is handling the switch of license keys.
      7. Disable and then enable the Automation for Jira App.
        • This is just an example of a concurrent task that may contribute to the issue and is not the root cause.

      Expected Results

      Jira continues to handle well the operations that are applying the license keys.
      Automation for Jira is also properly disabled/enabled.

      Actual Results

      Multiple license keys to the same Jira product are created in the productlicense database table, rendering the whole instance unusable to end-users.

      Any request to Jira fails with a 500 error similar to the below.

      com.atlassian.cache.CacheException: java.lang.IllegalArgumentException: Multiple entries with same key: jira-software=com.atlassian.jira.license.SubscriptionLicenseDetails@10ca1d5b and jira-software=com.atlassian.jira.license.SubscriptionLicenseDetails@93fc9545
      	at com.atlassian.cache.ehcache.DelegatingCachedReference.get(DelegatingCachedReference.java:75) [atlassian-cache-ehcache-6.0.2.jar:?]
      	at com.atlassian.cache.impl.metrics.InstrumentedCachedReference.get(InstrumentedCachedReference.java:58) [atlassian-cache-common-impl-6.0.2.jar:?]
      	at com.atlassian.jira.cache.stats.CachedReferenceWithStats.get(CachedReferenceWithStats.java:24) [classes/:?]
      	at com.atlassian.jira.license.JiraLicenseManagerImpl.getSupportEntitlementNumbers(JiraLicenseManagerImpl.java:111) [classes/:?]
      	at com.atlassian.jira.bc.license.JiraLicenseServiceImpl.getSupportEntitlementNumbers(JiraLicenseServiceImpl.java:169) [classes/:?]
      	at jdk.internal.reflect.GeneratedMethodAccessor488.invoke(Unknown Source) [?:?]
      	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [?:?]
      	at java.base/java.lang.reflect.Method.invoke(Method.java:566) [?:?]
      	at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26) [atlassian-plugins-core-7.1.7.jar:?]
      	at com.sun.proxy.$Proxy278.getSupportEntitlementNumbers(Unknown Source) [?:?]
      	at jdk.internal.reflect.GeneratedMethodAccessor488.invoke(Unknown Source) [?:?]
      	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [?:?]
      	at java.base/java.lang.reflect.Method.invoke(Method.java:566) [?:?]
      ...
      	at java.base/java.lang.Thread.run(Thread.java:829) [?:?]
      Caused by: java.lang.IllegalArgumentException: Multiple entries with same key: jira-software=com.atlassian.jira.license.SubscriptionLicenseDetails@10ca1d5b and jira-software=com.atlassian.jira.license.SubscriptionLicenseDetails@93fc9545
      	at com.google.common.collect.ImmutableMap.conflictException(ImmutableMap.java:376) [guava-31.0.1-jre.jar:?]
      	at com.google.common.collect.ImmutableMap.checkNoConflict(ImmutableMap.java:370) [guava-31.0.1-jre.jar:?]
      	at com.google.common.collect.RegularImmutableMap.checkNoConflictInKeyBucket(RegularImmutableMap.java:153) [guava-31.0.1-jre.jar:?]
      	at com.google.common.collect.RegularImmutableMap.fromEntryArray(RegularImmutableMap.java:115) [guava-31.0.1-jre.jar:?]
      	at com.google.common.collect.ImmutableMap$Builder.buildOrThrow(ImmutableMap.java:574) [guava-31.0.1-jre.jar:?]
      	at com.google.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:538) [guava-31.0.1-jre.jar:?]
      	at com.atlassian.jira.license.JiraLicenseManagerImpl$CachedLicenses.<init>(JiraLicenseManagerImpl.java:419) [classes/:?]
      	at com.atlassian.jira.license.JiraLicenseManagerImpl$CachedLicenses.<init>(JiraLicenseManagerImpl.java:392) [classes/:?]
      	at com.atlassian.jira.license.JiraLicenseManagerImpl.loadLicenses(JiraLicenseManagerImpl.java:389) [classes/:?]
      	at com.atlassian.cache.ehcache.EhCacheManager$SupplierAdapter.load(EhCacheManager.java:269) [atlassian-cache-ehcache-6.0.2.jar:?]
      	at com.atlassian.cache.ehcache.EhCacheManager$SupplierAdapter.load(EhCacheManager.java:256) [atlassian-cache-ehcache-6.0.2.jar:?]
      	at com.atlassian.cache.ehcache.wrapper.ValueProcessorAtlassianCacheLoaderDecorator.load(ValueProcessorAtlassianCacheLoaderDecorator.java:26) [atlassian-cache-ehcache-6.0.2.jar:?]
      	at com.atlassian.cache.ehcache.LoadingCache.getFromLoader(LoadingCache.java:174) [atlassian-cache-ehcache-6.0.2.jar:?]
      	at com.atlassian.cache.ehcache.SynchronizedLoadingCacheDecorator.synchronizedLoad(SynchronizedLoadingCacheDecorator.java:29) [atlassian-cache-ehcache-6.0.2.jar:?]
      	at com.atlassian.cache.ehcache.LoadingCache.loadValueAndReleaseLock(LoadingCache.java:142) [atlassian-cache-ehcache-6.0.2.jar:?]
      	at com.atlassian.cache.ehcache.LoadingCache.get(LoadingCache.java:121) [atlassian-cache-ehcache-6.0.2.jar:?]
      	at com.atlassian.cache.ehcache.DelegatingCachedReference.get(DelegatingCachedReference.java:71) [atlassian-cache-ehcache-6.0.2.jar:?]
      	... 103 more
      

      Workaround

      Currently there is no known workaround for this behavior. A workaround will be added here when available.

      Additional notes
      On a production instance the simple act of updating the license key for JSW or JSM may trigger the problem.
      The only way to fix the incident after being affected by this bug is to remove the duplicate entry from the productlicense database table.
      During tests you may not need to restart the Jira instance, but bear in mind this might be necessary.

      To minimize the impact on a production instance, you may want to consider applying a product license key during a time with low end-user activity and without any other concurrent administration task.

      Attachments

        Issue Links

          Activity

            People

              15609d8ba305 Filip Nowak
              tmasutti Thiago Masutti
              Votes:
              3 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: