Class AdminWebService
SystemMonitorController DWR calls
(getCacheStatus, clearAllCaches, clearCache,
getHibernateStatus) with structured JSON-returning endpoints.
All endpoints require GROUP_ADMIN authority.
Note: the legacy CacheMonitor.enableStatistics /
disableStatistics entry points are stubs on the current post-EhCache-2
build (see CacheMonitorImpl) and are not exposed here. The legacy
resetHibernateStatus is also not exposed pending a UX decision on
whether the admin panel needs a Hibernate-stats reset button at all.
- Author:
- phase 3 admin-panel wiring
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classResponse shape forgetCurationStatus().static classstatic classstatic classstatic classstatic classDry-run response.static classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classBody shape forrefreshOntology(String, boolean)returns.static classstatic classstatic final classWire shape forreindexSearchIndices(String): list of entity classes whose reindex was queued.static classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classstatic classPayload ofPOST /admin/tasks/platform-reports: the id of the task that was queued.static classstatic classstatic classstatic classstatic classstatic class -
Constructor Summary
ConstructorsConstructorDescriptionAdminWebService(org.springframework.cache.CacheManager cacheManager, SessionFactory sessionFactory, TaskRunningService taskRunningService, org.springframework.security.core.session.SessionRegistry sessionRegistry, List<OntologyService> ontologies, OntologyService ontologyFacade, DataSource dataSource, UserManager userManager, AnnotationSetService annotationSetService, TicketService ticketService, TaxonArgService taxonArgService, BlacklistedEntityService blacklistedEntityService, ExternalDatabaseReadService externalDatabaseReadService, GeoScrapeService geoScrapeService, IndexerService indexerService, PlatformArgService platformArgService, ArrayDesignReportService arrayDesignReportService, CurationLockService curationLockService) -
Method Summary
Modifier and TypeMethodDescriptionjakarta.ws.rs.core.ResponseAdds a single blacklist entry.jakarta.ws.rs.core.ResponseapplyObsoleteTermCorrections(Boolean dryRun, List<String> uris, Integer timeoutSeconds) Rewrite annotations that use an obsolete ontology term to the successor its ontology asserts.jakarta.ws.rs.core.ResponseClears every registered cache.jakarta.ws.rs.core.ResponseclearCache(String cacheName) Clears a single named cache.jakarta.ws.rs.core.ResponseCreate a new active user with a server-generated one-time temporary password.jakarta.ws.rs.core.ResponsedeleteBlacklistEntry(String accession) Removes a blacklist entry by its accession.jakarta.ws.rs.core.ResponsedeleteUser(String username) Soft delete — marks the account as deleted, disables it, and preserves the row so dependent references (ACL sids, audit-event authorship FKs) don't dangle.Every advisory curation lock currently held, corpus-wide.Lists the registered Spring caches by name.Out-of-process liveness probe for the gemma-curation-agents Python service.Snapshot of the annotation-set -> ticket lifecycle: per-roleAnnotationSetcounts in the recent windows, open-ticket counts byTicketType, distinct agent run id count, and latest-createdAt timestamp.jakarta.ws.rs.core.ResponseHikariCP pool snapshot.Returns a structured snapshot of Hibernate statistics.getJobs()Aggregated admin view of the in-memory background task queue.Deprecated.Reads the watermark written by the deprecated in-Gemma scrape.getObsoleteTerms(Integer timeoutSeconds) In-application port ofFindObsoleteTermsCli: which obsolete ontology terms do Gemma's annotations still use, and what does each owning ontology say should replace them.getOntologies(boolean includeTermCount) Per-ontology load status.Per-@Indexed-entity Hibernate Search 7 index status.Authenticated session listing.Process-level memory / GC / thread / load snapshot.getUsers(boolean includeDeleted) Admin user listing.Scrape GEO record metadata by accession without importing into Gemma.jakarta.ws.rs.core.ResponseBatch GEO accession import.listBlacklistEntries(int limit, int offset) Lists current blacklist entries.patchUser(String username, AdminWebService.UpdateUserRequest req) Partial update — toggle the enabled flag (lock/unlock) and/or admin role.jakarta.ws.rs.core.ResponserebuildOntologySlim(String name) Rebuild the slim-cache OWL for an ontology that supports it (currently CHEBI only).jakarta.ws.rs.core.ResponserefreshOntology(String name, boolean forceIndexing) Refresh a single ontology in-process: re-runinitialize(forceLoad=true)on a background thread so the source is re-fetched, the model is rebuilt, and the in-memory state is atomically swapped without a container restart.regeneratePlatformReport(PlatformArg<?> platformArg) Regenerate the cached report for ONE platform, synchronously.jakarta.ws.rs.core.ResponsereindexSearchIndices(String entity) Trigger a Hibernate Search 7 mass-reindex for one entity (or all of them).jakarta.ws.rs.core.ResponseResets the Hibernate statistics counters to zero.resetUserPassword(String username) Administrative password reset — set a user's password to a fresh server-generated one-time temporary password.jakarta.ws.rs.core.ResponseDeprecated.The curation agent scrapes GEO itself (scrape_geo_and_open_triage.py) and opens its own triage ticket.jakarta.ws.rs.core.ResponsesubmitMultifunctionalityRecompute(TaxonArg<?> taxonArg) Async port ofMultifunctionalityCli: recompute per-gene multifunctionality scores for a single taxon.jakarta.ws.rs.core.ResponseSubmit an async regeneration of the cached reports for EVERY platform.
-
Constructor Details
-
AdminWebService
@Autowired public AdminWebService(org.springframework.cache.CacheManager cacheManager, SessionFactory sessionFactory, TaskRunningService taskRunningService, org.springframework.security.core.session.SessionRegistry sessionRegistry, List<OntologyService> ontologies, OntologyService ontologyFacade, DataSource dataSource, UserManager userManager, AnnotationSetService annotationSetService, TicketService ticketService, TaxonArgService taxonArgService, BlacklistedEntityService blacklistedEntityService, ExternalDatabaseReadService externalDatabaseReadService, GeoScrapeService geoScrapeService, IndexerService indexerService, PlatformArgService platformArgService, ArrayDesignReportService arrayDesignReportService, CurationLockService curationLockService)
-
-
Method Details
-
getCaches
@GET @Path("/caches") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.CacheListResponse> getCaches()Lists the registered Spring caches by name. Replaces the HTML-returning legacySystemMonitorController.getCacheStatus(). -
clearAllCaches
@DELETE @Path("/caches") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response clearAllCaches()Clears every registered cache. Replaces the legacySystemMonitorController.clearAllCaches()DWR call. -
clearCache
@DELETE @Path("/caches/{cacheName}") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response clearCache(@PathParam("cacheName") String cacheName) Clears a single named cache. Replaces the legacySystemMonitorController.clearCache(name)DWR call. -
getHibernateStats
@GET @Path("/hibernate/stats") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.HibernateStatsResponse> getHibernateStats()Returns a structured snapshot of Hibernate statistics. Replaces the HTML-returning legacySystemMonitorController.getHibernateStatus(). -
resetHibernateStats
@POST @Path("/hibernate/reset") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response resetHibernateStats()Resets the Hibernate statistics counters to zero. Replaces the legacySystemMonitorController.resetHibernateStatus()DWR call. -
getJobs
@GET @Path("/jobs") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.JobsListResponse> getJobs()Aggregated admin view of the in-memory background task queue. Returns the per-taskTaskStatusValueObjectsnapshots plus counts of tasks in each status. The underlying task store is in-memory only and tasks are evicted ~10 minutes after completion. -
importGeoBatch
@POST @Path("/tasks/import-geo") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response importGeoBatch(@Nullable AdminWebService.ImportGeoBatchRequest body) Batch GEO accession import. Ports the bulk path ofubic.gemma.apps.LoadExpressionDataCli: iterate the accession list and submit oneExpressionExperimentLoadTaskCommandper accession, returning the resulting task-id list so the caller can poll each one through/tasks/{taskId}.The optional flags on the request body (loadPlatformOnly, suppressMatching, etc.) are applied to every accession in the batch. For one-off imports use
POST /datasets/import. -
submitMultifunctionalityRecompute
@POST @Path("/tasks/multifunctionality") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response submitMultifunctionalityRecompute(@QueryParam("taxon") TaxonArg<?> taxonArg) Async port ofMultifunctionalityCli: recompute per-gene multifunctionality scores for a single taxon. Submits aMultifunctionalityTaskCommand; the caller polls/tasks/{taskId}for completion.Taxon identifier may be the common name (e.g.
human), scientific name, NCBI ID, or Gemma taxon ID — same shape as elsewhere in the REST API (TaxonArg.valueOf(String)). -
regeneratePlatformReport
@POST @Path("/platforms/{platform}/report") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public ResponseDataObject<ArrayDesignValueObject> regeneratePlatformReport(@PathParam("platform") PlatformArg<?> platformArg) Regenerate the cached report for ONE platform, synchronously.The report holds the per-platform element / sequence / alignment / gene counts that
GET /platformsserves asnumberOfGenesandnumberOfMappedElements. They are never computed per request — counting distinct genes for one large platform measures ~1.7s against production — so they are read from a file that something has to write. On a production node nothing does: the Quartz trigger that refreshes them monthly (SchedulerConfig.arrayDesignReportTrigger) is gated on theschedulerprofile, which production does not run.Synchronous because a single platform is a couple of seconds and the caller wants the new numbers back. Use
POST /admin/tasks/platform-reportsfor the whole corpus. -
submitPlatformReportsRegeneration
@POST @Path("/tasks/platform-reports") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response submitPlatformReportsRegeneration()Submit an async regeneration of the cached reports for EVERY platform.The bulk counterpart of
regeneratePlatformReport(PlatformArg); the corpus-wide run is far too long to hold a request open. Mirrors the other admin task endpoints: returns 202 with the job id, poll/tasks/{taskId}. -
getSearchIndices
@GET @Path("/search/indices") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.SearchIndicesResponse> getSearchIndices()Per-@Indexed-entity Hibernate Search 7 index status. Replaces the legacy gemma-webindexer.jsflow that pinged the indexer directly to discover what was indexable. The new UI uses this read-only view to surface index sizes / on-disk paths; rebuild actions stay in the CLI (IndexGemmaCLI). -
reindexSearchIndices
@POST @Path("/search/indices") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response reindexSearchIndices(@QueryParam("entity") @Nullable String entity) Trigger a Hibernate Search 7 mass-reindex for one entity (or all of them).Destructive: HS 7's mass-indexer purges the existing on-disk Lucene index for the entity before rebuilding (
purgeAllOnStart(true)). Runs asynchronously on a background thread; this endpoint returns202 Acceptedas soon as the work is queued. UsegetSearchIndices()to monitor doc-count progress and thereindexStatusfield per entity.Concurrent reindex requests are rejected with
409 Conflict— the mass-indexer is single-flight per JVM so two parallel calls would purge each other's just-written segments.- Parameters:
entity- user-facing entity name (one ofgenes,datasets,platforms,bibliographicReferences,probes,sequences,datasetGroups,geneSets); or omit to reindex all indexable roots sequentially.
-
getSystem
@GET @Path("/system") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.SystemSnapshotResponse> getSystem()Process-level memory / GC / thread / load snapshot. Complements the anonymous/infoendpoint (build + JVM identity + OS identity) with the live, admin-only resource numbers the legacysystemStats.jsphand-rolled. Single read; no historical series — that's what/metricsis for. -
getSessions
@GET @Path("/sessions") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.SessionsResponse> getSessions()Authenticated session listing. The legacyactiveUsers.jspsurfaced a count viaSecurityController.getAuthenticatedUserCountand a JSP comment promising a table of users that was never built. This endpoint delivers that table: distinct authenticated principals (across both browser and basic-auth callers), each with the count of currently-tracked sessions, the most recent request time, and any granted GROUP_* authorities. -
getAllCurationLocks
@GET @Path("/curation-locks") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<List<AdminWebService.CurationLockValueObject>> getAllCurationLocks()Every advisory curation lock currently held, corpus-wide. Exists for an admin release panel: the per-dataset lock surface (seeDatasetsWebService's/curation/lock*routes) answers "is this one dataset locked", scoped to what the caller can already read, but there was no way to ask "what is locked right now" without already holding the list of dataset ids to check — which is exactly the thing an admin deciding whether to force-release something does not have.Unlike the per-dataset routes, this bypasses per-dataset ACL by construction — it names datasets the caller may not otherwise be able to read — so it is
GROUP_ADMIN-gated like the rest of this resource, notisAuthenticated()like the scoped ones.CURATION_LOCKholds one row per currently-locked dataset, not one per dataset in the corpus, so the answer is bounded by how much curation/agent activity is in flight right now. -
getOntologies
@GET @Path("/ontologies") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.OntologiesResponse> getOntologies(@QueryParam("includeTermCount") @DefaultValue("false") boolean includeTermCount) Per-ontology load status. Enumerates everyOntologyServicebean (Mondo, PATO, CHEBI, Uberon, CellType, the unified TDB, etc.) and reports each one's enable / load / initialization-thread state plus its inference and search settings. Term counts are skipped by default becausegetAllURIs()can be expensive on large ontologies; opt in with?includeTermCount=true. -
refreshOntology
@POST @Path("/ontologies/{name}/refresh") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response refreshOntology(@PathParam("name") String name, @QueryParam("forceIndexing") @DefaultValue("false") boolean forceIndexing) Refresh a single ontology in-process: re-runinitialize(forceLoad=true)on a background thread so the source is re-fetched, the model is rebuilt, and the in-memory state is atomically swapped without a container restart. Returns 202 immediately; the caller pollsgetOntologies(boolean)to watch theinitializingflag flip back to false.Matches the ontology through
OntologyServiceResolver, which accepts the well-known abbreviation (CLO, HPO, TGEMO, …), theidentifier, the implementing class name, or thedc:title, ignoring case and punctuation. Every ontology is therefore refreshable, including the ones whosedc:titleis absent or contains spaces. 404 if no bean matches, 409 if a refresh is already in flight on that bean.For the slim-CHEBI path the refresh re-runs the
loadModeloverride, which checks the seed-hash sidecar and re-extracts the slim if the corpus has drifted. -
rebuildOntologySlim
@POST @Path("/ontologies/{name}/rebuild-slim") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response rebuildOntologySlim(@PathParam("name") String name) Rebuild the slim-cache OWL for an ontology that supports it (currently CHEBI only). The service must already be loaded so the extractor can read the on-disk source. Returns 202 immediately and the extraction runs on a daemon thread; pollgetOntologies(boolean)to watch the result land (a fresh slim file at${ontology.cache.dir}/ontology/chebiOntology-slim.owl).Memory note: STAR module extraction via OWL-API holds the full CHEBI in heap during the run (~3 GB peak after this commit's source-release fix). Invoke on a host with that headroom, and not during another resource-intensive operation.
-
getObsoleteTerms
@GET @Path("/ontologies/obsolete-terms") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<List<ObsoleteTermUsage>> getObsoleteTerms(@QueryParam("timeoutSeconds") @DefaultValue("120") Integer timeoutSeconds) In-application port ofFindObsoleteTermsCli: which obsolete ontology terms do Gemma's annotations still use, and what does each owning ontology say should replace them.The CLI existed because the check needed ontologies in memory and a CLI had to load them itself — which is why it refuses to run unless
load.ontologies=falseand spends its first stretch warming up. A running application already holds them, so the only work left here is one grouped query over CHARACTERISTIC plus a lookup per distinct URI.Read-only. Correcting the terms is a separate, deliberate action: see
autoCorrectableon each row for whether a correction could be derived from the ontology at all. -
applyObsoleteTermCorrections
@POST @Path("/ontologies/obsolete-terms/apply") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response applyObsoleteTermCorrections(@QueryParam("dryRun") @DefaultValue("true") Boolean dryRun, @QueryParam("uris") List<String> uris, @QueryParam("timeoutSeconds") @DefaultValue("600") Integer timeoutSeconds) Rewrite annotations that use an obsolete ontology term to the successor its ontology asserts.Dry run unless
dryRun=falseis passed explicitly. The default is the safe one because this writes to production annotations, and a dry run returns the counts a live run would produce, so there is no reason to skip the rehearsal.Only
autoCorrectableterms are touched — those whose replacement was derived from the ontology rather than decided by a person. Terms offering onlyoboInOwl:considercandidates are never corrected here; seeGET /admin/ontologies/obsolete-termsfor what they are and why. -
getDbPool
@GET @Path("/db/pool") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response getDbPool()HikariCP pool snapshot. Reports the live connection census plus the configured upper bound, so the admin panel can show "12 / 50 active" at a glance and surface "threads awaiting" when the pool is saturated. -
getCurationAgentHealth
@GET @Path("/curation-agent/health") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public ResponseDataObject<AdminWebService.CurationAgentHealthResponse> getCurationAgentHealth()Out-of-process liveness probe for the gemma-curation-agents Python service. Configured viagemma.curationAgent.healthUrl(unset = endpoint reports "not configured" with 200, so the admin UI can render a neutral pill instead of an alarming red one). -
grabGeoRecords
@POST @Path("/tasks/geo-grab") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public ResponseDataObject<AdminWebService.GeoGrabResponse> grabGeoRecords(AdminWebService.GeoGrabRequest req) Scrape GEO record metadata by accession without importing into Gemma. Port ofGeoGrabberCli's -e / --acc mode. Synchronous: NCBI E-utilities responses are sub-second per accession in the typical case, so the curation-UI can call this on-demand to preview a GEO record before triggering a full import.Returns one
AdminWebService.GeoRecordValueObjectper requested accession that GEO successfully returns; accessions GEO doesn't know about are silently dropped (matching the CLI's behavior). -
submitGeoScrape
@POST @Deprecated @Path("/tasks/geo-scrape") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response submitGeoScrape(@Nullable AdminWebService.GeoScrapeRequest body) Deprecated.The curation agent scrapes GEO itself (scrape_geo_and_open_triage.py) and opens its own triage ticket. Still functional; seeGeoScrapeServicefor what an agent-side replacement has to reproduce -- the preboarded rows, the watermark, and ONE batch ticket. -
getLastGeoScrape
@GET @Deprecated @Path("/geo-scrape/last") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.GeoScrapeWatermarkValueObject> getLastGeoScrape()Deprecated.Reads the watermark written by the deprecated in-Gemma scrape. An agent that scrapes on its own side is the author of its own run records; this only ever sees runs Gemma performed. -
getCurationStatus
@GET @Path("/curation-status") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public ResponseDataObject<AdminWebService.CurationStatusResponse> getCurationStatus()Snapshot of the annotation-set -> ticket lifecycle: per-roleAnnotationSetcounts in the recent windows, open-ticket counts byTicketType, distinct agent run id count, and latest-createdAt timestamp.Backs the curation-UI "what's the Python agent doing right now" indicator. Counts are computed with bounded aggregates against the ANNOTATION_SET and TICKET tables — no per-row fetch.
-
getUsers
@GET @Path("/users") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.UsersListResponse> getUsers(@QueryParam("includeDeleted") @DefaultValue("false") boolean includeDeleted) Admin user listing. Soft-deleted users (DELETED_AT IS NOT NULL) are hidden by default; pass?includeDeleted=trueto surface them. -
createUser
@POST @Path("/users") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response createUser(AdminWebService.CreateUserRequest req) Create a new active user with a server-generated one-time temporary password. The plaintext password is returned in the response body — pass it to the new user out-of-band. It is not stored anywhere recoverable; if lost, an admin must reset it. -
patchUser
@PATCH @Path("/users/{username}") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.UserValueObject> patchUser(@PathParam("username") String username, AdminWebService.UpdateUserRequest req) Partial update — toggle the enabled flag (lock/unlock) and/or admin role. Other User fields (email, password, name) are not touched by this endpoint; those go through the user-profile flow. -
resetUserPassword
@POST @Path("/users/{username}/password") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public ResponseDataObject<AdminWebService.ResetPasswordResponse> resetUserPassword(@PathParam("username") String username) Administrative password reset — set a user's password to a fresh server-generated one-time temporary password. Does not require the user's current password (this is the recovery path for a locked-out or forgetful user). The plaintext temp password is returned once; pass it to the user out-of-band. The user should then change it via the self-servicePUT /users/me/passwordflow. Leaves the account enabled; distinct from the email-confirmation reset flow. -
deleteUser
@DELETE @Path("/users/{username}") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response deleteUser(@PathParam("username") String username) Soft delete — marks the account as deleted, disables it, and preserves the row so dependent references (ACL sids, audit-event authorship FKs) don't dangle. Hard delete is intentionally not exposed via REST. -
addBlacklistEntry
@POST @Path("/blacklist") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response addBlacklistEntry(@Nullable AdminWebService.BlacklistRequest body) Adds a single blacklist entry. Port of the-accession/-reasonarm ofBlacklistCli.doAuthenticatedWork(): validates the accession, looks up the GEOExternalDatabase, and creates either aBlacklistedPlatform(GPL*) orBlacklistedExperiment(GSE*) row with the supplied reason. -
deleteBlacklistEntry
@DELETE @Path("/blacklist/{accession}") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response deleteBlacklistEntry(@PathParam("accession") String accession) Removes a blacklist entry by its accession. Port of the-accession -undoarm ofBlacklistCli. Returns 204 on success, 404 when the accession is not on the blacklist. -
listBlacklistEntries
@GET @Path("/blacklist") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public ResponseDataObject<AdminWebService.BlacklistListResponse> listBlacklistEntries(@QueryParam("limit") @DefaultValue("100") int limit, @QueryParam("offset") @DefaultValue("0") int offset) Lists current blacklist entries. Convenience sibling for the curation-UI; the CLI has no equivalent. The underlying service exposes onlyloadAll(), so pagination is applied in-process: results are sorted by accession (alphabetic, nulls last) and sliced byoffset/limit.
-