BE - [License Approvals] - Cache queries for the SPDX database entries in the SoftwareLicenses table.
This is a follow up to !108527 (comment 1245032864)
Details
The SoftwareLicenses table is populated/updated by a cron job that runs once a week that pulls the data from https://spdx.org/licenses/. It can also be imported manually via a ruby script in the Air Gap network scenario for self-managed. This has been existing behavior for several years now. ~4 years
It rarely changes, so the data tends to be very static. There are roughly ~450 licenses that get returned every time we populate the full license dropdown.
In a dev environment they can be imported by:
bundle exec rails c
[1] pry(main)> ImportSoftwareLicensesWorker.new.perform
The existing License Compliance UI shows a list of licenses in a dropdown to select from. It includes all licenses from the SPDX database we have imported that lives in the SoftwareLicenses table that have not been classified in the project. The self.unclassified_licenses_for(project)
method on the SoftwareLicense
ActiveRecord model allows for this.
!108527 (merged) added a similar scope, that returns all SPDX licenses by dropping the id_not_in(project.software_licenses)
in the new scope. This was needed because the new License Scan Result Policies UI has a license search dropdown that ALWAYS shows the full list.
Eventually the License Management feature will be removed in favor of the newer License Scan Result Policies.
Implementation Plan
-
Cacheself.unclassified_licenses_for(project)
-
Cache self.all_license_names
- UseRails.cache
to cacheall_license_names
diff --git a/ee/app/models/software_license.rb b/ee/app/models/software_license.rb
index 680d68f6dab6..3d6ba8e6c729 100644
--- a/ee/app/models/software_license.rb
+++ b/ee/app/models/software_license.rb
@@ -5,6 +5,8 @@
class SoftwareLicense < ApplicationRecord
include Presentable
+ ALL_LICENSE_NAMES_CACHE_KEY = 'all_license_names'
+
validates :name, presence: true, uniqueness: true
validates :spdx_identifier, length: { maximum: 255 }
@@ -21,7 +23,9 @@ def self.unclassified_licenses_for(project)
end
def self.all_license_names
- spdx.ordered.unreachable_limit.pluck_names
+ Rails.cache.fetch(ALL_LICENSE_NAMES_CACHE_KEY, expires_in: 7.days) do
+ spdx.ordered.unreachable_limit.pluck_names
+ end
end
def self.pluck_names
diff --git a/ee/app/workers/import_software_licenses_worker.rb b/ee/app/workers/import_software_licenses_worker.rb
index 451533d2b983..eda6920e2046 100644
--- a/ee/app/workers/import_software_licenses_worker.rb
+++ b/ee/app/workers/import_software_licenses_worker.rb
@@ -24,6 +24,8 @@ def perform
)
end
end
+
+ Rails.cache.delete(SoftwareLicense::ALL_LICENSE_NAMES_CACHE_KEY)
end
private
Where the scopes are used in the UI
unclassified_licenses_for | self.all_license_names |
---|---|
License Compliance | License Scan Result Policy |
![]() |
Verification Steps
- Open a project
- Activate the performance bar
- Click in Security and Compliance -> Policies
- Click on New Policy
- Select Scan Result Policy
- Select License Scan in the "IF" section
- Click on
redis
on the performance bar - Look for the request
get cache:gitlab:SoftwareLicense/all_license_names