Page History
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
import com.exalate.api.domain.webhook.WebhookEntityType
import com.exalate.basic.domain.hubobject.v1.BasicHubIssue
import com.exalate.basic.domain.hubobject.v1.BasicHubUser
import com.exalate.basic.domain.hubobject.v1.BasicHubWorkLog
import com.exalate.replication.services.replication.impersonation.AuditLogService
import org.slf4j.LoggerFactory
import org.slf4j.Logger
import play.libs.Json
import scala.concurrent.Await$;
import scala.concurrent.duration.Duration$;
import java.text.SimpleDateFormat
import java.time.Instant
//Your normal Incoming Sync code
//Add these functions at the end
Worklogs.receive(
"B0V4tQJ22LhPnznllWoT2s0N29So5", // replace the "token" with the previously generated access token
replica,
replica,
issue,
httpClient,
traces,
nodeHelper
)
class Worklogs {
static receive(String token, BasicHubIssue replica, BasicHubIssue issue, httpClient, traces, nodeHelper){
receive(
token,
replica,
issue,
httpClient,
traces,
nodeHelper,
{ BasicHubWorkLog w ->
def getUser = { String key ->
def localAuthor = nodeHelper.getUser(key)
if (localAuthor == null) {
localAuthor = new BasicHubUser()
localAuthor.key = "557058:c020323a-70e4-4c07-9ccc-3ad89b1c02ec"
}
localAuthor
}
w.author = w.author ? getUser(w.author.key) : null
w.updateAuthor = w.updateAuthor ? getUser(w.updateAuthor.key) : null
w
}
)
}
static receive(String token, BasicHubIssue replica, BasicHubIssue issue, httpClient, traces, nodeHelper, Closure<?> onWorklogFn){
def http = { String method, String path, Map<String, List<String>> queryParams, String body, Map<String, List<String>> headers ->
def await = { future -> Await$.MODULE$.result(future, Duration$.MODULE$.apply(60, java.util.concurrent.TimeUnit.SECONDS)) }
def orNull = { scala.Option<?> opt -> opt.isDefined() ? opt.get() : null }
def pair = { l, r -> scala.Tuple2$.MODULE$.<?, ?>apply(l, r) }
def none = { scala.Option$.MODULE$.<?> empty() }
def getGeneralSettings = {
def classLoader = this.getClassLoader()
def gsp
try {
gsp = InjectorGetter.getInjector().instanceOf(classLoader.loadClass("com.exalate.api.persistence.issuetracker.jcloud.IJCloudGeneralSettingsRepository"))
} catch(ClassNotFoundException exception) {
gsp = InjectorGetter.getInjector().instanceOf(classLoader.loadClass("com.exalate.api.persistence.issuetracker.jcloud.IJCloudGeneralSettingsPersistence"))
}
def gsOpt = await(gsp.get())
def gs = orNull(gsOpt)
gs
}
final def gs = getGeneralSettings()
def removeTailingSlash = { String str -> str.trim().replace("/+\$", "") }
final def tempoRestApiUrl = "https://api.tempo.io/core/3"
def parseQueryString = { String string ->
string.split('&').collectEntries{ param ->
param.split('=', 2).collect{ URLDecoder.decode(it, 'UTF-8') }
}
}
def parseUri
parseUri = { String uri ->
def parsedUri
try {
parsedUri = new URI(uri)
if (parsedUri.scheme == 'mailto') {
def schemeSpecificPartList = parsedUri.schemeSpecificPart.split('\\?', 2)
def tempMailMap = parseQueryString(schemeSpecificPartList[1])
//noinspection GrUnresolvedAccess
parsedUri.metaClass.mailMap = [
recipient: schemeSpecificPartList[0],
cc : tempMailMap.find { //noinspection GrUnresolvedAccess
it.key.toLowerCase() == 'cc' }.value,
bcc : tempMailMap.find { //noinspection GrUnresolvedAccess
it.key.toLowerCase() == 'bcc' }.value,
subject : tempMailMap.find { //noinspection GrUnresolvedAccess
it.key.toLowerCase() == 'subject' }.value,
body : tempMailMap.find { //noinspection GrUnresolvedAccess
it.key.toLowerCase() == 'body' }.value
]
}
if (parsedUri.fragment?.contains('?')) {
//noinspection GrUnresolvedAccess
parsedUri.metaClass.rawQuery = parsedUri.rawFragment.split('\\?')[1]
//noinspection GrUnresolvedAccess
parsedUri.metaClass.query = parsedUri.fragment.split('\\?')[1]
//noinspection GrUnresolvedAccess
parsedUri.metaClass.rawFragment = parsedUri.rawFragment.split('\\?')[0]
//noinspection GrUnresolvedAccess
parsedUri.metaClass.fragment = parsedUri.fragment.split('\\?')[0]
}
if (parsedUri.rawQuery) {
//noinspection GrUnresolvedAccess
parsedUri.metaClass.queryMap = parseQueryString(parsedUri.rawQuery)
} else {
//noinspection GrUnresolvedAccess
parsedUri.metaClass.queryMap = null
}
//noinspection GrUnresolvedAccess
if (parsedUri.queryMap) {
//noinspection GrUnresolvedAccess
parsedUri.queryMap.keySet().each { key ->
def value = parsedUri.queryMap[key]
//noinspection GrUnresolvedAccess
if (value.startsWith('http') || value.startsWith('/')) {
parsedUri.queryMap[key] = parseUri(value)
}
}
}
} catch (e) {
throw new com.exalate.api.exception.IssueTrackerException("Parsing of URI failed: $uri\n$e", e)
}
parsedUri
}
def unsanitizedUrl = tempoRestApiUrl + path
def parsedUri = parseUri(unsanitizedUrl)
def embeddedQueryParams = parsedUri.queryMap
def allQueryParams = embeddedQueryParams instanceof Map ?
({
def m = [:] as Map<String, List<String>>;
m.putAll(embeddedQueryParams as Map<String, List<String>>)
m.putAll(queryParams)
})()
: (queryParams ?: [:] as Map<String, List<String>>)
def urlWithoutQueryParams = { String url ->
URI uri = new URI(url)
new URI(uri.getScheme(),
uri.getUserInfo(), uri.getHost(), uri.getPort(),
uri.getPath(),
null,
uri.getFragment()).toString()
}
def sanitizedUrl = urlWithoutQueryParams(unsanitizedUrl)
def response
try {
def request = httpClient
.ws()
.url(sanitizedUrl)
.withMethod(method)
if (headers != null && !headers.isEmpty()) {
def scalaHeaders = scala.collection.JavaConversions.asScalaBuffer(
headers.entrySet().inject([] as List<scala.Tuple2<String, String>>) { List<scala.Tuple2<String, String>> result, kv ->
kv.value.each { v -> result.add(pair(kv.key, v) as scala.Tuple2<String, String>) }
result
}
)
request = request.withHeaders(scalaHeaders)
}
if (!allQueryParams.isEmpty()) {
def scalaQueryParams = scala.collection.JavaConversions.asScalaBuffer(queryParams.entrySet().inject([] as List<scala.Tuple2<String, String>>) { List<scala.Tuple2<String, String>> result, kv ->
kv.value.each { v -> result.add(pair(kv.key, v) as scala.Tuple2<String, String>) }
result
})
request = request.withQueryString(scalaQueryParams)
}
if (body != null) {
def writable = play.api.libs.ws.WSBodyWritables$.MODULE$.writeableOf_String()
request = request.withBody(body, writable)
}
response = await(request.execute())
} catch (Exception e) {
throw new com.exalate.api.exception.IssueTrackerException("Unable to perform the request $method $path, please contact Exalate Support: ".toString() + e.message, e)
}
if (response.status() >= 300) {
throw new com.exalate.api.exception.IssueTrackerException("Failed to perform the request $method $path ${body ? "with body `$body`".toString() : ""}(status ${response.status()}), please contact Exalate Support: ".toString() + response.body())
}
response.body() as String
}
def gsp = InjectorGetter.getInjector().instanceOf(AuditLogService.class)
def js = new groovy.json.JsonSlurper()
def jo = new groovy.json.JsonOutput()
def listAdditionalParams = replica.customKeys."tempoWorklogParams" as Map<String, Map<String, Object>>;
replica.workLogs.findAll{it.id == null}.each{ BasicHubWorkLog worklog ->
def transformedWorklog
try {
transformedWorklog = onWorklogFn(worklog)
} catch (com.exalate.api.exception.IssueTrackerException ite) {
throw ite
} catch (Exception e) {
throw new com.exalate.api.exception.IssueTrackerException(e)
}
if (transformedWorklog instanceof BasicHubWorkLog) {
worklog = transformedWorklog as BasicHubWorkLog
} else if (transformedWorklog == null) {
return
}
def auditLogOpt = gsp.createAuditLog(scala.Option$.MODULE$.<String>apply(issue.id as String),
WebhookEntityType.WORKLOG_CREATED,
worklog.getAuthor().getKey()
)
def attributes = ((listAdditionalParams?.get(worklog.remoteId.toString())?.get("attributes") as Map<String, Object>)?.get("values") as List<Map<String, String>>)?.inject([]){
List<Map<String, String>>result, Map<String, String> attribute ->
result.add(
[
key: attribute.get("key"),
value: attribute.get("value")
]
)
result
} ?: []
def properties = [
issueKey : issue.key,
timeSpentSeconds : worklog.getTimeSpent(),
billableSeconds: listAdditionalParams?.get(worklog.remoteId.toString())?.get("billableSeconds") ?: worklog.getTimeSpent(),
startDate : new java.text.SimpleDateFormat("yyyy-MM-dd").format(worklog.startDate),
startTime : new java.text.SimpleDateFormat("hh:mm:ss").format(worklog.startDate) ?: listAdditionalParams?.get(worklog.remoteId.toString())?.get("startTime"),//strDateSplitted[1].split("\\.")[0],
description : worklog.getComment(),
authorAccountId : worklog.getAuthor().getKey(),
remainingEstimateSeconds: replica.remainingEstimate ?: listAdditionalParams?.get(worklog.remoteId.toString())?.get("remainingEstimateSeconds"),
attributes : attributes
]
def jsonTempoPost = jo.toJson(properties)
def response = js.parseText(http(
"POST",
"/worklogs",
null,
jsonTempoPost,
[
"Authorization":["Bearer ${token}".toString()],
"Content-Type":["application/json"],
]
))
println(response)
gsp.updateAuditLog(scala.Option$.MODULE$.apply(auditLogOpt), issue.id as String, response["jiraWorklogId"] as String, Json.stringify(Json.toJson(response)))
String localIdStr = response["tempoWorklogId"]
String remoteIdStr = worklog.remoteId.toString()
com.exalate.api.domain.twintrace.INonPersistentTrace trace = new com.exalate.basic.domain.BasicNonPersistentTrace()
.setLocalId(localIdStr)
.setRemoteId(remoteIdStr)
.setType(com.exalate.api.domain.twintrace.TraceType.WORKLOG)
.setAction(com.exalate.api.domain.twintrace.TraceAction.NONE)
.setToSynchronize(true)
traces.add(trace)
}
}
} |
...