From bee7371b24e4e6d595e8ded09b5750d19bc74d16 Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Wed, 24 Apr 2024 08:49:40 +0200 Subject: [PATCH 1/9] Update to preview 6 --- .../me/rafaelldi/aspire/workload/AspireWorkloadService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/me/rafaelldi/aspire/workload/AspireWorkloadService.kt b/src/main/kotlin/me/rafaelldi/aspire/workload/AspireWorkloadService.kt index daf851a3..b2f97354 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/workload/AspireWorkloadService.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/workload/AspireWorkloadService.kt @@ -34,7 +34,7 @@ class AspireWorkloadService(private val project: Project, private val scope: Cor private val LOG = logger() - private const val CURRENT_VERSION = "8.0.0-preview.5.24201.12" + private const val CURRENT_VERSION = "8.0.0-preview.6.24214.1" private val aspireRegex = Regex("^aspire", RegexOption.MULTILINE) private val aspireVersionRegex = Regex("^aspire\\s+([\\w.\\-]+)", RegexOption.MULTILINE) @@ -66,7 +66,7 @@ class AspireWorkloadService(private val project: Project, private val scope: Cor .addAction(object : NotificationAction(AspireBundle.message("notifications.go.to.documentation")) { override fun actionPerformed(e: AnActionEvent, notification: Notification) { - BrowserUtil.open("https://learn.microsoft.com/en-us/dotnet/aspire/whats-new/preview-5") + BrowserUtil.open("https://learn.microsoft.com/en-us/dotnet/aspire/whats-new/preview-6") } }) .addAction(object : From 5073003dc4944fe159e9dc32b5dfbef67da9bd22 Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Wed, 24 Apr 2024 08:51:24 +0200 Subject: [PATCH 2/9] Update version and changelog --- CHANGELOG.md | 4 ++++ gradle.properties | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f0f2e0c..da9fe11f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ ## [Unreleased] +### Changed + +- Support for .NET Aspire preview 6 + ## [0.5.0] - 2024-04-12 ### Changed diff --git a/gradle.properties b/gradle.properties index 6eb1df6e..f804a850 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ pluginGroup = me.rafaelldi.aspire pluginName = aspire-plugin pluginRepositoryUrl = https://github.com/rafaelldi/aspire-plugin # SemVer format -> https://semver.org -pluginVersion = 0.5.0 +pluginVersion = 0.6.0 # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html pluginSinceBuild = 241 From dd0f2c553752f5febc5c1bc319a32fc19f6a7ba7 Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Wed, 24 Apr 2024 08:52:27 +0200 Subject: [PATCH 3/9] Remove temporary activities --- .../aspire/run/DisableToolWindowActivity.kt | 19 ------------ .../run/RemoveBuildSolutionTaskActivity.kt | 31 ------------------- src/main/resources/META-INF/plugin.xml | 2 -- 3 files changed, 52 deletions(-) delete mode 100644 src/main/kotlin/me/rafaelldi/aspire/run/DisableToolWindowActivity.kt delete mode 100644 src/main/kotlin/me/rafaelldi/aspire/run/RemoveBuildSolutionTaskActivity.kt diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/DisableToolWindowActivity.kt b/src/main/kotlin/me/rafaelldi/aspire/run/DisableToolWindowActivity.kt deleted file mode 100644 index 93a7cb3c..00000000 --- a/src/main/kotlin/me/rafaelldi/aspire/run/DisableToolWindowActivity.kt +++ /dev/null @@ -1,19 +0,0 @@ -package me.rafaelldi.aspire.run - -import com.intellij.execution.RunManager -import com.intellij.ide.util.RunOnceUtil -import com.intellij.openapi.project.Project -import com.intellij.openapi.startup.ProjectActivity - -class DisableToolWindowActivity : ProjectActivity { - override suspend fun execute(project: Project) { - RunOnceUtil.runOnceForProject(project, "Disable tool window activation for Aspire run config") { - RunManager.getInstance(project).allSettings.forEach { - if (it.type.id == "AspireHostConfiguration") { - it.isActivateToolWindowBeforeRun = false - it.isFocusToolWindowBeforeRun = false - } - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/RemoveBuildSolutionTaskActivity.kt b/src/main/kotlin/me/rafaelldi/aspire/run/RemoveBuildSolutionTaskActivity.kt deleted file mode 100644 index 2e0fd270..00000000 --- a/src/main/kotlin/me/rafaelldi/aspire/run/RemoveBuildSolutionTaskActivity.kt +++ /dev/null @@ -1,31 +0,0 @@ -package me.rafaelldi.aspire.run - -import com.intellij.execution.RunManager -import com.intellij.ide.util.RunOnceUtil -import com.intellij.openapi.project.Project -import com.intellij.openapi.startup.ProjectActivity -import com.jetbrains.rider.build.tasks.BuildProjectBeforeRunTaskProvider -import com.jetbrains.rider.build.tasks.BuildSolutionBeforeRunTask - -class RemoveBuildSolutionTaskActivity : ProjectActivity { - override suspend fun execute(project: Project) { - RunOnceUtil.runOnceForProject(project, "Remove BuildProject before run task for Aspire run config") { - RunManager.getInstance(project).allSettings.forEach { setting -> - if (setting.type.id == "AspireHostConfiguration") { - val buildProjectTasks = setting.configuration.beforeRunTasks.filter { - it.providerId == BuildProjectBeforeRunTaskProvider.providerId - } - if (buildProjectTasks.isNotEmpty()) { - buildProjectTasks.forEach { - setting.configuration.beforeRunTasks.remove(it) - } - - val buildSolutionTask = BuildSolutionBeforeRunTask() - buildSolutionTask.isEnabled = true - setting.configuration.beforeRunTasks.add(buildSolutionTask) - } - } - } - } - } -} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 5082a5a0..f26ec974 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -15,8 +15,6 @@ - - From eb0cbda969bd9ad36daa08b578ef2ac45562f507 Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Wed, 24 Apr 2024 11:53:00 +0200 Subject: [PATCH 4/9] Fix default ports --- .../me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt | 6 +++--- .../me/rafaelldi/aspire/run/AspireHostProgramRunner.kt | 2 +- .../rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt index 457e36ab..88d2986d 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt @@ -67,7 +67,7 @@ class AspireHostExecutorFactory( val envs = parameters.envs.toMutableMap() val debugSessionToken = UUID.randomUUID().toString() - val debugSessionPort = NetUtils.findFreePort(67800) + val debugSessionPort = NetUtils.findFreePort(47100) envs[DEBUG_SESSION_TOKEN] = debugSessionToken envs[DEBUG_SESSION_PORT] = "localhost:$debugSessionPort" @@ -80,14 +80,14 @@ class AspireHostExecutorFactory( } if (!envs.containsKey(DOTNET_RESOURCE_SERVICE_ENDPOINT_URL)) { - val resourceEndpointPort = NetUtils.findFreePort(77800) + val resourceEndpointPort = NetUtils.findFreePort(47200) envs[DOTNET_RESOURCE_SERVICE_ENDPOINT_URL] = if (useHttp) "http://localhost:$resourceEndpointPort" else "https://localhost:$resourceEndpointPort" } if (!envs.containsKey(DOTNET_DASHBOARD_OTLP_ENDPOINT_URL)) { - val openTelemetryProtocolEndpointPort = NetUtils.findFreePort(87800) + val openTelemetryProtocolEndpointPort = NetUtils.findFreePort(47300) envs[DOTNET_DASHBOARD_OTLP_ENDPOINT_URL] = if (useHttp) "http://localhost:$openTelemetryProtocolEndpointPort" else "https://localhost:$openTelemetryProtocolEndpointPort" diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt index 25812b4a..2ff5a35c 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt @@ -67,7 +67,7 @@ class AspireHostProgramRunner : DotNetProgramRunner() { val openTelemetryProtocolUrl = environmentVariables[DOTNET_DASHBOARD_OTLP_ENDPOINT_URL] LOG.trace("Found $DOTNET_DASHBOARD_OTLP_ENDPOINT_URL $openTelemetryProtocolUrl") - val openTelemetryProtocolServerPort = NetUtils.findFreePort(77800) + val openTelemetryProtocolServerPort = NetUtils.findFreePort(57100) LOG.trace("Created OTLP Server port $openTelemetryProtocolServerPort") val isDebug = environment.executor.id == DefaultDebugExecutor.EXECUTOR_ID diff --git a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt index edace9a9..5a651331 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt @@ -165,8 +165,8 @@ class AspireSessionLauncher(private val project: Project) { lifetime: Lifetime ) { val debuggerSessionId = ExecutionEnvironment.getNextUnusedExecutionId() - val frontendToDebuggerPort = NetUtils.findFreePort(67700) - val backendToDebuggerPort = NetUtils.findFreePort(87700) + val frontendToDebuggerPort = NetUtils.findFreePort(57200) + val backendToDebuggerPort = NetUtils.findFreePort(57300) val lifetimeDefinition = lifetime.createNested() From 44d123c16ff6f0c12c2c34f38bdd1176717974a4 Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Wed, 24 Apr 2024 15:05:53 +0200 Subject: [PATCH 5/9] Specify DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN environment variable --- .../aspire/run/AspireHostExecutorFactory.kt | 110 ++++++++++++------ .../aspire/run/AspireHostProgramRunner.kt | 8 +- .../aspire/util/AspireEnvironmentVariables.kt | 11 ++ 3 files changed, 90 insertions(+), 39 deletions(-) create mode 100644 src/main/kotlin/me/rafaelldi/aspire/util/AspireEnvironmentVariables.kt diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt index 88d2986d..2d7199d4 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt @@ -19,23 +19,24 @@ import com.jetbrains.rider.run.environment.ProjectProcessOptions import com.jetbrains.rider.runtime.DotNetExecutable import com.jetbrains.rider.runtime.RiderDotNetActiveRuntimeHost import com.jetbrains.rider.util.NetUtils -import me.rafaelldi.aspire.run.AspireHostProgramRunner.Companion.DEBUG_SESSION_PORT -import me.rafaelldi.aspire.run.AspireHostProgramRunner.Companion.DEBUG_SESSION_TOKEN -import me.rafaelldi.aspire.run.AspireHostProgramRunner.Companion.DOTNET_DASHBOARD_OTLP_ENDPOINT_URL -import me.rafaelldi.aspire.run.AspireHostProgramRunner.Companion.DOTNET_RESOURCE_SERVICE_ENDPOINT_URL +import me.rafaelldi.aspire.util.ASPIRE_ALLOW_UNSECURED_TRANSPORT +import me.rafaelldi.aspire.util.ASPNETCORE_URLS +import me.rafaelldi.aspire.util.BROWSER_TOKEN +import me.rafaelldi.aspire.util.DEBUG_SESSION_PORT +import me.rafaelldi.aspire.util.DEBUG_SESSION_TOKEN +import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_FRONTEND_AUTHMODE +import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN +import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_OTLP_ENDPOINT_URL +import me.rafaelldi.aspire.util.DOTNET_RESOURCE_SERVICE_ENDPOINT_URL import org.jetbrains.concurrency.await import java.io.File +import java.net.URI import java.util.* class AspireHostExecutorFactory( private val project: Project, private val parameters: AspireHostConfigurationParameters ) : AsyncExecutorFactory { - companion object { - private const val ASPNETCORE_URLS = "ASPNETCORE_URLS" - private const val ASPIRE_ALLOW_UNSECURED_TRANSPORT = "ASPIRE_ALLOW_UNSECURED_TRANSPORT" - } - override suspend fun create( executorId: String, environment: ExecutionEnvironment, @@ -65,32 +66,20 @@ class AspireHostExecutorFactory( ?: throw CantRunException("Unable to find project output") val envs = parameters.envs.toMutableMap() - - val debugSessionToken = UUID.randomUUID().toString() - val debugSessionPort = NetUtils.findFreePort(47100) - envs[DEBUG_SESSION_TOKEN] = debugSessionToken - envs[DEBUG_SESSION_PORT] = "localhost:$debugSessionPort" - - val urls = envs[ASPNETCORE_URLS] - //see: https://learn.microsoft.com/en-us/dotnet/aspire/whats-new/preview-5?tabs=dotnet-cli#allow-unsecure-transport-for-http-endpoints - val useHttp = (urls != null && !urls.contains("https")) || envs.containsKey(ASPIRE_ALLOW_UNSECURED_TRANSPORT) - - if (useHttp && !envs.containsKey(ASPIRE_ALLOW_UNSECURED_TRANSPORT)) { - envs[ASPIRE_ALLOW_UNSECURED_TRANSPORT] = "true" - } - - if (!envs.containsKey(DOTNET_RESOURCE_SERVICE_ENDPOINT_URL)) { - val resourceEndpointPort = NetUtils.findFreePort(47200) - envs[DOTNET_RESOURCE_SERVICE_ENDPOINT_URL] = - if (useHttp) "http://localhost:$resourceEndpointPort" - else "https://localhost:$resourceEndpointPort" - } - - if (!envs.containsKey(DOTNET_DASHBOARD_OTLP_ENDPOINT_URL)) { - val openTelemetryProtocolEndpointPort = NetUtils.findFreePort(47300) - envs[DOTNET_DASHBOARD_OTLP_ENDPOINT_URL] = - if (useHttp) "http://localhost:$openTelemetryProtocolEndpointPort" - else "https://localhost:$openTelemetryProtocolEndpointPort" + val environmentVariableValues = configureEnvironmentVariables(envs) + + if (environmentVariableValues.browserToken != null) { + val url = URI(parameters.startBrowserParameters.url) + val updatedUrl = URI( + url.scheme, + null, + url.host, + url.port, + "/login", + "t=${environmentVariableValues.browserToken}", + null + ) + parameters.startBrowserParameters.url = updatedUrl.toString() } val processOptions = ProjectProcessOptions( @@ -126,4 +115,55 @@ class AspireHostExecutorFactory( true ) } + + private fun configureEnvironmentVariables(envs: MutableMap): EnvironmentVariableValues { + //Switch DCP to the IDE mode + //see: https://github.com/dotnet/aspire/blob/main/docs/specs/IDE-execution.md#enabling-ide-execution + val debugSessionToken = UUID.randomUUID().toString() + val debugSessionPort = NetUtils.findFreePort(47100) + envs[DEBUG_SESSION_TOKEN] = debugSessionToken + envs[DEBUG_SESSION_PORT] = "localhost:$debugSessionPort" + + //Configure Dashboard frontend authentication + //see: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/configuration#frontend-authentication + val dashboardFrontendAuthMode = envs[DOTNET_DASHBOARD_FRONTEND_AUTHMODE] + var browserToken: String? = null + if (dashboardFrontendAuthMode == null || dashboardFrontendAuthMode.equals(BROWSER_TOKEN, true)) { + browserToken = UUID.randomUUID().toString() + envs[DOTNET_DASHBOARD_FRONTEND_AUTHMODE] = BROWSER_TOKEN + envs[DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN] = browserToken + } + + val urls = envs[ASPNETCORE_URLS] + //Check if the use of the `http` protocol is enabled + val useHttp = (urls != null && !urls.contains("https")) || envs.containsKey(ASPIRE_ALLOW_UNSECURED_TRANSPORT) + + //Automatically set the `ASPIRE_ALLOW_UNSECURED_TRANSPORT` environment variable if the `http` protocol is used + //see: https://learn.microsoft.com/en-us/dotnet/aspire/troubleshooting/allow-unsecure-transport + if (useHttp && !envs.containsKey(ASPIRE_ALLOW_UNSECURED_TRANSPORT)) { + envs[ASPIRE_ALLOW_UNSECURED_TRANSPORT] = "true" + } + + //Set the DOTNET_RESOURCE_SERVICE_ENDPOINT_URL environment variable if not specified + if (!envs.containsKey(DOTNET_RESOURCE_SERVICE_ENDPOINT_URL)) { + val resourceEndpointPort = NetUtils.findFreePort(47200) + envs[DOTNET_RESOURCE_SERVICE_ENDPOINT_URL] = + if (useHttp) "http://localhost:$resourceEndpointPort" + else "https://localhost:$resourceEndpointPort" + } + + //Set the DOTNET_DASHBOARD_OTLP_ENDPOINT_URL environment variable if not specified + if (!envs.containsKey(DOTNET_DASHBOARD_OTLP_ENDPOINT_URL)) { + val openTelemetryProtocolEndpointPort = NetUtils.findFreePort(47300) + envs[DOTNET_DASHBOARD_OTLP_ENDPOINT_URL] = + if (useHttp) "http://localhost:$openTelemetryProtocolEndpointPort" + else "https://localhost:$openTelemetryProtocolEndpointPort" + } + + return EnvironmentVariableValues(browserToken) + } + + private data class EnvironmentVariableValues( + val browserToken: String? + ) } \ No newline at end of file diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt index 2ff5a35c..2829431c 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt @@ -27,16 +27,16 @@ import kotlinx.coroutines.withContext import me.rafaelldi.aspire.generated.aspireSessionHostModel import me.rafaelldi.aspire.services.AspireServiceManager import me.rafaelldi.aspire.sessionHost.AspireSessionHostManager +import me.rafaelldi.aspire.util.DEBUG_SESSION_PORT +import me.rafaelldi.aspire.util.DEBUG_SESSION_TOKEN +import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_OTLP_ENDPOINT_URL +import me.rafaelldi.aspire.util.DOTNET_RESOURCE_SERVICE_ENDPOINT_URL import org.jetbrains.concurrency.Promise import org.jetbrains.concurrency.asPromise import kotlin.io.path.Path class AspireHostProgramRunner : DotNetProgramRunner() { companion object { - const val DEBUG_SESSION_TOKEN = "DEBUG_SESSION_TOKEN" - const val DEBUG_SESSION_PORT = "DEBUG_SESSION_PORT" - const val DOTNET_RESOURCE_SERVICE_ENDPOINT_URL = "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL" - const val DOTNET_DASHBOARD_OTLP_ENDPOINT_URL = "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL" private const val RUNNER_ID = "aspire-runner" private val LOG = logger() diff --git a/src/main/kotlin/me/rafaelldi/aspire/util/AspireEnvironmentVariables.kt b/src/main/kotlin/me/rafaelldi/aspire/util/AspireEnvironmentVariables.kt new file mode 100644 index 00000000..07496753 --- /dev/null +++ b/src/main/kotlin/me/rafaelldi/aspire/util/AspireEnvironmentVariables.kt @@ -0,0 +1,11 @@ +package me.rafaelldi.aspire.util + +const val DEBUG_SESSION_TOKEN = "DEBUG_SESSION_TOKEN" +const val DEBUG_SESSION_PORT = "DEBUG_SESSION_PORT" +const val ASPNETCORE_URLS = "ASPNETCORE_URLS" +const val DOTNET_DASHBOARD_FRONTEND_AUTHMODE = "DOTNET_DASHBOARD_FRONTEND_AUTHMODE" +const val DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN = "DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN" +const val BROWSER_TOKEN = "BrowserToken" +const val ASPIRE_ALLOW_UNSECURED_TRANSPORT = "ASPIRE_ALLOW_UNSECURED_TRANSPORT" +const val DOTNET_RESOURCE_SERVICE_ENDPOINT_URL = "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL" +const val DOTNET_DASHBOARD_OTLP_ENDPOINT_URL = "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL" \ No newline at end of file From 21e1a96cd0611a8db849d33608385d69f008ff3e Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Wed, 24 Apr 2024 15:09:30 +0200 Subject: [PATCH 6/9] Fix RIDER_PARENT_PROCESS_ID env var --- src/dotnet/aspire-session-host/ParentProcessWatchdog.cs | 6 +++--- .../aspire/sessionHost/AspireSessionHostLauncher.kt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dotnet/aspire-session-host/ParentProcessWatchdog.cs b/src/dotnet/aspire-session-host/ParentProcessWatchdog.cs index 0d4e85e6..9ed98eb2 100644 --- a/src/dotnet/aspire-session-host/ParentProcessWatchdog.cs +++ b/src/dotnet/aspire-session-host/ParentProcessWatchdog.cs @@ -4,15 +4,15 @@ namespace AspireSessionHost; internal static class ParentProcessWatchdog { - private const string RiderParentProcessPid = "RIDER_PARENT_PROCESS_PID"; + private const string RiderParentProcessProcessId = "RIDER_PARENT_PROCESS_ID"; public static void StartNewIfAvailable() { - if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(RiderParentProcessPid))) + if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(RiderParentProcessProcessId))) { return; } - ProcessWatchdog.StartWatchdogForPidEnvironmentVariable(RiderParentProcessPid); + ProcessWatchdog.StartWatchdogForPidEnvironmentVariable(RiderParentProcessProcessId); } } \ No newline at end of file diff --git a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionHostLauncher.kt b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionHostLauncher.kt index 78ad17fa..05e7d4a7 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionHostLauncher.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionHostLauncher.kt @@ -33,7 +33,7 @@ class AspireSessionHostLauncher(private val project: Project) { private const val ASPNETCORE_URLS = "ASPNETCORE_URLS" private const val RIDER_RD_PORT = "RIDER_RD_PORT" - private const val RIDER_PARENT_PROCESS_PID = "RIDER_PARENT_PROCESS_PID" + private const val RIDER_PARENT_PROCESS_ID = "RIDER_PARENT_PROCESS_ID" private const val RIDER_RESOURCE_ENDPOINT_URL = "RIDER_RESOURCE_ENDPOINT_URL" private const val RIDER_OTLP_SERVER_PORT = "RIDER_OTLP_SERVER_PORT" private const val RIDER_OTLP_ENDPOINT_URL = "RIDER_OTLP_ENDPOINT_URL" @@ -104,7 +104,7 @@ class AspireSessionHostLauncher(private val project: Project) { buildMap { put(ASPNETCORE_URLS, "http://localhost:${aspireHostConfig.debugSessionPort}/") put(RIDER_RD_PORT, "$rdPort") - put(RIDER_PARENT_PROCESS_PID, ProcessHandle.current().pid().toString()) + put(RIDER_PARENT_PROCESS_ID, ProcessHandle.current().pid().toString()) if (aspireHostConfig.resourceServiceUrl != null) put(RIDER_RESOURCE_ENDPOINT_URL, aspireHostConfig.resourceServiceUrl) if (settings.collectTelemetry && aspireHostConfig.openTelemetryProtocolUrl != null) { From 4b4cc879743b9755e86f8c1bc1e9f1093d597fdc Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Wed, 24 Apr 2024 15:27:33 +0200 Subject: [PATCH 7/9] Refactoring --- .../me/rafaelldi/aspire/run/AspireHostProgramRunner.kt | 4 ++-- .../me/rafaelldi/aspire/run/AspireHostProjectConfig.kt | 2 +- .../me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt | 5 ++--- .../me/rafaelldi/aspire/sessionHost/AspireSessionManager.kt | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt index 2829431c..b63fa1ee 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt @@ -70,7 +70,7 @@ class AspireHostProgramRunner : DotNetProgramRunner() { val openTelemetryProtocolServerPort = NetUtils.findFreePort(57100) LOG.trace("Created OTLP Server port $openTelemetryProtocolServerPort") - val isDebug = environment.executor.id == DefaultDebugExecutor.EXECUTOR_ID + val debuggingMode = environment.executor.id == DefaultDebugExecutor.EXECUTOR_ID val parameters = (environment.runnerAndConfigurationSettings?.configuration as? AspireHostConfiguration)?.parameters @@ -85,7 +85,7 @@ class AspireHostProgramRunner : DotNetProgramRunner() { debugSessionPort, aspireHostProjectPath, aspireHostProjectUrl, - isDebug, + debuggingMode, resourceServiceUrl, openTelemetryProtocolUrl, openTelemetryProtocolServerPort diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProjectConfig.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProjectConfig.kt index 7dca7149..1354fe45 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProjectConfig.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProjectConfig.kt @@ -7,7 +7,7 @@ data class AspireHostProjectConfig( val debugSessionPort: Int, val aspireHostProjectPath: Path, val aspireHostProjectUrl: String, - val isDebug: Boolean, + val debuggingMode: Boolean, val resourceServiceUrl: String?, val openTelemetryProtocolUrl: String?, val openTelemetryProtocolServerPort: Int diff --git a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt index 5a651331..d7e148eb 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionLauncher.kt @@ -53,7 +53,7 @@ class AspireSessionLauncher(private val project: Project) { sessionModel: SessionModel, sessionLifetime: Lifetime, sessionEvents: MutableSharedFlow, - isHostDebug: Boolean, + debuggingMode: Boolean, openTelemetryPort: Int ): SessionUpsertResult? { LOG.info("Starting a session for the project ${sessionModel.projectPath}") @@ -82,8 +82,7 @@ class AspireSessionLauncher(private val project: Project) { return null } - val isDebug = isHostDebug || sessionModel.debug - if (isDebug) { + if (debuggingMode || sessionModel.debug) { launchDebugSession( sessionId, Path(sessionModel.projectPath).nameWithoutExtension, diff --git a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionManager.kt b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionManager.kt index 91b8d489..988ace1c 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionManager.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionManager.kt @@ -132,7 +132,7 @@ class AspireSessionManager(private val project: Project, scope: CoroutineScope) command.sessionModel, lifetime, command.sessionEvents, - command.aspireHostConfig.isDebug, + command.aspireHostConfig.debuggingMode, command.aspireHostConfig.openTelemetryProtocolServerPort ) } From 5325f07dd71375292608864c0cfdf144df001b95 Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Thu, 25 Apr 2024 14:45:55 +0200 Subject: [PATCH 8/9] Set up API key for resource service --- src/dotnet/aspire-session-host/Program.cs | 2 ++ ...rceLogService.cs => ResourceLogService.cs} | 18 +++++++--- ...nResourceService.cs => ResourceService.cs} | 18 +++++++--- .../Resources/ResourceServiceOptions.cs | 18 ++++++++++ .../Resources/ResourceServiceRegistration.cs | 14 ++++---- .../aspire/run/AspireHostExecutorFactory.kt | 34 ++++++++++++------- .../aspire/run/AspireHostProgramRunner.kt | 8 ++--- .../aspire/run/AspireHostProjectConfig.kt | 1 + .../sessionHost/AspireSessionHostLauncher.kt | 7 ++-- .../aspire/util/AspireEnvironmentVariables.kt | 4 +-- 10 files changed, 88 insertions(+), 36 deletions(-) rename src/dotnet/aspire-session-host/Resources/{SessionResourceLogService.cs => ResourceLogService.cs} (84%) rename src/dotnet/aspire-session-host/Resources/{SessionResourceService.cs => ResourceService.cs} (86%) create mode 100644 src/dotnet/aspire-session-host/Resources/ResourceServiceOptions.cs diff --git a/src/dotnet/aspire-session-host/Program.cs b/src/dotnet/aspire-session-host/Program.cs index 8a37d3b6..6efb4f23 100644 --- a/src/dotnet/aspire-session-host/Program.cs +++ b/src/dotnet/aspire-session-host/Program.cs @@ -19,6 +19,8 @@ var builder = WebApplication.CreateBuilder(args); +builder.Configuration.AddEnvironmentVariables("Rider_"); + builder.Services.AddGrpc(); var connection = new Connection(rdPort.Value); diff --git a/src/dotnet/aspire-session-host/Resources/SessionResourceLogService.cs b/src/dotnet/aspire-session-host/Resources/ResourceLogService.cs similarity index 84% rename from src/dotnet/aspire-session-host/Resources/SessionResourceLogService.cs rename to src/dotnet/aspire-session-host/Resources/ResourceLogService.cs index 4abcf740..bd16a86f 100644 --- a/src/dotnet/aspire-session-host/Resources/SessionResourceLogService.cs +++ b/src/dotnet/aspire-session-host/Resources/ResourceLogService.cs @@ -3,25 +3,35 @@ using Grpc.Core; using JetBrains.Collections.Viewable; using JetBrains.Lifetimes; +using Microsoft.Extensions.Options; using Polly; using Polly.Registry; namespace AspireSessionHost.Resources; -internal sealed class SessionResourceLogService( +internal sealed class ResourceLogService( Connection connection, DashboardService.DashboardServiceClient client, ResiliencePipelineProvider resiliencePipelineProvider, - ILogger logger + IOptions options, + ILogger logger ) : IDisposable { + private const string ApiKeyHeader = "x-resource-service-api-key"; + private readonly Metadata _headers = []; + private readonly ResourceServiceOptions _optionValue = options.Value; private readonly LifetimeDefinition _lifetimeDef = new(); private readonly ResiliencePipeline _pipeline = - resiliencePipelineProvider.GetPipeline(nameof(SessionResourceLogService)); + resiliencePipelineProvider.GetPipeline(nameof(ResourceLogService)); internal async Task Initialize() { + if (_optionValue.ApiKey is not null) + { + _headers.Add(ApiKeyHeader, _optionValue.ApiKey); + } + await connection.DoWithModel(model => { model.Resources.View(_lifetimeDef.Lifetime, (lifetime, resourceId, resource) => @@ -62,7 +72,7 @@ private async Task SendWatchResourceLogsRequest( logger.LogTrace("Sending log watching request for the resource {resourceName}", resourceName); var request = new WatchResourceConsoleLogsRequest { ResourceName = resourceName }; - var response = client.WatchResourceConsoleLogs(request, cancellationToken: ct); + var response = client.WatchResourceConsoleLogs(request, headers: _headers, cancellationToken: ct); await foreach (var update in response.ResponseStream.ReadAllAsync(ct)) { foreach (var logLine in update.LogLines) diff --git a/src/dotnet/aspire-session-host/Resources/SessionResourceService.cs b/src/dotnet/aspire-session-host/Resources/ResourceService.cs similarity index 86% rename from src/dotnet/aspire-session-host/Resources/SessionResourceService.cs rename to src/dotnet/aspire-session-host/Resources/ResourceService.cs index 22554f2c..49e9bac4 100644 --- a/src/dotnet/aspire-session-host/Resources/SessionResourceService.cs +++ b/src/dotnet/aspire-session-host/Resources/ResourceService.cs @@ -3,25 +3,35 @@ using Grpc.Core; using JetBrains.Lifetimes; using JetBrains.Rd.Base; +using Microsoft.Extensions.Options; using Polly; using Polly.Registry; namespace AspireSessionHost.Resources; -internal sealed class SessionResourceService( +internal sealed class ResourceService( Connection connection, DashboardService.DashboardServiceClient client, ResiliencePipelineProvider resiliencePipelineProvider, - ILogger logger + IOptions options, + ILogger logger ) : IDisposable { + private const string ApiKeyHeader = "x-resource-service-api-key"; + private readonly Metadata _headers = []; + private readonly ResourceServiceOptions _optionValue = options.Value; private readonly LifetimeDefinition _lifetimeDef = new(); private readonly ResiliencePipeline _pipeline = - resiliencePipelineProvider.GetPipeline(nameof(SessionResourceService)); + resiliencePipelineProvider.GetPipeline(nameof(ResourceService)); internal void Initialize() { + if (_optionValue.ApiKey is not null) + { + _headers.Add(ApiKeyHeader, _optionValue.ApiKey); + } + _lifetimeDef.Lifetime.StartAttachedAsync(TaskScheduler.Default, async () => await WatchResources()); } @@ -45,7 +55,7 @@ private async Task SendWatchResourcesRequest( CancellationToken ct) { var request = new WatchResourcesRequest { IsReconnect = retryCount > 1 }; - var response = client.WatchResources(request, cancellationToken: ct); + var response = client.WatchResources(request, headers: _headers, cancellationToken: ct); await foreach (var update in response.ResponseStream.ReadAllAsync(ct)) { switch (update.KindCase) diff --git a/src/dotnet/aspire-session-host/Resources/ResourceServiceOptions.cs b/src/dotnet/aspire-session-host/Resources/ResourceServiceOptions.cs new file mode 100644 index 00000000..83e2a508 --- /dev/null +++ b/src/dotnet/aspire-session-host/Resources/ResourceServiceOptions.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.Options; + +namespace AspireSessionHost.Resources; + +public sealed class ResourceServiceOptions +{ + public string? ApiKey { get; set; } +}; + +internal sealed class ResourceServiceOptionSetup(IConfiguration configuration) : IConfigureOptions +{ + private const string SectionName = "ResourceService"; + + public void Configure(ResourceServiceOptions options) + { + configuration.GetSection(SectionName).Bind(options); + } +} \ No newline at end of file diff --git a/src/dotnet/aspire-session-host/Resources/ResourceServiceRegistration.cs b/src/dotnet/aspire-session-host/Resources/ResourceServiceRegistration.cs index b502f28e..13532387 100644 --- a/src/dotnet/aspire-session-host/Resources/ResourceServiceRegistration.cs +++ b/src/dotnet/aspire-session-host/Resources/ResourceServiceRegistration.cs @@ -14,6 +14,8 @@ internal static void AddResourceServices(this IServiceCollection services) var resourceEndpointUrl = GetResourceEndpointUrl(); if (resourceEndpointUrl is null) return; + services.ConfigureOptions(); + var retryPolicy = new MethodConfig { Names = { MethodName.Default }, @@ -29,10 +31,10 @@ internal static void AddResourceServices(this IServiceCollection services) services .AddGrpcClient(o => { o.Address = resourceEndpointUrl; }) .ConfigureChannel(o => { o.ServiceConfig = new ServiceConfig { MethodConfigs = { retryPolicy } }; }); - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); - services.AddResiliencePipeline(nameof(SessionResourceLogService), builder => + services.AddResiliencePipeline(nameof(ResourceLogService), builder => { builder.AddRetry(new RetryStrategyOptions { @@ -43,7 +45,7 @@ internal static void AddResourceServices(this IServiceCollection services) }); }); - services.AddResiliencePipeline(nameof(SessionResourceService), builder => + services.AddResiliencePipeline(nameof(ResourceService), builder => { builder.AddRetry(new RetryStrategyOptions { @@ -57,9 +59,9 @@ internal static void AddResourceServices(this IServiceCollection services) internal static async Task InitializeResourceServices(this IServiceProvider services) { using var scope = services.CreateScope(); - var resourceService = scope.ServiceProvider.GetRequiredService(); + var resourceService = scope.ServiceProvider.GetRequiredService(); resourceService.Initialize(); - var resourceLogService = scope.ServiceProvider.GetRequiredService(); + var resourceLogService = scope.ServiceProvider.GetRequiredService(); await resourceLogService.Initialize(); } } \ No newline at end of file diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt index 2d7199d4..cb22e807 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt @@ -21,12 +21,12 @@ import com.jetbrains.rider.runtime.RiderDotNetActiveRuntimeHost import com.jetbrains.rider.util.NetUtils import me.rafaelldi.aspire.util.ASPIRE_ALLOW_UNSECURED_TRANSPORT import me.rafaelldi.aspire.util.ASPNETCORE_URLS -import me.rafaelldi.aspire.util.BROWSER_TOKEN import me.rafaelldi.aspire.util.DEBUG_SESSION_PORT import me.rafaelldi.aspire.util.DEBUG_SESSION_TOKEN -import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_FRONTEND_AUTHMODE import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_OTLP_ENDPOINT_URL +import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_RESOURCESERVICE_APIKEY +import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS import me.rafaelldi.aspire.util.DOTNET_RESOURCE_SERVICE_ENDPOINT_URL import org.jetbrains.concurrency.await import java.io.File @@ -124,26 +124,34 @@ class AspireHostExecutorFactory( envs[DEBUG_SESSION_TOKEN] = debugSessionToken envs[DEBUG_SESSION_PORT] = "localhost:$debugSessionPort" + val urls = requireNotNull(envs[ASPNETCORE_URLS]) + val isHttpUrl = !urls.contains("https") + val allowUnsecuredTransport = envs[ASPIRE_ALLOW_UNSECURED_TRANSPORT]?.equals("true", true) == true + + //Automatically set the `ASPIRE_ALLOW_UNSECURED_TRANSPORT` environment variable if the `http` protocol is used + //see: https://learn.microsoft.com/en-us/dotnet/aspire/troubleshooting/allow-unsecure-transport + if (isHttpUrl && !allowUnsecuredTransport) { + envs[ASPIRE_ALLOW_UNSECURED_TRANSPORT] = "true" + } + + val allowAnonymousDashboard = envs[DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS]?.equals("true", true) == true + //Configure Dashboard frontend authentication //see: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/configuration#frontend-authentication - val dashboardFrontendAuthMode = envs[DOTNET_DASHBOARD_FRONTEND_AUTHMODE] var browserToken: String? = null - if (dashboardFrontendAuthMode == null || dashboardFrontendAuthMode.equals(BROWSER_TOKEN, true)) { + if (!allowAnonymousDashboard) { browserToken = UUID.randomUUID().toString() - envs[DOTNET_DASHBOARD_FRONTEND_AUTHMODE] = BROWSER_TOKEN envs[DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN] = browserToken } - val urls = envs[ASPNETCORE_URLS] - //Check if the use of the `http` protocol is enabled - val useHttp = (urls != null && !urls.contains("https")) || envs.containsKey(ASPIRE_ALLOW_UNSECURED_TRANSPORT) - - //Automatically set the `ASPIRE_ALLOW_UNSECURED_TRANSPORT` environment variable if the `http` protocol is used - //see: https://learn.microsoft.com/en-us/dotnet/aspire/troubleshooting/allow-unsecure-transport - if (useHttp && !envs.containsKey(ASPIRE_ALLOW_UNSECURED_TRANSPORT)) { - envs[ASPIRE_ALLOW_UNSECURED_TRANSPORT] = "true" + //Configure ApiKey for the Resource service + //see: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/configuration#resources + if (!allowAnonymousDashboard) { + envs[DOTNET_DASHBOARD_RESOURCESERVICE_APIKEY] = UUID.randomUUID().toString() } + val useHttp = isHttpUrl || allowUnsecuredTransport + //Set the DOTNET_RESOURCE_SERVICE_ENDPOINT_URL environment variable if not specified if (!envs.containsKey(DOTNET_RESOURCE_SERVICE_ENDPOINT_URL)) { val resourceEndpointPort = NetUtils.findFreePort(47200) diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt index b63fa1ee..fe15c23a 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProgramRunner.kt @@ -30,6 +30,7 @@ import me.rafaelldi.aspire.sessionHost.AspireSessionHostManager import me.rafaelldi.aspire.util.DEBUG_SESSION_PORT import me.rafaelldi.aspire.util.DEBUG_SESSION_TOKEN import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_OTLP_ENDPOINT_URL +import me.rafaelldi.aspire.util.DOTNET_DASHBOARD_RESOURCESERVICE_APIKEY import me.rafaelldi.aspire.util.DOTNET_RESOURCE_SERVICE_ENDPOINT_URL import org.jetbrains.concurrency.Promise import org.jetbrains.concurrency.asPromise @@ -59,16 +60,12 @@ class AspireHostProgramRunner : DotNetProgramRunner() { ?.toInt() if (debugSessionToken == null || debugSessionPort == null) throw CantRunException("Unable to find token or port") - LOG.trace("Found $DEBUG_SESSION_TOKEN $debugSessionToken and $DEBUG_SESSION_PORT $debugSessionPort") val resourceServiceUrl = environmentVariables[DOTNET_RESOURCE_SERVICE_ENDPOINT_URL] - LOG.trace("Found $DOTNET_RESOURCE_SERVICE_ENDPOINT_URL $resourceServiceUrl") + val resourceServiceApiKey = environmentVariables[DOTNET_DASHBOARD_RESOURCESERVICE_APIKEY] val openTelemetryProtocolUrl = environmentVariables[DOTNET_DASHBOARD_OTLP_ENDPOINT_URL] - LOG.trace("Found $DOTNET_DASHBOARD_OTLP_ENDPOINT_URL $openTelemetryProtocolUrl") - val openTelemetryProtocolServerPort = NetUtils.findFreePort(57100) - LOG.trace("Created OTLP Server port $openTelemetryProtocolServerPort") val debuggingMode = environment.executor.id == DefaultDebugExecutor.EXECUTOR_ID @@ -87,6 +84,7 @@ class AspireHostProgramRunner : DotNetProgramRunner() { aspireHostProjectUrl, debuggingMode, resourceServiceUrl, + resourceServiceApiKey, openTelemetryProtocolUrl, openTelemetryProtocolServerPort ) diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProjectConfig.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProjectConfig.kt index 1354fe45..f20b1082 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProjectConfig.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostProjectConfig.kt @@ -9,6 +9,7 @@ data class AspireHostProjectConfig( val aspireHostProjectUrl: String, val debuggingMode: Boolean, val resourceServiceUrl: String?, + val resourceServiceApiKey: String?, val openTelemetryProtocolUrl: String?, val openTelemetryProtocolServerPort: Int ) \ No newline at end of file diff --git a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionHostLauncher.kt b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionHostLauncher.kt index 05e7d4a7..5b67fac8 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionHostLauncher.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/AspireSessionHostLauncher.kt @@ -34,7 +34,8 @@ class AspireSessionHostLauncher(private val project: Project) { private const val ASPNETCORE_URLS = "ASPNETCORE_URLS" private const val RIDER_RD_PORT = "RIDER_RD_PORT" private const val RIDER_PARENT_PROCESS_ID = "RIDER_PARENT_PROCESS_ID" - private const val RIDER_RESOURCE_ENDPOINT_URL = "RIDER_RESOURCE_ENDPOINT_URL" + private const val RIDER_RESOURCE_SERVICE_ENDPOINT_URL = "RIDER_RESOURCE_ENDPOINT_URL" + private const val RIDER_RESOURCE_SERVICE_API_KEY = "Rider_ResourceService__ApiKey" private const val RIDER_OTLP_SERVER_PORT = "RIDER_OTLP_SERVER_PORT" private const val RIDER_OTLP_ENDPOINT_URL = "RIDER_OTLP_ENDPOINT_URL" } @@ -106,7 +107,9 @@ class AspireSessionHostLauncher(private val project: Project) { put(RIDER_RD_PORT, "$rdPort") put(RIDER_PARENT_PROCESS_ID, ProcessHandle.current().pid().toString()) if (aspireHostConfig.resourceServiceUrl != null) - put(RIDER_RESOURCE_ENDPOINT_URL, aspireHostConfig.resourceServiceUrl) + put(RIDER_RESOURCE_SERVICE_ENDPOINT_URL, aspireHostConfig.resourceServiceUrl) + if (aspireHostConfig.resourceServiceApiKey != null) + put(RIDER_RESOURCE_SERVICE_API_KEY, aspireHostConfig.resourceServiceApiKey) if (settings.collectTelemetry && aspireHostConfig.openTelemetryProtocolUrl != null) { put(RIDER_OTLP_SERVER_PORT, aspireHostConfig.openTelemetryProtocolServerPort.toString()) put(RIDER_OTLP_ENDPOINT_URL, aspireHostConfig.openTelemetryProtocolUrl) diff --git a/src/main/kotlin/me/rafaelldi/aspire/util/AspireEnvironmentVariables.kt b/src/main/kotlin/me/rafaelldi/aspire/util/AspireEnvironmentVariables.kt index 07496753..5c908499 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/util/AspireEnvironmentVariables.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/util/AspireEnvironmentVariables.kt @@ -3,9 +3,9 @@ package me.rafaelldi.aspire.util const val DEBUG_SESSION_TOKEN = "DEBUG_SESSION_TOKEN" const val DEBUG_SESSION_PORT = "DEBUG_SESSION_PORT" const val ASPNETCORE_URLS = "ASPNETCORE_URLS" -const val DOTNET_DASHBOARD_FRONTEND_AUTHMODE = "DOTNET_DASHBOARD_FRONTEND_AUTHMODE" +const val DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS = "DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS" const val DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN = "DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN" -const val BROWSER_TOKEN = "BrowserToken" +const val DOTNET_DASHBOARD_RESOURCESERVICE_APIKEY = "DOTNET_DASHBOARD_RESOURCESERVICE_APIKEY" const val ASPIRE_ALLOW_UNSECURED_TRANSPORT = "ASPIRE_ALLOW_UNSECURED_TRANSPORT" const val DOTNET_RESOURCE_SERVICE_ENDPOINT_URL = "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL" const val DOTNET_DASHBOARD_OTLP_ENDPOINT_URL = "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL" \ No newline at end of file From 29de0c5a75f8a68f4cb9bd1efe865b7208215e7a Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Thu, 25 Apr 2024 15:10:17 +0200 Subject: [PATCH 9/9] Refactoring --- .../aspire/run/AspireHostExecutorFactory.kt | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt index cb22e807..cff21519 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/run/AspireHostExecutorFactory.kt @@ -134,22 +134,6 @@ class AspireHostExecutorFactory( envs[ASPIRE_ALLOW_UNSECURED_TRANSPORT] = "true" } - val allowAnonymousDashboard = envs[DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS]?.equals("true", true) == true - - //Configure Dashboard frontend authentication - //see: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/configuration#frontend-authentication - var browserToken: String? = null - if (!allowAnonymousDashboard) { - browserToken = UUID.randomUUID().toString() - envs[DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN] = browserToken - } - - //Configure ApiKey for the Resource service - //see: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/configuration#resources - if (!allowAnonymousDashboard) { - envs[DOTNET_DASHBOARD_RESOURCESERVICE_APIKEY] = UUID.randomUUID().toString() - } - val useHttp = isHttpUrl || allowUnsecuredTransport //Set the DOTNET_RESOURCE_SERVICE_ENDPOINT_URL environment variable if not specified @@ -168,6 +152,22 @@ class AspireHostExecutorFactory( else "https://localhost:$openTelemetryProtocolEndpointPort" } + val allowAnonymousDashboard = envs[DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS]?.equals("true", true) == true + + //Configure Dashboard frontend authentication + //see: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/configuration#frontend-authentication + var browserToken: String? = null + if (!allowAnonymousDashboard) { + browserToken = UUID.randomUUID().toString() + envs[DOTNET_DASHBOARD_FRONTEND_BROWSERTOKEN] = browserToken + } + + //Configure ApiKey for the Resource service + //see: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/configuration#resources + if (!allowAnonymousDashboard) { + envs[DOTNET_DASHBOARD_RESOURCESERVICE_APIKEY] = UUID.randomUUID().toString() + } + return EnvironmentVariableValues(browserToken) }