Skip to content

Commit

Permalink
Add create/get/delete tag endpoints. (#45)
Browse files Browse the repository at this point in the history
Also:
* fix Gitea PR creation
* refactor deferred result mechanism
  • Loading branch information
CamaradeRoman committed Jun 20, 2024
1 parent 3d877e9 commit 1990dd1
Show file tree
Hide file tree
Showing 35 changed files with 662 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,16 @@ package org.octopusden.octopus.vcsfacade.client
import feign.Param
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*

private const val ISO_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
import java.util.Date

class DateToISOExpander : Param.Expander {
override fun expand(value: Any?): String {
if (value == null) {
return ""
}
return (value as? Date)
?.let { date ->
return FORMATTER.format(date.toInstant())
}
override fun expand(value: Any?) = if (value == null) "" else {
(value as? Date)?.let { FORMATTER.format(it.toInstant()) }
?: throw IllegalArgumentException("Value must be as java.util.Date but was '${value::class.qualifiedName}'")
}

companion object {
private val FORMATTER = DateTimeFormatter.ofPattern(ISO_PATTERN)
private val FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
.withZone(ZoneId.systemDefault())
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.octopusden.octopus.vcsfacade.client.common.dto.Branch
import org.octopusden.octopus.vcsfacade.client.common.dto.Commit
import org.octopusden.octopus.vcsfacade.client.common.dto.CommitWithFiles
import org.octopusden.octopus.vcsfacade.client.common.dto.CreatePullRequest
import org.octopusden.octopus.vcsfacade.client.common.dto.CreateTag
import org.octopusden.octopus.vcsfacade.client.common.dto.PullRequest
import org.octopusden.octopus.vcsfacade.client.common.dto.SearchIssueInRangesResponse
import org.octopusden.octopus.vcsfacade.client.common.dto.SearchIssuesInRangesRequest
Expand Down Expand Up @@ -53,6 +54,16 @@ interface VcsFacadeClient {
@RequestLine("GET rest/api/2/repository/tags?sshUrl={sshUrl}")
fun getTags(@Param("sshUrl") sshUrl: String): List<Tag>

@RequestLine("POST rest/api/2/repository/tags?sshUrl={sshUrl}")
@Headers("Content-Type: application/json")
fun createTag(@Param("sshUrl") sshUrl: String, createTag: CreateTag): Tag

@RequestLine("GET rest/api/2/repository/tag?sshUrl={sshUrl}&name={name}")
fun getTag(@Param("sshUrl") sshUrl: String, @Param("name") name: String): Tag

@RequestLine("DELETE rest/api/2/repository/tag?sshUrl={sshUrl}&name={name}")
fun deleteTag(@Param("sshUrl") sshUrl: String, @Param("name") name: String)

@RequestLine("POST rest/api/2/repository/search-issues-in-ranges")
@Headers("Content-Type: application/json")
fun searchIssuesInRanges(searchRequest: SearchIssuesInRangesRequest): SearchIssueInRangesResponse
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.octopusden.octopus.vcsfacade.client

import com.fasterxml.jackson.databind.ObjectMapper
import feign.InvocationContext
import feign.ResponseInterceptor
import feign.RetryableException
import org.apache.http.HttpStatus
import org.octopusden.octopus.vcsfacade.client.common.Constants
import org.octopusden.octopus.vcsfacade.client.common.dto.RetryResponse

class VcsFacadeResponseInterceptor(private val objectMapper: ObjectMapper) : ResponseInterceptor {
override fun intercept(invocationContext: InvocationContext?, chain: ResponseInterceptor.Chain) =
invocationContext?.let {
with(it.response()) {
if (status() == HttpStatus.SC_ACCEPTED) {
val retryResponse = body().asInputStream().use { inputStream ->
objectMapper.readValue(inputStream, RetryResponse::class.java)
}
if (!request().headers().containsKey(Constants.DEFERRED_RESULT_HEADER)) {
request().requestTemplate().header(Constants.DEFERRED_RESULT_HEADER, retryResponse.requestId)
}
throw RetryableException(
HttpStatus.SC_ACCEPTED,
"Waiting for deferred result",
request().httpMethod(),
retryResponse.retryAfter.time,
request()
)
}
}
chain.next(it)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,24 @@ import java.util.concurrent.TimeUnit
import org.apache.http.HttpStatus
import org.slf4j.LoggerFactory

const val numberAttempts: Int = 5
const val timeDelayAttempt: Int = 300
const val numberIterations: Int = 5

class VcsFacadeRetry(private val timeRetryInMillis: Int = 60000) : Retryer {
private val timeDelayIteration: Int = timeRetryInMillis / numberIterations - (numberAttempts * timeDelayAttempt)
class VcsFacadeRetryer(private val timeRetryInMillis: Int = 60000) : Retryer {
private val timeDelayIteration: Int = timeRetryInMillis / NUMBER_ITERATIONS - (NUMBER_ATTEMPTS * TIME_DELAY_ATTEMPT)
private val stopTime = System.currentTimeMillis() + timeRetryInMillis
private var attempt: Int = numberAttempts
private var iteration: Int = numberIterations
private var attempt: Int = NUMBER_ATTEMPTS
private var iteration: Int = NUMBER_ITERATIONS

override fun continueOrPropagate(e: RetryableException) {
strategies.getOrDefault(e.status()) {
if (stopTime < System.currentTimeMillis()) {
throw e.cause!!
}
if (log.isDebugEnabled) {
log.debug("Retry: iteration=${numberIterations - iteration + 1}, attempt=${numberAttempts - attempt + 1}")
log.debug("Retry: iteration=${NUMBER_ITERATIONS - iteration + 1}, attempt=${NUMBER_ATTEMPTS - attempt + 1}")
}
if (attempt-- > 0) {
TimeUnit.MILLISECONDS.sleep(timeDelayAttempt.toLong())
TimeUnit.MILLISECONDS.sleep(TIME_DELAY_ATTEMPT.toLong())
} else if (iteration-- > 0) {
attempt = numberAttempts
attempt = NUMBER_ATTEMPTS
TimeUnit.MILLISECONDS.sleep(timeDelayIteration.toLong())
} else {
throw e.cause!!
Expand All @@ -37,11 +33,15 @@ class VcsFacadeRetry(private val timeRetryInMillis: Int = 60000) : Retryer {
}

override fun clone(): Retryer {
return VcsFacadeRetry(timeRetryInMillis)
return VcsFacadeRetryer(timeRetryInMillis)
}

companion object {
private val log = LoggerFactory.getLogger(VcsFacadeRetry::class.java)
private const val NUMBER_ATTEMPTS = 5
private const val TIME_DELAY_ATTEMPT = 300
private const val NUMBER_ITERATIONS = 5

private val log = LoggerFactory.getLogger(VcsFacadeRetryer::class.java)
private val strategies = mapOf<Int, (e: RetryableException) -> Unit>(HttpStatus.SC_ACCEPTED to { e ->
val currentDate = Date()
val retryAfterDate = Date(e.retryAfter())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import feign.Feign
import feign.Logger
import feign.Request
import feign.httpclient.ApacheHttpClient
import feign.jackson.JacksonDecoder
import feign.jackson.JacksonEncoder
import feign.slf4j.Slf4jLogger
import java.util.Date
import java.util.concurrent.TimeUnit
import org.octopusden.octopus.vcsfacade.client.DeferredResultDecoder
import org.octopusden.octopus.vcsfacade.client.VcsFacadeResponseInterceptor
import org.octopusden.octopus.vcsfacade.client.VcsFacadeClient
import org.octopusden.octopus.vcsfacade.client.VcsFacadeErrorDecoder
import org.octopusden.octopus.vcsfacade.client.VcsFacadeRetry
import org.octopusden.octopus.vcsfacade.client.VcsFacadeRetryer
import org.octopusden.octopus.vcsfacade.client.common.dto.CreatePullRequest
import org.octopusden.octopus.vcsfacade.client.common.dto.CreateTag
import org.octopusden.octopus.vcsfacade.client.common.dto.SearchIssuesInRangesRequest

class ClassicVcsFacadeClient(
Expand Down Expand Up @@ -50,6 +52,12 @@ class ClassicVcsFacadeClient(

override fun getTags(sshUrl: String) = client.getTags(sshUrl)

override fun createTag(sshUrl: String, createTag: CreateTag) = client.createTag(sshUrl, createTag)

override fun getTag(sshUrl: String, name: String) = client.getTag(sshUrl, name)

override fun deleteTag(sshUrl: String, name: String) = client.deleteTag(sshUrl, name)

override fun searchIssuesInRanges(searchRequest: SearchIssuesInRangesRequest) =
client.searchIssuesInRanges(searchRequest)

Expand Down Expand Up @@ -81,9 +89,10 @@ class ClassicVcsFacadeClient(
private fun createClient(apiUrl: String, objectMapper: ObjectMapper, timeRetryInMillis: Int): VcsFacadeClient {
return Feign.builder().client(ApacheHttpClient())
.options(Request.Options(30, TimeUnit.SECONDS, 30, TimeUnit.SECONDS, true))
.encoder(JacksonEncoder(objectMapper)).decoder(DeferredResultDecoder(objectMapper))
.errorDecoder(VcsFacadeErrorDecoder(objectMapper)).retryer(VcsFacadeRetry(timeRetryInMillis))
.logger(Slf4jLogger(VcsFacadeClient::class.java)).logLevel(Logger.Level.FULL)
.encoder(JacksonEncoder(objectMapper))
.responseInterceptor(VcsFacadeResponseInterceptor(objectMapper)).retryer(VcsFacadeRetryer(timeRetryInMillis))
.decoder(JacksonDecoder(objectMapper)).errorDecoder(VcsFacadeErrorDecoder(objectMapper))
.target(VcsFacadeClient::class.java, apiUrl)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ data class Commit(
val parents: List<String>,
val link: String,
val repository: Repository
) : VcsFacadeResponse, Comparable<Commit> {
) : Comparable<Commit> {
override fun compareTo(other: Commit) =
compareBy(Commit::repository).thenByDescending(Commit::date).compare(this, other)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ data class CommitWithFiles(
val commit: Commit,
val totalFiles: Int,
val files: List<FileChange>
) : VcsFacadeResponse, Comparable<CommitWithFiles> {
) : Comparable<CommitWithFiles> {
override fun compareTo(other: CommitWithFiles) = commit compareTo other.commit
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.octopusden.octopus.vcsfacade.client.common.dto

data class CreateTag(val name: String, val hashOrRef: String, val message: String)
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package org.octopusden.octopus.vcsfacade.client.common.dto

data class SearchIssueInRangesResponse(val issueRanges: Map<String, Set<RepositoryRange>>) : VcsFacadeResponse
data class SearchIssueInRangesResponse(val issueRanges: Map<String, Set<RepositoryRange>>)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ data class SearchSummary(
val branches: SearchBranchesSummary,
val commits: SearchCommitsSummary,
val pullRequests: SearchPullRequestsSummary
) : VcsFacadeResponse {
) {
data class SearchBranchesSummary(val size: Int, val updated: Date?)
data class SearchCommitsSummary(val size: Int, val latest: Date?)
data class SearchPullRequestsSummary(val size: Int, val updated: Date?, val status: PullRequestStatus?)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import java.util.Date
import org.octopusden.octopus.infrastructure.common.test.TestClient
import org.octopusden.octopus.vcsfacade.TestService.Companion.VCS_FACADE_API_URL
import org.octopusden.octopus.vcsfacade.client.common.dto.CreatePullRequest
import org.octopusden.octopus.vcsfacade.client.common.dto.CreateTag
import org.octopusden.octopus.vcsfacade.client.common.dto.SearchIssuesInRangesRequest
import org.octopusden.octopus.vcsfacade.client.impl.ClassicVcsFacadeClient
import org.octopusden.octopus.vcsfacade.client.impl.VcsFacadeClientParametersProvider
Expand Down Expand Up @@ -43,6 +44,12 @@ abstract class BaseVcsFacadeFunctionalTest(

override fun getTags(sshUrl: String) = client.getTags(sshUrl)

override fun createTag(sshUrl: String, createTag: CreateTag) = client.createTag(sshUrl, createTag)

override fun getTag(sshUrl: String, name: String) = client.getTag(sshUrl, name)

override fun deleteTag(sshUrl: String, name: String) = client.deleteTag(sshUrl, name)

override fun searchIssuesInRanges(searchRequest: SearchIssuesInRangesRequest) =
client.searchIssuesInRanges(searchRequest)

Expand Down
Loading

0 comments on commit 1990dd1

Please sign in to comment.