Skip to content

Commit

Permalink
handle redirects and return http 424 for file download failures
Browse files Browse the repository at this point in the history
  • Loading branch information
Foxcapades committed May 16, 2024
1 parent 32376cd commit f5d8e0a
Show file tree
Hide file tree
Showing 18 changed files with 460 additions and 234 deletions.
146 changes: 75 additions & 71 deletions docs/vdi-api.html

Large diffs are not rendered by default.

8 changes: 2 additions & 6 deletions platform/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
dependencies {
constraints {
api("org.gusdb:fgputil-db:2.13.1")
api("org.veupathdb.lib:jaxrs-container-core:7.0.9")
api("org.veupathdb.lib:jaxrs-container-core:7.1.0")
api("org.veupathdb.lib:multipart-jackson-pojo:1.1.7")

// VDI
Expand All @@ -29,11 +29,7 @@ dependencies {

// HTTP
api("io.foxcapades.lib:k-multipart:1.2.1")
api("org.glassfish.jersey.core:jersey-server:3.1.5")

// JSON
api("com.fasterxml.jackson.core:jackson-databind:2.17.0")
api("com.fasterxml.jackson.core:jackson-annotations:2.17.0")
api("org.glassfish.jersey.core:jersey-server")

// Messaging
api("org.apache.kafka:kafka-clients:3.7.0")
Expand Down
13 changes: 12 additions & 1 deletion service/rest-service/api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
extends: https://raw.githubusercontent.com/VEuPathDB/docs-api-schema/v2.2.0/libraries/base-service.raml

title: VEuPathDB Dataset Installer
version: 2.0.0
version: 2.1.0
mediaType: application/json

traits:
Expand Down Expand Up @@ -216,6 +216,17 @@ uses:
body:
application/json:
type: lib.UnprocessableEntityError
424:
description: |
Failed Dependency.
Returned when the dataset data source was a URL and the VDI service
encountered a non-success HTTP status code from the target URL. This
could be, for example, a 403 error from an expired AWS S3 URL, or a
404 for a file that no longer exists on the remote server.
body:
application/json:
type: lib.FailedDependencyError
500:
description: |
Internal Server Error.
Expand Down
1 change: 0 additions & 1 deletion service/rest-service/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")


// Jersey
implementation("org.glassfish.jersey.core:jersey-server")

Expand Down
2 changes: 1 addition & 1 deletion service/rest-service/schema/common.raml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#%RAML 1.0 Library

uses:
error: https://raw.githubusercontent.com/VEuPathDB/docs-api-schema/v2.2.1/libraries/errors.raml
error: https://raw.githubusercontent.com/VEuPathDB/docs-api-schema/v2.3.0/libraries/errors.raml

types:
VDI-ID:
Expand Down
11 changes: 11 additions & 0 deletions service/rest-service/schema/library.raml
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,7 @@ types:
- conflict
- gone
- invalid-input
- failed-dependency
- server-error
BadRequestError:
displayName: Bad Request
Expand Down Expand Up @@ -872,6 +873,16 @@ types:
general: []
byKey:
id: [Given ID value does not point to an existing record.]
FailedDependencyError:
displayName: Failed Dependency Error
type: Error
discriminatorValue: failed-dependency
properties:
dependency: string
example:
status: failed-dependency
dependency: google.com
message: unexpected status code 403 from google.com
ServerError:
displayName: Internal Server Error
type: Error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
@JsonSubTypes({
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.ConflictError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.MethodNotAllowedError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.FailedDependencyError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.ServerError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.BadRequestError.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.ForbiddenError.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.UnprocessableEntityError.class),
@JsonSubTypes.Type(java.lang.String.class),
@JsonSubTypes.Type(org.veupathdb.service.vdi.generated.model.Error.class)
})
@JsonDeserialize(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public enum ErrorType {
@JsonProperty("invalid-input")
INVALIDINPUT("invalid-input"),

@JsonProperty("failed-dependency")
FAILEDDEPENDENCY("failed-dependency"),

@JsonProperty("server-error")
SERVERERROR("server-error");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.veupathdb.service.vdi.generated.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@JsonTypeName("failed-dependency")
@JsonDeserialize(
as = FailedDependencyErrorImpl.class
)
public interface FailedDependencyError extends Error {
ErrorType _DISCRIMINATOR_TYPE_NAME = ErrorType.FAILEDDEPENDENCY;

@JsonProperty("status")
ErrorType getStatus();

@JsonProperty("message")
String getMessage();

@JsonProperty("message")
void setMessage(String message);

@JsonProperty("dependency")
String getDependency();

@JsonProperty("dependency")
void setDependency(String dependency);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.veupathdb.service.vdi.generated.model;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeName;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonTypeName("failed-dependency")
@JsonPropertyOrder({
"status",
"message",
"dependency"
})
public class FailedDependencyErrorImpl implements FailedDependencyError {
@JsonProperty("status")
private final ErrorType status = _DISCRIMINATOR_TYPE_NAME;

@JsonProperty("message")
private String message;

@JsonProperty("dependency")
private String dependency;

@JsonProperty("status")
public ErrorType getStatus() {
return this.status;
}

@JsonProperty("message")
public String getMessage() {
return this.message;
}

@JsonProperty("message")
public void setMessage(String message) {
this.message = message;
}

@JsonProperty("dependency")
public String getDependency() {
return this.dependency;
}

@JsonProperty("dependency")
public void setDependency(String dependency) {
this.dependency = dependency;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

package org.veupathdb.service.vdi.generated.model;

import java.io.IOException;
import java.io.OutputStream;
import java.util.function.Consumer;

import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.StreamingOutput;

public class FailedDependencyErrorStream extends FailedDependencyErrorImpl implements StreamingOutput {

private final Consumer<OutputStream> _streamer;

public FailedDependencyErrorStream(Consumer<OutputStream> streamer) {
_streamer = streamer;
}

@Override
public void write(OutputStream output) throws IOException, WebApplicationException {
_streamer.accept(output);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
= Generated Java Model Extensions

This package contains extension/mixin helper methods for working with the model
Java classes generated by the RAML -> JaxRS code generator.

The file names all follow the scheme `x-\{generated class name}` where the
prefix `x` is short for 'extension'.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@ package org.veupathdb.service.vdi.generated.model

import org.veupathdb.service.vdi.util.ValidationErrors

internal fun DatasetPostMeta.cleanup() {
datasetType?.cleanup()

name = name?.trim()
summary = summary?.takeIf { it.isNotBlank() }
?.trim()
description = description?.takeIf { it.isNotBlank() }
?.trim()
origin = origin?.trim()

projects?.forEachIndexed { i, s -> projects[i] = s?.takeIf { it.isNotBlank() } ?.trim() }

dependencies?.forEach {
it.resourceVersion = it.resourceVersion?.takeIf { it.isNotBlank() } ?.trim()
it.resourceIdentifier = it.resourceIdentifier?.takeIf { it.isNotBlank() } ?.trim()
it.resourceDisplayName = it.resourceDisplayName?.takeIf { it.isNotBlank() } ?.trim()
}
}

internal fun DatasetPostMeta.validate(validationErrors: ValidationErrors) {
if (datasetType == null)
validationErrors.add("meta.type", "field is required")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import org.veupathdb.vdi.lib.common.model.VDIDatasetTypeImpl
import org.veupathdb.vdi.lib.common.model.VDIDatasetVisibility
import java.time.OffsetDateTime

internal fun DatasetPostRequest.cleanup() {
meta?.cleanup()
url = url?.takeIf { it.isNotBlank() } ?.trim()
}

internal fun DatasetPostRequest.validate(): ValidationErrors {
val validationErrors = ValidationErrors()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package org.veupathdb.service.vdi.generated.model

import org.veupathdb.service.vdi.util.ValidationErrors

internal fun DatasetPostType.cleanup() {
name = name?.trim()
version = version?.trim()
}

internal fun DatasetPostType.validate(validationErrors: ValidationErrors) {
if (name.isNullOrBlank())
validationErrors.add("meta.type.name", "field is required")
Expand Down
Loading

0 comments on commit f5d8e0a

Please sign in to comment.