Skip to content

Commit

Permalink
GH-2076 Prototype redirect plugin + a little bit more user-friendly r…
Browse files Browse the repository at this point in the history
…outing api (#2077)
  • Loading branch information
dzikoysk authored Mar 21, 2024
1 parent 2bed99d commit d3137a5
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .run/Run Reposilite - Test workspace.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<option name="MAIN_CLASS_NAME" value="com.reposilite.ReposiliteLauncherKt" />
<module name="reposilite-parent.reposilite-backend.main" />
<option name="PROGRAM_PARAMETERS" value="--token name:secret --level=DEBUG" />
<option name="VM_PARAMETERS" value="-Xmx32M" />
<option name="VM_PARAMETERS" value="-Xmx32M -Dreposilite.redirect.default-repository=releases" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/reposilite-test/workspace" />
<extension name="net.ashald.envfile">
<option name="IS_ENABLED" value="false" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import com.reposilite.shared.extensions.LoomExtensions
import com.reposilite.shared.extensions.newFixedThreadPool
import com.reposilite.shared.extensions.newSingleThreadScheduledExecutor
import com.reposilite.web.HttpServer
import panda.utilities.console.Effect
import kotlin.io.path.absolutePathString
import panda.utilities.console.Effect

object ReposiliteFactory {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ import com.reposilite.maven.api.DeleteRequest
import com.reposilite.maven.api.DeployRequest
import com.reposilite.maven.api.LookupRequest
import com.reposilite.shared.extensions.resultAttachment
import com.reposilite.shared.extensions.uri
import com.reposilite.storage.api.Location
import com.reposilite.token.AccessTokenIdentifier
import com.reposilite.web.api.ReposiliteRoute
import io.javalin.community.routing.Route.DELETE
import io.javalin.community.routing.Route.GET
import io.javalin.community.routing.Route.HEAD
import io.javalin.community.routing.Route.POST
import io.javalin.community.routing.Route.PUT
import io.javalin.http.Context
import io.javalin.openapi.ContentType.FORM_DATA_MULTIPART
import io.javalin.openapi.HttpMethod
import io.javalin.openapi.OpenApi
Expand Down Expand Up @@ -61,26 +65,30 @@ internal class MavenEndpoints(
private val findFile = ReposiliteRoute<Unit>("/{repository}/<gav>", HEAD, GET) {
accessed {
requireGav { gav ->
LookupRequest(this?.identifier, requireParameter("repository"), gav)
.let { request -> mavenFacade.findFile(request) }
.peek {
ctx.resultAttachment(
name = it.document.name,
contentType = it.document.contentType,
contentLength = it.document.contentLength,
compressionStrategy = compressionStrategy,
cache = it.cachable,
data = it.content
)
}
.onError {
ctx.status(it.status).html(frontendFacade.createNotFoundPage(uri, it.message))
mavenFacade.logger.debug("FIND | Could not find file due to $it")
}
findFile(ctx, this?.identifier, requireParameter("repository"), gav)
}
}
}

fun findFile(ctx: Context, identifier: AccessTokenIdentifier?, repository: String, gav: Location) {
LookupRequest(identifier, repository, gav)
.let { request -> mavenFacade.findFile(request) }
.peek {
ctx.resultAttachment(
name = it.document.name,
contentType = it.document.contentType,
contentLength = it.document.contentLength,
compressionStrategy = compressionStrategy,
cache = it.cachable,
data = it.content
)
}
.onError {
ctx.status(it.status).html(frontendFacade.createNotFoundPage(ctx.uri(), it.message))
mavenFacade.logger.debug("FIND | Could not find file due to $it")
}
}

@OpenApi(
tags = [ "Maven" ],
path = "/{repository}/{gav}",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.reposilite.redirect

import com.reposilite.configuration.local.LocalConfiguration
import com.reposilite.frontend.FrontendFacade
import com.reposilite.maven.MavenFacade
import com.reposilite.maven.infrastructure.MavenEndpoints
import com.reposilite.plugin.api.Facade
import com.reposilite.plugin.api.Plugin
import com.reposilite.plugin.api.ReposilitePlugin
import com.reposilite.plugin.event
import com.reposilite.plugin.facade
import com.reposilite.storage.api.Location
import com.reposilite.web.api.ReposiliteRoute
import com.reposilite.web.api.RoutingSetupEvent
import io.javalin.community.routing.Route.GET
import io.javalin.community.routing.Route.HEAD

@Plugin(name = "redirect", dependencies = ["local-configuration", "frontend", "maven"])
class RedirectPlugin : ReposilitePlugin() {

private val redirectTo: String? = System.getProperty("reposilite.redirect.default-repository", "")

override fun initialize(): Facade? {
if (redirectTo.isNullOrEmpty()) {
return null
}

val mavenFacade = facade<MavenFacade>()

val mavenEndpoints = MavenEndpoints(
mavenFacade = mavenFacade,
frontendFacade = facade<FrontendFacade>(),
compressionStrategy = facade<LocalConfiguration>().compressionStrategy.get()
)

logger.info("")
logger.info("--- Redirect")

val redirectedRoutes = mavenFacade.getRepository(redirectTo)
?.storageProvider
?.getFiles(Location.of("/"))
?.orNull()
?.map {
logger.info("Redirecting /${it.getSimpleName()}/<gav> to /$redirectTo/${it.getSimpleName()}/<gav>")

ReposiliteRoute<Unit>("/${it.getSimpleName()}/<gav>", HEAD, GET) {
accessed {
mavenEndpoints.findFile(
ctx = ctx,
identifier = this?.identifier,
repository = redirectTo,
gav = it.resolve(requireParameter("gav"))
)
}
}
}
?: emptyList()

event { event: RoutingSetupEvent ->
event.register(redirectedRoutes)
}

return null
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.reposilite.web.api

import com.reposilite.shared.ContextDsl
import com.reposilite.web.infrastructure.ReposiliteDslRoute
import com.reposilite.web.routing.RouteMethod
import io.javalin.community.routing.Route
import io.javalin.community.routing.dsl.DefaultDslRoute
Expand All @@ -33,17 +34,8 @@ abstract class ReposiliteRoutes : DslContainer<DslRoute<ContextDsl<*>, Unit>, Co
.map { it as ReposiliteRoute<Any> }
.toSet()

@Suppress("UNCHECKED_CAST")
override fun routes(): Collection<DslRoute<ContextDsl<*>, Unit>> =
routes.flatMap { route ->
route.methods.map { method ->
DefaultDslRoute(
path = route.path,
method = method,
handler = route.handler as ContextDsl<*>.() -> Unit
)
}
}
override fun routes(): Collection<ReposiliteDslRoute> =
routes.flatMap { it.toDslRoutes() }

}

Expand All @@ -62,9 +54,19 @@ class ReposiliteRoute<R>(
path = path,
methods = methods
.map { Route.valueOf(it.name) }
.toTypedArray()
,
.toTypedArray(),
handler = handler
)

@Suppress("UNCHECKED_CAST")
fun toDslRoutes(): Set<ReposiliteDslRoute> =
methods.mapTo(HashSet()) { method ->
@Suppress("UNCHECKED_CAST")
DefaultDslRoute(
path = path,
method = method,
handler = handler as ContextDsl<*>.() -> Unit
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,25 @@ import com.reposilite.plugin.api.Event

class RoutingSetupEvent(val reposilite: Reposilite) : Event {

private val routes: MutableSet<ReposiliteRoutes> = mutableSetOf()
private val routes: MutableSet<ReposiliteRoute<*>> = mutableSetOf()

fun registerRoutes(routesToAdd: ReposiliteRoutes) {
routes.add(routesToAdd)
fun register(routeToAdd: ReposiliteRoute<*>) {
routes.add(routeToAdd)
}

fun registerRoutes(routesToAdd: Set<ReposiliteRoutes>) {
fun register(routesToAdd: Collection<ReposiliteRoute<*>>) {
routes.addAll(routesToAdd)
}

fun getRoutes(): Collection<ReposiliteRoutes> =
fun registerRoutes(routesToAdd: ReposiliteRoutes) {
routes.addAll(routesToAdd.routes)
}

fun registerRoutes(routesToAdd: Collection<ReposiliteRoutes>) {
routes.addAll(routesToAdd.map { it.routes }.flatten())
}

fun getRoutes(): Collection<ReposiliteRoute<*>> =
routes

}
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,13 @@ internal object JavalinConfiguration {
authenticationFacade = extensionManager.facade()
)

extensionManager.emitEvent(RoutingSetupEvent(reposilite)).getRoutes().asSequence().flatMap { it.routes() }.distinctBy { "${it.method.name}:${it.path}" }
.toSet().let { route ->
extensionManager.emitEvent(RoutingSetupEvent(reposilite))
.getRoutes()
.asSequence()
.flatMap { it.toDslRoutes() }
.distinctBy { "${it.method.name}:${it.path}" }
.toSet()
.let { route ->
config.router.mount(reposiliteDsl) {
it.routes(route)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ import io.javalin.http.Header
import io.javalin.http.HttpStatus.INTERNAL_SERVER_ERROR
import io.javalin.util.javalinLazy

typealias ReposiliteRouting = DslRouting<ReposiliteConfiguration, ReposiliteRoute, ReposiliteScope, Unit>
typealias ReposiliteRoute = DslRoute<ContextDsl<*>, Unit>
typealias ReposiliteRouting = DslRouting<ReposiliteConfiguration, ReposiliteDslRoute, ReposiliteScope, Unit>
typealias ReposiliteDslRoute = DslRoute<ContextDsl<*>, Unit>
typealias ReposiliteExceptionHandler = DslExceptionHandler<ContextDsl<*>, Exception, Unit>
typealias ReposiliteScope = ContextDsl<*>

class ReposiliteDsl(
private val routeFactory: (ReposiliteRoute) -> Handler,
private val routeFactory: (ReposiliteDslRoute) -> Handler,
private val exceptionRouteFactory: (ReposiliteExceptionHandler) -> ExceptionHandler<Exception>
) : RoutingDslFactory<ReposiliteConfiguration, ReposiliteRoute, ContextDsl<*>, Unit> {
) : RoutingDslFactory<ReposiliteConfiguration, ReposiliteDslRoute, ContextDsl<*>, Unit> {

open class ReposiliteConfiguration : RoutingDslConfiguration<ReposiliteRoute, ContextDsl<*>, Unit>()
open class ReposiliteConfiguration : RoutingDslConfiguration<ReposiliteDslRoute, ContextDsl<*>, Unit>()

override fun createConfiguration(): ReposiliteConfiguration =
ReposiliteConfiguration()

override fun createHandler(route: ReposiliteRoute): Handler =
override fun createHandler(route: ReposiliteDslRoute): Handler =
routeFactory.invoke(route)

override fun createExceptionHandler(handler: ReposiliteExceptionHandler): ExceptionHandler<Exception> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ com.reposilite.auth.application.AuthenticationPlugin
com.reposilite.console.application.ConsolePlugin
com.reposilite.frontend.application.FrontendPlugin
com.reposilite.maven.application.MavenPlugin
com.reposilite.redirect.RedirectPlugin
com.reposilite.javadocs.application.JavadocPlugin
com.reposilite.configuration.application.ConfigurationPlugin
com.reposilite.configuration.local.LocalConfigurationPlugin
Expand Down

0 comments on commit d3137a5

Please sign in to comment.