Skip to content

Commit 65ca1da

Browse files
roboquatfelladrin
authored andcommitted
Adjust JetBrains Backend Plugin to work with the new Port Forwarding API
1 parent 403ac45 commit 65ca1da

File tree

4 files changed

+100
-43
lines changed

4 files changed

+100
-43
lines changed

components/ide/jetbrains/backend-plugin/gradle-latest.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ pluginUntilBuild=223.*
66
# See https://jb.gg/intellij-platform-builds-list for available build versions.
77
pluginVerifierIdeVersions=2022.3
88
# Version from "com.jetbrains.intellij.idea" which can be found at https://www.jetbrains.com/intellij-repository/snapshots
9-
platformVersion=223.5756-EAP-CANDIDATE-SNAPSHOT
9+
platformVersion=223.6160-EAP-CANDIDATE-SNAPSHOT

components/ide/jetbrains/backend-plugin/launch-dev-server.sh

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,50 @@ set -e
77
set -o pipefail
88

99
# Default Options
10-
DEBUG_PORT=0
10+
DEBUG_PORT=44444
1111
JB_QUALIFIER="latest"
1212
TEST_REPO=https://github.com/gitpod-io/spring-petclinic
13+
RUN_FROM="release"
1314

1415
# Parsing Custom Options
15-
while getopts "p:r:s" OPTION
16+
while getopts "p:r:su" OPTION
1617
do
1718
case $OPTION in
1819
s) JB_QUALIFIER="stable" ;;
1920
r) TEST_REPO=$OPTARG ;;
2021
p) DEBUG_PORT=$OPTARG ;;
22+
u) RUN_FROM="snapshot" ;;
2123
*) ;;
2224
esac
2325
done
2426

2527
TEST_BACKEND_DIR="/workspace/ide-backend-$JB_QUALIFIER"
2628
if [ ! -d "$TEST_BACKEND_DIR" ]; then
2729
mkdir -p $TEST_BACKEND_DIR
28-
if [[ $JB_QUALIFIER == "stable" ]]; then
29-
PRODUCT_TYPE="release"
30+
if [[ $RUN_FROM == "snapshot" ]]; then
31+
(cd $TEST_BACKEND_DIR &&
32+
SNAPSHOT_VERSION=$(grep "platformVersion=" "gradle-$JB_QUALIFIER.properties" | sed 's/platformVersion=//') &&
33+
echo "Downloading the $JB_QUALIFIER version of IntelliJ IDEA ($SNAPSHOT_VERSION)..." &&
34+
curl -sSLo backend.zip "https://www.jetbrains.com/intellij-repository/snapshots/com/jetbrains/intellij/idea/ideaIU/$SNAPSHOT_VERSION/ideaIU-$SNAPSHOT_VERSION.zip" &&
35+
unzip backend.zip &&
36+
rm backend.zip &&
37+
ln -s "ideaIU-$SNAPSHOT_VERSION" . &&
38+
rm -r "ideaIU-$SNAPSHOT_VERSION" &&
39+
cp -r /ide-desktop/backend/jbr . &&
40+
cp /ide-desktop/backend/bin/idea.properties ./bin &&
41+
cp /ide-desktop/backend/bin/idea64.vmoptions ./bin)
3042
else
31-
PRODUCT_TYPE="release,rc,eap"
43+
if [[ $JB_QUALIFIER == "stable" ]]; then
44+
PRODUCT_TYPE="release"
45+
else
46+
PRODUCT_TYPE="release,rc,eap"
47+
fi
48+
(cd $TEST_BACKEND_DIR &&
49+
echo "Downloading the $JB_QUALIFIER version of IntelliJ IDEA..." &&
50+
curl -sSLo backend.tar.gz "https://download.jetbrains.com/product?type=$PRODUCT_TYPE&distribution=linux&code=IIU" &&
51+
tar -xf backend.tar.gz --strip-components=1 &&
52+
rm backend.tar.gz)
3253
fi
33-
(cd $TEST_BACKEND_DIR &&
34-
echo "Downloading the $JB_QUALIFIER version of IntelliJ IDEA..." &&
35-
curl -sSLo backend.tar.gz "https://download.jetbrains.com/product?type=$PRODUCT_TYPE&distribution=linux&code=IIU" &&
36-
tar -xf backend.tar.gz --strip-components=1 &&
37-
rm backend.tar.gz)
3854
fi
3955

4056
TEST_PLUGINS_DIR="$TEST_BACKEND_DIR/plugins"

components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/latest/GitpodPortForwardingService.kt

Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44

55
package io.gitpod.jetbrains.remote.latest
66

