Interface TrackableRepository<D extends Trackable>

  • Type Parameters:
    D - The domain type the repository manages
    All Superinterfaces:
    com.broadleafcommerce.common.extension.DomainTypeAware, com.broadleafcommerce.common.messaging.notification.NotificationStateRepository, org.springframework.data.repository.Repository<D,​String>
    All Known Subinterfaces:
    BaseTrackableRepository<D>, CommonApplicationRepository<D>, CommonCatalogRepository<D>, CommonMarketplaceApplicationCatalogRepository<D>

    @NoRepositoryBean
    public interface TrackableRepository<D extends Trackable>
    extends org.springframework.data.repository.Repository<D,​String>, com.broadleafcommerce.common.messaging.notification.NotificationStateRepository, com.broadleafcommerce.common.extension.DomainTypeAware
    Special Spring Data Repository version targeted specifically at maintaining persistence for Trackable domain objects. Actual maintenance of Tracking state during a save operation, including ChangeDetail, SandboxInfo and CatalogInfo information is generally performed by a DefaultTrackableDomainMapperMemberSupport instance prior to passing to the repository.

    Fetch behavior may be enhanced by including an additional Narrow annotation to an extending interface that also utilizes the Repository annotation. Narrow annotations take a required NarrowExecutor class argument. The NarrowExecutor is responsible for executing the fetch query defined by the repository query method (or by direct Query definitions through repository specific helper - for example - JpaNarrowingHelper). Furthermore, it is responsible for possibly enhancing the query to perform additional filtering, such as sandbox narrowing and/or catalog filtering.

    As a framework, we generaly want to provide the possibility for consumption of repository data by vanilla services that are agnostic to the platform specific nature of a given repository defintion (e.g. a Jpa repository). To achieve this, we generally employ a two-step pattern for setting up a new repository definition in a microservice. First, an interface that extends from TrackableRepository is created. The generics on this interface are kept purposefully general and any general query methods are added here. If specific implementations of a method are required per database platform, an additional interface may be defined and fragment implementation created for each platform. A bean whose id matches the [fragment interface name]Impl pattern should be defined in the platform config (e.g. JpaConfig) to allow the correct fragment implementation to be identified and loaded for execution as part of the Spring Data repository proxy. If overriding existing methods from the TrackableRepository interface, it is important that the overriding method declared in the fragment implementation has a matching signature. for example, to override the save(Trackable, ContextInfo) method implementation, use a concrete method declaration in your fragment implementation similar to this:

     public Trackable save(Trackable catalog, ContextInfo contextInfo) {
         // do something interesting
     }
     

    See https://docs.spring.io/spring-data/commons/docs/current/reference/html/#repositories.single-repository-behavior for more information on adding explicit query code behavior to Spring Data repositories.

     @NoRepositoryBean
     public interface ProductRepository<D extends Trackable, I> extends TrackableRepository<D, I> {
    
        Page<D> findAllByNameContainingIgnoreCase(String query, Pageable page, ContextInfo contextInfo);
    
     }
     

    Next, a platform specific interface is created to reference the database specific definition. An optional Narrow annotation may also be included. This interface is generally empty, unless there is a method to be defined that is truly only possible on a specific platform (e.g. something that can only be done in JpaDB).

     @Repository
     @Narrow(JpaNarrowExecutor.class)
     public interface JpaProductRepository<D extends JpaProduct> extends ProductRepository<D, String> {
    
     }
     
    Service implementations should inject an instance of the general repository interface, and as a result, remain database platform agnostic while using a common interface.

    Support for a specific platform repository should be enabled via configuration. For example,

     @Configuration
     @EnableJpaRepositories(
             basePackages = "com.broadleafcommerce.adminnavigation.provider.jpa.repository",
             repositoryFactoryBeanClass = JpaTrackableRepositoryFactoryBean.class)
     @EntityScan(basePackages = "com.broadleafcommerce.menu.provider.jpa.domain")
     @AutoConfigureAfter(JpaDataAutoConfiguration.class)
     public class AdminNavigationJpaAutoConfiguration {}
     
    Author:
    Jeff Fischer
    • Method Detail

      • save

        @Policy(operationTypes={UPDATE,DELETE,CREATE},
                param=0)
        @NonNull
        D save​(@NonNull
               D entity,
               @Nullable
               ContextInfo contextInfo)
        Insert (if not exists) or update the domain instance in the datastore.
        Parameters:
        entity - The Trackable instance
        contextInfo - context information related to multitenancy. Often used to validate visibility and mutability of persistence operations for a catalog.
        Returns:
        The persisted instance
      • saveAll

        @Policy(operationTypes={UPDATE,DELETE,CREATE},
                param=0)
        @NonNull
        Iterable<D> saveAll​(@NonNull
                            Iterable<D> entities,
                            @Nullable
                            ContextInfo contextInfo)
        Insert (if not exists) or update all the domain instances in the datastore. This can end up being a mixture of insert and update operations.
        Parameters:
        entities - The Trackable instances
        contextInfo - context information related to multitenancy. Often used to validate visibility and mutability of persistence operations for a catalog.
        Returns:
        The list of persisted instances
      • findMinSortMember

        @Policy(operationTypes=READ)
        @Nullable
        Sortable findMinSortMember​(@NonNull
                                   Sortable example,
                                   @Nullable
                                   String minSort,
                                   @Nullable
                                   ContextInfo contextInfo)
        Given an example member from a sort group, find the first member from that group whose sort value is greater than minSort. If minSort is not specified, then find the first member in the group.

        This can be used to find a member before which to sort the example. In such a case, the minSort value is the sort position of the member after which the example will be sorted. In this case, the reason to get the minSortMember (i.e., the one to sort example before) would be to ensure that example's new sorting value is between minSort and minSortMember's sort value, thereby avoiding collisions.

        Parameters:
        example - The example member of the group used to fashion a query that restricts to the group
        minSort - Results are filtered to be greater than this value
        contextInfo - context information related to multitenancy. Often used to validate visibility and mutability of persistence operations for a catalog.
        Returns:
        The first sorted member based on this fetch
      • findMaxSortMember

        @Policy(operationTypes=READ)
        @Nullable
        Sortable findMaxSortMember​(@NonNull
                                   Sortable example,
                                   @Nullable
                                   String maxSort,
                                   @Nullable
                                   ContextInfo contextInfo)
        Given an example member from a sort group, find the first member from that group whose sort value is less than maxSort. If maxSort is not specified, then find the first member in the group.

        This is essentially the complement to findMinSortMember(Sortable, String, ContextInfo). Instead of finding the member before which to sort example using the sorting value of the member after which to sort example, this finds the position-after-member given the sort value of the position-before-member.

        Parameters:
        example - The example member of the group used to fashion a query that restricts to the group
        maxSort - Results are filtered to be less than this value
        contextInfo - context information related to multitenancy. Often used to validate visibility and mutability of persistence operations for a catalog.
        Returns:
        The first sorted member based on this fetch
      • findByContextId

        @Policy(operationTypes=READ)
        @NonNull
        Optional<D> findByContextId​(@NonNull
                                    String contextId,
                                    @Nullable
                                    ContextInfo contextInfo)
        Retrieve a domain instance based on the context id (see Trackable.getContextId()). If a NarrowExecutor implementation was specified via Narrow, the result should be narrowed based on sandbox and catalog state.
        Parameters:
        contextId - An identifying id
        contextInfo - Request context information around sandbox and multitenant state
        Returns:
        If nothing found, an empty Optional. Otherwise, an Optional containing the narrowed entity.
      • findByContextIdAndCatalog

        @Policy(operationTypes=READ)
        @NonNull
        Optional<D> findByContextIdAndCatalog​(@NonNull
                                              String contextId,
                                              @NonNull
                                              String catalogId,
                                              @Nullable
                                              ContextInfo contextInfo)
        Retrieve a domain instance based on the context id (see Trackable.getContextId()). Also restrict the result to a single catalog. This is only useful for catalog discriminated domain types.
        Parameters:
        contextId - An identifying id
        catalogId - The catalog to restrict the result to
        contextInfo - Request context information around sandbox and multitenant state
        Returns:
        If nothing found, an empty Optional. Otherwise, an Optional containing the filtered entity.
      • existsByContextId

        @Policy(operationTypes=READ)
        boolean existsByContextId​(@NonNull
                                  String contextId,
                                  @Nullable
                                  ContextInfo contextInfo)
        Retrieve whether or not an active instance of the item exists for the given context id after any narrowing context is applied.
        Parameters:
        contextId - An identifying id
        contextInfo - Request context information around sandbox and multitenant state
        Returns:
        Whether or not an active instance of the item exists
      • archive

        @Policy(operationTypes=DELETE,
                param=0)
        @NonNull
        D archive​(@NonNull
                  D entity,
                  @Nullable
                  ContextInfo contextInfo)
        Archive a record so that it is no longer considered active and is filtered out of results. For production records, this results in the Tracking.getArchived() field being set to True. For sandbox records, both Tracking.getArchived() and SandboxInfo.getArchived() are set to True.
        Parameters:
        entity - The Trackable instance to save as archived
        contextInfo - context information related to multitenancy. Often used to validate visibility and mutability of persistence operations for a catalog.
      • purgeObsoleteSandboxData

        @Policy(operationTypes=DELETE)
        void purgeObsoleteSandboxData​(@NonNull
                                      Duration beforeNow)
        Hard-deletes all records which satisfy the following criteria:

        After that, performs an update on all records to prune all ChangeDetails which satisfy the following criteria:

        Parameters:
        beforeNow - duration used to determine whether sandbox data is outdated. The current time minus this duration is the age cutoff that will be used.
      • pruneRestingNotificationStates

        @Policy(operationTypes=UPDATE)
        void pruneRestingNotificationStates​(@NonNull
                                            Duration beforeNow)
        Performs an update on all records to prune all NotificationStates from NotificationStateAware.getNotificationStates() which satisfy the following criteria:
        • NotificationState.isAcked() is true or NotificationState.isStopped() is true
        • NotificationState.getChangeTimestamp() is before Instant.now() minus the beforeNow duration
        Parameters:
        beforeNow - NotificationStates whose timestamps are older than the current time minus this duration will be pruned
      • pruneChangeDetails

        @Policy(operationTypes=UPDATE)
        boolean pruneChangeDetails​(@NonNull
                                   Object nativeId)
        Updates the entity whose native id matches the given nativeId, setting its Tracking.getChangeDetails() to null.
        Parameters:
        nativeId - the native id of the entity whose change details should be set to null
        Returns:
        true if the update was successful, false otherwise
      • findAll

        @Policy(operationTypes=READ)
        @NonNull
        List<D> findAll​(@Nullable
                        ContextInfo contextInfo)
        Retrieve all domain instances. If a NarrowExecutor implementation was specified via Narrow, the result should be narrowed based on sandbox and catalog state.
        Parameters:
        contextInfo - Request context information around sandbox and multitenant state
        Returns:
        The list of narrowed entities
      • findAll

        @Policy(operationTypes=READ)
        @NonNull
        List<D> findAll​(@Nullable
                        ContextInfo contextInfo,
                        @NonNull
                        Class<D> type)
        Retrieve all domain instances. If a NarrowExecutor implementation was specified via Narrow, the result should be narrowed based on sandbox and catalog state.
        Parameters:
        contextInfo - Request context information around sandbox and multitenant state
        type - The results will be limited to the explicit type
        Returns:
        The list of narrowed entities
      • findAllByContextId

        @Policy(operationTypes=READ)
        @NonNull
        Iterable<D> findAllByContextId​(@NonNull
                                       Iterable<String> contextIds,
                                       @Nullable
                                       ContextInfo contextInfo)
        Retrieve all domain instances based on a list of context ids (see Trackable.getContextId()). If a NarrowExecutor implementation was specified via Narrow, the result should be narrowed based on sandbox and catalog state.
        Parameters:
        contextIds - A list of identifying ids
        contextInfo - Request context information around sandbox and multitenant state
        Returns:
        The list of narrowed entities
      • findAll

        @Policy(operationTypes=READ)
        @NonNull
        org.springframework.data.domain.Page<D> findAll​(@NonNull
                                                        org.springframework.data.domain.Pageable pageable,
                                                        @Nullable
                                                        ContextInfo contextInfo)
        Retrieve all domain instances, a page at a time. If a NarrowExecutor implementation was specified via Narrow, the result should be narrowed based on sandbox and catalog state.
        Parameters:
        pageable - Information regarding the current page of data to retrieve
        contextInfo - Request context information around sandbox and multitenant state
        Returns:
        The subset (page) of narrowed entities
      • findAll

        @Policy(operationTypes=READ)
        @NonNull
        org.springframework.data.domain.Page<D> findAll​(@NonNull
                                                        org.springframework.data.domain.Pageable pageable,
                                                        @Nullable
                                                        ContextInfo contextInfo,
                                                        @NonNull
                                                        Class<D> type)
        Retrieve all domain instances, a page at a time. If a NarrowExecutor implementation was specified via Narrow, the result should be narrowed based on sandbox and catalog state.
        Parameters:
        pageable - Information regarding the current page of data to retrieve
        contextInfo - Request context information around sandbox and multitenant state
        type - The results will be limited to the explicit type
        Returns:
        The subset (page) of narrowed entities
      • findAll

        @Policy(operationTypes=READ)
        @NonNull
        List<D> findAll​(@NonNull
                        org.springframework.data.domain.Sort sort,
                        @Nullable
                        ContextInfo contextInfo)
        Retrieve all domain instances using a sort. If a NarrowExecutor implementation was specified via Narrow, the result should be narrowed based on sandbox and catalog state.
        Parameters:
        sort - The sorting information used to define the sort for the query results
        contextInfo - Request context information around sandbox and multitenant state
        Returns:
        The list of narrowed, sorted entities
      • findAll

        @Policy(operationTypes=READ)
        @NonNull
        List<D> findAll​(@NonNull
                        org.springframework.data.domain.Sort sort,
                        @Nullable
                        ContextInfo contextInfo,
                        @NonNull
                        Class<D> type)
        Retrieve all domain instances using a sort. If a NarrowExecutor implementation was specified via Narrow, the result should be narrowed based on sandbox and catalog state.
        Parameters:
        sort - The sorting information used to define the sort for the query results
        contextInfo - Request context information around sandbox and multitenant state
        type - The results will be limited to the explicit type
        Returns:
        The list of narrowed, sorted entities
      • getEntityInformation

        org.springframework.data.repository.core.EntityInformation<D,​String> getEntityInformation()
        Retrieve information about the domain type backing this repository. Generally, the Java type of the backing domain class is the most useful, especially for mapping purposes.
        Returns:
        The backing domain information
      • setTrackableBehaviorUtil

        void setTrackableBehaviorUtil​(TrackableBehaviorUtil behaviorUtil)
        Set a utility that is capable of determining the TrackableBehavior state for a domain class.
        Parameters:
        behaviorUtil - A utility that is capable of determining the TrackableBehavior state for a domain class.
      • getDomainType

        default Class<?> getDomainType()
        Specified by:
        getDomainType in interface com.broadleafcommerce.common.extension.DomainTypeAware
      • getTypesToRegisterInMappingContext

        List<Class<?>> getTypesToRegisterInMappingContext()
        Should return the domain type along with all of its extensions that are registered as managed entities. This is useful to inform MappingContext about which persistent entities are available.
        Returns:
        the domain type along with all extensions that are registered as managed entities
      • findByNativeId

        @Policy(operationTypes=READ)
        @NonNull
        Optional<D> findByNativeId​(@NonNull
                                   Object id)
        Finds the entity corresponding to the given native id.
        Parameters:
        id - the native id to find the entity for
        Returns:
        an optional containing the matching entity, Optional.empty() otherwise
      • findPromoteOrientedItems

        default TransitionPackage<D> findPromoteOrientedItems​(TargetRelatedRequest request)
        Find items positioned for original and tracking from the perspective of a promotion request. Original should be a less advanced state and target should be a more advanced sandbox state.
        Parameters:
        request - Request that includes properties identifying a sandbox target state
        Returns:
        A package describing the original and target state (if any)
      • findPromotable

        @NonNull
        default TransitionPackage<D> findPromotable​(@NonNull
                                                    WorkflowPromoteRequest request)
        Retrieve the domain item identified via WorkflowPromoteRequest and also retrieve any domain item existing at the requested target position (if any). The purpose of this call is to establish origin and target in order to advance all or some of the state of the origin object to the state of the target object in the workflow for a promotion.

        Target position is determined by two values in the PromotionRequest: targetSandBoxId, and targetLevel. In most cases, the targetSandBoxId remains the same and the targetLevel increases incrementally beyond TrackingLevel.USER until the final deployment PromotionRequest, which uses a targetLevel of TrackingLevel.PRODUCTION. Different targetSandboxId values can be used to compose isolated sandbox flows. Furthermore, different targetStage values can be used to further inform the system about state in a more complex composed flow.

        Parameters:
        request - container for holding information about the originating domain item and target position for the promotion
        Returns:
        A container for the original and target entities
      • findRebasable

        @NonNull
        default TransitionPackage<D> findRebasable​(@NonNull
                                                   WorkflowRebaseRequest request)
        Retrieve the domain item identified via WorkflowRebaseRequest and also retrieve any domain item existing at the requested target position (if any). The purpose of this call is to establish origin and target in order to move any missing changes by another author in the target to the original. In this way, the original state is brought up-to-date with the target. If the original contains conflicting changes, the original changes should win.

        Target position is determined by two values in the PromotionRequest: targetSandBoxId, and targetLevel. In most cases, the targetSandBoxId remains the same and the targetLevel increases incrementally beyond TrackingLevel.USER until the final deployment PromotionRequest, which uses a targetLevel of TrackingLevel.PRODUCTION. Different targetSandboxId values can be used to compose isolated sandbox flows. Furthermore, different targetStage values can be used to further inform the system about state in a more complex composed flow.

        Parameters:
        request - container for holding information about the originating domain item and target position for the promotion
        Returns:
        A container for the original and target entities
      • findDeployable

        @NonNull
        default TransitionPackage<D> findDeployable​(@NonNull
                                                    WorkflowDeployRequest request)
        Retrieve the domain item identified via WorkflowDeployRequest and also retrieve any domain item existing at the requested target position (if any). The purpose of this call is to establish origin and target in order to advance all or some of the state of the origin object to the state of the target object in the workflow for a deployment.

        Target position is determined by two values in the PromotionRequest: targetSandBoxId, and targetLevel. In most cases, the targetSandBoxId remains the same and the targetLevel increases incrementally beyond TrackingLevel.USER until the final deployment PromotionRequest, which uses a targetLevel of TrackingLevel.PRODUCTION. Different targetSandboxId values can be used to compose isolated sandbox flows. Furthermore, different targetStage values can be used to further inform the system about state in a more complex composed flow.

        Parameters:
        request - container for holding information about the originating domain item and target position for the deployment
        Returns:
        A container for the original and target entities
      • findRejectable

        @NonNull
        default TransitionPackage<D> findRejectable​(@NonNull
                                                    WorkflowRejectRequest request)
        Retrieve the domain item identified via WorkflowRejectRequest and also retrieve any domain item existing at the requested target position (if any). The purpose of this call is to establish origin and target in order to reverse all or some of the state of the origin object to the state of the target object in the workflow for a rejection.

        Target position is determined by two values in the PromotionRequest: targetSandBoxId, and targetLevel. In most cases, the targetSandBoxId remains the same and the targetLevel increases incrementally beyond TrackingLevel.USER until the final deployment PromotionRequest, which uses a targetLevel of TrackingLevel.PRODUCTION. Different targetSandboxId values can be used to compose isolated sandbox flows. Furthermore, different targetStage values can be used to further inform the system about state in a more complex composed flow.

        Parameters:
        request - container for holding information about the originating domain item and target position for the rejection
        Returns:
        A container for the original and target entities
      • findRevertable

        @Nullable
        default D findRevertable​(@NonNull
                                 WorkflowRevertRequest request)
        Retrieve the domain item identified via WorkflowRevertRequest. The purpose of this call is to establish origin in order to reverse the state of the origin object.
        Parameters:
        request - container for holding information about the originating domain item
        Returns:
        The repository domain instance to revert
      • findOriginal

        D findOriginal​(String contextId,
                       @Nullable
                       String catalogId,
                       @Nullable
                       String applicationId,
                       @Nullable
                       String author,
                       @Nullable
                       String stage,
                       @Nullable
                       String sandboxId,
                       Integer level)
        Given context information, find the original state for the workflow transition operation. Includes promote, deploy, reject and revert operations.
        Parameters:
        contextId - The identifier for the sandboxable item
        catalogId - Any catalog to which the original is related (if any)
        applicationId - Any application to which the original is related (if any)
        author - The author of the entity. Used when the original is a user level sandbox state.
        stage - Additional identifying information
        sandboxId - The sandbox in which the original state exists
        level - The tracking level at which the original state resides
        Returns:
        The originating state for the transition
      • findTarget

        @Nullable
        D findTarget​(String contextId,
                     @Nullable
                     String catalogId,
                     @Nullable
                     String applicationId,
                     @Nullable
                     String author,
                     @Nullable
                     String stage,
                     @Nullable
                     String sandboxId,
                     Integer level,
                     Set<String> visibleFromCatalog)
        Given context information, find the target state (if any) for the workflow transition operation. Includes promote, deploy, reject and revert operations.
        Parameters:
        contextId - The identifier for the sandboxable item
        catalogId - Any catalog to which the target is related (if any)
        applicationId - Any application to which the original is related (if any)
        author - The author of the entity. Used when the target is a user level sandbox state.
        stage - Additional identifying information
        sandboxId - The sandbox in which the target state exists
        level - The tracking level at which the target state resides
        visibleFromCatalog - other catalogs that are visible based on the catalogId
        Returns:
        The target state, or null if no target found