Skip to content

Commit

Permalink
GH-1821 Improve handling around shouldPrioritizeMirrorRepository
Browse files Browse the repository at this point in the history
  • Loading branch information
dzikoysk committed Aug 26, 2023
1 parent 5db56cf commit ac0f944
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 13 deletions.
2 changes: 1 addition & 1 deletion reposilite-backend/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ dependencies {
val bcrypt = "0.10.2"
implementation("at.favre.lib:bcrypt:$bcrypt")

val expressible = "1.3.5"
val expressible = "1.3.6"
api("org.panda-lang:expressible:$expressible")
api("org.panda-lang:expressible-kt:$expressible")
testImplementation("org.panda-lang:expressible-junit:$expressible")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ internal class MirrorService(private val journalist: Journalist) : Journalist {
fun shouldPrioritizeMirrorRepository(repository: Repository, gav: Location): Boolean =
repository.storagePolicy == StoragePolicy.PRIORITIZE_UPSTREAM_METADATA && gav.getSimpleName().contains(METADATA_FILE)

fun findRemoteDetails(repository: Repository, gav: Location): Result<out FileDetails, ErrorResponse> =
fun findRemoteDetails(repository: Repository, gav: Location): Result<FileDetails, ErrorResponse> =
searchInRemoteRepositories(repository, gav) { (host, config, client) ->
client.head("${host.removeSuffix("/")}/$gav", config.authorization, config.connectTimeout, config.readTimeout)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal class RepositoryLoopbackClient(
private val repositoryName: String
) : RemoteClient {

override fun head(uri: String, credentials: RemoteCredentials?, connectTimeoutInSeconds: Int, readTimeoutInSeconds: Int): Result<out FileDetails, ErrorResponse> =
override fun head(uri: String, credentials: RemoteCredentials?, connectTimeoutInSeconds: Int, readTimeoutInSeconds: Int): Result<FileDetails, ErrorResponse> =
repositoryService.findDetails(
LookupRequest(
accessToken = credentials.toAccessToken(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ internal class RepositoryService(
}
}

fun findDetails(lookupRequest: LookupRequest): Result<out FileDetails, ErrorResponse> =
fun findDetails(lookupRequest: LookupRequest): Result<FileDetails, ErrorResponse> =
resolve(lookupRequest) { repository, gav -> findDetails(lookupRequest.accessToken, repository, gav) }

fun findFile(lookupRequest: LookupRequest): Result<Pair<DocumentInfo, InputStream>, ErrorResponse> =
Expand Down Expand Up @@ -135,7 +135,13 @@ internal class RepositoryService(

private fun findInputStream(repository: Repository, gav: Location): Result<InputStream, ErrorResponse> =
when {
!mirrorService.shouldPrioritizeMirrorRepository(repository, gav) && repository.storageProvider.exists(gav) -> { // todo: add fallback to local for shouldPrioritizeMirrorRepository
mirrorService.shouldPrioritizeMirrorRepository(repository, gav) -> {
logger.debug("Prioritizing mirror repository for '$gav'")
mirrorService
.findRemoteFile(repository, gav)
.flatMapErr { repository.storageProvider.getFile(gav) }
}
repository.storageProvider.exists(gav) -> {
logger.debug("Gav '$gav' found in '${repository.name}' repository")
repository.storageProvider.getFile(gav)
}
Expand All @@ -145,23 +151,29 @@ internal class RepositoryService(
}
}

private fun findDetails(accessToken: AccessTokenIdentifier?, repository: Repository, gav: Location): Result<out FileDetails, ErrorResponse> =
private fun findDetails(accessToken: AccessTokenIdentifier?, repository: Repository, gav: Location): Result<FileDetails, ErrorResponse> =
when {
!mirrorService.shouldPrioritizeMirrorRepository(repository, gav) && repository.storageProvider.exists(gav) -> findLocalDetails(accessToken, repository, gav) // todo: add fallback to local for shouldPrioritizeMirrorRepository
mirrorService.shouldPrioritizeMirrorRepository(repository, gav) -> {
logger.debug("Prioritizing mirror repository for '$gav'")
this
.findProxiedDetails(repository, gav)
.flatMapErr { findLocalDetails(accessToken, repository, gav) }
}
repository.storageProvider.exists(gav) -> findLocalDetails(accessToken, repository, gav) // todo: add fallback to local for shouldPrioritizeMirrorRepository
else -> findProxiedDetails(repository, gav)
}.peek {
recordResolvedRequest(Identifier(repository.name, gav.toString()), it)
}

private fun findLocalDetails(accessToken: AccessTokenIdentifier?, repository: Repository, gav: Location): Result<out FileDetails, ErrorResponse> =
private fun findLocalDetails(accessToken: AccessTokenIdentifier?, repository: Repository, gav: Location): Result<FileDetails, ErrorResponse> =
repository.storageProvider.getFileDetails(gav)
.flatMap {
it.takeIf { it.type == DIRECTORY }
?.let { securityProvider.canBrowseResource(accessToken, repository, gav).map { _ -> it } }
?: it.asSuccess()
}

private fun findProxiedDetails(repository: Repository, gav: Location): Result<out FileDetails, ErrorResponse> =
private fun findProxiedDetails(repository: Repository, gav: Location): Result<FileDetails, ErrorResponse> =
mirrorService
.findRemoteDetails(repository, gav)
.mapErr { notFound("Cannot find '$gav' in local and remote repositories") }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ data class RepositorySettings(
val visibility: RepositoryVisibility = PUBLIC,
@get:Doc(title = "Redeployment", description = "Does this repository accept redeployment of the same artifact version.")
val redeployment: Boolean = false,
@get:Doc(title = "Preserved snapshots", "By default Reposilite deletes all deprecated build files. If you'd like to preserve them, set this property to true.")
@get:Doc(title = "Preserved snapshots", "By default, Reposilite deletes all deprecated build files. If you'd like to preserve them, set this property to true.")
val preserveSnapshots: Boolean = false,
@get:Doc(title = "Storage provider", description = "The storage type of this repository.")
@get:OneOf(FileSystemStorageProviderSettings::class, S3StorageProviderSettings::class)
val storageProvider: StorageProviderSettings = FileSystemStorageProviderSettings(),
@get:Doc(title = "Storage policy", description = """
By default Reposilite prioritizes upstream metadata over a cached version, so it'll always try to fetch the latest version of the artifact from the remote repository. <br/>
If you'd like to go full offline mode, set this property to STRICT.
Defines how Reposilite should handle requests to repository with configured mirrored repositories. <br/>
PRIORITIZE_UPSTREAM_METADATA - try to fetch the latest version of the artifact from the remote repository <br/>
STRICT - prioritize cached version over upstream metadata (full offline mode)
""")
val storagePolicy: StoragePolicy = StoragePolicy.PRIORITIZE_UPSTREAM_METADATA,
@get:Doc(title = "Mirrored repositories", description = "List of mirrored repositories associated with this repository.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ interface RemoteClient {
* @param connectTimeoutInSeconds - connection establishment timeout in seconds
* @param readTimeoutInSeconds - connection read timeout in seconds
*/
fun head(uri: String, credentials: RemoteCredentials?, connectTimeoutInSeconds: Int, readTimeoutInSeconds: Int): Result<out FileDetails, ErrorResponse>
fun head(uri: String, credentials: RemoteCredentials?, connectTimeoutInSeconds: Int, readTimeoutInSeconds: Int): Result<FileDetails, ErrorResponse>

/**
* @param uri - full remote host address with a gav
Expand Down

0 comments on commit ac0f944

Please sign in to comment.