Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Foxcapades committed May 14, 2024
1 parent 61a3306 commit 8c6fb2b
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/api-docs.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
on:
push:
branches:
- main
- production
paths:
- 'docs/vdi-api.html'

Expand Down
8 changes: 6 additions & 2 deletions docs/vdi-api.html

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion lib/env/src/main/kotlin/vdi/component/env/EnvKey.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ package vdi.component.env
import org.veupathdb.vdi.lib.common.env.EnvKey

object EnvKey {
inline val Admin get() = EnvKey.Admin
object Admin {
inline val SecretKey get() = EnvKey.Admin.SecretKey

const val EnablePurgeEndpoint = "ENABLE_USER_DATASET_PURGE_ENDPOINT"
}

inline val AppDB get() = EnvKey.AppDB

Expand Down
37 changes: 35 additions & 2 deletions service/rest-service/api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,41 @@ uses:
application/json:
type: lib.AllDatasetsListResponse

/system-purge:
displayName: System Purge
get:
displayName: Generate Purge Token
description: |
Generates a temporary system purge token which will be required by a
`POST` request to this endpoint to execute the system purge.
Having this process be 2 steps is to help avoid accidental calls to the
endpoint resulting in an unwanted system wipe.
Any scripts wrapping or automating system purges should include a prompt
confirming the user actually intends to perform this action.
responses:
200:
body:
text/plain:
type: string
example: ccdc1583ae814b4da99f689ad88f0394303c2ec49a264dc28fa5262bcd7f9091
post:
displayName: Execute Purge
description: |
Executes a full system purge, uninstalling all datasets known to VDI.
This endpoint does not perform the uninstallation synchronously, instead
it marks all datasets
body:
text/plain:
type: string
example: ccdc1583ae814b4da99f689ad88f0394303c2ec49a264dc28fa5262bcd7f9091
responses:
204:
description: Success


/vdi-datasets/community:
displayName: Community Datasets
get:
Expand Down Expand Up @@ -662,7 +697,6 @@ uses:
message: Dataset store is unreachable
requestId: b296c3d9-4032-41b1-906e-c97ccfc447e3


/vdi-datasets/{vd-id}:
displayName: Dataset by ID

Expand Down Expand Up @@ -976,7 +1010,6 @@ uses:
application/json:
type: lib.ServerError


/vdi-datasets/{vd-id}/shares/{recipient-user-id}:
displayName: Dataset Sharing

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
property = "status"
)
@JsonSubTypes({
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.ConflictError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.MethodNotAllowedError.class),
@JsonSubTypes.Type(java.lang.String.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.NotFoundError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.ServerError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.UnprocessableEntityError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.BadRequestError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.ConflictError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.UnauthorizedError.class),
@JsonSubTypes.Type(java.lang.String.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.UnprocessableEntityError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.NotFoundError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.MethodNotAllowedError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.ForbiddenError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.Error.class)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ GetAdminListAllDatasetsResponse getAdminListAllDatasets(
@QueryParam("project_id") String projectId,
@QueryParam("include_deleted") @DefaultValue("false") Boolean includeDeleted);

@GET
@Path("/system-purge")
@Produces("text/plain")
GetAdminSystemPurgeResponse getAdminSystemPurge();

@POST
@Path("/system-purge")
@Consumes("text/plain")
PostAdminSystemPurgeResponse postAdminSystemPurge(String entity);

class PostAdminProxyUploadResponse extends ResponseDelegate {
private PostAdminProxyUploadResponse(Response response, Object entity) {
super(response, entity);
Expand Down Expand Up @@ -297,4 +307,35 @@ public static GetAdminListAllDatasetsResponse respond200WithApplicationJson(
return new GetAdminListAllDatasetsResponse(responseBuilder.build(), entity);
}
}

class GetAdminSystemPurgeResponse extends ResponseDelegate {
private GetAdminSystemPurgeResponse(Response response, Object entity) {
super(response, entity);
}

private GetAdminSystemPurgeResponse(Response response) {
super(response);
}

public static GetAdminSystemPurgeResponse respond200WithTextPlain(String entity) {
Response.ResponseBuilder responseBuilder = Response.status(200).header("Content-Type", "text/plain");
responseBuilder.entity(entity);
return new GetAdminSystemPurgeResponse(responseBuilder.build(), entity);
}
}

class PostAdminSystemPurgeResponse extends ResponseDelegate {
private PostAdminSystemPurgeResponse(Response response, Object entity) {
super(response, entity);
}

private PostAdminSystemPurgeResponse(Response response) {
super(response);
}

public static PostAdminSystemPurgeResponse respond204() {
Response.ResponseBuilder responseBuilder = Response.status(204);
return new PostAdminSystemPurgeResponse(responseBuilder.build());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ public int getStatus() {
}

@Override
public Response.StatusType getStatusInfo() {
return this.delegate.getStatusInfo();
public <T> T readEntity(Class<T> p0, Annotation[] p1) {
return this.delegate.readEntity(p0,p1);
}

@Override
public <T> T readEntity(Class<T> p0, Annotation[] p1) {
public <T> T readEntity(GenericType<T> p0, Annotation[] p1) {
return this.delegate.readEntity(p0,p1);
}

Expand All @@ -80,13 +80,13 @@ public <T> T readEntity(GenericType<T> p0) {
}

@Override
public <T> T readEntity(GenericType<T> p0, Annotation[] p1) {
return this.delegate.readEntity(p0,p1);
public <T> T readEntity(Class<T> p0) {
return this.delegate.readEntity(p0);
}

@Override
public <T> T readEntity(Class<T> p0) {
return this.delegate.readEntity(p0);
public Response.StatusType getStatusInfo() {
return this.delegate.getStatusInfo();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.veupathdb.service.vdi.service.admin

import org.slf4j.LoggerFactory

internal val Logger = LoggerFactory.getLogger("AdminRPC")
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package org.veupathdb.service.vdi.service.admin

import jakarta.ws.rs.NotFoundException
import org.veupathdb.vdi.lib.common.field.DatasetID
import vdi.component.db.cache.CacheDB
import vdi.component.db.cache.model.AdminDatasetDetailsRecord

internal fun getDatasetDetails(datasetID: DatasetID): AdminDatasetDetailsRecord {
return vdi.component.db.cache.CacheDB().selectAdminDatasetDetails(datasetID = datasetID) ?: throw NotFoundException("No such dataset $datasetID")
return CacheDB().selectAdminDatasetDetails(datasetID = datasetID)
?: throw NotFoundException("No such dataset $datasetID")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.veupathdb.service.vdi.service.admin

import vdi.component.db.cache.CacheDB


internal fun purgeUserDatasets() {
Logger.warn("BEGINNING USER DATASET PURGE")

val cacheDB = CacheDB()


}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import jakarta.ws.rs.NotFoundException
import org.veupathdb.service.vdi.s3.DatasetStore
import org.veupathdb.vdi.lib.common.field.DatasetID
import org.veupathdb.vdi.lib.common.field.UserID
import vdi.component.db.cache.CacheDB
import vdi.component.db.cache.withTransaction

internal fun adminDeleteDataset(datasetID: DatasetID) {
val ds = vdi.component.db.cache.CacheDB().selectDataset(datasetID) ?: throw NotFoundException()
val ds = CacheDB().selectDataset(datasetID) ?: throw NotFoundException()
deleteUserDataset(ds.ownerID, datasetID)
}

Expand All @@ -27,7 +28,7 @@ internal fun adminDeleteDataset(datasetID: DatasetID) {
*/
internal fun userDeleteDataset(userID: UserID, datasetID: DatasetID) {
// Verify that the target dataset exists.
val ds = vdi.component.db.cache.CacheDB().selectDataset(datasetID) ?: throw NotFoundException()
val ds = CacheDB().selectDataset(datasetID) ?: throw NotFoundException()

// Verify the dataset is owned by the requesting user.
if (ds.ownerID != userID)
Expand All @@ -37,7 +38,7 @@ internal fun userDeleteDataset(userID: UserID, datasetID: DatasetID) {
}

private fun deleteUserDataset(userID: UserID, datasetID: DatasetID) {
vdi.component.db.cache.CacheDB().withTransaction {
CacheDB().withTransaction {
// Update the deleted flag in the local pg.
it.updateDatasetDeleted(datasetID, true)

Expand Down
8 changes: 6 additions & 2 deletions service/rest-service/src/main/resources/api.html

Large diffs are not rendered by default.

0 comments on commit 8c6fb2b

Please sign in to comment.