From bd51a4e8ea68a28afd851efdaade897edfb6ae33 Mon Sep 17 00:00:00 2001 From: Christian Kurz Date: Tue, 27 Aug 2024 16:29:43 +0200 Subject: [PATCH 1/4] data center related changes --- .../gropius/sync/jira/JiraDataService.kt | 37 +++++++++++++++++-- .../gropius/sync/jira/JiraTokenManager.kt | 9 ++++- .../gropius/sync/jira/model/IssueData.kt | 12 +++--- .../gropius/sync/jira/model/ProjectQuery.kt | 2 +- .../main/kotlin/gropius/sync/AbstractSync.kt | 2 +- .../main/kotlin/gropius/sync/TokenManager.kt | 7 +++- 6 files changed, 55 insertions(+), 14 deletions(-) diff --git a/jira/src/main/kotlin/gropius/sync/jira/JiraDataService.kt b/jira/src/main/kotlin/gropius/sync/jira/JiraDataService.kt index 46181564..e701ddab 100644 --- a/jira/src/main/kotlin/gropius/sync/jira/JiraDataService.kt +++ b/jira/src/main/kotlin/gropius/sync/jira/JiraDataService.kt @@ -152,8 +152,10 @@ class JiraDataService( * @return the IMSUser for the Jira user */ suspend fun mapUser(imsProject: IMSProject, user: JsonElement): User { - val encodedAccountId = - jsonNodeMapper.jsonNodeToDeterministicString(objectMapper.valueToTree(user.jsonObject["accountId"]!!.jsonPrimitive.content)) + val encodedAccountId = if (user.jsonObject["accountId"] != null) jsonNodeMapper.jsonNodeToDeterministicString( + objectMapper.valueToTree(user.jsonObject["accountId"]!!.jsonPrimitive.content) + ) + else jsonNodeMapper.jsonNodeToDeterministicString(objectMapper.valueToTree(user.jsonObject["key"]!!.jsonPrimitive.content)) val foundImsUser = imsProject.ims().value.users().firstOrNull { it.templatedFields["jira_id"] == encodedAccountId } if (foundImsUser != null) { @@ -221,7 +223,36 @@ class JiraDataService( val cloudId = token.cloudIds?.filter { URI(it.url + "/rest/api/2") == URI(imsConfig.rootUrl.toString()) }?.map { it.id } ?.firstOrNull() - if (cloudId != null) { + if (token.type == "PAT") { + try { + val res = client.request(imsConfig.rootUrl.toString()) { + method = requestMethod + url { + appendPathSegments("/rest/api/2/") + urlBuilder(this) + } + headers { + append( + HttpHeaders.Authorization, "Bearer ${token.token}" + ) + } + if (body != null) { + contentType(ContentType.parse(JSON_CHARSET_MIME_TYPE)) + setBody(body) + } + } + logger.info("Response Code for request with token token is ${res.status}(${res.status.isSuccess()}): $body is ${res.bodyAsText()}") + return if (res.status.isSuccess()) { + logger.trace("Response for {} {}", res.request.url, res.bodyAsText()) + Optional.of(res) + } else { + Optional.empty() + } + } catch (e: ClientRequestException) { + e.printStackTrace() + return Optional.empty() + } + } else if (cloudId != null) { try { val res = client.request("https://api.atlassian.com/ex/jira/") { method = requestMethod diff --git a/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt b/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt index 777a5109..6389b491 100644 --- a/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt +++ b/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt @@ -21,7 +21,10 @@ data class JiraCloudId(val id: String, val url: String, val name: String, val sc */ @Serializable data class JiraTokenResponse( - override val token: String?, override val isImsUserKnown: Boolean, val cloudIds: List? = null + override val token: String?, + override val isImsUserKnown: Boolean, + val cloudIds: List? = null, + val type: String? = null ) : BaseResponseType @Component @@ -30,6 +33,8 @@ class JiraTokenManager( neoOperations: ReactiveNeo4jOperations, syncConfigurationProperties: SyncConfigurationProperties ) : TokenManager(neoOperations, syncConfigurationProperties) { override suspend fun parseHttpBody(response: HttpResponse): JiraTokenResponse? { - return response.body() + val v = response.body() + println("Response ${response.bodyAsText()} leading to $v had no token") + return v } } \ No newline at end of file diff --git a/jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt b/jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt index 30df2925..0e3ebee2 100644 --- a/jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt +++ b/jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt @@ -62,13 +62,15 @@ class JiraTimelineItem(val id: String, val created: String, val author: JsonObje issue: Issue ): Pair, TimelineItemConversionInformation> { val jiraService = (service as JiraDataService) - if (data.fieldId == "summary") { + println("SYNC FIELD ${data.fieldId} ${data.field}") + val fieldId = data.fieldId ?: data.field + if (fieldId == "summary") { return gropiusSummary(timelineItemConversionInformation, imsProject, service, jiraService) - } else if (data.fieldId == "resolution") { + } else if (fieldId == "resolution") { return gropiusState( timelineItemConversionInformation, imsProject, service, jiraService ) - } else if (data.fieldId == "labels") { + } else if (fieldId == "labels") { return gropiusLabels( timelineItemConversionInformation, imsProject, service, jiraService ) @@ -216,6 +218,7 @@ class JiraTimelineItem(val id: String, val created: String, val author: JsonObje titleChangedEvent.lastModifiedBy().value = jiraService.mapUser(imsProject, author) titleChangedEvent.oldState().value = jiraService.issueState(imsProject, data.fromString == null) titleChangedEvent.newState().value = jiraService.issueState(imsProject, data.toString == null) + println("MAPPING STATE ${data.fromString} to ${data.toString} ==> ${titleChangedEvent.oldState().value} to ${titleChangedEvent.newState().value}") return listOf( titleChangedEvent ) to convInfo; @@ -360,8 +363,7 @@ data class IssueData( } override suspend fun fillImsIssueTemplatedFields( - templatedFields: MutableMap, - service: SyncDataService + templatedFields: MutableMap, service: SyncDataService ) { } diff --git a/jira/src/main/kotlin/gropius/sync/jira/model/ProjectQuery.kt b/jira/src/main/kotlin/gropius/sync/jira/model/ProjectQuery.kt index 8a0f82de..5869a1f2 100644 --- a/jira/src/main/kotlin/gropius/sync/jira/model/ProjectQuery.kt +++ b/jira/src/main/kotlin/gropius/sync/jira/model/ProjectQuery.kt @@ -133,7 +133,7 @@ data class JiraComment( val updateAuthor: JsonObject, val created: String, val updated: String, - val jsdPublic: Boolean + val jsdPublic: Boolean? = null ) {} /** diff --git a/sync/src/main/kotlin/gropius/sync/AbstractSync.kt b/sync/src/main/kotlin/gropius/sync/AbstractSync.kt index 2847c651..e53e6f9d 100644 --- a/sync/src/main/kotlin/gropius/sync/AbstractSync.kt +++ b/sync/src/main/kotlin/gropius/sync/AbstractSync.kt @@ -503,7 +503,7 @@ abstract class AbstractSync( rawTimelineItems = dereplicationResult.resultingTimelineItems } val timelineItems = rawTimelineItems.toMutableList() - integrateLabelToState(timelineItems, rawTimelineItems, issue, imsProject) + //integrateLabelToState(timelineItems, rawTimelineItems, issue, imsProject) if (timelineItems.isNotEmpty()) {//TODO: Handle multiple timelineItems.forEach { it.issue().value = issue } issue.timelineItems() += timelineItems diff --git a/sync/src/main/kotlin/gropius/sync/TokenManager.kt b/sync/src/main/kotlin/gropius/sync/TokenManager.kt index c024cbf0..10021cc7 100644 --- a/sync/src/main/kotlin/gropius/sync/TokenManager.kt +++ b/sync/src/main/kotlin/gropius/sync/TokenManager.kt @@ -12,6 +12,7 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.serialization.kotlinx.json.* +import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier @@ -34,6 +35,7 @@ interface BaseResponseType { val isImsUserKnown: Boolean } +@Serializable data class LinkImsUserQuery(val imsUserIds: List) /** @@ -203,7 +205,8 @@ abstract class TokenManager( } else { logger.trace("User ${user.rawId} had no token") } - } + } else + logger.trace("User $user does not allow sync from $owner") } TODO("Error Message for no working users") } @@ -234,7 +237,7 @@ abstract class TokenManager( * @param user The user AFTER BEING SAVED TO DB (valid, non-null rawId) */ suspend fun advertiseIMSUser(user: IMSUser) { - client.post(syncConfigurationProperties.loginServiceBase.toString()) { + client.put(syncConfigurationProperties.loginServiceBase.toString()) { url { appendPathSegments("auth", "api", "sync", "link-ims-users") } From b1e1495e724c2fb92c199d62dece06e9cfdfb05c Mon Sep 17 00:00:00 2001 From: Christian Kurz Date: Tue, 27 Aug 2024 16:31:18 +0200 Subject: [PATCH 2/4] reduce println --- jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt | 4 +--- jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt | 2 -- sync/src/main/kotlin/gropius/sync/AbstractSync.kt | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt b/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt index 6389b491..3dd54641 100644 --- a/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt +++ b/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt @@ -33,8 +33,6 @@ class JiraTokenManager( neoOperations: ReactiveNeo4jOperations, syncConfigurationProperties: SyncConfigurationProperties ) : TokenManager(neoOperations, syncConfigurationProperties) { override suspend fun parseHttpBody(response: HttpResponse): JiraTokenResponse? { - val v = response.body() - println("Response ${response.bodyAsText()} leading to $v had no token") - return v + return response.body() } } \ No newline at end of file diff --git a/jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt b/jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt index 0e3ebee2..9feb4e84 100644 --- a/jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt +++ b/jira/src/main/kotlin/gropius/sync/jira/model/IssueData.kt @@ -62,7 +62,6 @@ class JiraTimelineItem(val id: String, val created: String, val author: JsonObje issue: Issue ): Pair, TimelineItemConversionInformation> { val jiraService = (service as JiraDataService) - println("SYNC FIELD ${data.fieldId} ${data.field}") val fieldId = data.fieldId ?: data.field if (fieldId == "summary") { return gropiusSummary(timelineItemConversionInformation, imsProject, service, jiraService) @@ -218,7 +217,6 @@ class JiraTimelineItem(val id: String, val created: String, val author: JsonObje titleChangedEvent.lastModifiedBy().value = jiraService.mapUser(imsProject, author) titleChangedEvent.oldState().value = jiraService.issueState(imsProject, data.fromString == null) titleChangedEvent.newState().value = jiraService.issueState(imsProject, data.toString == null) - println("MAPPING STATE ${data.fromString} to ${data.toString} ==> ${titleChangedEvent.oldState().value} to ${titleChangedEvent.newState().value}") return listOf( titleChangedEvent ) to convInfo; diff --git a/sync/src/main/kotlin/gropius/sync/AbstractSync.kt b/sync/src/main/kotlin/gropius/sync/AbstractSync.kt index e53e6f9d..2847c651 100644 --- a/sync/src/main/kotlin/gropius/sync/AbstractSync.kt +++ b/sync/src/main/kotlin/gropius/sync/AbstractSync.kt @@ -503,7 +503,7 @@ abstract class AbstractSync( rawTimelineItems = dereplicationResult.resultingTimelineItems } val timelineItems = rawTimelineItems.toMutableList() - //integrateLabelToState(timelineItems, rawTimelineItems, issue, imsProject) + integrateLabelToState(timelineItems, rawTimelineItems, issue, imsProject) if (timelineItems.isNotEmpty()) {//TODO: Handle multiple timelineItems.forEach { it.issue().value = issue } issue.timelineItems() += timelineItems From 4aaad5a040abe4901462c3219f117f8230d44762 Mon Sep 17 00:00:00 2001 From: Christian Kurz Date: Tue, 27 Aug 2024 16:32:14 +0200 Subject: [PATCH 3/4] dokka --- jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt b/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt index 3dd54641..f973c7eb 100644 --- a/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt +++ b/jira/src/main/kotlin/gropius/sync/jira/JiraTokenManager.kt @@ -18,6 +18,8 @@ data class JiraCloudId(val id: String, val url: String, val name: String, val sc * Response of the getIMSToken login endpoint * @param token Token if available * @param isImsUserKnown True if the user exists and just has no token + * @param cloudIds List of cloud ids + * @param type Type of the token */ @Serializable data class JiraTokenResponse( From e83209acc6d2f05d0667cb17029094ca76e2b2bd Mon Sep 17 00:00:00 2001 From: Christian Kurz Date: Tue, 27 Aug 2024 18:33:02 +0200 Subject: [PATCH 4/4] {}{}{}{}{}{} --- sync/src/main/kotlin/gropius/sync/TokenManager.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sync/src/main/kotlin/gropius/sync/TokenManager.kt b/sync/src/main/kotlin/gropius/sync/TokenManager.kt index 10021cc7..d9cf7d39 100644 --- a/sync/src/main/kotlin/gropius/sync/TokenManager.kt +++ b/sync/src/main/kotlin/gropius/sync/TokenManager.kt @@ -205,8 +205,9 @@ abstract class TokenManager( } else { logger.trace("User ${user.rawId} had no token") } - } else + } else { logger.trace("User $user does not allow sync from $owner") + } } TODO("Error Message for no working users") }