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.findByOwnerIdentityId(long ownerIdentityId, org.springframework.data.domain.Pageable pageable) Finds the subscriptions of an owner: a user's personal ones, or a space's (EXO-90373).findByUrlKey(String urlKey) Finds the subscription of an owner to a URL.findCalendarIdsByOwnerIdentityId(long ownerIdentityId, org.springframework.data.domain.Pageable pageable) The calendars an owner's subscriptions fill, so that a space's subscribed calendars can take the space's colour (EXO-90373).findCalendarIdsByOwnerIdentityIdIn(Collection<Long> ownerIdentityIds, org.springframework.data.domain.Pageable pageable) The calendars the subscriptions of several owners fill, in one statement (EXO-90373).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.intforgetContent(long id) Forgets the validators and the digest of the last read, so that the next read that answers imports again whatever it answers — once the imported events were purged (EXO-90373).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 an owner to a URL.- Parameters:
urlKey- SHA-256 of the owner and the normalized URL- Returns:
- the subscription, or null when none
-
findByOwnerIdentityId
List<CalendarSubscriptionEntity> findByOwnerIdentityId(long ownerIdentityId, org.springframework.data.domain.Pageable pageable) Finds the subscriptions of an owner: a user's personal ones, or a space's (EXO-90373).- Parameters:
ownerIdentityId- identity identifier of the ownerpageable- the page, whose sort orders them- Returns:
- the subscriptions, never null
-
findCalendarIdsByOwnerIdentityId
@Query("SELECT s.calendarId FROM AgendaCalendarSubscription s WHERE s.ownerIdentityId = :ownerIdentityId ORDER BY s.id ASC") List<Long> findCalendarIdsByOwnerIdentityId(@Param("ownerIdentityId") long ownerIdentityId, org.springframework.data.domain.Pageable pageable) The calendars an owner's subscriptions fill, so that a space's subscribed calendars can take the space's colour (EXO-90373).- Parameters:
ownerIdentityId- identity identifier of the ownerpageable- the page- Returns:
- technical identifiers of the calendars, the oldest subscription first
-
findCalendarIdsByOwnerIdentityIdIn
@Query("SELECT s.calendarId FROM AgendaCalendarSubscription s WHERE s.ownerIdentityId IN :ownerIdentityIds ORDER BY s.id ASC") List<Long> findCalendarIdsByOwnerIdentityIdIn(@Param("ownerIdentityIds") Collection<Long> ownerIdentityIds, org.springframework.data.domain.Pageable pageable) The calendars the subscriptions of several owners fill, in one statement (EXO-90373).The per-owner query above is asked once per owner, which a listing cannot afford: a member's agenda reads their own identity and every space they belong to, and the availability reader repeats that for every attendee of a meeting being scheduled. This is the same projection over a set.
- Parameters:
ownerIdentityIds- identity identifiers of the owners, never empty (an emptyINlist is not valid JPQL)pageable- the page- Returns:
- technical identifiers of the calendars, the oldest subscription first
-
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
-
forgetContent
@Transactional @Modifying(clearAutomatically=true, flushAutomatically=true) @Query("UPDATE AgendaCalendarSubscription s SET s.etag = NULL, s.lastModified = NULL, s.contentHash = NULL WHERE s.id = :id") int forgetContent(@Param("id") long id) Forgets the validators and the digest of the last read, so that the next read that answers imports again whatever it answers — once the imported events were purged (EXO-90373).- Parameters:
id- technical identifier of the subscription- Returns:
- one when the row exists, 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
-