From 3426801f1f5147bf600233b6dc372447fc85377e Mon Sep 17 00:00:00 2001 From: hwen Date: Mon, 19 Aug 2024 17:57:15 +0800 Subject: [PATCH] fix logger caller stack --- .../gitpod/toolbox/auth/GitpodAuthManager.kt | 21 ++++---- .../toolbox/gateway/GitpodRemoteProvider.kt | 54 +++++++++---------- .../toolbox/gateway/GitpodUriHandler.kt | 3 +- .../io/gitpod/toolbox/service/DataManager.kt | 40 ++++++++++++-- .../service/GitpodConnectionProvider.kt | 4 +- .../io/gitpod/toolbox/utils/GitpodLogger.kt | 19 +++---- 6 files changed, 87 insertions(+), 54 deletions(-) diff --git a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/auth/GitpodAuthManager.kt b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/auth/GitpodAuthManager.kt index 53b656402eda2b..37159c5eced7e4 100644 --- a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/auth/GitpodAuthManager.kt +++ b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/auth/GitpodAuthManager.kt @@ -4,7 +4,6 @@ package io.gitpod.toolbox.auth -import com.connectrpc.Code import com.connectrpc.ConnectException import com.jetbrains.toolbox.gateway.auth.* import io.gitpod.publicapi.experimental.v1.UserServiceClient @@ -33,9 +32,6 @@ val authScopesJetBrainsToolbox = listOf( "function:startWorkspace", "function:stopWorkspace", "function:deleteWorkspace", - "function:getTeams", - "function:getTeamMembers", - "function:getTeamProjects", "function:getToken", "resource:default", ) @@ -79,13 +75,13 @@ class GitpodAuthManager { manager.addEventListener { when (it.type) { AuthEvent.Type.LOGIN -> { - GitpodLogger.debug("gitpod: user logged in ${it.accountId}") + GitpodLogger.info(" user logged in ${it.accountId}") resetCurrentAccount(it.accountId) loginListeners.forEach { it() } } AuthEvent.Type.LOGOUT -> { - GitpodLogger.debug("gitpod: user logged out ${it.accountId}") + GitpodLogger.info("user logged out ${it.accountId}") resetCurrentAccount(it.accountId) logoutListeners.forEach { it() } } @@ -207,16 +203,19 @@ class GitpodAccount : Account { } suspend fun isValidate(): Boolean { - val client = GitpodPublicApiManager.createClient(URI(host).host, credentials) + // TODO(hw): 11 + val client = GitpodPublicApiManager.createClient(URI("https://$host").host, credentials) + GitpodLogger.debug("validating account $host") try { GitpodPublicApiManager.tryGetAuthenticatedUser(UserServiceClient(client)) return true } catch (e: ConnectException) { - if (e.code == Code.UNAUTHENTICATED) { - return false - } +// // TODO(hw): Server close jsonrpc so papi server respond internal error +// if (e.code == Code.UNAUTHENTICATED) { +// } + GitpodLogger.error("account $host is not valid") + return false } - return true } companion object { diff --git a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/gateway/GitpodRemoteProvider.kt b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/gateway/GitpodRemoteProvider.kt index 1feff02b43b04b..d6ae81f118d85f 100644 --- a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/gateway/GitpodRemoteProvider.kt +++ b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/gateway/GitpodRemoteProvider.kt @@ -10,14 +10,12 @@ import com.jetbrains.toolbox.gateway.RemoteProvider import com.jetbrains.toolbox.gateway.ui.AccountDropdownField import com.jetbrains.toolbox.gateway.ui.ActionDescription import com.jetbrains.toolbox.gateway.ui.UiPage +import io.gitpod.publicapi.experimental.v1.Workspaces import io.gitpod.toolbox.auth.GitpodAuthManager import io.gitpod.toolbox.auth.GitpodLoginPage import io.gitpod.toolbox.components.GitpodIcon import io.gitpod.toolbox.components.SimpleButton -import io.gitpod.toolbox.service.ConnectParams -import io.gitpod.toolbox.service.GitpodPublicApiManager -import io.gitpod.toolbox.service.Utils -import io.gitpod.toolbox.service.getConnectParams +import io.gitpod.toolbox.service.* import io.gitpod.toolbox.utils.GitpodLogger import kotlinx.coroutines.launch import java.net.URI @@ -31,7 +29,7 @@ class GitpodRemoteProvider( private val loginPage = GitpodLoginPage(authManger) // cache consumed environments map locally - private val environmentMap = mutableMapOf() + private val environmentMap = mutableMapOf>() private var pendingConnectParams: Pair? = null private val openInToolboxUriHandler = GitpodOpenInToolboxUriHandler { (gitpodHost, connectParams) -> @@ -50,30 +48,25 @@ class GitpodRemoteProvider( return@GitpodOpenInToolboxUriHandler future } - private fun setEnvironmentVisibility(connectParams: ConnectParams) { + private suspend fun setEnvironmentVisibility(connectParams: ConnectParams) { val workspaceId = connectParams.workspaceId GitpodLogger.debug("setEnvironmentVisibility $workspaceId, $connectParams") - val env = environmentMap[connectParams.uniqueID] - if (env != null) { - env.markActive() - Utils.clientHelper.setAutoConnectOnEnvironmentReady( - connectParams.uniqueID, - "GO-242.20224.39", - "/workspace/empty" - ) - } else { - GitpodRemoteProviderEnvironment( + val obj = environmentMap[connectParams.uniqueID] + var (workspace, env) = obj ?: Pair(null, null) + if (obj == null) { + workspace = publicApi.getWorkspace(workspaceId) + env = GitpodRemoteProviderEnvironment( authManger, connectParams, publicApi, Utils.observablePropertiesFactory - ).apply { - environmentMap[connectParams.uniqueID] = this - this.markActive() - consumer.consumeEnvironments(listOf(this)) - Utils.clientHelper.setAutoConnectOnEnvironmentReady(workspaceId, "GO-242.20224.39", "/workspace/empty") - } + ) + environmentMap[connectParams.uniqueID] = Pair(workspace, env) + consumer.consumeEnvironments(environmentMap.values.map { it.second }) } + env!!.markActive() + val joinLinkInfo = workspace!!.fetchJoinLink2Info(publicApi.getWorkspaceOwnerToken(workspaceId)) + Utils.clientHelper.setAutoConnectOnEnvironmentReady(workspaceId, joinLinkInfo.ideVersion, joinLinkInfo.projectPath) } private fun showWorkspacesList() { @@ -84,13 +77,13 @@ class GitpodRemoteProvider( } consumer.consumeEnvironments(workspaces.map { val connectParams = it.getConnectParams() - val env = environmentMap[connectParams.uniqueID] ?: GitpodRemoteProviderEnvironment( + val env = environmentMap[connectParams.uniqueID]?.second ?: GitpodRemoteProviderEnvironment( authManger, connectParams, publicApi, Utils.observablePropertiesFactory ) - environmentMap[connectParams.uniqueID] = env + environmentMap[connectParams.uniqueID] = Pair(it, env) if (connectParams.uniqueID == pendingConnectParams?.second?.uniqueID) { setEnvironmentVisibility(connectParams) pendingConnectParams = null @@ -108,9 +101,6 @@ class GitpodRemoteProvider( } override fun getOverrideUiPage(): UiPage? { - val account = authManger.getCurrentAccount() - account ?: return loginPage - startup() authManger.addLoginListener { Utils.toolboxUi.showWindow() Utils.toolboxUi.showPluginEnvironmentsPage() @@ -120,6 +110,16 @@ class GitpodRemoteProvider( Utils.toolboxUi.showWindow() Utils.toolboxUi.showPluginEnvironmentsPage() } + val account = authManger.getCurrentAccount() + account ?: return loginPage + startup() + Utils.coroutineScope.launch { + if (account.isValidate()) { + return@launch + } + authManger.logout() + Utils.toolboxUi.showPluginEnvironmentsPage() + } return null } diff --git a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/gateway/GitpodUriHandler.kt b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/gateway/GitpodUriHandler.kt index 631f461fc8621e..a9aa7fcfab6be7 100644 --- a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/gateway/GitpodUriHandler.kt +++ b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/gateway/GitpodUriHandler.kt @@ -56,6 +56,7 @@ class GitpodOpenInToolboxUriHandler(val handler: (Pair) - throw IllegalArgumentException("invalid host: $host") } GitpodLogger.debug("parsed URI: $host, $workspaceId, $debugWorkspace") - return Pair("https://$host", ConnectParams(workspaceId, debugWorkspace)) + val gitpodHost = "https://$host" + return Pair(gitpodHost, ConnectParams(workspaceId, gitpodHost, debugWorkspace)) } } diff --git a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/service/DataManager.kt b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/service/DataManager.kt index ef8f14c2485eaa..6e0161cb29d670 100644 --- a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/service/DataManager.kt +++ b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/service/DataManager.kt @@ -4,8 +4,42 @@ package io.gitpod.toolbox.service -import io.gitpod.publicapi.experimental.v1.Workspaces +import io.gitpod.publicapi.experimental.v1.Workspaces.Workspace +import io.gitpod.toolbox.utils.await +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import okhttp3.Request +import java.net.URL -fun Workspaces.Workspace.getConnectParams(): ConnectParams { - return ConnectParams(workspaceId, false) +fun Workspace.getConnectParams(): ConnectParams { + return ConnectParams(workspaceId, getGitpodHost(), false) } + +fun Workspace.getIDEUrl(): String { + return status.instance.status.url +} + +fun Workspace.getGitpodHost(): String { + val ideUrl = URL(getIDEUrl()) + val hostSegments = ideUrl.host.split(".") + return hostSegments.takeLast(2).joinToString(".") +} + +@Serializable +class JoinLink2Response(val appPid: Int, val joinLink: String, val ideVersion: String, val projectPath: String) + +suspend fun Workspace.fetchJoinLink2Info(ownerToken: String): JoinLink2Response { + val backendUrl = "https://24000-${URL(getIDEUrl()).host}/joinLink2" + val client = Utils.httpClient + val req = Request.Builder().url(backendUrl).header("x-gitpod-owner-token", ownerToken) + val response = client.newCall(req.build()).await() + if (!response.isSuccessful) { + throw IllegalStateException("Failed to get join link $backendUrl info: ${response.code} ${response.message}") + } + if (response.body == null) { + throw IllegalStateException("Failed to get join link $backendUrl info: no body") + } + return Json.decodeFromString(response.body!!.string()) +} + diff --git a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/service/GitpodConnectionProvider.kt b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/service/GitpodConnectionProvider.kt index de24556bd121f0..61ce202fc9ad54 100644 --- a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/service/GitpodConnectionProvider.kt +++ b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/service/GitpodConnectionProvider.kt @@ -24,9 +24,6 @@ class GitpodConnectionProvider( val ownerToken = publicApi.getWorkspaceOwnerToken(workspaceId) val account = authManager.getCurrentAccount() ?: throw Exception("No account found") - // TODO: debug workspace - val connectParams = ConnectParams(workspaceId, false) - val (serverPort, cancel) = tunnelWithWebSocket(workspace, connectParams, ownerToken) val connInfo = GitpodWebSocketSshConnectionInfo( @@ -82,6 +79,7 @@ class GitpodWebSocketSshConnectionInfo( data class ConnectParams( val workspaceId: String, + val host: String, val debugWorkspace: Boolean = false, ) { val resolvedWorkspaceId = "${if (debugWorkspace) "debug-" else ""}$workspaceId" diff --git a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/utils/GitpodLogger.kt b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/utils/GitpodLogger.kt index dd339cbbbb21a3..fad157ef56d5cf 100644 --- a/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/utils/GitpodLogger.kt +++ b/components/ide/jetbrains/toolbox/src/main/kotlin/io/gitpod/toolbox/utils/GitpodLogger.kt @@ -4,41 +4,42 @@ package io.gitpod.toolbox.utils -import org.slf4j.Logger import org.slf4j.LoggerFactory +import org.slf4j.spi.LocationAwareLogger object GitpodLogger { - private val logger: Logger = LoggerFactory.getLogger(javaClass) + private val logger: LocationAwareLogger = LoggerFactory.getLogger(javaClass) as LocationAwareLogger + private val FQCN = GitpodLogger::class.java.name private fun formatMessage(msg: String): String { return "[gitpod] $msg" } fun info(message: String) { - logger.info(formatMessage(message)) + logger.log(null, FQCN, LocationAwareLogger.INFO_INT, formatMessage(message), null, null) } fun debug(message: String) { - logger.debug(formatMessage(message)) + logger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, formatMessage(message), null, null) } fun warn(message: String) { - logger.warn(formatMessage(message)) + logger.log(null, FQCN, LocationAwareLogger.WARN_INT, formatMessage(message), null, null) } fun warn(message: String, throwable: Throwable?) { - logger.warn(formatMessage(message), throwable) + logger.log(null, FQCN, LocationAwareLogger.WARN_INT, formatMessage(message), null, throwable) } fun error(message: String) { - logger.error(formatMessage(message)) + logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, formatMessage(message), null, null) } fun error(message: String, throwable: Throwable?) { - logger.error(formatMessage(message), throwable) + logger.log(null, FQCN, LocationAwareLogger.ERROR_INT, formatMessage(message), null, throwable) } fun trace(message: String) { - logger.trace(formatMessage(message)) + logger.log(null, FQCN, LocationAwareLogger.TRACE_INT, formatMessage(message), null, null) } }