spring:
cloud:
stream:
bindings:
searchTenantSearchGroupInput:
group: search-tenant-search-group
destination: tenantSearchGroup
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
Version 2.1.0-GA includes all changes up to 2.0.1 Release Notes
To support the new Application-Specific Search Settings feature detailed below, all products regardless of "online" or "searchable" flags are now indexed.
To revert to the previous functionality, See Disabling Search Settings.
This release includes a new feature called Search Settings that allow Facets and Sort Options to be grouped and configured per application and context. New metadata has also been added to support using Search Facets for filtering on Browse Entity List Grids in the admin. This is now the default for Products. The following domain has been added or modified to support this:
Catalog: Introduced new type of Catalog, SEARCH_GROUP
, to support inheritance and overrides for Search Settings-related domain.
Only a single "Search Group" should be assigned to each Application and Tenant. As such, one is provisioned automatically when an Application is created in Tenant Service.
Facets: Facets have been extracted from FieldDefinitions into their own table and should now be managed independently. They are now also Catalog Trackable and are intended to be placed within Search Groups.
Sort Options: Likewise have been extracted from FieldDefinitions and are Catalog Trackable.
Facet Group: Allows grouping related Facets together to be shared in different Search Settings. They are also Catalog Trackable.
Facet Group Facet: The cross-reference entity that links a Facet and Facet Group. It is sortable.
Sort Group: Allows grouping related Sort Options. They are Catalog Trackable.
Sort Group Sort Option: The cross-reference entity that links a Facet and Facet Group. It is sortable.
Search Settings: Represents a group of search settings for an application or tenant to allow sharing Facets and Sort Options. Facets and Sort Options are assigned to Search Settings through Facet and Sort Groups.
They are Catalog Trackable.
Settings Facet Group: The cross-reference entity that links a Facet Group and Search Settings.
Settings Sort Group: The cross-reference entity that links a Sort Group and Search Settings.
Upgrading requires migration scripts to be added in your project:
Add db/sql/search-migration.sql
(or db/sql/search-migration-oracle.sql
for Oracle) to search.flexdemo.postgresql.changelog-master
after any scripts that currently load Field Definitions.
This script will:
Create Facets and Field Sort Options for all existing Field Definitions as appropriate
Set up Search Settings for each Tenant and Application
Migrated existing Facets and Sort Options to the appropriate Facet and Sort Groups for Storefront and Admin Settings.
Add a new Field Definition for Business Types to support using Search Service to power the Product Browse list grid instead of Catalog Service.
Add db/sql/search-settings-field-translation-migration.sql
(or db/sql/search-settings-field-translation-migration-oracle.sql
for Oracle) to search.flexdemo.postgresql.changelog-master
after the db/sql/search-migration.sql
.
This script will:
Update existing translations targeting JpaFieldDefinition
's label
, facetLabel
, and sortLabel
to the newly introduced domains
Note that this migration script should not be added if you have extended the relevant Search domains (e.g. JpaFieldDefinition, JpaFacet, JpaFieldSortOption). Instead, update and use the migration scripts in the Translations Migration section
When a new Tenant is created via APIs, a new Search Group is automatically created as well.
This will produce a TenantSearchGroupEvent
that other services like Search can handle to provision related entities.
For Search, this means creating new SearchSettings
for Admin and Storefront for the new Tenant Search Group.
spring:
cloud:
stream:
bindings:
searchTenantSearchGroupInput:
group: search-tenant-search-group
destination: tenantSearchGroup
New Permissions are required for working with the new domain in the Admin.
Note
|
This step is not necessary if running Project Initializer’s data module |
-- Scopes
INSERT INTO BLC_SECURITY_SCOPE (ID, NAME, OPEN) VALUES ('-506', 'FACET', 'N');
INSERT INTO BLC_SECURITY_SCOPE (ID, NAME, OPEN) VALUES ('-507', 'FACET_GROUP', 'N');
INSERT INTO BLC_SECURITY_SCOPE (ID, NAME, OPEN) VALUES ('-508', 'SEARCH_SETTINGS', 'N');
INSERT INTO BLC_SECURITY_SCOPE (ID, NAME, OPEN) VALUES ('-509', 'SORT', 'N');
INSERT INTO BLC_SECURITY_SCOPE (ID, NAME, OPEN) VALUES ('-510', 'SORT_GROUP', 'N');
-- Permissions
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-506', 'N', '2024-02-08 18:29:35.368553', 'READ_FACET', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-505', 'N', '2024-02-08 18:29:35.382348', 'ALL_FACET', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-508', 'N', '2024-02-08 18:29:35.474195', 'READ_FACET_GROUP', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-507', 'N', '2024-02-08 18:29:35.485897', 'ALL_FACET_GROUP', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-510', 'N', '2024-02-08 18:29:35.564176', 'READ_SEARCH_SETTINGS', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-509', 'N', '2024-02-08 18:29:35.576240', 'ALL_SEARCH_SETTINGS', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-512', 'N', '2024-02-08 18:29:35.671244', 'READ_SORT', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-511', 'N', '2024-02-08 18:29:35.683019', 'ALL_SORT', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-514', 'N', '2024-02-08 18:29:35.767416', 'READ_SORT_GROUP', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-513', 'N', '2024-02-08 18:29:35.777030', 'ALL_SORT_GROUP', 'N', 'Y');
-- Permissions Scopes
INSERT INTO BLC_PERMISSION_SCOPE (ID, PERMISSION, IS_PERMISSION_ROOT, SCOPE_ID) VALUES ('-506', 'FACET', 'Y', '-506');
INSERT INTO BLC_PERMISSION_SCOPE (ID, PERMISSION, IS_PERMISSION_ROOT, SCOPE_ID) VALUES ('-507', 'FACET_GROUP', 'Y', '-507');
INSERT INTO BLC_PERMISSION_SCOPE (ID, PERMISSION, IS_PERMISSION_ROOT, SCOPE_ID) VALUES ('-508', 'SEARCH_SETTINGS', 'Y', '-508');
INSERT INTO BLC_PERMISSION_SCOPE (ID, PERMISSION, IS_PERMISSION_ROOT, SCOPE_ID) VALUES ('-509', 'SORT', 'Y', '-509');
INSERT INTO BLC_PERMISSION_SCOPE (ID, PERMISSION, IS_PERMISSION_ROOT, SCOPE_ID) VALUES ('-510', 'SORT_GROUP', 'Y', '-510');
-- Role Permissions
-- Full Access
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-2', '-505');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-2', '-507');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-2', '-509');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-2', '-511');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-2', '-513');
-- Partial Access
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-1', '-506');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-1', '-508');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-1', '-510');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-1', '-512');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-1', '-514');
-- Client Scopes
INSERT INTO BLC_CLIENT_SCOPES (ID, SCOPE) VALUES ('openapi', 'FACET');
INSERT INTO BLC_CLIENT_SCOPES (ID, SCOPE) VALUES ('openapi', 'FACET_GROUP');
INSERT INTO BLC_CLIENT_SCOPES (ID, SCOPE) VALUES ('openapi', 'SORT');
INSERT INTO BLC_CLIENT_SCOPES (ID, SCOPE) VALUES ('openapi', 'SORT_GROUP');
INSERT INTO BLC_CLIENT_SCOPES (ID, SCOPE) VALUES ('openapi', 'SEARCH_SETTINGS');
-- Client Permissions
INSERT INTO BLC_CLIENT_PERMISSIONS (ID, PERMISSION) VALUES ('openapi', 'ALL_FACET');
INSERT INTO BLC_CLIENT_PERMISSIONS (ID, PERMISSION) VALUES ('openapi', 'ALL_FACET_GROUP');
INSERT INTO BLC_CLIENT_PERMISSIONS (ID, PERMISSION) VALUES ('openapi', 'ALL_SEARCH_SETTINGS');
INSERT INTO BLC_CLIENT_PERMISSIONS (ID, PERMISSION) VALUES ('openapi', 'ALL_SORT');
INSERT INTO BLC_CLIENT_PERMISSIONS (ID, PERMISSION) VALUES ('openapi', 'ALL_SORT_GROUP');
Existing translations that are targeting JpaFieldDefinition
are required to be updated to target the new domains (use the most extended domains if customized).
Note
|
This step is not necessary if db/sql/search-settings-field-translation-migration.sql is already added to your project or if running Project Initializer’s data module, unless you have domain extensions against the relevant Search domains (e.g. JpaFieldDefinition , JpaFacet , JpaFieldSortOption )
|
Important
|
The entityType fields need to be updated to the most extended type, e.g. com.mycompany.search.jpa.domain.MyExtendedJpaFieldDefinition in place of com.broadleafcommerce.search.core.provider.jpa.domain.JpaFieldDefinition
|
-- update facet label
-- IMPORTANT: The entity type should be set to the most extended domain
UPDATE BLC_TRANSLATION
SET ENTITY_TYPE = 'com.broadleafcommerce.search.core.provider.jpa.domain.JpaFacet',
ENTITY_FIELD = 'label'
WHERE ENTITY_TYPE = 'com.broadleafcommerce.search.core.provider.jpa.domain.JpaFieldDefinition'
AND ENTITY_FIELD = 'facet.label';
-- update facet ranges labels
UPDATE BLC_TRANSLATION
SET ENTITY_TYPE = 'com.broadleafcommerce.search.core.provider.jpa.domain.JpaFacet'
, ENTITY_FIELD = SUBSTRING(ENTITY_FIELD, length('facet.') + 1)
WHERE ENTITY_TYPE = 'com.broadleafcommerce.search.core.provider.jpa.domain.JpaFieldDefinition'
AND ENTITY_FIELD LIKE 'facet.ranges[%';
-- update sortOption label
UPDATE BLC_TRANSLATION
SET ENTITY_TYPE = 'com.broadleafcommerce.search.core.provider.jpa.domain.JpaFieldSortOption'
, ENTITY_FIELD = 'label'
WHERE ENTITY_TYPE = 'com.broadleafcommerce.search.core.provider.jpa.domain.JpaFieldDefinition'
AND ENTITY_FIELD = 'sortOption.label';
The functionality of catalog access policies is primarily managed in Catalog Services, and it is supported by parallel changes in Search Services to guarantee the influence of catalog access policies in search queries.
The catalogAccessPolicyModified
channel is used to synchronize updates to catalog access policies across both services.
Important
|
com.broadleafcommerce.search.customer.web.endpoint.CustomerContextRequestHydrator has been removed and replaced with com.broadleafcommerce.search.core.web.endpoint.SearchContextRequestHydrator since there can only be one hydrator in the service used and numerous changes were required to support CatalogAccessPolicies .
SearchContextRequestHydrator does all that CustomerContextRequestHydrator as well as new behavior to support policies but is in Search Core library rather than Customer Search so as to be available universally.
|
SearchContextRequestHydrator
: Handles finding CatalogAccessPolicies
applying to entire Catalogs and modifying the ContextRequest
to include or exclude Catalogs based on the which policies match.
This is primarily a commerce-facing filtering process.
However, to assist in management in the admin at the Application level, this will also filter out any Catalog targeted by a policy.
Catalogs targeted by policies can instead be selected individual using a Catalog selector ribbon.
There will also be a "default" option to view the contents of all non-restricted Catalogs, which is equivalent to the normal Application-leve behavior.
CatalogAccessPolicyQueryContributor
: Handles CatalogAccessPolicies
applying to Products rather than entire Catalogs.
This will apply Solr query filters to the search request using the filterRules
of any policies that match the request.
CatalogAccessPolicyChangeListener
: Handlers persistence changes to CatalogAccessPolicies
since Catalog Service is the owner of the domain.
broadleaf.search.common.catalog-access-policy.request-attribute-list
Represents the list of attribute from a WebRequest
to store on SearchCatalogAccessPolicyContext
.
The attribute name should be matched by a field name configured in metadata for the SearchCatalogAccessPolicy#matchRule
rule-builder.
broadleaf.search.common.catalog-access-policy.additional-claims
Represents a list of additional auth token claims to add as attributes to the SearchCatalogAccessPolicyContext
for rules to be evaluated against.
The attribute name should be matched by a field name configured in metadata for the SearchCatalogAccessPolicy#matchRule
rule-builder.
broadleaf.search.common.catalog-access-policy.whitelisted-service-callers
: The names of external microservices that are expected to call Search Service for admin or bulk processing requests and should be whitelisted so that they bypass Catalog Access Policy filtering.
When another service calls Search, the original user’s (e.g., admin user’s) auth token is replaced by the calling service’s, so any information about them must be provided in the request rather than in the auth.
Default is ["bulkopsclient"]
The channel message bindings to receive catalogAccessPolicyModifiedEvents
must be registered in the yaml configuration file, see below for example.
spring:
cloud:
stream:
bindings:
catalogAccessPolicyModifiedOutput:
destination: catalogAccessPolicyModified
The ZooKeeper server will expire a client connection session if it does not receive a heartbeat within a specified deadline.
When this happens, the ZooKeeper
handle used by ReentrantDistributedZookeeperLock
is invalidated and no longer usable.
Previously, this was irrecoverable and resolution required a full restart of the Spring application.
With the latest changes, ReentrantDistributedZookeeperLock
now interacts with ZooKeeper through SolrZkClient
instead of ZooKeeper
directly.
SolrZkClient
transparently recycles the ZooKeeper
connection when it detects expiration, which ensures subsequent retries will not run into the same issue and a full application restart is not required.
Important
|
This is technically a code-level (not API level) breaking change, since references to However, it likely will not affect most clients, since most will not have overridden logic in For those who have, migration is very simple, as |