Skip to content
This repository has been archived by the owner on Mar 26, 2024. It is now read-only.

Commit

Permalink
Add status endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
SerVB committed Feb 15, 2022
1 parent 0a68d1e commit 1b08e11
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ val commonVersionList = listOf(
1980644253,
1328208692,
-1867356666,
-1218764012,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* MIT License
*
* Copyright (c) 2019-2022 JetBrains s.r.o.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package org.jetbrains.projector.common.protocol.toClient

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json

@Serializable
data class Status(
val mainWindowsCount: Int,
val lastUserActionTimeStampMs: Long,
)

private val json = Json.Default
private val serializer = Status.serializer()

fun Status.toJson(): String = json.encodeToString(serializer, this)

fun String.toStatus(): Status = json.decodeFromString(serializer, this)
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ enum class KeyModifier {
@Serializable
sealed class ClientEvent

@Serializable
sealed class ClientUserEvent : ClientEvent()

@Serializable
sealed class ClientNonUserEvent : ClientEvent()

@Serializable
data class ClientMouseEvent(
/** From connection opening. */
Expand All @@ -67,7 +73,7 @@ data class ClientMouseEvent(
val clickCount: Int,
val modifiers: Set<MouseModifier>,
val mouseEventType: MouseEventType,
) : ClientEvent() {
) : ClientUserEvent() {

enum class MouseEventType {
MOVE,
Expand All @@ -91,7 +97,7 @@ data class ClientWheelEvent(
val y: Int,
val deltaX: Double,
val deltaY: Double,
) : ClientEvent() {
) : ClientUserEvent() {

enum class ScrollingMode {
PIXEL,
Expand All @@ -109,7 +115,7 @@ data class ClientKeyEvent(
val location: KeyLocation,
val modifiers: Set<KeyModifier>,
val keyEventType: KeyEventType,
) : ClientEvent() {
) : ClientUserEvent() {

enum class KeyEventType {
DOWN,
Expand All @@ -130,7 +136,7 @@ data class ClientKeyPressEvent(
val timeStamp: Int,
val char: Char,
val modifiers: Set<KeyModifier>,
) : ClientEvent()
) : ClientUserEvent()

@Serializable
data class ClientRawKeyEvent(
Expand All @@ -141,7 +147,7 @@ data class ClientRawKeyEvent(
val modifiers: Int,
val location: Int,
val keyEventType: RawKeyEventType,
) : ClientEvent() {
) : ClientUserEvent() {

enum class RawKeyEventType {
DOWN,
Expand All @@ -151,38 +157,38 @@ data class ClientRawKeyEvent(
}

@Serializable
data class ClientResizeEvent(val size: CommonIntSize) : ClientEvent()
data class ClientResizeEvent(val size: CommonIntSize) : ClientUserEvent()

@Serializable
data class ClientRequestImageDataEvent(val imageId: ImageId) : ClientEvent()
data class ClientRequestImageDataEvent(val imageId: ImageId) : ClientNonUserEvent()

@Serializable
data class ClientClipboardEvent(
val stringContent: String, // TODO: support more types
) : ClientEvent()
) : ClientNonUserEvent()

@Serializable
data class ClientRequestPingEvent(
/** From connection opening. */
val clientTimeStamp: Int,
) : ClientEvent()
) : ClientNonUserEvent()

@Serializable
data class ClientSetKeymapEvent(
val keymap: UserKeymap,
) : ClientEvent()
) : ClientUserEvent()

@Serializable
data class ClientOpenLinkEvent(
val link: String,
) : ClientEvent()
) : ClientUserEvent()

@Serializable
data class ClientWindowMoveEvent(
val windowId: Int,
val deltaX: Int,
val deltaY: Int,
) : ClientEvent()
) : ClientUserEvent()

// If delta is negative, we resizing to the left top
@Serializable
Expand All @@ -191,38 +197,38 @@ data class ClientWindowResizeEvent(
val deltaX: Int,
val deltaY: Int,
val direction: ResizeDirection,
) : ClientEvent()
) : ClientUserEvent()

@Serializable
data class ClientWindowSetBoundsEvent(
val windowId: Int,
val bounds: CommonIntRectangle
) : ClientEvent()
val bounds: CommonIntRectangle,
) : ClientUserEvent()

@Serializable
data class ClientDisplaySetChangeEvent(
val newDisplays: List<DisplayDescription>
) : ClientEvent()
val newDisplays: List<DisplayDescription>,
) : ClientUserEvent()

@Serializable
data class ClientWindowCloseEvent(
val windowId: Int,
) : ClientEvent()
) : ClientUserEvent()

@Serializable
data class ClientWindowInterestEvent(
val windowId: Int,
val isInterested: Boolean
): ClientEvent()
val isInterested: Boolean,
) : ClientNonUserEvent()

@Suppress("unused") //used in client-web/org.jetbrains.projector.client.web.window.WindowManager and at server side
@Serializable
data class ClientWindowsActivationEvent(
val windowIds: List<Int>,
) : ClientEvent()
) : ClientUserEvent()

