Skip to content

Commit

Permalink
GH-465 Simplify error responses
Browse files Browse the repository at this point in the history
  • Loading branch information
dzikoysk committed Jun 24, 2021
1 parent ca79220 commit b91bad6
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 95 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ package org.panda_lang.reposilite.maven
import net.dzikoysk.dynamiclogger.Journalist
import net.dzikoysk.dynamiclogger.Logger
import org.apache.http.HttpStatus
import org.panda_lang.reposilite.failure.ResponseUtils
import org.panda_lang.reposilite.failure.api.ErrorResponse
import org.panda_lang.reposilite.failure.api.errorResponse
import org.panda_lang.reposilite.maven.api.DeployRequest
import org.panda_lang.reposilite.maven.api.FileDetailsResponse
import org.panda_lang.utilities.commons.function.Result
Expand All @@ -31,17 +31,17 @@ internal class DeployService(
) : Journalist {

fun deployArtifact(deployRequest: DeployRequest): Result<FileDetailsResponse, ErrorResponse> {
val repository = repositoryService.getRepository(deployRequest.repository) ?: return ResponseUtils.error(HttpStatus.SC_NOT_FOUND, "Repository not found")
val repository = repositoryService.getRepository(deployRequest.repository) ?: return errorResponse(HttpStatus.SC_NOT_FOUND, "Repository not found")

if (!repository.isDeployEnabled) {
return ResponseUtils.error(HttpStatus.SC_METHOD_NOT_ALLOWED, "Artifact deployment is disabled")
return errorResponse(HttpStatus.SC_METHOD_NOT_ALLOWED, "Artifact deployment is disabled")
}

if (repository.isFull()) {
return ResponseUtils.error(HttpStatus.SC_INSUFFICIENT_STORAGE, "Not enough storage space available")
return errorResponse(HttpStatus.SC_INSUFFICIENT_STORAGE, "Not enough storage space available")
}

val path = repository.relativize(deployRequest.gav) ?: return ResponseUtils.error(HttpStatus.SC_BAD_REQUEST, "Invalid GAV")
val path = repository.relativize(deployRequest.gav) ?: return errorResponse(HttpStatus.SC_BAD_REQUEST, "Invalid GAV")
val metadataFile = path.resolveSibling(METADATA_FILE)
metadataService.clearMetadata(metadataFile)

Expand All @@ -57,7 +57,7 @@ internal class DeployService(
result.peek { logger.info("DEPLOY Artifact successfully deployed $path by ${deployRequest.by}") }
}
catch (exception: Exception) {
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Failed to upload artifact"))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Failed to upload artifact")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper
import org.apache.http.HttpStatus
import org.panda_lang.reposilite.failure.FailureFacade
import org.panda_lang.reposilite.failure.api.ErrorResponse
import org.panda_lang.reposilite.failure.api.errorResponse
import org.panda_lang.reposilite.maven.api.FileDetailsResponse
import org.panda_lang.reposilite.shared.utils.FilesUtils
import org.panda_lang.reposilite.web.projectToError
Expand Down Expand Up @@ -49,7 +50,7 @@ internal class MetadataService(private val failureFacade: FailureFacade) {

fun getMetadata(repository: Repository, requested: Path): Result<Pair<FileDetailsResponse, String>, ErrorResponse> {
if (requested.fileName.toString() != "maven-metadata.xml") {
return Result.error(ErrorResponse(HttpStatus.SC_BAD_REQUEST, "Bad request"))
return errorResponse(HttpStatus.SC_BAD_REQUEST, "Bad request")
}

val cachedContent: Pair<FileDetailsResponse, String>? = metadataCache[requested]
Expand All @@ -61,7 +62,7 @@ internal class MetadataService(private val failureFacade: FailureFacade) {
val artifactDirectory = requested.parent

if (repository.exists(artifactDirectory)) {
return Result.error(ErrorResponse(HttpStatus.SC_BAD_REQUEST, "Bad request"))
return errorResponse(HttpStatus.SC_BAD_REQUEST, "Bad request")
}

val versions: Result<List<Path>, ErrorResponse> = MetadataUtils.toSortedVersions(repository, artifactDirectory)
Expand Down Expand Up @@ -114,7 +115,7 @@ internal class MetadataService(private val failureFacade: FailureFacade) {
}

val latestBuild = builds.get().firstOrNull()
?: return Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "Latest build not found"))
?: return errorResponse(HttpStatus.SC_NOT_FOUND, "Latest build not found")

val name = artifactDirectory.fileName.toString()
val version = StringUtils.replace(versionDirectory.fileName.toString(), "-SNAPSHOT", StringUtils.EMPTY)
Expand Down Expand Up @@ -176,7 +177,7 @@ internal class MetadataService(private val failureFacade: FailureFacade) {
}
catch (ioException: IOException) {
failureFacade.throwException(metadataFile.toAbsolutePath().toString(), ioException)
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Cannot generate metadata"))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Cannot generate metadata")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import org.apache.commons.io.IOUtils.copyLarge
import org.apache.http.HttpStatus
import org.panda_lang.reposilite.ReposiliteException
import org.panda_lang.reposilite.failure.FailureFacade
import org.panda_lang.reposilite.failure.ResponseUtils
import org.panda_lang.reposilite.failure.api.ErrorResponse
import org.panda_lang.reposilite.failure.api.errorResponse
import org.panda_lang.reposilite.maven.api.FileDetailsResponse
import org.panda_lang.reposilite.maven.api.LookupResponse
import org.panda_lang.reposilite.storage.StorageProvider
Expand All @@ -33,7 +33,6 @@ import org.panda_lang.utilities.commons.StringUtils
import org.panda_lang.utilities.commons.function.Option
import org.panda_lang.utilities.commons.function.Result
import java.io.IOException
import java.io.OutputStream
import java.net.SocketTimeoutException
import java.nio.file.Paths
import java.util.*
Expand Down Expand Up @@ -65,20 +64,20 @@ internal class ProxyService(
}

if (repository == null) {
return Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "Unknown repository"))
return errorResponse(HttpStatus.SC_NOT_FOUND, "Unknown repository")
}

if (!proxyPrivate && repository.isPrivate()) {
return Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "Proxying is disabled in private repositories"))
return errorResponse(HttpStatus.SC_NOT_FOUND, "Proxying is disabled in private repositories")
}

