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>
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).
Service implementations should inject an instance of the general repository interface, and as a result, remain database platform agnostic while using a common interface.@Repository
@Narrow(JpaNarrowExecutor.class)
public interface JpaProductRepository<D extends JpaProduct> extends ProductRepository<D, String>
{ }
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 Summary
Modifier and TypeMethodDescriptionarchive
(D entity, ContextInfo contextInfo) Archive a record so that it is no longer considered active and is filtered out of results.boolean
existsByContextId
(String contextId, ContextInfo contextInfo) Retrieve whether or not an active instance of the item exists for the given context id after any narrowing context is applied.findAll
(ContextInfo contextInfo) Retrieve all domain instances.findAll
(ContextInfo contextInfo, Class<D> type) Retrieve all domain instances.org.springframework.data.domain.Page<D>
findAll
(org.springframework.data.domain.Pageable pageable, ContextInfo contextInfo) Retrieve all domain instances, a page at a time.org.springframework.data.domain.Page<D>
findAll
(org.springframework.data.domain.Pageable pageable, ContextInfo contextInfo, Class<D> type) Retrieve all domain instances, a page at a time.findAll
(org.springframework.data.domain.Sort sort, ContextInfo contextInfo) Retrieve all domain instances using a sort.findAll
(org.springframework.data.domain.Sort sort, ContextInfo contextInfo, Class<D> type) Retrieve all domain instances using a sort.findAllByContextId
(Iterable<String> contextIds, ContextInfo contextInfo) Retrieve all domain instances based on a list of context ids (seeTrackable.getContextId()
).findByContextId
(String contextId, ContextInfo contextInfo) Retrieve a domain instance based on the context id (seeTrackable.getContextId()
).findByContextIdAndCatalog
(String contextId, String catalogId, ContextInfo contextInfo) Retrieve a domain instance based on the context id (seeTrackable.getContextId()
).findByNativeId
(Object id) Finds the entity corresponding to the given native id.default TransitionPackage<D>
findDeployable
(WorkflowDeployRequest request) Retrieve the domain item identified viaWorkflowDeployRequest
and also retrieve any domain item existing at the requested target position (if any).findMaxSortMember
(Sortable example, String maxSort, ContextInfo contextInfo) Given an example member from a sort group, find the first member from that group whose sort value is less than maxSort.findMinSortMember
(Sortable example, String minSort, ContextInfo contextInfo) Given an example member from a sort group, find the first member from that group whose sort value is greater than minSort.findOriginal
(String contextId, String catalogId, String applicationId, String author, String stage, String sandboxId, Integer level) Given context information, find the original state for the workflow transition operation.default TransitionPackage<D>
findPromotable
(WorkflowPromoteRequest request) Retrieve the domain item identified viaWorkflowPromoteRequest
and also retrieve any domain item existing at the requested target position (if any).default TransitionPackage<D>
Find items positioned for original and tracking from the perspective of a promotion request.default TransitionPackage<D>
findRebasable
(WorkflowRebaseRequest request) Retrieve the domain item identified viaWorkflowRebaseRequest
and also retrieve any domain item existing at the requested target position (if any).default TransitionPackage<D>
findRejectable
(WorkflowRejectRequest request) Retrieve the domain item identified viaWorkflowRejectRequest
and also retrieve any domain item existing at the requested target position (if any).default D
findRevertable
(WorkflowRevertRequest request) Retrieve the domain item identified viaWorkflowRevertRequest
.findTarget
(String contextId, String catalogId, String applicationId, String author, String stage, String sandboxId, Integer level, Set<String> visibleFromCatalog) Given context information, find the target state (if any) for the workflow transition operation.default Class<?>
Retrieve information about the domain type backing this repository.Get a utility that is capable of determining theTrackableBehavior
state for a domain class.Should return the domain type along with all of its extensions that are registered as managed entities.boolean
pruneChangeDetails
(Object nativeId) Updates the entity whose native id matches the givennativeId
, setting itsTracking.getChangeDetails()
tonull
.void
pruneRestingNotificationStates
(Duration beforeNow) Deprecated.void
purgeObsoleteSandboxData
(Duration beforeNow) Hard-deletes all records which satisfy the following criteria:Tracking.getSandbox()
has itsarchived
property set to true AllNotificationStateAware.getNotificationStates()
(if there are any) are eitheracked
orstopped
AllTracking.getChangeDetails()
(if there are any) have atimestamp
that is beforeInstant.now()
minus thebeforeNow
durationsave
(D entity, ContextInfo contextInfo) Insert (if not exists) or update the domain instance in the datastore.saveAll
(Iterable<D> entities, ContextInfo contextInfo) Insert (if not exists) or update all the domain instances in the datastore.void
setTrackableBehaviorUtil
(TrackableBehaviorUtil behaviorUtil) Set a utility that is capable of determining theTrackableBehavior
state for a domain class.Methods inherited from interface com.broadleafcommerce.common.messaging.notification.NotificationStateRepository
findNotificationReadyMembers, setFailedNotificationAttempt, setNotificationAcknowledged
-
Method Details
-
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
- TheTrackable
instancecontextInfo
- 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
- TheTrackable
instancescontextInfo
- 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 groupminSort
- Results are filtered to be greater than this valuecontextInfo
- 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 groupmaxSort
- Results are filtered to be less than this valuecontextInfo
- 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 (seeTrackable.getContextId()
). If aNarrowExecutor
implementation was specified viaNarrow
, the result should be narrowed based on sandbox and catalog state.- Parameters:
contextId
- An identifying idcontextInfo
- 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 (seeTrackable.getContextId()
). Also restrict the result to a single catalog. This is only useful for catalog discriminated domain types.- Parameters:
contextId
- An identifying idcatalogId
- The catalog to restrict the result tocontextInfo
- 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 idcontextInfo
- 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 theTracking.getArchived()
field being set to True. For sandbox records, bothTracking.getArchived()
andSandboxInfo.getArchived()
are set to True.- Parameters:
entity
- TheTrackable
instance to save as archivedcontextInfo
- context information related to multitenancy. Often used to validate visibility and mutability of persistence operations for a catalog.
-
purgeObsoleteSandboxData
Hard-deletes all records which satisfy the following criteria:Tracking.getSandbox()
has itsarchived
property set to true- All
NotificationStateAware.getNotificationStates()
(if there are any) are eitheracked
orstopped
- All
Tracking.getChangeDetails()
(if there are any) have atimestamp
that is beforeInstant.now()
minus thebeforeNow
duration
After that, performs an update on all records to prune all
ChangeDetails
which satisfy the following criteria:obsolete
is truetimestamp
is beforeInstant.now()
minus thebeforeNow
duration
- 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
@Deprecated @Policy(operationTypes=UPDATE) void pruneRestingNotificationStates(@NonNull Duration beforeNow) Deprecated.Performs an update on all records to prune allNotificationStates
fromNotificationStateAware.getNotificationStates()
which satisfy the following criteria:NotificationState.isAcked()
istrue
orNotificationState.isStopped()
istrue
NotificationState.getChangeTimestamp()
is beforeInstant.now()
minus thebeforeNow
duration
- Parameters:
beforeNow
-NotificationStates
whosetimestamps
are older than the current time minus this duration will be pruned
-
pruneChangeDetails
Updates the entity whose native id matches the givennativeId
, setting itsTracking.getChangeDetails()
tonull
.- Parameters:
nativeId
- the native id of the entity whose change details should be set tonull
- Returns:
true
if the update was successful,false
otherwise
-
findAll
Retrieve all domain instances. If aNarrowExecutor
implementation was specified viaNarrow
, 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 aNarrowExecutor
implementation was specified viaNarrow
, the result should be narrowed based on sandbox and catalog state.- Parameters:
contextInfo
- Request context information around sandbox and multitenant statetype
- 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 (seeTrackable.getContextId()
). If aNarrowExecutor
implementation was specified viaNarrow
, the result should be narrowed based on sandbox and catalog state.- Parameters:
contextIds
- A list of identifying idscontextInfo
- 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 aNarrowExecutor
implementation was specified viaNarrow
, the result should be narrowed based on sandbox and catalog state.- Parameters:
pageable
- Information regarding the current page of data to retrievecontextInfo
- 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 aNarrowExecutor
implementation was specified viaNarrow
, the result should be narrowed based on sandbox and catalog state.- Parameters:
pageable
- Information regarding the current page of data to retrievecontextInfo
- Request context information around sandbox and multitenant statetype
- 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 aNarrowExecutor
implementation was specified viaNarrow
, the result should be narrowed based on sandbox and catalog state.- Parameters:
sort
- The sorting information used to define the sort for the query resultscontextInfo
- 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 aNarrowExecutor
implementation was specified viaNarrow
, the result should be narrowed based on sandbox and catalog state.- Parameters:
sort
- The sorting information used to define the sort for the query resultscontextInfo
- Request context information around sandbox and multitenant statetype
- The results will be limited to the explicit type- Returns:
- The list of narrowed, sorted entities
-
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
Set a utility that is capable of determining theTrackableBehavior
state for a domain class.- Parameters:
behaviorUtil
- A utility that is capable of determining theTrackableBehavior
state for a domain class.
-
getTrackableBehaviorUtil
TrackableBehaviorUtil getTrackableBehaviorUtil()Get a utility that is capable of determining theTrackableBehavior
state for a domain class.- Returns:
- A utility that is capable of determining the
TrackableBehavior
state for a domain class.
-
getDomainType
- Specified by:
getDomainType
in interfacecom.broadleafcommerce.common.extension.DomainTypeAware
-
getTypesToRegisterInMappingContext
Should return the domain type along with all of its extensions that are registered as managed entities. This is useful to informMappingContext
about which persistent entities are available.- Returns:
- the domain type along with all extensions that are registered as managed entities
-
findByNativeId
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
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
Retrieve the domain item identified viaWorkflowPromoteRequest
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 ofTrackingLevel.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
Retrieve the domain item identified viaWorkflowRebaseRequest
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 ofTrackingLevel.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
Retrieve the domain item identified viaWorkflowDeployRequest
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 ofTrackingLevel.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
Retrieve the domain item identified viaWorkflowRejectRequest
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 ofTrackingLevel.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
Retrieve the domain item identified viaWorkflowRevertRequest
. 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 itemcatalogId
- 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 informationsandboxId
- The sandbox in which the original state existslevel
- 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 itemcatalogId
- 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 informationsandboxId
- The sandbox in which the target state existslevel
- The tracking level at which the target state residesvisibleFromCatalog
- other catalogs that are visible based on the catalogId- Returns:
- The target state, or null if no target found
-
StandaloneCleanupRepository.pruneRestingNotificationStates(Duration)