Interface Store
- All Known Implementing Classes:
FileStore
$JENKINS_HOME/batch-control/
(layout in docs/ARCHITECTURE.md section 5). Records are append-only; there is no update or
delete API (retention cleanup is the only deletion path; config
snapshots are working data, not records, and keep only the latest version).
All methods throw UncheckedIOException on I/O failure, except that a failed
save of an XML entity (request, grant, incident, activation) throws StoreWriteException
and leaves nothing behind (D-72b (2), security-35 S-35-03).
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intDefaultmaxScannedof the page queries: the per-request record cap. -
Method Summary
Modifier and TypeMethodDescriptionvoidappendChangeRecord(ChangeRecord record) Appends one change record to the monthly JSONL bucket derived from its timestamp.voidappendRunRecord(RunRecord record) Appends one run record to the monthly JSONL bucket derived from its start time.voidcreateIncident(Incident incident) Persists a freshly opened incident: writesincidents/<id>.xmland appends the monthly index line (incidents/index/YYYY-MM.jsonl, bucket derived from the incident's creation time).booleandeleteActivationState(String jobFullName) Removes the activation state of a job;trueif one existed.deleteClosedEntitiesBefore(Instant cutoff) Retention of the XML entities: deletes closed run requests (not PENDING or APPROVED) and closed grant requests (not PENDING) whose last activity lies beforecutoff, and grants that stopped conferring anything (expiry or revocation) before it.voiddeleteConfigSnapshot(String jobFullName) Removes the config snapshot of a job (after deletion, rename or move).booleandeleteMonth(YearMonth month) Deletes every record bucket of the given month: the runs and changes JSONL files, the diff patches of that month's change records, the incident XMLs listed in that month's index and the index file itself.voidDeletes the typed values of requestid(<id>.values.xml), when the approved run starts or the request ends (D-72b (5), D-74); nothing happens when there are none.static Storeget()The store every caller uses (D-44).grantRevokeRecordsSince(Instant since, Set<String> grantIds, Predicate<? super ChangeRecord> boundary) S-39-03: everyGRANT_REVOKEchange record of a grant ingrantIdswith a time at or aftersince, newest first, for re-ending windows at startup (D-74).booleanhasActivationRequestBy(String userId) Whether at least one stored activation or hold request, in any status, was filed byuserId(D-38b).booleanhasConfigSnapshot(String jobFullName) Whether anything is stored where the config snapshot of a job belongs: a snapshot, or something else in its place (whichloadConfigSnapshot(java.lang.String)refuses).booleanhasRunRequestBy(String userId) Whether at least one stored run request, in any status, was filed byuserId(D-38b).booleanWhether the one-time upgrade seeding markeractivations/.schemaexists.Loads every stored activation request, sorted by id (creation order).Every stored activation state (unordered).listChangeRecords(YearMonth month) Reads every change record of the given month (empty list if the month file is absent).Loads every stored grant request, sorted by id (creation order).Loads every stored grant, sorted by id (creation order).listIncidents(YearMonth month) Loads every incident created in the given month via the monthly index, in index (creation) order.default List<ActivationRequest> Loads the PENDING activation requests only, sorted by id, via the entity index.listOpenActivationRequests(Consumer<String> unreadable) AslistOpenActivationRequests(), and hands the id of every open request left out because its file cannot be read tounreadable.Loads the PENDING grant requests only, sorted by id, via the entity index.default List<RunRequest> Loads the PENDING and APPROVED run requests only, sorted by creation time.listOpenRunRequests(Consumer<String> unreadable) AslistOpenRunRequests(), and hands the id of every open request left out because its file cannot be read tounreadable, for a caller that must act on it once it can be read (an invalidation it would otherwise miss).listRunRecords(YearMonth month) Reads every run record of the given month (empty list if the month file is absent).Loads every stored run request, sorted by creation time.The listing fields of every stored run request, sorted by id, from memory.Every month for which any record bucket exists (runs, changes or incident index), sorted ascending.listStoredMonths(Period period) #33: the stored month buckets (aslistStoredMonths()) that may hold a record whose timestamp lies inperiod, whatever time zone the plugin clock had when the record was written: a bucket is named by the month of the record in the zone of its writer (SPEC 4), so after the controller's zone changed, a record near a month boundary sits in the neighbouring month's bucket.Loads an activation request by id, or returnsnullif it does not exist.loadActivationState(String jobFullName) The stored activation state of a job, ornullif none exists.loadConfigSnapshot(String jobFullName) The stored config snapshot text of a job, ornullif none exists.Loads a grant by id, or returnsnullif it does not exist.Loads a grant request by id, or returnsnullif it does not exist.loadIncident(String id) Loads an incident by id, or returnsnullif it does not exist.loadRunRequest(String id) Loads a request by id from<id>.xml, or returnsnullif it does not exist.The typed values of requestidfrom<id>.values.xml(D-74), ornullwhen there is no values file (the request has no parameters, or its values were deleted when its run started or it ended).voidWrites the upgrade seeding markeractivations/.schema(atomically).pageChangeRecords(Collection<YearMonth> months, Period period, Predicate<? super ChangeRecord> filter, int offset, int limit, int maxScanned) pageChangeRecords(Collection<YearMonth> months, Predicate<? super ChangeRecord> filter, int offset, int limit, int maxScanned) AspageRunRecords(java.util.Collection<java.time.YearMonth>, io.jenkins.plugins.batchcontrol.store.Period, java.util.function.Predicate<? super io.jenkins.plugins.batchcontrol.model.RunRecord>, int, int, int)for change records (time, then id, newest first), over all ofmonths.pageIncidents(Collection<YearMonth> months, Period period, Predicate<? super IncidentSummary> indexFilter, Predicate<? super Incident> filter, int offset, int limit, int maxScanned) AspageRunRecords(java.util.Collection<java.time.YearMonth>, io.jenkins.plugins.batchcontrol.store.Period, java.util.function.Predicate<? super io.jenkins.plugins.batchcontrol.model.RunRecord>, int, int, int)for incidents, walking the monthly index newest first (creation time, then id); every index line read counts againstmaxScanned.pageRunRecords(Collection<YearMonth> months, Period period, Predicate<? super RunRecord> filter, int offset, int limit, int maxScanned) One page of the run records ofmonthsthat matchfilter, newest first (start time, then run id).runMonthStats(YearMonth month) Run counters of one month, maintained incrementally from the bucket.voidsaveActivationRequest(ActivationRequest request) Writes (or rewrites, on a status transition) the activation request XML atomically.voidWrites the activation state of a job atomically toactivations/<PathCodec-encoded full name>.xml; the file name comes fromActivationState.getJobFullName().voidsaveConfigSnapshot(String jobFullName, String configXml) Stores the latest config.xml snapshot of a job (diff baseline; only the latest version is kept, ARCHITECTURE section 5).voidWrites (or rewrites, on revocation) the grant XML atomically.voidsaveGrantRequest(GrantRequest request) Writes (or rewrites, on a status transition) the grant request XML atomically.voidsaveIncident(Incident incident) Rewrites an existing incident's XML atomically (handling transitions, links).voidsaveNewRunRequest(RunRequest request, List<ParameterValue> values) Stores a new request (D-72, D-74):<id>.xml, then its typed values in<id>.values.xmlwhen there are any (a request without parameters has no values file).voidsaveRunRequest(RunRequest request) Writes (or rewrites, on a status transition) the request XML<id>.xmlatomically.voidwarmUp()Prepares derived in-memory data (indexes, caches) ahead of the first request so no later save pays for it.
-
Field Details
-
MAX_SCANNED_RECORDS
static final int MAX_SCANNED_RECORDSDefaultmaxScannedof the page queries: the per-request record cap.- See Also:
-
-
Method Details
-
get
The store every caller uses (D-44). This is the one place that names the implementation, so a database-backed store (D-11) replaces this line and nothing else. -
warmUp
void warmUp()Prepares derived in-memory data (indexes, caches) ahead of the first request so no later save pays for it. Called once at startup. -
saveRunRequest
Writes (or rewrites, on a status transition) the request XML<id>.xmlatomically. Never touches the request's typed values (D-74).- Throws:
StoreWriteException- when it cannot be written; nothing is left behind
-
saveNewRunRequest
Stores a new request (D-72, D-74):<id>.xml, then its typed values in<id>.values.xmlwhen there are any (a request without parameters has no values file). Each file is written atomically; when either cannot be written, neither is left behind.- Throws:
StoreWriteException- when it cannot be stored; nothing is left behind
-
loadRunRequest
Loads a request by id from<id>.xml, or returnsnullif it does not exist. Its typed values are never read here (D-74): this is the read for screens, badges, listings, listeners and periodic work. -
loadRunRequestValues
The typed values of requestidfrom<id>.values.xml(D-74), ornullwhen there is no values file (the request has no parameters, or its values were deleted when its run started or it ended). Only for approving, submitting, recovering and disposing of a request. An element that could not be loaded may benull.- Throws:
UncheckedIOException- when the file exists but cannot be read
-
deleteRunRequestValues
Deletes the typed values of requestid(<id>.values.xml), when the approved run starts or the request ends (D-72b (5), D-74); nothing happens when there are none. -
listRunRequests
List<RunRequest> listRunRequests()Loads every stored run request, sorted by creation time. A file that cannot be read (corrupt, or not readable at all) is left out with a warning, so one such file never breaks a listing. -
listOpenRunRequests
Loads the PENDING and APPROVED run requests only, sorted by creation time. Served from the in-memory entity index, so closed requests are never read; this is what the per-minute expiry work, startup recovery and rename invalidation iterate.An open request whose file cannot be read (permission, I/O error or damaged content) is left out with a warning naming it, so it is never expired, approved, run, recovered or counted while unreadable, and it never breaks the listing for the others. Its index entry is kept, so the next listing reads it again and it is back as soon as it can be read.
-
listOpenRunRequests
AslistOpenRunRequests(), and hands the id of every open request left out because its file cannot be read tounreadable, for a caller that must act on it once it can be read (an invalidation it would otherwise miss). -
listRunRequestSummaries
List<RequestSummary> listRunRequestSummaries()The listing fields of every stored run request, sorted by id, from memory. A listing filters and pages on these and loads only the XML of the rows it renders. -
hasRunRequestBy
Whether at least one stored run request, in any status, was filed byuserId(D-38b). Answered from the in-memory entity index; no request file and no item is read. -
saveGrantRequest
Writes (or rewrites, on a status transition) the grant request XML atomically. -
loadGrantRequest
Loads a grant request by id, or returnsnullif it does not exist. -
listGrantRequests
List<GrantRequest> listGrantRequests()Loads every stored grant request, sorted by id (creation order). -
listOpenGrantRequests
List<GrantRequest> listOpenGrantRequests()Loads the PENDING grant requests only, sorted by id, via the entity index. An open request whose file cannot be read is left out with a warning and its index entry kept, as forlistOpenRunRequests(). -
saveGrant
Writes (or rewrites, on revocation) the grant XML atomically. -
loadGrant
Loads a grant by id, or returnsnullif it does not exist. -
listGrants
Loads every stored grant, sorted by id (creation order). A file that cannot be read (corrupt, or not readable at all) is left out with a warning: that grant confers nothing, and the permission checks of everyone else keep working. -
saveActivationRequest
Writes (or rewrites, on a status transition) the activation request XML atomically. -
loadActivationRequest
Loads an activation request by id, or returnsnullif it does not exist. -
listActivationRequests
List<ActivationRequest> listActivationRequests()Loads every stored activation request, sorted by id (creation order). -
listOpenActivationRequests
Loads the PENDING activation requests only, sorted by id, via the entity index. An open request whose file cannot be read is left out with a warning and its index entry kept, as forlistOpenRunRequests(). -
listOpenActivationRequests
AslistOpenActivationRequests(), and hands the id of every open request left out because its file cannot be read tounreadable. -
hasActivationRequestBy
Whether at least one stored activation or hold request, in any status, was filed byuserId(D-38b). Answered from the in-memory entity index. -
saveActivationState
Writes the activation state of a job atomically toactivations/<PathCodec-encoded full name>.xml; the file name comes fromActivationState.getJobFullName(). -
loadActivationState
The stored activation state of a job, ornullif none exists. -
listActivationStates
List<ActivationState> listActivationStates()Every stored activation state (unordered). -
deleteActivationState
Removes the activation state of a job;trueif one existed. -
isActivationSchemaMarked
boolean isActivationSchemaMarked()Whether the one-time upgrade seeding markeractivations/.schemaexists. -
markActivationSchema
void markActivationSchema()Writes the upgrade seeding markeractivations/.schema(atomically). -
saveConfigSnapshot
Stores the latest config.xml snapshot of a job (diff baseline; only the latest version is kept, ARCHITECTURE section 5). -
loadConfigSnapshot
The stored config snapshot text of a job, ornullif none exists.- Throws:
UncheckedIOException- when a snapshot exists but cannot be read, also when something other than a file is in its place
-
hasConfigSnapshot
Whether anything is stored where the config snapshot of a job belongs: a snapshot, or something else in its place (whichloadConfigSnapshot(java.lang.String)refuses). Nothing is read, so seeding the missing snapshots of every item costs one file system lookup per item. -
deleteConfigSnapshot
Removes the config snapshot of a job (after deletion, rename or move). -
appendRunRecord
Appends one run record to the monthly JSONL bucket derived from its start time. The line carriesappendedAt(D-81): the record's ownRunRecord.getAppendedAt()when the caller set it, else the plugin clock's instant of this append. -
listRunRecords
Reads every run record of the given month (empty list if the month file is absent). -
pageRunRecords
RecordPage<RunRecord> pageRunRecords(Collection<YearMonth> months, Period period, Predicate<? super RunRecord> filter, int offset, int limit, int maxScanned) One page of the run records ofmonthsthat matchfilter, newest first (start time, then run id). Reads newest first and stops aftermaxScannedrecords, so the cost of a page load is bounded whatever a month holds; only records whose start time lies insideperiodcount towardmaxScanned(security-10 S-03).- Parameters:
offset- matches to skip (page index times page size)limit- rows to returnmaxScanned- records to read at most; seeMAX_SCANNED_RECORDS
-
runMonthStats
Run counters of one month, maintained incrementally from the bucket. -
appendChangeRecord
Appends one change record to the monthly JSONL bucket derived from its timestamp. -
listChangeRecords
Reads every change record of the given month (empty list if the month file is absent). -
pageChangeRecords
RecordPage<ChangeRecord> pageChangeRecords(Collection<YearMonth> months, Predicate<? super ChangeRecord> filter, int offset, int limit, int maxScanned) AspageRunRecords(java.util.Collection<java.time.YearMonth>, io.jenkins.plugins.batchcontrol.store.Period, java.util.function.Predicate<? super io.jenkins.plugins.batchcontrol.model.RunRecord>, int, int, int)for change records (time, then id, newest first), over all ofmonths. Diff patches are read for the returned rows only. -
pageChangeRecords
RecordPage<ChangeRecord> pageChangeRecords(Collection<YearMonth> months, Period period, Predicate<? super ChangeRecord> filter, int offset, int limit, int maxScanned) -
grantRevokeRecordsSince
RecordPage<ChangeRecord> grantRevokeRecordsSince(Instant since, Set<String> grantIds, Predicate<? super ChangeRecord> boundary) S-39-03: everyGRANT_REVOKEchange record of a grant ingrantIdswith a time at or aftersince, newest first, for re-ending windows at startup (D-74). Bounded by time, not by a record count: the change log is read back only to the first record appended beforesince, and every record after it is read, however many there are. The page is truncated when that could not be done completely.Reading also stops at the first record before
sincethatboundaryaccepts (T-SEC-109): the caller's statement that no line appended before that record can be the end of any window ingrantIds, so the append-order slack is not read past it.- Throws:
UncheckedIOException- when the change log cannot be read
-
createIncident
Persists a freshly opened incident: writesincidents/<id>.xmland appends the monthly index line (incidents/index/YYYY-MM.jsonl, bucket derived from the incident's creation time). -
saveIncident
Rewrites an existing incident's XML atomically (handling transitions, links). -
loadIncident
Loads an incident by id, or returnsnullif it does not exist. -
listIncidents
Loads every incident created in the given month via the monthly index, in index (creation) order. Index lines whose XML has been deleted are skipped. -
pageIncidents
RecordPage<Incident> pageIncidents(Collection<YearMonth> months, Period period, Predicate<? super IncidentSummary> indexFilter, Predicate<? super Incident> filter, int offset, int limit, int maxScanned) AspageRunRecords(java.util.Collection<java.time.YearMonth>, io.jenkins.plugins.batchcontrol.store.Period, java.util.function.Predicate<? super io.jenkins.plugins.batchcontrol.model.RunRecord>, int, int, int)for incidents, walking the monthly index newest first (creation time, then id); every index line read counts againstmaxScanned.indexFilteris tested on the index line and an incident's XML is loaded only when it passes (security-10 S-06);filterthen sees the loaded incident. -
listStoredMonths
Every month for which any record bucket exists (runs, changes or incident index), sorted ascending. Used by retention cleanup. -
listStoredMonths
#33: the stored month buckets (aslistStoredMonths()) that may hold a record whose timestamp lies inperiod, whatever time zone the plugin clock had when the record was written: a bucket is named by the month of the record in the zone of its writer (SPEC 4), so after the controller's zone changed, a record near a month boundary sits in the neighbouring month's bucket. A date-range query reads these buckets and keeps the records insideperiod; existing files need no migration. A bucket outside the period's own months is included only when the period comes within the largest zone offset (18 hours) of it. -
deleteMonth
Deletes every record bucket of the given month: the runs and changes JSONL files, the diff patches of that month's change records, the incident XMLs listed in that month's index and the index file itself. This is the ONLY deletion path of the store (SPEC item 4: append-only apart from retention cleanup).- Returns:
trueif anything was deleted
-
deleteClosedEntitiesBefore
Retention of the XML entities: deletes closed run requests (not PENDING or APPROVED) and closed grant requests (not PENDING) whose last activity lies beforecutoff, and grants that stopped conferring anything (expiry or revocation) before it. A grant request is kept while a grant issued from it is kept. Each file is deleted under its own lock, so no store lock is held for longer than one deletion.
-