Class SandboxTrackableSolrQueryContributor
- All Implemented Interfaces:
SolrQueryContributor,org.springframework.core.Ordered
-
Field Summary
Fields inherited from interface org.springframework.core.Ordered
HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected StringbuildCatalogAwareSandboxOverridesFilter(Set<String> catalogIdsToFilterBy, Set<String> plainSandboxOverrideValuesToFilter) protected StringbuildMarketplaceAndCatalogAwareSandboxOverridesFilter(Set<String> directImplicitIsolatedCatalogIdsForApp, Set<String> allIsolatedCatalogIdsForApp, Set<String> plainSandboxOverrideValuesToFilter) Should only be used if the request is in the context of a marketplace application.protected StringbuildPlainSandboxOverridesFilter(Set<String> plainSandboxOverrideValuesToFilter) protected voidcontributeInternal(org.apache.solr.client.solrj.SolrQuery solrQuery, com.broadleafcommerce.search.api.domain.SearchRequest searchRequest, List<com.broadleafcommerce.search.api.domain.FieldDefinition> fieldDefinitions, org.springframework.data.domain.Pageable page, com.broadleafcommerce.search.core.service.SearchRequestProperties properties, String locale, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Customize the providedsolrQuerywith some additional behavior.booleandeterminePlainSandboxOverrideFilterValues(com.broadleafcommerce.data.tracking.core.context.ContextInfo context) protected StringfilterOnOtherSandboxes(com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Create a filter for sandboxes other than the current user's sandbox.protected StringCreate a filter for the production sandbox.protected StringfilterOnUserSandbox(com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Create a filter for the current user's sandbox.protected voidfilterOverriddenSandboxes(org.apache.solr.client.solrj.SolrQuery solrQuery, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) The other filters applied viafilterOnUserSandbox(ContextInfo),filterOnOtherSandboxes(ContextInfo), andfilterOnProductionSandbox()will return a list of multiple candidate records that may be relevant for the current sandbox request.protected voidfilterOverriddenSandboxesWithCatalogAwareness(org.apache.solr.client.solrj.SolrQuery solrQuery, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Similar tofilterOverriddenSandboxes(SolrQuery, ContextInfo), but for catalog-discriminated entities.generateCatalogAwareSandboxOverrides(Set<String> plainSandboxOverrideValues, String catalogId) protected booleanshouldContribute(org.apache.solr.client.solrj.SolrQuery solrQuery, com.broadleafcommerce.search.api.domain.SearchRequest searchRequest, org.springframework.data.domain.Pageable page, com.broadleafcommerce.search.core.service.SearchRequestProperties properties, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Determines if this contributor should run.Methods inherited from class com.broadleafcommerce.search.provider.solr.AbstractCatalogTrackableSolrQueryContributor
addPositiveExpressionModifier, getArchivedCatalogs, getCatalogs, getCatalogsForApplication, getDirectImplicitCatalogsForApplicationMethods inherited from class com.broadleafcommerce.search.provider.solr.AbstractSolrQueryContributor
contributeMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface com.broadleafcommerce.search.provider.solr.SolrQueryContributor
getOrder, isTypeAheadRequest
-
Constructor Details
-
SandboxTrackableSolrQueryContributor
public SandboxTrackableSolrQueryContributor()
-
-
Method Details
-
contributeInternal
protected void contributeInternal(org.apache.solr.client.solrj.SolrQuery solrQuery, com.broadleafcommerce.search.api.domain.SearchRequest searchRequest, List<com.broadleafcommerce.search.api.domain.FieldDefinition> fieldDefinitions, org.springframework.data.domain.Pageable page, com.broadleafcommerce.search.core.service.SearchRequestProperties properties, @Nullable String locale, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Description copied from class:AbstractSolrQueryContributorCustomize the providedsolrQuerywith some additional behavior.- Specified by:
contributeInternalin classAbstractSolrQueryContributor- Parameters:
solrQuery- The query to customizesearchRequest- The search query requestfieldDefinitions- The fields to perform the search onpage- Page information for page to retrieve for queryproperties- Additional properties for this querylocale- The locale of this searchcontext- The context information surrounding sandboxing/multitenant state
-
filterOnUserSandbox
protected String filterOnUserSandbox(com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Create a filter for the current user's sandbox.- Parameters:
context- The context information surrounding sandboxing/multitenant state- Returns:
- Filter for the current user's sandbox
-
filterOnOtherSandboxes
protected String filterOnOtherSandboxes(com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Create a filter for sandboxes other than the current user's sandbox.- Parameters:
context- The context information surrounding sandboxing/multitenant state- Returns:
- Filter for sandboxes other than the current user's sandbox
-
filterOnProductionSandbox
Create a filter for the production sandbox.- Returns:
- Filter for the production sandbox
-
filterOverriddenSandboxes
protected void filterOverriddenSandboxes(org.apache.solr.client.solrj.SolrQuery solrQuery, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) The other filters applied via
filterOnUserSandbox(ContextInfo),filterOnOtherSandboxes(ContextInfo), andfilterOnProductionSandbox()will return a list of multiple candidate records that may be relevant for the current sandbox request.However, the current user should only see the 'most-derived' representation of a record, so the filter applied in this method eliminates all but the most relevant record.
Here is what the current user should be seeing, from highest to lowest precedence:
- If there is a user-level record by the current user, return that.
- If there is a higher-than-user-level record (ex: promoted) by any user, return that.
- If there is a production-level record by any user, return that.
During indexing, if we know a record has a more-derived change somewhere, we track it on
SolrNarrowFields.SANDBOX_OVERRIDES. If there is a user-level record that is applying changes to the base record, the base record'sSolrNarrowFields.SANDBOX_OVERRIDESwill contain an element that looks likesandboxId,sandboxOwner(where sandboxOwner is the author of the user-level change). If there is a higher-than-user-level record that is applying changes to the base record, the base record'sSolrNarrowFields.SANDBOX_OVERRIDESwill contain an element that just looks likesandboxId.Thus, the filtering logic here should exclude any records where
SolrNarrowFields.SANDBOX_OVERRIDEScontainssandboxId, since that means there is a potentially visible higher-than-user-level record that should be returned instead. Furthermore, the filtering logic should also exclude any records whereSolrNarrowFields.SANDBOX_OVERRIDEScontainssandboxId,sandboxOwnerwhere sandboxOwner is the current user, since that means there is a potentially visible user-level record by the current user that should be returned instead.- Parameters:
solrQuery- Query to execute in Solrcontext- The context information surrounding sandboxing/multitenant state- See Also:
-
determinePlainSandboxOverrideFilterValues
-
buildPlainSandboxOverridesFilter
-
filterOverriddenSandboxesWithCatalogAwareness
protected void filterOverriddenSandboxesWithCatalogAwareness(org.apache.solr.client.solrj.SolrQuery solrQuery, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Similar to
filterOverriddenSandboxes(SolrQuery, ContextInfo), but for catalog-discriminated entities.When an entity is not catalog discriminated, it is a safe assumption that we can filter out a record purely based on
SolrNarrowFields.SANDBOX_OVERRIDES, because we have confidence that the override itself will be visible within the current context filtration constraints and therefore will appear in the results.However, when an entity is catalog discriminated, it's possible that the sandbox override of this record is not visible from the current catalog context. In Broadleaf, we only allow child catalogs to inherit production records: sandbox changes in parent catalogs are excluded. Thus, it is possible that within a particular context, the 'sandbox override' is not actually visible and the base record should be the one that is returned.
For example, assume there is a production recordA in parentCatalog. Now assume there is also a promoted sandbox change to recordA in parentCatalog and sandboxX. If you submit a search in childCatalog and sandboxX, you expect to see production recordA from the parentCatalog.
The only catalogs from which we should allow sandbox changes are the 'most derived' catalogs in our current context. In other words, for tenant-level requests, or application requests with
ContextRequest.isForceFilterByCatalogIncludeInheritance(), we only expect to see sandbox results fromContextRequest.getCatalogId()and none of its ancestors. For application requests that don't have any forced-catalog settings, we only expect to see sandbox results from all the directApplication.getIsolatedCatalogs()(the implicit ones only), and none of their ancestors.This is why we must leverage
SolrNarrowFields.CATALOG_AWARE_SANDBOX_OVERRIDESinstead, which will allow us to only consider sandbox overrides visible to the current catalog context.A special consideration is still required for marketplace catalogs, since our narrowing process for marketplace is different from our normal catalog narrowing. See
buildMarketplaceAndCatalogAwareSandboxOverridesFilter(Set, Set, Set)for more details.- Parameters:
solrQuery- The query to customizecontext- context information around sandboxing and multitenant state
-
buildCatalogAwareSandboxOverridesFilter
-
generateCatalogAwareSandboxOverrides
-
buildMarketplaceAndCatalogAwareSandboxOverridesFilter
protected String buildMarketplaceAndCatalogAwareSandboxOverridesFilter(Set<String> directImplicitIsolatedCatalogIdsForApp, Set<String> allIsolatedCatalogIdsForApp, Set<String> plainSandboxOverrideValuesToFilter) Should only be used if the request is in the context of a marketplace application. Narrowing against marketplace catalogs is done differently than normal catalogs due to the fact that a single marketplace may contain thousands of marketplace application catalogs.
For the purposes of this filter, it's infeasible to enumerate all of those catalogs. However, we can get by with a few assumptions about the structure of marketplace catalogs.
Most importantly, we don't expect any 'inheritance' for marketplace catalogs. For each assigned catalog, there is just the base tenant-level vendor catalog + the implicit application-level vendor-marketplace catalog. That's the only two catalogs we expect to get data from in a particular hierarchy. There can be no further children.
1. Notably, because the vendor catalog is at the tenant level and the implicit catalog is at the application level, they will never have changes in the same sandbox. The vendor catalog will have changes in tenant-level sandboxes and the implicit catalog will only have changes in application-level sandboxes.
2. At the application level, the caller will be in an application-level sandbox. Here, we will only inherit tenant-level records that are in production - this is actually handled implicitly be the fact that they are in the application-level sandbox instead of in the tenant-level sandbox (and therefore can never see tenant level sandbox changes). Next, for application-level overrides, the production tenant record will have an entry in
SolrNarrowFields.SANDBOX_OVERRIDESfor the current app-specific sandbox. We do not expect this app-level override to itself be overridden anywhere deeper due to the limited inheritance structure of marketplace catalogs. So we can reliably assume that this override will be visible in the caller's context.Putting this all together, we can conclude that for marketplace catalog items, we support an alternate filtration based on the original
SolrNarrowFields.SANDBOX_OVERRIDESfield.- Parameters:
directImplicitIsolatedCatalogIdsForApp- the directly assigned isolated implicit catalog ids for the application fromApplication.getIsolatedCatalogs()allIsolatedCatalogIdsForApp- all visible assigned isolated catalog IDs for the application, including inherited catalogsplainSandboxOverrideValuesToFilter- the vanilla sandbox override values to consider during filtration- Returns:
- a solr filter that can be used to filter sandbox overrides with marketplace and catalog awareness
-
shouldContribute
protected boolean shouldContribute(org.apache.solr.client.solrj.SolrQuery solrQuery, com.broadleafcommerce.search.api.domain.SearchRequest searchRequest, org.springframework.data.domain.Pageable page, com.broadleafcommerce.search.core.service.SearchRequestProperties properties, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Description copied from class:AbstractSolrQueryContributorDetermines if this contributor should run.- Specified by:
shouldContributein classAbstractSolrQueryContributor- Parameters:
solrQuery- The query to customizesearchRequest- The search query requestpage- Page information for page to retrieve for queryproperties- Additional properties for this query.context- The context information surrounding sandboxing/multitenant state- Returns:
- whether this contributor should run
-
contributeOnTypeAhead
public boolean contributeOnTypeAhead()- Returns:
- Should this contributor be executed on TypeAhead requests?
-