7+
import com.intellij.openapi.Disposable
8+
import com.intellij.openapi.client.ClientProjectSession
79
import com.intellij.openapi.components.service
810
import com.intellij.openapi.diagnostic.thisLogger
9-
import com.intellij.openapi.project.Project
11+
import com.intellij.openapi.util.Disposer
1012
import com.intellij.remoteDev.util.onTerminationOrNow
1113
import com.intellij.util.application
12-
import com.jetbrains.codeWithMe.model.RdPortType
14+
import com.jetbrains.rd.platform.codeWithMe.portForwarding.*
1315
import com.jetbrains.rd.platform.util.lifetime
1416
import com.jetbrains.rd.util.lifetime.LifetimeStatus
15-
import com.jetbrains.rdserver.portForwarding.ForwardedPortInfo
16-
import com.jetbrains.rdserver.portForwarding.PortForwardingManager
17-
import com.jetbrains.rdserver.portForwarding.remoteDev.PortEventsProcessor
1817
import io.gitpod.jetbrains.remote.GitpodManager
1918
import io.gitpod.jetbrains.remote.GitpodPortsService
2019
import io.gitpod.supervisor.api.Status
@@ -24,14 +23,17 @@ import io.grpc.stub.ClientResponseObserver
2423
import io.ktor.utils.io.*
2524
import java.util.concurrent.CompletableFuture
2625
import java.util.concurrent.TimeUnit
26+
import javax.swing.Icon
2727

