Skip to content

Commit

Permalink
fix deserialization problems
Browse files Browse the repository at this point in the history
  • Loading branch information
alyssaruth committed Oct 13, 2024
1 parent a989bba commit dba2302
Show file tree
Hide file tree
Showing 15 changed files with 68 additions and 46 deletions.
2 changes: 2 additions & 0 deletions client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ dependencies {
implementation("com.miglayout:miglayout-swing:5.2")
implementation("com.konghq:unirest-java:3.14.2")
implementation("ch.qos.logback:logback-classic:1.5.8")
implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.16.1")
implementation(project(":core"))
testImplementation(project(":test-core"))
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
Expand Down
10 changes: 5 additions & 5 deletions client/src/main/java/online/screen/EntropyLobby.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package online.screen;

import game.GameMode;
import http.dto.LobbyResponse;
import http.dto.LobbyMessage;
import http.dto.OnlineUser;
import http.dto.RoomSummary;
import object.RoomTable;
Expand Down Expand Up @@ -137,7 +137,7 @@ public EntropyLobby()
private final JButton btnSettings = new JButton("");
private final OnlineChatPanel chatPanel = new OnlineChatPanel(LOBBY_ID);

public void init(LobbyResponse lobbyResponse)
public void init(LobbyMessage lobbyMessage)
{
SwingUtilities.invokeLater(new Runnable()
{
Expand All @@ -157,7 +157,7 @@ public void run()

initChatPanelIfNecessary();

syncLobbyOnEventThread(lobbyResponse);
syncLobbyOnEventThread(lobbyMessage);
}
});

Expand Down Expand Up @@ -227,14 +227,14 @@ public GameRoom createGameRoom(RoomSummary room)
return gameRoom;
}

public void syncLobby(LobbyResponse response)
public void syncLobby(LobbyMessage response)
{
SwingUtilities.invokeLater(() -> {
syncLobbyOnEventThread(response);
});
}

