Package org.exoplatform.agenda.dao
Interface CalendarSubscriptionDAO
- All Superinterfaces:
org.springframework.data.repository.CrudRepository<CalendarSubscriptionEntity,,Long> org.springframework.data.jpa.repository.JpaRepository<CalendarSubscriptionEntity,,Long> org.springframework.data.repository.ListCrudRepository<CalendarSubscriptionEntity,,Long> org.springframework.data.repository.ListPagingAndSortingRepository<CalendarSubscriptionEntity,,Long> org.springframework.data.repository.PagingAndSortingRepository<CalendarSubscriptionEntity,,Long> org.springframework.data.repository.query.QueryByExampleExecutor<CalendarSubscriptionEntity>,org.springframework.data.repository.Repository<CalendarSubscriptionEntity,Long>
public interface CalendarSubscriptionDAO
extends org.springframework.data.jpa.repository.JpaRepository<CalendarSubscriptionEntity,Long>
Reads and writes calendar subscriptions (EXO-90278).
The refresh job runs on every node of a cluster, so the rows it works on are
shared between nodes, and its writes carry their correctness in their WHERE
clause, as email-connector's EmailSyncStateDAO does: a claim lands only
on a due row nobody holds — or whose holder's claim went stale — and the row
count it returns is the answer; an outcome is recorded, and a claim released,
only by the node holding it.
-
Method Summary
Modifier and TypeMethodDescriptionintThe owner's claim, for a refresh asked now: the same as the job's, due or not.intThe job's claim: lands only on a subscription still due and held by nobody live, so of every node trying at once exactly one sees a row count of one.findByCalendarId(long calendarId) Finds the subscription of a calendar.findByUrlKey(String urlKey) Finds the subscription of a user to a URL.findByUserIdentityId(long userIdentityId, org.springframework.data.domain.Pageable pageable) Finds a user's subscriptions.findDueIds(Date now, Date staleBefore, org.springframework.data.domain.Pageable pageable) The subscriptions due for a refresh that nobody holds a live claim on, the one waiting longest first.intrecordFailure(long id, String node, Date attempt, String lastError, Date nextRefreshDate) Records a failed refresh and releases the claim, only by the node holding it.intrecordSuccess(long id, String node, String urlKey, String etag, String lastModified, String contentHash, Integer refreshMinutes, Date attempt, boolean truncated, Date nextRefreshDate) Records a successful refresh and releases the claim — only by the node that holds it, and only while the subscription still points at the URL that was read: an edit of the URL during the refresh leaves the row to the next one.intReleases a claim without recording anything, only by the node holding it.intPoints a subscription at a new URL and makes it due at once, forgetting the validators and the digest of the previous URL.Methods inherited from interface org.springframework.data.repository.CrudRepository
count, delete, deleteAll, deleteAll, deleteAllById, deleteById, existsById, findById, saveMethods inherited from interface org.springframework.data.jpa.repository.JpaRepository
deleteAllByIdInBatch, deleteAllInBatch, deleteAllInBatch, deleteInBatch, findAll, findAll, flush, getById, getOne, getReferenceById, saveAllAndFlush, saveAndFlushMethods inherited from interface org.springframework.data.repository.ListCrudRepository
findAll, findAllById, saveAllMethods inherited from interface org.springframework.data.repository.ListPagingAndSortingRepository
findAllMethods inherited from interface org.springframework.data.repository.PagingAndSortingRepository
findAllMethods inherited from interface org.springframework.data.repository.query.QueryByExampleExecutor
count, exists, findAll, findBy, findOne
-
Method Details
-
findByCalendarId
Finds the subscription of a calendar.- Parameters:
calendarId- technical identifier of the calendar- Returns:
- the subscription, or null when the calendar has none
-
findByUrlKey
Finds the subscription of a user to a URL.- Parameters:
urlKey- SHA-256 of the user and the normalized URL- Returns:
- the subscription, or null when none
-
findByUserIdentityId
List<CalendarSubscriptionEntity> findByUserIdentityId(long userIdentityId, org.springframework.data.domain.Pageable pageable) Finds a user's subscriptions.- Parameters:
userIdentityId- identity identifier of the userpageable- the page, whose sort orders them- Returns:
- the subscriptions, never null
-
findDueIds
@Query("SELECT s.id FROM AgendaCalendarSubscription s WHERE s.nextRefreshDate <= :now AND (s.claimedDate IS NULL OR s.claimedDate < :staleBefore) ORDER BY s.nextRefreshDate ASC, s.id ASC") List<Long> findDueIds(@Param("now") Date now, @Param("staleBefore") Date staleBefore, org.springframework.data.domain.Pageable pageable) The subscriptions due for a refresh that nobody holds a live claim on, the one waiting longest first.- Parameters:
now- a subscription whose next refresh is at or before this instant is duestaleBefore- a claim taken strictly before this instant no longer countspageable- the batch- Returns:
- technical identifiers of the due subscriptions
-
claimDue
@Transactional @Modifying(clearAutomatically=true, flushAutomatically=true) @Query("UPDATE AgendaCalendarSubscription s SET s.claimedBy = :node, s.claimedDate = :now WHERE s.id = :id AND s.nextRefreshDate <= :now AND (s.claimedDate IS NULL OR s.claimedDate < :staleBefore)") int claimDue(@Param("id") long id, @Param("node") String node, @Param("now") Date now, @Param("staleBefore") Date staleBefore) The job's claim: lands only on a subscription still due and held by nobody live, so of every node trying at once exactly one sees a row count of one.- Parameters:
id- technical identifier of the subscriptionnode- the claiming nodenow- the claim's stamp; the row must be due at this instantstaleBefore- a claim taken strictly before this instant may be taken over- Returns:
- one when the caller now holds the claim, zero otherwise
-
claim
@Transactional @Modifying(clearAutomatically=true, flushAutomatically=true) @Query("UPDATE AgendaCalendarSubscription s SET s.claimedBy = :node, s.claimedDate = :now WHERE s.id = :id AND (s.claimedDate IS NULL OR s.claimedDate < :staleBefore)") int claim(@Param("id") long id, @Param("node") String node, @Param("now") Date now, @Param("staleBefore") Date staleBefore) The owner's claim, for a refresh asked now: the same as the job's, due or not.- Parameters:
id- technical identifier of the subscriptionnode- the claiming nodenow- the claim's stampstaleBefore- a claim taken strictly before this instant may be taken over- Returns:
- one when the caller now holds the claim, zero otherwise
-
recordSuccess
@Transactional @Modifying(clearAutomatically=true, flushAutomatically=true) @Query("UPDATE AgendaCalendarSubscription s SET s.etag = :etag, s.lastModified = :lastModified, s.contentHash = :contentHash, s.refreshMinutes = :refreshMinutes, s.lastSuccessDate = :attempt, s.lastAttemptDate = :attempt, s.lastError = NULL, s.truncated = :truncated, s.nextRefreshDate = :nextRefreshDate, s.claimedBy = NULL, s.claimedDate = NULL WHERE s.id = :id AND s.claimedBy = :node AND s.urlKey = :urlKey") int recordSuccess(@Param("id") long id, @Param("node") String node, @Param("urlKey") String urlKey, @Param("etag") String etag, @Param("lastModified") String lastModified, @Param("contentHash") String contentHash, @Param("refreshMinutes") Integer refreshMinutes, @Param("attempt") Date attempt, @Param("truncated") boolean truncated, @Param("nextRefreshDate") Date nextRefreshDate) Records a successful refresh and releases the claim — only by the node that holds it, and only while the subscription still points at the URL that was read: an edit of the URL during the refresh leaves the row to the next one.- Parameters:
id- technical identifier of the subscriptionnode- the node holding the claimurlKey- the key of the URL that was readetag- the entity tag readlastModified- the Last-Modified header readcontentHash- digest of the body importedrefreshMinutes- refresh interval the feed advertised, null for noneattempt- when the refresh rantruncated- whether only part of the feed was importednextRefreshDate- when the next refresh is due- Returns:
- one when recorded, zero otherwise
-
recordFailure
@Transactional @Modifying(clearAutomatically=true, flushAutomatically=true) @Query("UPDATE AgendaCalendarSubscription s SET s.lastAttemptDate = :attempt, s.lastError = :lastError, s.nextRefreshDate = :nextRefreshDate, s.claimedBy = NULL, s.claimedDate = NULL WHERE s.id = :id AND s.claimedBy = :node") int recordFailure(@Param("id") long id, @Param("node") String node, @Param("attempt") Date attempt, @Param("lastError") String lastError, @Param("nextRefreshDate") Date nextRefreshDate) Records a failed refresh and releases the claim, only by the node holding it. The last good copy, its validators and its digest are left as they were.- Parameters:
id- technical identifier of the subscriptionnode- the node holding the claimattempt- when the refresh ranlastError- message code of the failurenextRefreshDate- when the next attempt is due- Returns:
- one when recorded, zero otherwise
-
release
@Transactional @Modifying(clearAutomatically=true, flushAutomatically=true) @Query("UPDATE AgendaCalendarSubscription s SET s.claimedBy = NULL, s.claimedDate = NULL WHERE s.id = :id AND s.claimedBy = :node") int release(@Param("id") long id, @Param("node") String node) Releases a claim without recording anything, only by the node holding it.- Parameters:
id- technical identifier of the subscriptionnode- the node holding the claim- Returns:
- one when released, zero otherwise
-
updateUrl
@Transactional @Modifying(clearAutomatically=true, flushAutomatically=true) @Query("UPDATE AgendaCalendarSubscription s SET s.urlEncrypted = :urlEncrypted, s.urlKey = :urlKey, s.etag = NULL, s.lastModified = NULL, s.contentHash = NULL, s.nextRefreshDate = :now WHERE s.id = :id") int updateUrl(@Param("id") long id, @Param("urlEncrypted") String urlEncrypted, @Param("urlKey") String urlKey, @Param("now") Date now) Points a subscription at a new URL and makes it due at once, forgetting the validators and the digest of the previous URL.- Parameters:
id- technical identifier of the subscriptionurlEncrypted- the new URL encryptedurlKey- the key of the new URLnow- the instant it becomes due- Returns:
- one when the row exists, zero otherwise
-