Skip to content

Commit 7f45780

Browse files
felladrinroboquat
authored andcommitted
Adjust JetBrains Backend Plugin to work with the new Port Forwarding API
1 parent bbd0afd commit 7f45780

File tree

4 files changed

+108
-48
lines changed

4 files changed

+108
-48
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: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
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
17+
import io.gitpod.jetbrains.remote.GitpodIgnoredPortsForNotificationService
1818
import io.gitpod.jetbrains.remote.GitpodManager
1919
import io.gitpod.jetbrains.remote.GitpodPortsService
2020
import io.gitpod.supervisor.api.Status
@@ -24,14 +24,18 @@ import io.grpc.stub.ClientResponseObserver
2424
import io.ktor.utils.io.*
2525
import java.util.concurrent.CompletableFuture
2626
import java.util.concurrent.TimeUnit
27+
import javax.swing.Icon
2728

2829
@Suppress("UnstableApiUsage")
29-
class GitpodPortForwardingService(private val project: Project) {
30+
class GitpodPortForwardingService(private val session: ClientProjectSession) {
3031
companion object {
3132
const val FORWARDED_PORT_LABEL = "gitpod"
3233
}
3334

3435
private val portsService = service<GitpodPortsService>()
36+
private val perClientPortForwardingManager = service<PerClientPortForwardingManager>()
37+
private val ignoredPortsForNotificationService = service<GitpodIgnoredPortsForNotificationService>()
38+
private val portToDisposableMap = mutableMapOf<Int,Disposable>()
3539

3640
init { start() }
3741

@@ -42,7 +46,7 @@ class GitpodPortForwardingService(private val project: Project) {
4246
}
4347

4448
private fun observePortsListWhileProjectIsOpen() = application.executeOnPooledThread {
45-
while (project.lifetime.status == LifetimeStatus.Alive) {
49+
while (session.project.lifetime.status == LifetimeStatus.Alive) {
4650
try {
4751
observePortsList().get()
4852
} catch (throwable: Throwable) {
@@ -70,7 +74,7 @@ class GitpodPortForwardingService(private val project: Project) {
7074
val portsStatusResponseObserver = object :
7175
ClientResponseObserver<Status.PortsStatusRequest, Status.PortsStatusResponse> {
7276
override fun beforeStart(request: ClientCallStreamObserver<Status.PortsStatusRequest>) {
73-
project.lifetime.onTerminationOrNow { request.cancel("gitpod: Project terminated.", null) }
77+
session.project.lifetime.onTerminationOrNow { request.cancel("gitpod: Project terminated.", null) }
7478
}
7579
override fun onNext(response: Status.PortsStatusResponse) {
7680
application.invokeLater { updateForwardedPortsList(response) }
@@ -85,46 +89,86 @@ class GitpodPortForwardingService(private val project: Project) {
8589
}
8690

8791
private fun updateForwardedPortsList(response: Status.PortsStatusResponse) {
88-
val portForwardingManager = PortForwardingManager.getInstance(project)
89-
val forwardedPortsList = portForwardingManager.getForwardedPortsWithLabel(FORWARDED_PORT_LABEL)
92+
val ignoredPorts = ignoredPortsForNotificationService.getIgnoredPorts()
9093

9194
for (port in response.portsList) {
95+
if (ignoredPorts.contains(port.localPort)) continue
96+
9297
val hostPort = port.localPort
9398
val isServed = port.served
94-
val isForwarded = forwardedPortsList.find { it.hostPort == hostPort } != null
99+
val isForwarded = perClientPortForwardingManager.getPorts(hostPort).isNotEmpty()
95100

96101
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.")
101-
}
102-
103-
override fun onPortForwardingEnded(hostPort: Int) {
104-
thisLogger().info("gitpod: Finished forwarding port $hostPort.")
105-
}
106-
107-
override fun onPortForwardingFailed(hostPort: Int, reason: String) {
108-
thisLogger().error("gitpod: Failed to forward port $hostPort: $reason")
109-
}
110-
}
111-
112-
val portInfo = ForwardedPortInfo(
102+
try {
103+
val forwardedPort = perClientPortForwardingManager.forwardPort(
113104
hostPort,
114-
RdPortType.HTTP,
115-
port.exposed.url,
116-
port.name,
117-
port.description,
105+
PortType.TCP,
118106
setOf(FORWARDED_PORT_LABEL),
119-
emptyList(),
120-
portEventsProcessor
121-
)
107+
hostPort,
108+
ClientPortPickingStrategy.REASSIGN_WHEN_BUSY
109+
) {
110+
this.name = port.name
111+
this.description = port.description
112+
this.icon = null
113+
this.tooltip = "Forwarded Port"
114+
}
122115

123-
portForwardingManager.forwardPort(portInfo)
116+
val portListenerDisposable = portToDisposableMap.getOrPut(hostPort, fun() = Disposer.newDisposable())
117+
118+
forwardedPort.addPortListener(portListenerDisposable, object: ForwardedPortListener {
119+
override fun becameReadOnly(port: ForwardedPort, reason: String?) {
120+
thisLogger().warn("gitpod: becameReadOnly($port, $reason)")
121+
}
122+
123+
override fun descriptionChanged(port: ForwardedPort, oldDescription: String?, newDescription: String?) {
124+
thisLogger().warn("gitpod: descriptionChanged($port, $oldDescription, $newDescription)")
125+
}
126+
127+
override fun exposedUrlChanged(port: ForwardedPort, newUrl: String) {
128+
thisLogger().warn("gitpod: exposedUrlChanged($port, $newUrl)")
129+
}
130+
131+
override fun iconChanged(port: ForwardedPort, oldIcon: Icon?, newIcon: Icon?) {
132+
thisLogger().warn("gitpod: iconChanged($port, $oldIcon, $newIcon)")
133+
}
134+
135+
override fun nameChanged(port: ForwardedPort, oldName: String?, newName: String?) {
136+
thisLogger().warn("gitpod: nameChanged($port, $oldName, $newName)")
137+
}
138+
139+
override fun stateChanged(port: ForwardedPort, newState: ClientPortState) {
140+
when (newState) {
141+
is ClientPortState.Assigned -> {
142+
thisLogger().warn("gitpod: Started forwarding host port $hostPort to client port ${newState.clientPort}.")
143+
portsService.setForwardedPort(hostPort, newState.clientPort)
144+
}
145+
is ClientPortState.FailedToAssign -> {
146+
thisLogger().warn("gitpod: Detected that host port $hostPort failed to be assigned to a client port.")
147+
}
148+
else -> {
149+
thisLogger().warn("gitpod: Detected that host port $hostPort is not assigned to any client port.")
150+
}
151+
}
152+
}
153+
154+
override fun tooltipChanged(port: ForwardedPort, oldTooltip: String?, newTooltip: String?) {
155+
thisLogger().warn("gitpod: tooltipChanged($port, $oldTooltip, $newTooltip)")
156+
}
157+
})
158+
} catch (error: Error) {
159+
thisLogger().warn("gitpod: ${error.message}")
160+
}
124161
}
125162

126163
if (!isServed && isForwarded) {
127-
portForwardingManager.removePort(hostPort)
164+
val portListenerDisposable = portToDisposableMap[hostPort]
165+
if (portListenerDisposable != null) {
166+
portListenerDisposable.dispose()
167+
portToDisposableMap.remove(hostPort)
168+
}
169+
perClientPortForwardingManager.getPorts(hostPort).forEach { portToRemove ->
170+
perClientPortForwardingManager.removePort(portToRemove)
171+
}
128172
portsService.removeForwardedPort(hostPort)
129173
thisLogger().info("gitpod: Stopped forwarding port $hostPort.")
130174
}

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)