Skip to content

Commit

Permalink
cid-2908: Add send manifest files to the backend
Browse files Browse the repository at this point in the history
  • Loading branch information
henriq-amaral-leanix committed Oct 22, 2024
1 parent ff4e492 commit 08df32b
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 4 deletions.
12 changes: 12 additions & 0 deletions src/main/kotlin/net/leanix/githubagent/dto/ManifestFilesDTO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.leanix.githubagent.dto

data class ManifestFilesDTO(
val repositoryId: String,
val repositoryFullName: String,
val manifestFiles: List<ManifestFileDTO>
)

data class ManifestFileDTO(
val path: String,
val content: String?,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ package net.leanix.githubagent.services

import net.leanix.githubagent.client.GitHubClient
import net.leanix.githubagent.dto.Installation
import net.leanix.githubagent.dto.ItemResponse
import net.leanix.githubagent.dto.LogLevel
import net.leanix.githubagent.dto.ManifestFileDTO
import net.leanix.githubagent.dto.ManifestFilesDTO
import net.leanix.githubagent.dto.Organization
import net.leanix.githubagent.dto.OrganizationDto
import net.leanix.githubagent.dto.RepositoryDto
import net.leanix.githubagent.dto.Trigger
import net.leanix.githubagent.exceptions.JwtTokenNotFound
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
Expand All @@ -24,15 +30,30 @@ class GitHubScanningService(
fun scanGitHubResources() {
cachingService.set("runId", UUID.randomUUID(), null)
runCatching {
syncLogService.sendSyncLog(
trigger = Trigger.START_FULL_SYNC,
logLevel = LogLevel.INFO,
)
val jwtToken = cachingService.get("jwtToken") ?: throw JwtTokenNotFound()
val installations = getInstallations(jwtToken.toString())
fetchAndSendOrganisationsData(installations)
installations.forEach { installation ->
fetchAndSendRepositoriesData(installation)
.forEach { repository ->
fetchManifestFilesAndSend(installation, repository)
}
}
syncLogService.sendSyncLog(
trigger = Trigger.FINISH_FULL_SYNC,
logLevel = LogLevel.INFO,
)
}.onFailure {
val message = "Error while scanning GitHub resources"
syncLogService.sendErrorLog(message)
syncLogService.sendSyncLog(
trigger = Trigger.FINISH_FULL_SYNC,
logLevel = LogLevel.ERROR,
message = message
)
cachingService.remove("runId")
logger.error(message)
throw it
Expand Down Expand Up @@ -66,11 +87,12 @@ class GitHubScanningService(
webSocketService.sendMessage("${cachingService.get("runId")}/organizations", organizations)
}

private fun fetchAndSendRepositoriesData(installation: Installation) {
private fun fetchAndSendRepositoriesData(installation: Installation): List<RepositoryDto> {
val installationToken = cachingService.get("installationToken:${installation.id}").toString()
var cursor: String? = null
var totalRepos = 0
var page = 1
val repositories = mutableListOf<RepositoryDto>()
do {
val repositoriesPage = gitHubGraphQLService.getRepositories(
token = installationToken,
Expand All @@ -80,10 +102,54 @@ class GitHubScanningService(
"${cachingService.get("runId")}/repositories",
repositoriesPage.repositories
)
repositories.addAll(repositoriesPage.repositories)
cursor = repositoriesPage.cursor
totalRepos += repositoriesPage.repositories.size
page++
} while (repositoriesPage.hasNextPage)
logger.info("Fetched $totalRepos repositories data from organisation ${installation.account.login}")
return repositories
}

private fun fetchManifestFilesAndSend(installation: Installation, repository: RepositoryDto) {
val manifestFiles = fetchManifestFiles(installation, repository.name).getOrThrow().items
val manifestFilesContents = fetchManifestContents(installation, manifestFiles, repository.name).getOrThrow()

webSocketService.sendMessage(
"${cachingService.get("runId")}/manifestFiles",
ManifestFilesDTO(
repositoryId = repository.id,
repositoryFullName = repository.fullName,
manifestFiles = manifestFilesContents,
)
)
}

private fun fetchManifestFiles(installation: Installation, repositoryName: String) = runCatching {
val installationToken = cachingService.get("installationToken:${installation.id}").toString()
gitHubClient.searchManifestFiles(
"Bearer $installationToken",
"" +
"repo:${installation.account.login}/$repositoryName filename:leanix.yaml"
)
}
private fun fetchManifestContents(
installation: Installation,
items: List<ItemResponse>,
repositoryName: String
) = runCatching {
val installationToken = cachingService.get("installationToken:${installation.id}").toString()
items.map { manifestFile ->
val content = gitHubGraphQLService.getManifestFileContent(
owner = installation.account.login,
repositoryName = repositoryName,
filePath = manifestFile.path,
token = installationToken
)
ManifestFileDTO(
path = manifestFile.path.replace("/leanix.yaml", ""),
content = content
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import io.mockk.mockk
import io.mockk.verify
import net.leanix.githubagent.client.GitHubClient
import net.leanix.githubagent.dto.Account
import net.leanix.githubagent.dto.GitHubSearchResponse
import net.leanix.githubagent.dto.Installation
import net.leanix.githubagent.dto.InstallationTokenResponse
import net.leanix.githubagent.dto.ItemResponse
import net.leanix.githubagent.dto.Organization
import net.leanix.githubagent.dto.PagedRepositories
import net.leanix.githubagent.dto.RepositoryDto
import net.leanix.githubagent.dto.RepositoryItemResponse
import net.leanix.githubagent.exceptions.JwtTokenNotFound
import net.leanix.githubagent.graphql.data.enums.RepositoryVisibility
import org.junit.jupiter.api.BeforeEach
Expand All @@ -19,12 +22,12 @@ import java.util.UUID

class GitHubScanningServiceTest {

private val gitHubClient = mockk<GitHubClient>()
private val gitHubClient = mockk<GitHubClient>(relaxUnitFun = true)
private val cachingService = mockk<CachingService>()
private val webSocketService = mockk<WebSocketService>(relaxUnitFun = true)
private val gitHubGraphQLService = mockk<GitHubGraphQLService>()
private val gitHubAuthenticationService = mockk<GitHubAuthenticationService>()
private val syncLogService = mockk<SyncLogService>()
private val syncLogService = mockk<SyncLogService>(relaxUnitFun = true)
private val gitHubScanningService = GitHubScanningService(
gitHubClient,
cachingService,
Expand Down Expand Up @@ -103,7 +106,53 @@ class GitHubScanningServiceTest {
hasNextPage = false,
cursor = null
)
every { gitHubClient.searchManifestFiles(any(), any()) } returns GitHubSearchResponse(0, emptyList())
gitHubScanningService.scanGitHubResources()
verify { webSocketService.sendMessage(eq("$runId/repositories"), any()) }
}

@Test
fun `scanGitHubResources should send repositories and manifest files over WebSocket`() {
// given
every { cachingService.get("runId") } returns runId
every { gitHubGraphQLService.getRepositories(any(), any()) } returns PagedRepositories(
repositories = listOf(
RepositoryDto(
id = "repo1",
name = "TestRepo",
organizationName = "testOrg",
description = "A test repository",
url = "https://github.com/testRepo",
archived = false,
visibility = RepositoryVisibility.PUBLIC,
updatedAt = "2024-01-01T00:00:00Z",
languages = listOf("Kotlin", "Java"),
topics = listOf("test", "example"),
)
),
hasNextPage = false,
cursor = null
)
every { gitHubClient.searchManifestFiles(any(), any()) } returns GitHubSearchResponse(
1,
listOf(
ItemResponse(
name = "leanix.yaml",
path = "dir/leanix.yaml",
repository = RepositoryItemResponse(
name = "TestRepo",
fullName = "testOrg/TestRepo"
),
url = "http://url"
)
)
)
every { gitHubGraphQLService.getManifestFileContent(any(), any(), "dir/leanix.yaml", any()) } returns "content"

// when
gitHubScanningService.scanGitHubResources()

// then
verify { webSocketService.sendMessage(eq("$runId/manifestFiles"), any()) }
}
}

0 comments on commit 08df32b

Please sign in to comment.