// /groupId/artifactId/<content>
if (StringUtils.countOccurrences(uri, "/") < 3) {
return Result.error(ErrorResponse(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION, "Invalid proxied request"))
return errorResponse(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION, "Invalid proxied request")
}

val remoteUri = uri
val list: MutableList<CompletableFuture<Void>> = ArrayList<CompletableFuture<Void>>()
val list: MutableList<CompletableFuture<Void>> = ArrayList()
val responses = Collections.synchronizedList(ArrayList<HttpResponse>())

for (proxied in proxied) {
Expand Down Expand Up @@ -130,9 +129,7 @@ internal class ProxyService(

Result.ok(lookupResponse)
}
else {
ResponseUtils.error(HttpStatus.SC_NOT_FOUND, "Artifact $uri not found")
}
else errorResponse(HttpStatus.SC_NOT_FOUND, "Artifact $uri not found")
}

private fun store(uri: String, remoteResponse: HttpResponse, context: ReposiliteContext): Result<FileDetailsResponse, ErrorResponse> {
Expand All @@ -141,13 +138,13 @@ internal class ProxyService(
if (storageProvider.isFull()) {
val error = "Not enough storage space available for $uri"
context.logger.warn(error)
return Result.error(ErrorResponse(HttpStatus.SC_INSUFFICIENT_STORAGE, error))
return errorResponse(HttpStatus.SC_INSUFFICIENT_STORAGE, error)
}

val repositoryName = StringUtils.split(uri.substring(1), "/")[0] // skip first path separator

val repository = repositoryService.getRepository(repositoryName)
?: return Result.error(ErrorResponse(HttpStatus.SC_BAD_REQUEST, "Missing valid repository name"))
?: return errorResponse(HttpStatus.SC_BAD_REQUEST, "Missing valid repository name")

val proxiedFile = Paths.get(uri)

Expand All @@ -156,17 +153,12 @@ internal class ProxyService(

if (result.isOk) {
context.logger.info("Stored proxied $proxiedFile from ${remoteResponse.request.url}")

context.output { output: OutputStream ->
output.write(
storageProvider.getFile(proxiedFile).get()
)
}
context.output { it.write(storageProvider.getFile(proxiedFile).get()) }
}
result
}
catch (ioException: IOException) {
Result.error(ErrorResponse(HttpStatus.SC_UNPROCESSABLE_ENTITY, "Cannot process artifact"))
errorResponse(HttpStatus.SC_UNPROCESSABLE_ENTITY, "Cannot process artifact")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package org.panda_lang.reposilite.storage.infrastructure

import org.apache.http.HttpStatus
import org.panda_lang.reposilite.failure.api.ErrorResponse
import org.panda_lang.reposilite.failure.api.errorResponse
import org.panda_lang.reposilite.maven.api.FileDetailsResponse
import org.panda_lang.reposilite.shared.utils.FilesUtils
import org.panda_lang.reposilite.shared.utils.FilesUtils.getMimeType
Expand All @@ -38,6 +39,7 @@ import java.nio.file.attribute.FileTime
import java.time.LocalDate
import java.util.concurrent.atomic.AtomicLong
import java.util.stream.Collectors
import kotlin.streams.toList

/**
* @param rootDirectory root directory of storage space
Expand Down Expand Up @@ -106,7 +108,7 @@ internal abstract class FileSystemStorageProvider private constructor(
val size = measure.apply(input).toLong()

if (!canHold(size)) {
return Result.error(ErrorResponse(HttpStatus.SC_INSUFFICIENT_STORAGE, "Not enough storage space available"))
return errorResponse(HttpStatus.SC_INSUFFICIENT_STORAGE, "Not enough storage space available")
}

if (file.parent != null && !Files.exists(file.parent)) {
Expand Down Expand Up @@ -136,25 +138,25 @@ internal abstract class FileSystemStorageProvider private constructor(
)
}
catch (ioException: IOException) {
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage)
}
}

override fun getFile(file: Path): Result<ByteArray, ErrorResponse> {
return if (!Files.exists(file) || Files.isDirectory(file)) {
Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file"))
errorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file")
}
else try {
Result.ok(Files.readAllBytes(file))
}
catch (ioException: IOException) {
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage)
}
}

override fun getFileDetails(file: Path): Result<FileDetailsResponse, ErrorResponse> {
return if (!Files.exists(file)) {
Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file"))
errorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file")
}
else try {
Result.ok(
Expand All @@ -167,46 +169,47 @@ internal abstract class FileSystemStorageProvider private constructor(
)
)
} catch (ioException: IOException) {
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage)
}
}

override fun removeFile(file: Path): Result<Unit, ErrorResponse> {
return try {
if (!Files.exists(file)) {
return Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file"))
return errorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file")
}

Files.delete(file)
Result.ok(Unit)
} catch (ioException: IOException) {
Result.error(ErrorResponse(500, ioException.localizedMessage))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage)
}
}

override fun getFiles(directory: Path): Result<List<Path>, ErrorResponse> {
return try {
Result.ok(Files.walk(directory, 1).filter { path: Path -> path != directory }
.collect(Collectors.toList()))
Result.ok(Files.walk(directory, 1)
.filter { path: Path -> path != directory }
.toList())
} catch (ioException: IOException) {
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage)
}
}

override fun getLastModifiedTime(file: Path): Result<FileTime, ErrorResponse> {
return try {
if (!Files.exists(file)) {
Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file"))
errorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file")
} else Result.ok(Files.getLastModifiedTime(file))
} catch (ioException: IOException) {
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage)
}
}

override fun getFileSize(file: Path): Result<Long, ErrorResponse> {
return try {
if (!Files.exists(file)) {
return Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file"))
return errorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file")
}

var size: Long = 0
Expand All @@ -223,7 +226,7 @@ internal abstract class FileSystemStorageProvider private constructor(
Result.ok(size)
}
catch (ioException: IOException) {
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ioException.localizedMessage)
}
}

Expand All @@ -249,6 +252,7 @@ internal abstract class FileSystemStorageProvider private constructor(
} catch (e: IOException) {
usage.set(-1L)
}

return usage.get()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ internal class S3StorageProvider(private val bucket: String, region: String) : S
}
catch (exception: Exception) {
exception.printStackTrace()
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Failed to write $file"))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Failed to write $file")
}
}

Expand Down Expand Up @@ -106,7 +106,7 @@ internal class S3StorageProvider(private val bucket: String, region: String) : S
}
catch (ioException: IOException) {
ioException.printStackTrace()
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Failed to write $file"))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Failed to write $file")
}
}

Expand All @@ -124,10 +124,10 @@ internal class S3StorageProvider(private val bucket: String, region: String) : S
Result.ok(bytes)
}
catch (noSuchKeyException: NoSuchKeyException) {
Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file"))
errorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file")
}
catch (ioException: IOException) {
Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file"))
errorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file")
}
}

Expand Down Expand Up @@ -186,7 +186,7 @@ internal class S3StorageProvider(private val bucket: String, region: String) : S
Result.ok(paths)
}
catch (exception: Exception) {
Result.error(ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, exception.localizedMessage))
errorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, exception.localizedMessage)
}
}

Expand All @@ -201,7 +201,7 @@ internal class S3StorageProvider(private val bucket: String, region: String) : S
override fun getFileSize(file: Path): Result<Long, ErrorResponse> =
head(file)
?.let { Result.ok(it.contentLength()) }
?: Result.error(ErrorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file"))
?: errorResponse(HttpStatus.SC_NOT_FOUND, "File not found: $file")

private fun head(file: Path): HeadObjectResponse? {
try {
Expand Down

0 comments on commit b91bad6

Please sign in to comment.