Skip to content

Commit

Permalink
GH-460 Rebuild frontend and improve routes handling
Browse files Browse the repository at this point in the history
  • Loading branch information
dzikoysk committed Jul 6, 2021
1 parent 11067f2 commit 8f22e22
Show file tree
Hide file tree
Showing 16 changed files with 69 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
*/
package org.panda_lang.reposilite.frontend.infrastructure

import com.dzikoysk.openapi.annotations.HttpMethod
import com.dzikoysk.openapi.annotations.OpenApi
import com.dzikoysk.openapi.annotations.OpenApiResponse
import io.javalin.http.Context
import org.eclipse.jetty.http.HttpStatus
import org.eclipse.jetty.http.MimeTypes
import org.panda_lang.reposilite.frontend.FrontendFacade
Expand All @@ -26,30 +24,30 @@ import org.panda_lang.reposilite.web.api.RouteMethod.GET
import org.panda_lang.reposilite.web.api.Routes
import org.panda_lang.reposilite.web.encoding

private const val ROUTE = "/*"

internal class FrontendHandler(private val frontendFacade: FrontendFacade) : Routes {

@OpenApi(
path = ROUTE,
methods = [ HttpMethod.GET ],
summary = "Get frontend application",
description = "Returns Vue.js application wrapped into one app.js file",
tags = [ "Resource" ],
responses = [ OpenApiResponse(status = "200", description = "Default response") ]
)
private val frontend = Route(ROUTE, GET) {
val qualifier = wildcard(defaultValue = "index.html")

FrontendFacade::class.java.getResourceAsStream("/static/$qualifier")
private val defaultHandler = Route("/", GET) {
bindResource(ctx, "index.html")
}

private val indexHandler = Route("/index.html", GET) {
bindResource(ctx, "index.html")
}

private val assetsHandler = Route("/assets/*", GET) {
bindResource(ctx, "assets/${wildcard()}")
}

override val routes = setOf(defaultHandler, indexHandler, assetsHandler)

private fun bindResource(ctx: Context, uri: String) {
FrontendFacade::class.java.getResourceAsStream("/static/$uri")
?.let {
ctx.result(it)
.contentType(MimeTypes.getDefaultMimeByExtension(qualifier))
.contentType(MimeTypes.getDefaultMimeByExtension(uri))
.encoding("UTF-8")
}
?: ctx.status(HttpStatus.NOT_FOUND_404)
}

override val routes = setOf(frontend)

}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class MavenFacade internal constructor(
}

fun deleteFile(repositoryName: String, gav: String): Result<*, ErrorResponse> {
val repository = repositoryService.getRepository(repositoryName) ?: return errorResponse<Any>(NOT_FOUND, "xxx")
val repository = repositoryService.getRepository(repositoryName) ?: return errorResponse<Any>(NOT_FOUND, "Repository $repositoryName not found")
return repository.removeFile(gav)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import org.panda_lang.utilities.commons.function.Result
internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes {

@OpenApi(
path = "/:repositoryName/*",
path = "/:repository-name/*",
methods = [HttpMethod.GET],
tags = ["Maven"],
summary = "Browse the contents of repositories",
Expand All @@ -39,9 +39,9 @@ internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes
OpenApiResponse(status = "404", description = "Returns 404 (for Maven) with frontend (for user) as a response if requested resource is not located in the current repository")
]
)
val findFile = Route("/:repositoryName/*", GET) {
val findFile = Route("/:repository-name/*", GET) {
accessed {
LookupRequest(parameter("repositoryName"), wildcard(), this?.accessToken)
LookupRequest(parameter("repository-name"), wildcard(), this?.accessToken)
.let { mavenFacade.findFile(it) }
.peek {
when (it) {
Expand All @@ -54,7 +54,7 @@ internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes
}

@OpenApi(
path = "/:repositoryName/*",
path = "/:repository-name/*",
methods = [HttpMethod.POST, HttpMethod.PUT],
summary = "Deploy artifact to the repository",
description = "Deploy supports both, POST and PUT, methods and allows to deploy artifact builds",
Expand All @@ -76,7 +76,7 @@ internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes
}

@OpenApi(
path = "/:repositoryName/*",
path = "/:repository-name/*",
summary = "Delete the given file from repository",
methods = [HttpMethod.DELETE]
)
Expand All @@ -87,7 +87,7 @@ internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes
}

@OpenApi(
path = "/api/maven/details/:repositoryName/*",
path = "/api/maven/details/:repository-name/*",
methods = [HttpMethod.HEAD, HttpMethod.GET],
summary = "Browse the contents of repositories using API",
description = "Get details about the requested file as JSON response",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import org.panda_lang.reposilite.web.api.Routes

internal class StatisticsHandler(private val statisticsFacade: StatisticsFacade) : Routes {

private val collectRequests = Route("*", BEFORE) {
private val collectRequests = Route("/*", BEFORE) {
if (ctx.req.requestURI.length < MAX_IDENTIFIER_LENGTH) {
statisticsFacade.increaseRecord(REQUEST, ctx.req.requestURI)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Route(
val path: String,
vararg val methods: RouteMethod,
private val handler: ContextDsl.() -> Unit
) {
) : Comparable<Route> {

fun createHandler(reposiliteContextFactory: ReposiliteContextFactory): Handler =
Handler {
Expand All @@ -44,6 +44,30 @@ class Route(
}
}

override fun compareTo(other: Route): Int {
val itPaths = path.split("/")
val toPaths = other.path.split("/")
var index = 0

while (true) {
if (index >= itPaths.size || index >= toPaths.size) {
break
}

val itPart = itPaths[index]
val toPart = toPaths[index]
val result = toPart.compareTo(itPart)

if (result != 0) {
return result
}

index++
}

return other.path.compareTo(path)
}

}

interface Routes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,14 @@ internal class JavalinWebServer : WebServer {

ReposiliteWebConfiguration.javalin(reposilite, javalin)

reposilite.logger.debug("--- Routes")
ReposiliteWebConfiguration.routing(reposilite)
.flatMap { it.routes }
.sortedByDescending { it.path.length }
.sorted()
.map { Pair(it, it.createHandler(reposilite.contextFactory)) }
.forEach { (route, handler) ->
reposilite.logger.debug("- ${route.path}")

route.methods.forEach { method ->
when (method) {
HEAD -> javalin.head(route.path, handler)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8f22e22

Please sign in to comment.