private void syncLobbyOnEventThread(LobbyResponse response) {
private void syncLobbyOnEventThread(LobbyMessage response) {
roomTable.synchroniseRooms(response.getRooms());
synchUsernames(response.getUsers());
}
Expand Down
18 changes: 11 additions & 7 deletions client/src/main/kotlin/http/WebSocketReceiver.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package http

import http.dto.ClientMessage
import http.dto.LobbyResponse
import kong.unirest.JsonObjectMapper
import http.dto.LobbyMessage
import screen.ScreenCache
import utils.CoreGlobals
import utils.CoreGlobals.logger

class WebSocketReceiver {
private val jsonObjectMapper = JsonObjectMapper()

fun receiveMessage(rawMessage: String) {
val clientMessage = deserializeClientMessage(rawMessage)
logger.info(
"serverMessage",
"Received server message of type ${clientMessage::class.simpleName}"
)

when (val clientMessage = deserializeClientMessage(rawMessage)) {
is LobbyResponse -> handleLobbyResponse(clientMessage)
is LobbyMessage -> handleLobbyResponse(clientMessage)
}
}

Expand All @@ -29,9 +33,9 @@ class WebSocketReceiver {
}

private fun deserializeClientMessage(rawMessage: String): ClientMessage =
jsonObjectMapper.readValue(rawMessage, ClientMessage::class.java)
CoreGlobals.jsonMapper.readValue(rawMessage, ClientMessage::class.java)

private fun handleLobbyResponse(clientMessage: LobbyResponse) {
private fun handleLobbyResponse(clientMessage: LobbyMessage) {
ScreenCache.getEntropyLobby().syncLobby(clientMessage)
}
}
8 changes: 4 additions & 4 deletions client/src/test/kotlin/http/SessionApiTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.github.alyssaburlton.swingtest.flushEdt
import http.Routes.BEGIN_SESSION
import http.dto.BeginSessionRequest
import http.dto.BeginSessionResponse
import http.dto.LobbyResponse
import http.dto.LobbyMessage
import io.kotest.matchers.shouldBe
import io.mockk.every
import io.mockk.mockk
Expand Down Expand Up @@ -104,12 +104,12 @@ class SessionApiTest : AbstractTest() {
val mockLobby = mockk<EntropyLobby>(relaxed = true)
ScreenCache.setEntropyLobby(mockLobby)

val lobbyResponse = LobbyResponse(emptyList(), emptyList())
val lobbyMessage = LobbyMessage(emptyList(), emptyList())
val httpClient =
mockHttpClient(
SuccessResponse(
200,
BeginSessionResponse("alyssa", UUID.randomUUID(), lobbyResponse)
BeginSessionResponse("alyssa", UUID.randomUUID(), lobbyMessage)
)
)

Expand All @@ -119,7 +119,7 @@ class SessionApiTest : AbstractTest() {
verify {
lobby.username = "alyssa"
lobby.isVisible = true
lobby.init(lobbyResponse)
lobby.init(lobbyMessage)
}
}

Expand Down
1 change: 1 addition & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ktfmt { kotlinLangStyle() }
dependencies {
implementation("javax.activation:activation:1.1.1")
implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.16.1")
implementation("ch.qos.logback:logback-classic:1.5.8")
implementation("net.logstash.logback:logstash-logback-encoder:8.0")
testImplementation(project(":test-core"))
Expand Down
10 changes: 8 additions & 2 deletions core/src/main/java/util/XmlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,12 @@ public static String getStringFromDocument(Document xmlDoc)
return "";
}
}

public static Document getDocumentFromXmlString(String xmlStr) {
return getDocumentFromXmlString(xmlStr, false);
}

public static Document getDocumentFromXmlString(String xmlStr)
public static Document getDocumentFromXmlString(String xmlStr, boolean suppressError)
{
try
{
Expand All @@ -79,7 +83,9 @@ public static Document getDocumentFromXmlString(String xmlStr)
}
catch (Throwable t)
{
CoreGlobals.logger.error("xmlParseError", "Failed to parse XML " + xmlStr, t);
if (!suppressError) {
CoreGlobals.logger.error("xmlParseError", "Failed to parse XML " + xmlStr, t);
}
return null;
}
}
Expand Down
5 changes: 0 additions & 5 deletions core/src/main/kotlin/http/ClientMessageType.kt

This file was deleted.

2 changes: 1 addition & 1 deletion core/src/main/kotlin/http/dto/BeginSessionResponse.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package http.dto

import java.util.*

data class BeginSessionResponse(val name: String, val sessionId: UUID, val lobby: LobbyResponse)
data class BeginSessionResponse(val name: String, val sessionId: UUID, val lobby: LobbyMessage)
9 changes: 3 additions & 6 deletions core/src/main/kotlin/http/dto/ClientMessage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ package http.dto

import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
import http.ClientMessageType

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
include = JsonTypeInfo.As.PROPERTY,
property = "messageType",
)
@JsonSubTypes(JsonSubTypes.Type(value = LobbyResponse::class, name = "LOBBY"))
sealed class ClientMessage {
abstract val messageType: ClientMessageType
}
@JsonSubTypes(JsonSubTypes.Type(value = LobbyMessage::class, name = "LOBBY"))
abstract class ClientMessage
4 changes: 4 additions & 0 deletions core/src/main/kotlin/http/dto/LobbyMessage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package http.dto

data class LobbyMessage(val rooms: List<RoomSummary>, val users: List<OnlineUser>) :
ClientMessage()
8 changes: 0 additions & 8 deletions core/src/main/kotlin/http/dto/LobbyResponse.kt

This file was deleted.

5 changes: 3 additions & 2 deletions core/src/main/kotlin/utils/CoreGlobals.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package utils

import ch.qos.logback.classic.Logger as LogbackLogger
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import java.time.Clock
import logging.Logger
import org.slf4j.LoggerFactory
Expand All @@ -10,5 +11,5 @@ object CoreGlobals {
val slf4jLogger: LogbackLogger = LoggerFactory.getLogger("entropy") as LogbackLogger
@JvmField var logger: Logger = Logger(slf4jLogger)
var clock: Clock = Clock.systemUTC()
val objectMapper = ObjectMapper()
val jsonMapper = JsonMapper().also { it.registerKotlinModule() }
}
20 changes: 20 additions & 0 deletions core/src/test/kotlin/http/dto/ClientMessageTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package http.dto

import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test
import testCore.AbstractTest

class ClientMessageTest : AbstractTest() {
@Test
fun `Should be able to deserialize based on messageType`() {
val message = LobbyMessage(emptyList(), listOf(OnlineUser("Alyssa")))

val mapper = JsonMapper().registerKotlinModule()
val json = mapper.writeValueAsString(message)

val deserialized = mapper.readValue(json, ClientMessage::class.java)
deserialized shouldBe message
}
}
2 changes: 1 addition & 1 deletion server/src/main/java/server/MessageHandlerRunnable.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private void initVariablesFromSocket()
*/
private Document getResponse(String encryptedMessage) throws Throwable
{
Document unencryptedDocument = XmlUtil.getDocumentFromXmlString(encryptedMessage);
Document unencryptedDocument = XmlUtil.getDocumentFromXmlString(encryptedMessage, true);
if (unencryptedDocument != null)
{
//We've been sent an unencrypted XML message. Either this is the client agreeing a new
Expand Down
10 changes: 5 additions & 5 deletions server/src/main/kotlin/routes/lobby/LobbyService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ package routes.lobby
import auth.UserConnection
import game.GameMode
import game.GameSettings
import http.dto.LobbyResponse
import http.dto.LobbyMessage
import http.dto.OnlineUser
import http.dto.RoomSummary
import `object`.Room
import util.GameConstants
import util.ServerGlobals
import util.XmlConstants
import utils.CoreGlobals.objectMapper
import utils.CoreGlobals

class LobbyService {
fun getLobby(): LobbyResponse {
fun getLobby(): LobbyMessage {
val rooms = ServerGlobals.server.rooms.map { it.toSummary() }
val users = ServerGlobals.sessionStore.getAll().map { OnlineUser(it.name) }
return LobbyResponse(rooms, users)
return LobbyMessage(rooms, users)
}

@JvmOverloads
Expand All @@ -29,7 +29,7 @@ class LobbyService {
val lobbyMessage = getLobby()
ServerGlobals.server.sendViaNotificationSocket(
usersToNotify,
objectMapper.writeValueAsString(lobbyMessage),
CoreGlobals.jsonMapper.writeValueAsString(lobbyMessage),
XmlConstants.SOCKET_NAME_LOBBY,
)
}
Expand Down

0 comments on commit dba2302

Please sign in to comment.