From a1adae7a1a23f916fdfe7ca4586684d5ca82ed5c Mon Sep 17 00:00:00 2001 From: Daniel Tavares Agostinho Date: Wed, 26 Jun 2024 15:04:37 +0200 Subject: [PATCH 1/8] log storage done --- be2-scala/src/main/resources/logback.xml | 2 +- .../scala/ch/epfl/pop/storage/DbActor.scala | 89 +++++++++---------- .../pop/storage/SecurityModuleActor.scala | 8 +- 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/be2-scala/src/main/resources/logback.xml b/be2-scala/src/main/resources/logback.xml index b0019fde22..5247a6e776 100644 --- a/be2-scala/src/main/resources/logback.xml +++ b/be2-scala/src/main/resources/logback.xml @@ -3,7 +3,7 @@ - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + %d{HH:mm:ss.SSS} - %highlight(%-5level) : %logger{0} > %msg%n diff --git a/be2-scala/src/main/scala/ch/epfl/pop/storage/DbActor.scala b/be2-scala/src/main/scala/ch/epfl/pop/storage/DbActor.scala index 3a94d7a6ce..30961beeca 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/storage/DbActor.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/storage/DbActor.scala @@ -1,7 +1,7 @@ package ch.epfl.pop.storage import akka.actor.{Actor, ActorLogging, ActorRef, Status} -import akka.event.LoggingReceive +import akka.event.{Logging, LoggingReceive} import akka.pattern.AskableActorRef import ch.epfl.pop.decentralized.ConnectionMediator import ch.epfl.pop.json.MessageDataProtocol @@ -38,7 +38,6 @@ final case class DbActor( storage.close() super.postStop() } - private val duration: FiniteDuration = Duration(1, TimeUnit.SECONDS) /* --------------- Functions handling messages DbActor may receive --------------- */ @@ -85,7 +84,7 @@ final case class DbActor( storage.write((storage.DATA_KEY + storage.SETUP_ELECTION_KEY + channel.toString, message.message_id.toString())) writeAndPropagate(mainLaoChan, message) - case _ => log.info("Error: Trying to write an ElectionSetup message on an invalid channel") + case _ => log.error(s"Trying to write an ElectionSetup message on an invalid channel ${channel.channel}. Not writing message ${message.message_id} in memory") } } @@ -101,7 +100,7 @@ final case class DbActor( } case _ => - log.info("Error: Trying to read an ElectionSetup message from an invalid channel") + log.error(s"Trying to read an ElectionSetup message from an invalid channel ${channel.channel}.") None } } @@ -117,7 +116,7 @@ final case class DbActor( val builder = registry.getBuilder(_object, action).get Some(msg.copy(decodedData = Some(builder(data)))) case Failure(ex) => - log.error(s"Unable to decode message data: $ex") + log.error(s"Unable to parse header. Therefore unable to decode message data: $ex") Some(msg) } case Success(None) => None @@ -213,7 +212,7 @@ final case class DbActor( } - val noCreateLAOMessageError = "Critical error encountered: no create_lao message was found in the db" + val noCreateLAOMessageError = "No create_lao message was found in the db." val laoID = channel.decodeChannelLaoId match { case Some(id) => id @@ -229,7 +228,7 @@ final case class DbActor( case None => if (reactionsChannel.isMainLaoChannel) { - log.error(noCreateLAOMessageError) + log.error(s"$noCreateLAOMessageError") } buildCatchupList(reactionsChannelData.messages, Nil, reactionsChannel) } @@ -249,7 +248,7 @@ final case class DbActor( case None => if (reactionsChannel.isMainLaoChannel) { - log.error(noCreateLAOMessageError) + log.error(s"$noCreateLAOMessageError") } buildCatchupList(reactionsChannelDataIDs, Nil, reactionsChannel) } @@ -410,7 +409,7 @@ final case class DbActor( Try(read(fromChannel, head)).recover(_ => None) match { case Success(Some(msg)) => buildCatchupList(tail, msg :: acc, fromChannel) case _ => - log.error(s"/!\\ Critical error encountered: message_id '$head' is listed in channel '$fromChannel' but not stored in db") + log.error(s"message_id '$head' is listed in channel '$fromChannel' but not stored in db. This entry will be ignored.") buildCatchupList(tail, acc, fromChannel) } } @@ -459,7 +458,7 @@ final case class DbActor( case None => if (channel.isMainLaoChannel) { - log.error("Critical error encountered: no create_lao message was found in the db") + log.error("No create_lao message was found in the db") } buildCatchupList(channelData.messages, Nil, channel) } @@ -482,7 +481,7 @@ final case class DbActor( Try(read(channelToPage, head)).recover(_ => None) match { case Success(Some(msg)) => buildPagedCatchupList(tail, msg :: acc, channelToPage) case _ => - log.error(s"/!\\ Critical error encountered: message_id '$head' is listed in channel '$channelToPage' but not stored in db") + log.error(s"Critical error encountered: message_id '$head' is listed in channel '$channelToPage' but not stored in db. This entry will be ignored.") buildPagedCatchupList(tail, acc, channelToPage) } } @@ -678,7 +677,7 @@ final case class DbActor( case Success(Some(msg)) => msg.addWitnessSignature(WitnessSignaturePair(msg.sender, signature)) case Success(None) => - log.error(s"Actor $self (db) encountered a problem while reading the message having as id '$messageId'") + log.error(s"Encountered a problem while reading the message having as id '$messageId'. Signature $signature was not added to message $messageId.") throw DbActorNAckException(ErrorCodes.SERVER_ERROR.id, s"Could not read message of message id $messageId") case Failure(ex) => throw ex } @@ -689,7 +688,7 @@ final case class DbActor( channel.decodeChannelLaoId match { case Some(data) => storage.DATA_KEY + s"${Channel.ROOT_CHANNEL_PREFIX}$data$LAO_DATA_LOCATION" case None => - log.error(s"Actor $self (db) encountered a problem while decoding LAO channel from '$channel'") + log.error(s"Encountered a problem while decoding LAO channel from '$channel'. LAO data key for channel ${channel.channel} was not generated.") throw DbActorNAckException(ErrorCodes.SERVER_ERROR.id, s"Could not extract the LAO id for channel $channel") } } @@ -854,105 +853,105 @@ final case class DbActor( override def receive: Receive = LoggingReceive { case Write(channel, message) => - log.info(s"Actor $self (db) received a WRITE request on channel '$channel'") + log.info(s"Received a WRITE request on channel '$channel' for message ${message.message_id}") Try(write(channel, message)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case Read(channel, messageId) => - log.info(s"Actor $self (db) received a READ request for message_id '$messageId' from channel '$channel'") + log.info(s"Received a READ request for message_id '$messageId' from channel '$channel'") Try(read(channel, messageId)) match { case Success(opt) => sender() ! DbActorReadAck(opt) case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadChannelData(channel) => - log.info(s"Actor $self (db) received a ReadChannelData request from channel '$channel'") + log.info(s"Received a ReadChannelData request for channel '$channel'") Try(readChannelData(channel)) match { case Success(channelData) => sender() ! DbActorReadChannelDataAck(channelData) case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadElectionData(laoId, electionId) => - log.info(s"Actor $self (db) received a ReadElectionData request for election '$electionId'") + log.info(s"Received a ReadElectionData request for election '$electionId' in lao_id $laoId") Try(readElectionData(laoId, electionId)) match { case Success(electionData) => sender() ! DbActorReadElectionDataAck(electionData) case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadLaoData(channel) => - log.info(s"Actor $self (db) received a ReadLaoData request") + log.info(s"Received a ReadLaoData request for channel ${channel.channel}") Try(readLaoData(channel)) match { case Success(laoData) => sender() ! DbActorReadLaoDataAck(laoData) case failure => sender() ! failure.recover(Status.Failure(_)) } case WriteLaoData(channel, message, address) => - log.info(s"Actor $self (db) received a WriteLaoData request for channel $channel") + log.info(s"Received a WriteLaoData request for channel $channel and message_id ${message.message_id}") Try(writeLaoData(channel, message, address)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case WriteCreateLaoMessage(channel, message) => - log.info(s"Actor $self (db) received a WriteCreateLaoMessage request") + log.info(s"Received a WriteCreateLaoMessage request for channel ${channel.channel} and message_id ${message.message_id}") Try(writeCreateLao(channel, message)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case WriteSetupElectionMessage(channel, message) => - log.info(s"Actor $self (db) received a WriteSetupElectionMessage request") + log.info(s"Received a WriteSetupElectionMessage request on channel ${channel.channel} and message_id ${message.message_id}") Try(writeSetupElectionMessage(channel, message)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadSetupElectionMessage(channel) => - log.info(s"Actor $self (db) received a ReadSetupElectionMessage request") + log.info(s"Received a ReadSetupElectionMessage request on channel ${channel.channel}") Try(readSetupElectionMessage(channel)) match { case Success(msg) => sender() ! DbActorReadAck(msg) case failure => sender() ! failure.recover(Status.Failure(_)) } case Catchup(channel) => - log.info(s"Actor $self (db) received a CATCHUP request for channel '$channel'") + log.info(s"Received a CATCHUP request for channel '$channel'") Try(catchupChannel(channel)) match { case Success(messages) => sender() ! DbActorCatchupAck(messages) case failure => sender() ! failure.recover(Status.Failure(_)) } case PagedCatchup(channel, numberOfMessages, beforeMessageID) => - log.info(s"Actor $self (db) received a PagedCatchup request for channel '$channel' for '$numberOfMessages' messages before message ID: '$beforeMessageID") + log.info(s"Received a PagedCatchup request for channel '$channel' for '$numberOfMessages' messages before message ID: '$beforeMessageID") Try(pagedCatchupChannel(channel, numberOfMessages, beforeMessageID)) match { case Success(messages) => sender() ! DbActorCatchupAck(messages) case failure => sender() ! failure.recover(Status.Failure(_)) } case GetAllChannels() => - log.info(s"Actor $self (db) receveid a GetAllChannels request") + log.info(s"Received a GetAllChannels request") Try(getAllChannels) match { case Success(setOfChannels) => sender() ! DbActorGetAllChannelsAck(setOfChannels) case failure => sender() ! failure.recover(Status.Failure(_)) } case WriteAndPropagate(channel, message) => - log.info(s"Actor $self (db) received a WriteAndPropagate request on channel '$channel'") + log.info(s"Received a WriteAndPropagate request on channel '$channel' for message_id ${message.message_id}") Try(writeAndPropagate(channel, message)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case CreateChannel(channel, objectType) => - log.info(s"Actor $self (db) received an CreateChannel request for channel '$channel' of type '$objectType'") + log.info(s"Received an CreateChannel request for channel '$channel' of type '$objectType'") Try(createChannel(channel, objectType)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case CreateElectionData(laoId, id, keyPair) => - log.info(s"Actor $self (db) received an CreateElection request for election '$id'" + + log.info(s"Received an CreateElection request for election '$id'" + s"\n\tprivate key = ${keyPair.privateKey.toString}" + s"\n\tpublic key = ${keyPair.publicKey.toString}") Try(createElectionData(laoId, id, keyPair)) match { @@ -961,14 +960,14 @@ final case class DbActor( } case CreateChannelsFromList(list) => - log.info(s"Actor $self (db) received a CreateChannelsFromList request for list $list") + log.info(s"Received a CreateChannelsFromList request for list $list") Try(createChannels(list)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case ChannelExists(channel) => - log.info(s"Actor $self (db) received an ChannelExists request for channel '$channel'") + log.info(s"Received an ChannelExists request for channel '$channel'") if (checkChannelExistence(channel)) { sender() ! DbActorAck() } else { @@ -976,7 +975,7 @@ final case class DbActor( } case AssertChannelMissing(channel) => - log.info(s"Actor $self (db) received an AssertChannelMissing request for channel '$channel'") + log.info(s"Received an AssertChannelMissing request for channel '$channel'") if (checkChannelExistence(channel)) { sender() ! Status.Failure(DbActorNAckException(ErrorCodes.INVALID_ACTION.id, s"channel '$channel' already exists in db")) } else { @@ -984,35 +983,35 @@ final case class DbActor( } case AddWitnessSignature(channel, messageId, signature) => - log.info(s"Actor $self (db) received an AddWitnessSignature request for message_id '$messageId'") + log.info(s"Received an AddWitnessSignature request for message_id '$messageId' on channel ${channel.channel} with signature ${signature.toString}") Try(addWitnessSignature(channel, messageId, signature)) match { case Success(witnessMessage) => sender() ! DbActorAddWitnessSignatureAck(witnessMessage) case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadRollCallData(laoId) => - log.info(s"Actor $self (db) received an ReadRollCallData request for RollCall '$laoId'") + log.info(s"Received an ReadRollCallData request for RollCall '$laoId'") Try(readRollCallData(laoId)) match { case Success(rollcallData) => sender() ! DbActorReadRollCallDataAck(rollcallData) case failure => sender() ! failure.recover(Status.Failure(_)) } case WriteRollCallData(laoId, message) => - log.info(s"Actor $self (db) received a WriteRollCallData request for RollCall id $laoId") + log.info(s"Received a WriteRollCallData request for RollCall id $laoId and message_id ${message.message_id}") Try(writeRollCallData(laoId, message)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case WriteUserAuthenticated(popToken, clientId, user) => - log.info(s"Actor $self (db) received a WriteUserAuthenticated request for user $user, id $popToken and clientId $clientId") + log.info(s"Received a WriteUserAuthenticated request for user $user, id $popToken and clientId $clientId") Try(storage.write(generateAuthenticatedKey(popToken, clientId) -> user.base64Data.toString())) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadUserAuthenticated(popToken, clientId) => - log.info(s"Actor $self (db) received a ReadUserAuthenticated request for pop token $popToken and clientId $clientId") + log.info(s"Received a ReadUserAuthenticated request for pop token $popToken and clientId $clientId") Try(storage.read(generateAuthenticatedKey(popToken, clientId))) match { case Success(Some(id)) => sender() ! DbActorReadUserAuthenticationAck(Some(PublicKey(Base64Data(id)))) case Success(None) => sender() ! DbActorReadUserAuthenticationAck(None) @@ -1020,56 +1019,56 @@ final case class DbActor( } case ReadServerPublicKey() => - log.info(s"Actor $self (db) received a ReadServerPublicKey request") + log.info(s"Received a ReadServerPublicKey request") Try(readServerPublicKey()) match { case Success(publicKey) => sender() ! DbActorReadServerPublicKeyAck(publicKey) case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadServerPrivateKey() => - log.info(s"Actor $self (db) received a ReadServerPrivateKey request") + log.info(s"Received a ReadServerPrivateKey request") Try(readServerPrivateKey()) match { case Success(privateKey) => sender() ! DbActorReadServerPrivateKeyAck(privateKey) case failure => sender() ! failure.recover(Status.Failure(_)) } case GenerateHeartbeat() => - log.info(s"Actor $self (db) received a GenerateHeartbeat request") + log.info(s"Received a GenerateHeartbeat request") Try(generateHeartbeat()) match { case Success(heartbeat) => sender() ! DbActorGenerateHeartbeatAck(heartbeat) case failure => sender() ! failure.recover(Status.Failure(_)) } case WriteRumor(rumor) => - log.info(s"Actor $self (db) received a WriteRumor request") + log.info(s"Received a WriteRumor request") Try(writeRumor(rumor)) match { case Success(_) => sender() ! DbActorAck() case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadRumor(desiredRumor) => - log.info(s"Actor $self (db) received a ReadRumor request") + log.info(s"Received a ReadRumor request for rumor $desiredRumor") Try(readRumor(desiredRumor)) match { case Success(foundRumor) => sender() ! DbActorReadRumor(foundRumor) case failure => sender() ! failure.recover(Status.Failure(_)) } case ReadRumorData(senderPk) => - log.info(s"Actor $self (db) received a ReadRumorData request") + log.info(s"Received a ReadRumorData request for sender_pk $senderPk") Try(readRumorData(senderPk)) match { case Success(foundRumorIds) => sender() ! DbActorReadRumorData(foundRumorIds) case failure => sender() ! failure.recover(Status.Failure(_)) } case GenerateRumorStateAns(rumorState: RumorState) => - log.info(s"Actor $self (db) received a GenerateRumorStateAns request") + log.info(s"Received a GenerateRumorStateAns request based on rumor_state ${rumorState.state}") Try(generateRumorStateAns(rumorState)) match { case Success(rumorList) => sender() ! DbActorGenerateRumorStateAns(rumorList) case failure => sender() ! failure.recover(Status.Failure(_)) } case GetRumorState() => - log.info(s"Actor $self (db) received a GetRumorState request") + log.info(s"Received a GetRumorState request") Try(getRumorState) match case Success(rumorState) => sender() ! DbActorGetRumorStateAck(rumorState) case failure => sender() ! failure.recover(Status.Failure(_)) @@ -1078,7 +1077,7 @@ final case class DbActor( updateNumberOfNewChirpsReactions(channel, false) case m => - log.info(s"Actor $self (db) received an unknown message") + log.warning(s"Received an unknown message $m") sender() ! Status.Failure(DbActorNAckException(ErrorCodes.INVALID_ACTION.id, s"database actor received a message '$m' that it could not recognize")) } } diff --git a/be2-scala/src/main/scala/ch/epfl/pop/storage/SecurityModuleActor.scala b/be2-scala/src/main/scala/ch/epfl/pop/storage/SecurityModuleActor.scala index 4ee2ac06be..02cac9b678 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/storage/SecurityModuleActor.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/storage/SecurityModuleActor.scala @@ -53,22 +53,22 @@ final case class SecurityModuleActor(keysFolderPath: String) extends Actor with override def receive: Receive = LoggingReceive { case ReadRsaPublicKey() => - log.info(s"Actor $self (SecurityModuleActor) received a ReadRsaPublicKey request") + log.info(s"Received a ReadRsaPublicKey request") sender() ! ReadRsaPublicKeyAck(rsaPublicKey) case ReadRsaPublicKeyPem() => - log.info(s"Actor $self (SecurityModuleActor) received a ReadRsaPublicKeyPem request") + log.info(s"Received a ReadRsaPublicKeyPem request") sender() ! ReadRsaPublicKeyPemAck(rsaPublicKeyPem) case SignJwt(jwt) => - log.info(s"Actor $self (SecurityModuleActor) received a SignJwt request for jwt $jwt") + log.info(s"Received a SignJwt request for jwt $jwt") Try(signJwt(jwt)) match { case Success(jwtStr) => sender() ! SignJwtAck(jwtStr) case failure => sender() ! failure.recover(Status.Failure(_)) } case m => - log.info(s"Actor $self (SecurityModuleActor) received an unknown message") + log.warning(s"Received an unknown message $m") sender() ! Status.Failure(DbActorNAckException(ErrorCodes.INVALID_ACTION.id, s"securityModuleActor actor received a message '$m' that it could not recognize")) } } From 28543bb845c6de728f3d2cdc5ba6d04feebad76b Mon Sep 17 00:00:00 2001 From: Daniel Tavares Agostinho Date: Wed, 26 Jun 2024 15:59:06 +0200 Subject: [PATCH 2/8] adapted log messages --- .../src/main/scala/ch/epfl/pop/Server.scala | 10 +++---- .../decentralized/ConnectionMediator.scala | 2 +- .../pop/decentralized/GossipManager.scala | 27 ++++++++++--------- .../ch/epfl/pop/decentralized/Monitor.scala | 2 +- .../ch/epfl/pop/pubsub/ClientActor.scala | 10 +++---- .../ch/epfl/pop/pubsub/PubSubMediator.scala | 24 ++++++++--------- .../ch/epfl/pop/pubsub/PublishSubscribe.scala | 2 +- .../ch/epfl/pop/pubsub/graph/Answerer.scala | 6 +++-- .../pubsub/graph/handlers/ParamsHandler.scala | 2 +- .../handlers/ProcessMessagesHandler.scala | 2 +- 10 files changed, 45 insertions(+), 42 deletions(-) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/Server.scala b/be2-scala/src/main/scala/ch/epfl/pop/Server.scala index c32ae51293..ba1ea65fe7 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/Server.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/Server.scala @@ -100,11 +100,11 @@ object Server { bindingFuture.onComplete { case Success(_) => - println(f"[Client] ch.epfl.pop.Server online at $ownClientAddress") - println(f"[Server] ch.epfl.pop.Server online at $ownServerAddress") - println(f"[Server] ch.epfl.pop.Server auth server online at $ownAuthAddress") - println(f"[Server] ch.epfl.pop.Server auth ws server online at $ownResponseAddress") - println(f"[Server] ch.epfl.pop.Server public key available at $ownPublicKeyAddress") + logger.info(f"[Client] online at $ownClientAddress") + logger.info(f"[Server] online at $ownServerAddress") + logger.info(f"[Server] auth server online at $ownAuthAddress") + logger.info(f"[Server] auth ws server online at $ownResponseAddress") + logger.info(f"[Server] public key available at $ownPublicKeyAddress") case Failure(_) => logger.error( diff --git a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/ConnectionMediator.scala b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/ConnectionMediator.scala index e90e371995..241038d99b 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/ConnectionMediator.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/ConnectionMediator.scala @@ -54,7 +54,7 @@ final case class ConnectionMediator( ) case ConnectionMediator.ServerLeft(serverRef) => - log.info("Server left") + log.info(s"Server ${serverMap(serverRef).serverAddress} left") serverMap -= serverRef // Tell monitor to stop scheduling heartbeats since there is no one to receive them if (serverMap.isEmpty) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/GossipManager.scala b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/GossipManager.scala index 258cd97cce..052dd5c4c2 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/GossipManager.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/GossipManager.scala @@ -42,7 +42,7 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou Await.result(readPk, duration) match case DbActor.DbActorReadServerPublicKeyAck(pk) => Some(pk) case _ => - log.info(s"Actor (gossip) $self will not be able to create rumors because it has no publicKey") + log.error(s"Will not be able to create rumors because it has no publicKey") None } @@ -67,6 +67,7 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou // checks the peers to which we already forwarded the message val activeGossip: Set[ActorRef] = peersAlreadyReceived(rumorRpc) // selects a random peer from remaining peers + val rumor = rumorRpc.getParams.asInstanceOf[Rumor] val randomPeer = connectionMediatorRef ? ConnectionMediator.GetRandomPeer(activeGossip) Await.result(randomPeer, duration) match { // updates the list based on response @@ -74,7 +75,7 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou case ConnectionMediator.GetRandomPeerAck(serverRef, greetServer) => val alreadySent: Set[ActorRef] = activeGossip + serverRef activeGossipProtocol += (rumorRpc -> alreadySent) - log.info(s"rumorSent > dest : ${greetServer.clientAddress}, rumor : $rumorRpc") + log.info(s"Sent rumor {${rumor.senderPk}:${rumor.rumorId}} to ${greetServer.clientAddress}") serverRef ! ClientAnswer( Right(rumorRpc) ) @@ -82,7 +83,7 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou case ConnectionMediator.NoPeer() => activeGossipProtocol = activeGossipProtocol.removed(rumorRpc) case _ => - log.info(s"Actor $self received an unexpected message waiting for a random peer") + log.warning(s"Received an unexpected message waiting for a random peer. Gossip step has been ignored for rumor {${rumor.senderPk}:${rumor.rumorId}}") } } @@ -115,7 +116,7 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou } } } else { - log.info(s"Unexpected match for active gossip. Response with id ${response.id} matched with ${activeGossipPeers.size} entries") + log.warning(s"Unexpected match for active gossip. Response with id ${response.id} matched with ${activeGossipPeers.size} entries. Duplicates will be removed.") // removes duplicate entries to come back to a stable state activeGossipPeers.foreach { (rumorRpc, _) => activeGossipProtocol -= rumorRpc @@ -135,16 +136,16 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou case DbActorGetRumorStateAck(rumorState) => state = rumorState case _ => - log.info(s"Actor (gossip) $self was not able to get its rumor state. Gossip has not started") + log.warning(s"Was not able to get its rumor state. Gossip has not started") return val rumor: Rumor = Rumor(publicKey.get, getRumorId(publicKey.get) + 1, messages, state) val jsonRpcRequest = prepareRumor(rumor) val writeRumor = dbActorRef ? DbActor.WriteRumor(rumor) Await.result(writeRumor, duration) match case DbActorAck() => updateGossip(jsonRpcRequest) - case _ => log.info(s"Actor (gossip) $self was not able to write rumor in memory. Gossip has not started.") + case _ => log.warning(s"Was not able to write rumor in memory. Gossip has not started.") else - log.info(s"Actor (gossip) $self will not be able to start rumors because it has no publicKey") + log.error(s"Will not be able to start rumors because it has no publicKey") } private def getRumorId(publicKey: PublicKey): Int = { @@ -172,9 +173,9 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou )) ) jsonId += 1 - case _ => log.info(s"Actor $self failed on creating rumor state") - case _ => - log.info(s"Actor $self received an unexpected message waiting for a random peer") + case _ => log.error(s"Actor $self failed on creating rumor state. State wasn't gossiped.") + case m @ _ => + log.warning(s"Received an unexpected message $m waiting for a random peer") } } @@ -207,7 +208,7 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou startGossip(messages) case ConnectionMediator.Ping() => - log.info(s"Actor $self received a ping from Connection Mediator") + log.info(s"Received a ping from Connection Mediator") connectionMediatorRef = sender() case Monitor.AtLeastOneServerConnected => @@ -219,8 +220,8 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou case TriggerPullState() => sendRumorState() - case _ => - log.info(s"Actor $self received an unexpected message") + case m @ _ => + log.info(s"Received an unexpected message $m.") } } diff --git a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/Monitor.scala b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/Monitor.scala index 8042965d72..05242f941c 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/Monitor.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/Monitor.scala @@ -59,7 +59,7 @@ final case class Monitor( timers.cancelAll() case Monitor.TriggerHeartbeat => - log.info("triggering a heartbeat") + log.info("Triggering a heartbeat") timers.cancel(singleHbKey) val askForHeartbeat = dbActorRef ? DbActor.GenerateHeartbeat() diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/ClientActor.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/ClientActor.scala index 3628092028..fc737aa9b6 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/ClientActor.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/ClientActor.scala @@ -65,15 +65,15 @@ final case class ClientActor(mediator: ActorRef, connectionMediatorRef: ActorRef } case message: PubSubMediatorMessage => message match { case SubscribeToAck(channel) => - log.info(s"Actor $self received ACK mediator $mediator for the subscribe to channel '$channel' request") + log.info(s"Received ACK from Mediator to subscribe request on channel '$channel'") subscribedChannels += channel case UnsubscribeFromAck(channel) => - log.info(s"Actor $self received ACK mediator $mediator for the unsubscribe from channel '$channel' request") + log.info(s"Received ACK from Mediator to unsubscribe request on channel '$channel' request") subscribedChannels -= channel case SubscribeToNAck(channel, reason) => - log.info(s"Actor $self received NACK mediator $mediator for the subscribe to channel '$channel' request for reason: $reason") + log.info(s"Received NACK from Mediator to subscribe request on channel '$channel' for reason: $reason") case UnsubscribeFromNAck(channel, reason) => - log.info(s"Actor $self received NACK mediator $mediator for the unsubscribe from channel '$channel' request for reason: $reason") + log.info(s"Received NACK from Mediator for unsubscribe request on channel '$channel' for reason: $reason") case PropagateAck() => // Nothing to do. } case greetServer: GreetServer => @@ -114,7 +114,7 @@ final case class ClientActor(mediator: ActorRef, connectionMediatorRef: ActorRef } if (publicKey.isDefined) { - log.info("Sending greet") + log.info("Sending greetServer") val greetServer = GreetServer(publicKey.get, clientAddress, serverAddress) messageWsHandle(ClientAnswer(Right(JsonRpcRequest( RpcValidator.JSON_RPC_VERSION, diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/PubSubMediator.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/PubSubMediator.scala index db66f2ff9f..34a1150ee8 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/PubSubMediator.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/PubSubMediator.scala @@ -31,41 +31,41 @@ class PubSubMediator extends Actor with ActorLogging with AskPatternConstants { // if we have people already subscribed to said channel case Some(set) => if (set.contains(clientActorRef)) { - log.info(s"$clientActorRef already subscribed to '$channel'") + log.warning(s"client $clientActorRef already subscribed to '$channel'") Future(SubscribeToAck(channel)) } else { - log.info(s"Subscribing $clientActorRef to channel '$channel'") + log.info(s"Subscribing client $clientActorRef to channel '$channel'") set += clientActorRef Future(SubscribeToAck(channel)) } // if we have no one subscribed to said channel case _ => - log.info(s"Subscribing $clientActorRef to channel '$channel'") + log.info(s"Subscribing client $clientActorRef to channel '$channel'") channelMap = channelMap ++ List(channel -> mutable.Set(clientActorRef)) Future(SubscribeToAck(channel)) } // db doesn't recognize the channel, thus mediator cannot subscribe anyone to a non existing channel case _ => - val reason: String = s"Channel '$channel' doesn't exist in db" - log.info(reason) + val reason: String = s"Channel '$channel' doesn't exist in db." + log.warning(s"$reason. Mediator cannot subscribe to non-existing channel") Future(SubscribeToNAck(channel, reason)) } } private def unsubscribeFrom(channel: Channel, clientActorRef: ActorRef): PubSubMediatorMessage = channelMap.get(channel) match { case Some(set) if set.contains(clientActorRef) => - log.info(s"Unsubscribing $clientActorRef from channel '$channel'") + log.info(s"Unsubscribing client $clientActorRef from channel '$channel'") set -= clientActorRef UnsubscribeFromAck(channel) case Some(_) => - val reason: String = s"Actor $clientActorRef is not subscribed to channel '$channel'" - log.info(reason) + val reason: String = s"Client $clientActorRef is not subscribed to channel '$channel'" + log.warning(reason) UnsubscribeFromNAck(channel, reason) case _ => val reason: String = s"Channel '$channel' does not exist in the system" - log.info(reason) + log.warning(reason) UnsubscribeFromNAck(channel, reason) } @@ -79,11 +79,11 @@ class PubSubMediator extends Actor with ActorLogging with AskPatternConstants { channelMap.get(channel) match { case Some(clientRefs: mutable.Set[ActorRef]) => - log.info(s"Actor $self (PubSubMediator) is propagating a message to ${clientRefs.size} clients") + log.info(s"Propagating a message to ${clientRefs.size} clients") clientRefs.foreach(clientRef => clientRef ! ClientActor.ClientAnswer(generateAnswer())) case _ => - log.info(s"Actor $self (PubSubMediator) did not propagate any message since no client is subscribed to channel $channel") + log.warning(s"Did not propagate any message since no client is subscribed to channel $channel") } } @@ -102,7 +102,7 @@ class PubSubMediator extends Actor with ActorLogging with AskPatternConstants { sender() ! PropagateAck() case m @ _ => - log.error(s"PubSubMediator received an unknown message : $m") + log.warning(s"Received an unknown message : $m. Message is ignored.") } } diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/PublishSubscribe.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/PublishSubscribe.scala index 573c5c1f04..e5cb2e9998 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/PublishSubscribe.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/PublishSubscribe.scala @@ -59,7 +59,7 @@ object PublishSubscribe { /* building blocks */ // input message from the client - val input = builder.add(Flow[Message].collect { case TextMessage.Strict(s) => println(s">>> Incoming message : $s"); s }) + val input = builder.add(Flow[Message].collect { case TextMessage.Strict(s) => system.log.info(s"Incoming message : $s"); s }) val schemaVerifier = builder.add(SchemaVerifier.rpcSchemaVerifier) val jsonRpcDecoder = builder.add(MessageDecoder.jsonRpcParser) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala index cf58e02945..ca7702635c 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala @@ -2,17 +2,19 @@ package ch.epfl.pop.pubsub.graph import akka.NotUsed import akka.actor.{ActorRef, ActorSystem} +import akka.event.Logging import akka.http.scaladsl.model.ws.TextMessage import akka.stream.scaladsl.{Flow, Sink, Source} import akka.stream.{CompletionStrategy, OverflowStrategy} -import ch.epfl.pop.json.HighLevelProtocol._ +import ch.epfl.pop.json.HighLevelProtocol.* import ch.epfl.pop.model.network.{ErrorObject, JsonRpcRequest, JsonRpcResponse} import ch.epfl.pop.pubsub.ClientActor.{ClientAnswer, ConnectWsHandle, DisconnectWsHandle} import ch.epfl.pop.pubsub.graph.validators.RpcValidator -import spray.json._ +import spray.json.* object Answerer { private val CLIENT_BUFFER_SIZE: Int = 256 + private def errorResponseString(code: Int, reason: String, rpcId: Option[Int]): String = JsonRpcResponse( RpcValidator.JSON_RPC_VERSION, diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ParamsHandler.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ParamsHandler.scala index c1d5e14cf8..18fb6d5b10 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ParamsHandler.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ParamsHandler.scala @@ -125,7 +125,7 @@ object ParamsHandler extends AskPatternConstants { system.log.info(s"All messages from rumor ${rumor.rumorId} were processed correctly") return Right(jsonRpcMessage) } - system.log.info(s"Some messages from rumor ${rumor.rumorId} were not processed") + system.log.warning(s"Some messages from rumor ${rumor.rumorId} were not processed. Unprocessed rumor not written in memory") Left(PipelineError(ErrorCodes.SERVER_ERROR.id, s"Some messages from Rumor ${rumor.rumorId} with jsonRpcId : ${jsonRpcMessage.id} couldn't be processed", jsonRpcMessage.id)) } diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ProcessMessagesHandler.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ProcessMessagesHandler.scala index 9899587525..3502c306f6 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ProcessMessagesHandler.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ProcessMessagesHandler.scala @@ -63,7 +63,7 @@ object ProcessMessagesHandler extends AskPatternConstants { processedRumors = processedRumors.prepended(rumor) } if !successful then - system.log.info(s"Failed to process all rumors from rumorStateAnswer $jsonId. Processed rumors where ${processedRumors.map(rumor => (rumor.senderPk, rumor.rumorId)).tail}") + system.log.info(s"Failed to process all rumors from rumorStateAnswer $jsonId. Processed rumors where ${processedRumors.map(rumor => (rumor.senderPk, rumor.rumorId)).tail}. Unprocessed rumors not written in memory.") Left(PipelineError( ErrorCodes.SERVER_ERROR.id, s"Rumor state handler was not able to process all rumors from $msg", From 5d4f32edfdf2665aa9be002b11a07c87857987ce Mon Sep 17 00:00:00 2001 From: Daniel Tavares Agostinho Date: Wed, 26 Jun 2024 16:07:30 +0200 Subject: [PATCH 3/8] scalafmt --- be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala index ca7702635c..07ba970197 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/Answerer.scala @@ -14,7 +14,6 @@ import spray.json.* object Answerer { private val CLIENT_BUFFER_SIZE: Int = 256 - private def errorResponseString(code: Int, reason: String, rpcId: Option[Int]): String = JsonRpcResponse( RpcValidator.JSON_RPC_VERSION, From e21128709c5bea9adf7d0f895f75e57ebfa145e5 Mon Sep 17 00:00:00 2001 From: Daniel Tavares Agostinho Date: Wed, 26 Jun 2024 18:44:39 +0200 Subject: [PATCH 4/8] corrected log --- .../scala/ch/epfl/pop/decentralized/ConnectionMediator.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/ConnectionMediator.scala b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/ConnectionMediator.scala index 241038d99b..2135341651 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/ConnectionMediator.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/ConnectionMediator.scala @@ -54,7 +54,10 @@ final case class ConnectionMediator( ) case ConnectionMediator.ServerLeft(serverRef) => - log.info(s"Server ${serverMap(serverRef).serverAddress} left") + log.info(s"Server ${serverMap.get(serverRef) match + case Some(greet) => greet.serverAddress + case None => serverRef.path.name + } left") serverMap -= serverRef // Tell monitor to stop scheduling heartbeats since there is no one to receive them if (serverMap.isEmpty) From a02010ae71728840005624c31c7ad2ff4d82ccc3 Mon Sep 17 00:00:00 2001 From: Daniel Tavares Agostinho Date: Thu, 27 Jun 2024 00:36:21 +0200 Subject: [PATCH 5/8] added log for result and sending state --- .../scala/ch/epfl/pop/decentralized/GossipManager.scala | 1 + .../scala/ch/epfl/pop/model/network/ResultObject.scala | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/GossipManager.scala b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/GossipManager.scala index 6f7fc71856..04a07e4b0a 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/decentralized/GossipManager.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/decentralized/GossipManager.scala @@ -165,6 +165,7 @@ final case class GossipManager(dbActorRef: AskableActorRef, stopProbability: Dou val rumorStateGet = dbActorRef ? GetRumorState() Await.result(rumorStateGet, duration) match case DbActorGetRumorStateAck(rumorState) => + log.info(s"Sending rumor_state ${rumorState.state} to ${greetServer.serverAddress}") serverRef ! ClientAnswer( Right(JsonRpcRequest( RpcValidator.JSON_RPC_VERSION, diff --git a/be2-scala/src/main/scala/ch/epfl/pop/model/network/ResultObject.scala b/be2-scala/src/main/scala/ch/epfl/pop/model/network/ResultObject.scala index cd1e466be4..e9ee0cd709 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/model/network/ResultObject.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/model/network/ResultObject.scala @@ -59,4 +59,13 @@ class ResultObject(val result: Option[ResultType]) { case _ => false case _ => false } + + override def toString: String = { + result.get match + case ResultInt(result) => result.toString + case ResultMessage(result) => result.toString() + case ResultMap(result) => result.toString() + case ResultRumor(result) => result.toString() + case ResultEmptyList() => List.empty.toString() + } } From 8a45c7acf6b04206305857252172c1ab0b27521e Mon Sep 17 00:00:00 2001 From: Daniel Tavares Agostinho Date: Thu, 27 Jun 2024 11:08:27 +0200 Subject: [PATCH 6/8] scalafmt --- .../scala/ch/epfl/pop/model/network/ResultObject.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/model/network/ResultObject.scala b/be2-scala/src/main/scala/ch/epfl/pop/model/network/ResultObject.scala index e9ee0cd709..0de5bcf598 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/model/network/ResultObject.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/model/network/ResultObject.scala @@ -62,10 +62,10 @@ class ResultObject(val result: Option[ResultType]) { override def toString: String = { result.get match - case ResultInt(result) => result.toString + case ResultInt(result) => result.toString case ResultMessage(result) => result.toString() - case ResultMap(result) => result.toString() - case ResultRumor(result) => result.toString() - case ResultEmptyList() => List.empty.toString() + case ResultMap(result) => result.toString() + case ResultRumor(result) => result.toString() + case ResultEmptyList() => List.empty.toString() } } From b0ec6ad16b6a227b5c401156a27a5d867b00a70d Mon Sep 17 00:00:00 2001 From: DanielTavaresA Date: Thu, 27 Jun 2024 09:08:47 +0000 Subject: [PATCH 7/8] auto-format action fixes --- docs/messageData.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/messageData.md b/docs/messageData.md index 47b11c274d..a1be6f5d58 100644 --- a/docs/messageData.md +++ b/docs/messageData.md @@ -3364,6 +3364,7 @@ This message is sent by both organizers to their servers to be broadcast. The me ```json5 // ../protocol/examples/messageData/federation_tokens_exchange/federation_tokens_exchange.json + { "object": "federation", "action": "tokens_exchange", @@ -3372,11 +3373,13 @@ This message is sent by both organizers to their servers to be broadcast. The me "tokens": ["M5ZychEi5rwm22FjwjNuljL1qMJWD2sE7oX9fcHNMDU="], "timestamp": 1712854874 } + ``` ```json5 // ../protocol/query/method/message/data/dataFederationTokensExchange.json + { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://raw.githubusercontent.com/dedis/popstellar/master/protocol/query/method/message/data/dataFederationTokensExchange.json", From a0f81e7897e7938004fe928476f7253a16a71667 Mon Sep 17 00:00:00 2001 From: Daniel Tavares Agostinho Date: Thu, 27 Jun 2024 12:25:00 +0200 Subject: [PATCH 8/8] improved logs --- .../main/scala/ch/epfl/pop/pubsub/ClientActor.scala | 12 +++++++----- .../scala/ch/epfl/pop/pubsub/graph/package.scala | 11 +++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/ClientActor.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/ClientActor.scala index fc737aa9b6..191f57dfb7 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/ClientActor.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/ClientActor.scala @@ -8,9 +8,9 @@ import ch.epfl.pop.decentralized.ConnectionMediator import ch.epfl.pop.model.network.{JsonRpcRequest, MethodType} import ch.epfl.pop.model.network.method.GreetServer import ch.epfl.pop.model.objects.Channel -import ch.epfl.pop.pubsub.ClientActor._ -import ch.epfl.pop.pubsub.PubSubMediator._ -import ch.epfl.pop.pubsub.graph.GraphMessage +import ch.epfl.pop.pubsub.ClientActor.* +import ch.epfl.pop.pubsub.PubSubMediator.* +import ch.epfl.pop.pubsub.graph.{GraphMessage, compactPrinter, prettyPrinter} import ch.epfl.pop.pubsub.graph.validators.RpcValidator import ch.epfl.pop.storage.DbActor @@ -83,7 +83,7 @@ final case class ClientActor(mediator: ActorRef, connectionMediatorRef: ActorRef connectionMediatorRef ! ConnectionMediator.NewServerConnected(self, greetServer) case clientAnswer @ ClientAnswer(_) => - log.info(s"Sending an answer back to client $wsHandle: $clientAnswer") + log.info(s"Sending an answer back to ${if isServer then "server" else "client"} ${wsHandle.get.path.name}: $clientAnswer") messageWsHandle(clientAnswer) case m @ _ => m match { @@ -135,7 +135,9 @@ object ClientActor { sealed trait ClientActorMessage // answer to be sent to the client represented by the client actor - final case class ClientAnswer(graphMessage: GraphMessage) extends ClientActorMessage + final case class ClientAnswer(graphMessage: GraphMessage) extends ClientActorMessage { + override def toString: String = compactPrinter(graphMessage) + } sealed trait Event diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/package.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/package.scala index 0f224fec53..a263017f83 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/package.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/package.scala @@ -17,4 +17,15 @@ package object graph { case Left(pipelineError) => pipelineError.toString } } + + def compactPrinter(graphMessage: GraphMessage): String = { + graphMessage match { + case Right(jsonRpcMessage: JsonRpcMessage) => + jsonRpcMessage match { + case jsonRpcRequest: JsonRpcRequest => HighLevelProtocol.jsonRpcRequestFormat.write(jsonRpcRequest).compactPrint + case jsonRpcResponse: JsonRpcResponse => HighLevelProtocol.jsonRpcResponseFormat.write(jsonRpcResponse).compactPrint + } + case Left(pipelineError) => pipelineError.toString + } + } }