@Suppress("unused") //used in client-web/org.jetbrains.projector.client.web.window.WindowManager and at server side
@Serializable
data class ClientWindowsDeactivationEvent(
val windowIds: List<Int>,
) : ClientEvent()
) : ClientUserEvent()
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import kotlinx.coroutines.runBlocking
import org.java_websocket.WebSocket
import org.jetbrains.projector.common.protocol.toClient.MainWindow
import org.jetbrains.projector.common.protocol.toClient.toMainWindowList
import org.jetbrains.projector.common.protocol.toClient.toStatus
import org.jetbrains.projector.server.core.websocket.HttpWsServer
import java.io.File
import java.nio.ByteBuffer
Expand Down Expand Up @@ -75,6 +76,8 @@ class ProjectorHttpWsServerTest {
pngBase64Icon = "png base 64",
)
)

override fun getLastUserActionTimeStampMs(): Long = 123
}
}

Expand Down Expand Up @@ -143,6 +146,20 @@ class ProjectorHttpWsServerTest {
server.stop()
}

@Test
fun testStatus() {
val server = createServer().also { it.start() }
val client = HttpClient()

val response = runBlocking { client.get<String>(prj("/status")) }.toStatus()

assertEquals(1, response.mainWindowsCount)
assertEquals(123, response.lastUserActionTimeStampMs)

client.close()
server.stop()
}

@Test
fun testFiles() {
val server = createServer().also { it.start() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import org.java_websocket.handshake.*
import org.java_websocket.server.WebSocketServer
import org.java_websocket.util.Charsetfunctions
import org.jetbrains.projector.common.protocol.toClient.MainWindow
import org.jetbrains.projector.common.protocol.toClient.Status
import org.jetbrains.projector.common.protocol.toClient.toJson
import org.jetbrains.projector.server.core.ClientWrapper
import org.jetbrains.projector.server.core.util.getWildcardHostAddress
Expand All @@ -60,6 +61,7 @@ public abstract class HttpWsServer(host: InetAddress, port: Int) : HttpWsTranspo
public constructor(port: Int) : this(getWildcardHostAddress(), port)

public abstract fun getMainWindows(): List<MainWindow>
public abstract fun getLastUserActionTimeStampMs(): Long

public fun onGetRequest(path: String): GetRequestResult {
val pathWithoutParams = path.substringBefore('?').substringBefore('#')
Expand All @@ -75,6 +77,22 @@ public abstract class HttpWsServer(host: InetAddress, port: Int) : HttpWsTranspo
)
}

if (pathWithoutParams == "/status") {
val mainWindows = getMainWindows()
val lastUserActionTimeStampMs = getLastUserActionTimeStampMs()
val status = Status(
mainWindowsCount = mainWindows.size,
lastUserActionTimeStampMs = lastUserActionTimeStampMs,
)
val json = status.toJson().toByteArray()
return GetRequestResult(
statusCode = 200,
statusText = "OK",
contentType = "text/json",
content = json,
)
}

val resourceFileName = getResourceName(pathWithoutParams)
val resourceBytes = getResource(resourceFileName)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ import java.nio.ByteBuffer
public class HttpWsServerBuilder(private val host: InetAddress, private val port: Int): WsTransportBuilder() {

public lateinit var getMainWindows: () -> List<MainWindow>
public lateinit var getLastUserActionTimeStampMs: () -> Long

override fun build(): HttpWsServer {
val wsServer = object : HttpWsServer(host, port) {
override fun getMainWindows(): List<MainWindow> = this@HttpWsServerBuilder.getMainWindows()
override fun getLastUserActionTimeStampMs() = this@HttpWsServerBuilder.getLastUserActionTimeStampMs()
override fun onError(connection: WebSocket?, e: Exception) = this@HttpWsServerBuilder.onError(connection, e)
override fun onWsOpen(connection: WebSocket) = this@HttpWsServerBuilder.onWsOpen(connection)
override fun onWsClose(connection: WebSocket) = this@HttpWsServerBuilder.onWsClose(connection)
Expand Down

0 comments on commit 1b08e11

Please sign in to comment.