2828
@Suppress("UnstableApiUsage")
29-
class GitpodPortForwardingService(private val project: Project) {
29+
class GitpodPortForwardingService(private val session: ClientProjectSession) {
3030
companion object {
3131
const val FORWARDED_PORT_LABEL = "gitpod"
3232
}
3333

3434
private val portsService = service<GitpodPortsService>()
35+
private val perClientPortForwardingManager = service<PerClientPortForwardingManager>()
36+
private val portToDisposableMap = mutableMapOf<Int,Disposable>()
3537

3638
init { start() }
3739

@@ -42,7 +44,7 @@ class GitpodPortForwardingService(private val project: Project) {
4244
}
4345

4446
private fun observePortsListWhileProjectIsOpen() = application.executeOnPooledThread {
45-
while (project.lifetime.status == LifetimeStatus.Alive) {
47+
while (session.project.lifetime.status == LifetimeStatus.Alive) {
4648
try {
4749
observePortsList().get()
4850
} catch (throwable: Throwable) {
@@ -70,7 +72,7 @@ class GitpodPortForwardingService(private val project: Project) {
7072
val portsStatusResponseObserver = object :
7173
ClientResponseObserver<Status.PortsStatusRequest, Status.PortsStatusResponse> {
7274
override fun beforeStart(request: ClientCallStreamObserver<Status.PortsStatusRequest>) {
73-
project.lifetime.onTerminationOrNow { request.cancel("gitpod: Project terminated.", null) }
75+
session.project.lifetime.onTerminationOrNow { request.cancel("gitpod: Project terminated.", null) }
7476
}
7577
override fun onNext(response: Status.PortsStatusResponse) {
7678
application.invokeLater { updateForwardedPortsList(response) }
@@ -85,48 +87,87 @@ class GitpodPortForwardingService(private val project: Project) {
8587
}
8688

8789
private fun updateForwardedPortsList(response: Status.PortsStatusResponse) {
88-
val portForwardingManager = PortForwardingManager.getInstance(project)
89-
val forwardedPortsList = portForwardingManager.getForwardedPortsWithLabel(FORWARDED_PORT_LABEL)
90-
9190
for (port in response.portsList) {
9291
val hostPort = port.localPort
9392
val isServed = port.served
94-
val isForwarded = forwardedPortsList.find { it.hostPort == hostPort } != null
93+
val isForwarded = perClientPortForwardingManager.getPorts(hostPort).isNotEmpty()
9594

9695
if (isServed && !isForwarded) {
97-
val portEventsProcessor = object : PortEventsProcessor {
98-
override fun onPortForwarded(hostPort: Int, clientPort: Int) {
99-
portsService.setForwardedPort(hostPort, clientPort)
100-
thisLogger().info("gitpod: Forwarded port $hostPort to client's port $clientPort.")
96+
val forwardedPortListener = object: ForwardedPortListener {
97+
override fun becameReadOnly(port: ForwardedPort, reason: String?) {
98+
thisLogger().warn("gitpod: becameReadOnly($port, $reason)")
99+
}
100+
101+
override fun descriptionChanged(port: ForwardedPort, oldDescription: String?, newDescription: String?) {
102+
thisLogger().warn("gitpod: descriptionChanged($port, $oldDescription, $newDescription)")
103+
}
104+
105+
override fun exposedUrlChanged(port: ForwardedPort, newUrl: String) {
106+
thisLogger().warn("gitpod: exposedUrlChanged($port, $newUrl)")
107+
}
108+
109+
override fun iconChanged(port: ForwardedPort, oldIcon: Icon?, newIcon: Icon?) {
110+
thisLogger().warn("gitpod: iconChanged($port, $oldIcon, $newIcon)")
101111
}
102112

103-
override fun onPortForwardingEnded(hostPort: Int) {
104-
thisLogger().info("gitpod: Finished forwarding port $hostPort.")
113+
override fun nameChanged(port: ForwardedPort, oldName: String?, newName: String?) {
114+
thisLogger().warn("gitpod: nameChanged($port, $oldName, $newName)")
105115
}
106116

107-
override fun onPortForwardingFailed(hostPort: Int, reason: String) {
108-
thisLogger().error("gitpod: Failed to forward port $hostPort: $reason")
117+
override fun stateChanged(port: ForwardedPort, newState: ClientPortState) {
118+
when (newState) {
119+
is ClientPortState.Assigned -> {
120+
thisLogger().warn("gitpod: Started forwarding host port $hostPort to client port ${newState.clientPort}.")
121+
portsService.setForwardedPort(hostPort, newState.clientPort)
122+
}
123+
is ClientPortState.FailedToAssign -> {
124+
thisLogger().warn("gitpod: Detected that host port $hostPort failed to be assigned to a client port.")
125+
}
126+
else -> {
127+
thisLogger().warn("gitpod: Detected that host port $hostPort is not assigned to any client port.")
128+
}
129+
}
130+
}
131+
132+
override fun tooltipChanged(port: ForwardedPort, oldTooltip: String?, newTooltip: String?) {
133+
thisLogger().warn("gitpod: tooltipChanged($port, $oldTooltip, $newTooltip)")
109134
}
110135
}
111136

112-
val portInfo = ForwardedPortInfo(
137+
try {
138+
val forwardedPort = perClientPortForwardingManager.forwardPort(
113139
hostPort,
114-
RdPortType.HTTP,
115-
port.exposed.url,
116-
port.name,
117-
port.description,
140+
PortType.TCP,
118141
setOf(FORWARDED_PORT_LABEL),
119-
emptyList(),
120-
portEventsProcessor
121-
)
142+
hostPort,
143+
ClientPortPickingStrategy.REASSIGN_WHEN_BUSY,
144+
fun(portPresentation: PortPresentation) {
145+
portPresentation.name = port.name
146+
portPresentation.description = port.description
147+
portPresentation.icon = null
148+
portPresentation.tooltip = "Forwarded Port"
149+
}
150+
)
151+
152+
val portListenerDisposable = portToDisposableMap.getOrPut(hostPort, fun() = Disposer.newDisposable())
122153

123-
portForwardingManager.forwardPort(portInfo)
154+
forwardedPort.addPortListener(portListenerDisposable, forwardedPortListener)
155+
} catch (error: Error) {
156+
thisLogger().warn("gitpod: ${error.message}")
157+
}
124158
}
125159

126160
if (!isServed && isForwarded) {
127-
portForwardingManager.removePort(hostPort)
161+
val portListenerDisposable = portToDisposableMap[hostPort]
162+
if (portListenerDisposable != null) {
163+
portListenerDisposable.dispose()
164+
portToDisposableMap.remove(hostPort)
165+
}
166+
perClientPortForwardingManager.getPorts(hostPort).forEach { portToRemove ->
167+
perClientPortForwardingManager.removePort(portToRemove)
168+
}
128169
portsService.removeForwardedPort(hostPort)
129-
thisLogger().info("gitpod: Stopped forwarding port $hostPort.")
170+
thisLogger().warn("gitpod: Stopped forwarding port $hostPort.")
130171
}
131172
}
132173
}

components/ide/jetbrains/backend-plugin/src/main/resources-latest/META-INF/extensions.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
<idea-plugin>
88
<extensions defaultExtensionNs="com.intellij">
99
<applicationService serviceInterface="io.gitpod.jetbrains.remote.GitpodIgnoredPortsForNotificationService" serviceImplementation="io.gitpod.jetbrains.remote.latest.GitpodIgnoredPortsForNotificationServiceImpl" preload="true"/>
10-
<projectService serviceImplementation="io.gitpod.jetbrains.remote.latest.GitpodPortForwardingService" preload="true"/>
10+
<projectService serviceImplementation="io.gitpod.jetbrains.remote.latest.GitpodPortForwardingService" preload="true" client="guest"/>
1111
</extensions>
1212
</idea-plugin>

0 commit comments

Comments
 (0)