Class CatalogTrackableSolrQueryContributor

All Implemented Interfaces:
SolrQueryContributor, org.springframework.core.Ordered

public class CatalogTrackableSolrQueryContributor extends AbstractCatalogTrackableSolrQueryContributor
Add query filters to narrow query results down to the most specific Catalog context provided.
  • Constructor Details

    • CatalogTrackableSolrQueryContributor

      public CatalogTrackableSolrQueryContributor()
  • 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: AbstractSolrQueryContributor
      Customize the provided solrQuery with some additional behavior.
      Specified by:
      contributeInternal in class AbstractSolrQueryContributor
      Parameters:
      solrQuery - The query to customize
      searchRequest - The search query request
      fieldDefinitions - The fields to perform the search on
      page - Page information for page to retrieve for query
      properties - Additional properties for this query
      locale - The locale of this search
      context - The context information surrounding sandboxing/multitenant state
    • getForcedCatalogs

      protected Set<String> getForcedCatalogs(com.broadleafcommerce.data.tracking.core.context.ContextInfo context)
      Retrieve currently specified visible catalogs.
      Parameters:
      context - The context information surrounding sandboxing/multitenant state
      Returns:
      Catalogs narrowed to only specified visible catalogs
    • addMarketplaceFilter

      protected void addMarketplaceFilter(@NonNull @NonNull org.apache.solr.client.solrj.SolrQuery solrQuery, @NonNull @NonNull com.broadleafcommerce.search.api.domain.SearchRequest searchRequest, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.context.ContextInfo context, @NonNull @NonNull com.broadleafcommerce.data.tracking.core.tenant.domain.Application application)
      Adds filtering when the requested Application is a marketplace. This will add filtering by SolrNarrowFields.MARKETPLACE_APPLICATIONS as well as isolated catalog ids.
      Parameters:
      solrQuery - Query to add the filter to
      searchRequest - details about the search request
      context - Additional context info
      application - Requested application
    • addPendingMarketplaceApplicationFilter

      protected String addPendingMarketplaceApplicationFilter(com.broadleafcommerce.data.tracking.core.tenant.domain.Application application, String marketplaceApplication)
    • getApplicationCatalogs

      protected Set<String> getApplicationCatalogs(com.broadleafcommerce.data.tracking.core.context.ContextInfo context)
      Retrieve all catalogs visible from the current application.
      Parameters:
      context - The context information surrounding sandboxing/multitenant state
      Returns:
      Catalogs narrowed to all catalogs visible from the current application.
    • filterOnNoCatalog

      protected String filterOnNoCatalog()
      Create a filter for documents with no specified catalog.

      Note that the nested negative filter must contain a "*:* AND" as well. See https://stackoverflow.com/questions/7363819

      Returns:
      A filter for documents with no specified catalog.
    • filterOverriddenCatalogs

      protected String filterOverriddenCatalogs(Set<String> catalogIds, com.broadleafcommerce.search.api.domain.SearchRequest searchRequest, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Create a filter to exclude documents for which more specific versions exist for this catalog context.
      Parameters:
      catalogIds - The IDs of the catalogs which are used for this context
      searchRequest - details about the search request
      contextInfo - context information around multitenant state
      Returns:
      Filter query to exclude less specific catalog documents
    • buildFilterOnPlainCatalogOverrides

      protected String buildFilterOnPlainCatalogOverrides(Set<String> catalogIds)
    • buildFilterOnSandboxAwareCatalogOverrides

      protected String buildFilterOnSandboxAwareCatalogOverrides(Set<String> catalogIds, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)

      SolrNarrowFields.CATALOG_OVERRIDES will contain an entry if there is _any_ override record in a more derived catalog, regardless of whether the override is at user level, higher-than-user level (ex: promoted), or production, and regardless of which sandbox the change is in (ex: even if the base record and derived record are both sandbox changes, but are in different sandboxes, in which case the derived record really isn't an override of the base record at all).

      Normally, we universally filter out records who have an override in a more derived catalog, with the expectation that the more derived record will be included in the results and can be returned to the caller. However, we cannot do this with sandboxable entities, because the override itself may not be visible to the current user.

      Consider a scenario where we have 'Tenant Catalog Product X', and UserA has made a user-level change to that product in 'childCatalog' (ex: application catalog). Then, UserB performs a search for products in 'childCatalog'.

      In this case, even though SolrNarrowFields.CATALOG_OVERRIDES for 'Tenant Catalog Product X' would contain 'childCatalog', we actually cannot exclude this record because the current user should only be able to see user-level records _they_ have created, higher-than-user-level records, or production records. And as such, the 'Tenant Catalog Product X' record should actually be included in the results.

      The SandboxTrackableSolrQueryContributor already takes care of adding appropriate filters to only expose the appropriate sandbox changes to the current user.

      However, we still need to make sure our catalog override filters are not overzealous and are incorporating sandboxing awareness before excluding a record. Thus, we should only exclude a record that has been overridden in one of the provided catalogs if we know that at least one of those overrides is actually visible to the current user. That is why we must use SolrNarrowFields.SANDBOX_AWARE_CATALOG_OVERRIDES.

      Parameters:
      catalogIds - the catalog IDs that should be included in the results
      contextInfo - context information about sandboxing and multitenant state
      Returns:
      a solr filter on sandbox-aware catalog overrides
    • 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: AbstractSolrQueryContributor
      Determines if this contributor should run.
      Specified by:
      shouldContribute in class AbstractSolrQueryContributor
      Parameters:
      solrQuery - The query to customize
      searchRequest - The search query request
      page - Page information for page to retrieve for query
      properties - 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?
    • buildFilterOnIncludedCatalogs

      protected String buildFilterOnIncludedCatalogs(Set<String> catalogsToInclude)
      Parameters:
      catalogsToInclude - IDs of catalogs to include
      Returns:
      a solr filter against SolrNarrowFields.CATALOG
    • buildFilterForProductionTrackingLevel

      protected String buildFilterForProductionTrackingLevel()
      Returns:
      solr filter to get production-level records
    • buildFilterOnCreatingApplication

      protected String buildFilterOnCreatingApplication(String applicationId)
      Parameters:
      applicationId - the application ID to filter on
      Returns:
      solr filter where SolrNarrowFields.CREATING_APPLICATION_ID matches the given applicationId
    • buildFilterOnCatalogOmissions

      protected String buildFilterOnCatalogOmissions(Set<String> catalogIds)

      We expect catalog omissions to be populated any time we expect a trackable record to not be inherited by a certain catalog. This can be because the current record is a new creation at the sandbox level (only production inheritance is allowed), or because we have inclusion/exclusion filters on the catalogs for specific records.

      Omissions are calculated from a production context, so generally speaking are safe to indiscriminately filter against, since the omission should apply everywhere.

      Parameters:
      catalogIds - the catalog IDs that should be included in the results
      Returns:
      a solr filter on SolrNarrowFields.CATALOG_OMISSIONS
    • getAuthenticationUtils

      protected com.broadleafcommerce.resource.security.utils.service.AuthenticationUtils getAuthenticationUtils()
    • setAuthenticationUtils

      @Autowired public void setAuthenticationUtils(com.broadleafcommerce.resource.security.utils.service.AuthenticationUtils authenticationUtils)