1
0
mirror of https://github.com/ACINQ/eclair.git synced 2024-11-20 02:27:32 +01:00

Use nicer custom type hints when serializing to json (websocket)

This commit is contained in:
Andrea 2019-03-28 17:54:56 +01:00
parent 9a7e2158be
commit 52b17fe75f
No known key found for this signature in database
GPG Key ID: FFB3470FFF04CA76
4 changed files with 30 additions and 16 deletions

View File

@ -34,7 +34,7 @@ import fr.acinq.eclair.transactions.Transactions.{InputInfo, TransactionWithInpu
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{ShortChannelId, UInt64}
import org.json4s.JsonAST._
import org.json4s.{CustomKeySerializer, CustomSerializer, jackson}
import org.json4s.{CustomKeySerializer, CustomSerializer, TypeHints, jackson}
import scodec.bits.ByteVector
/**
@ -186,4 +186,15 @@ object JsonSupport extends Json4sSupport {
implicit val shouldWritePretty: ShouldWritePretty = ShouldWritePretty.True
case class CustomTypeHints(custom: Map[Class[_], String]) extends TypeHints {
val reverse: Map[String, Class[_]] = custom.map(_.swap)
override val hints: List[Class[_]] = custom.keys.toList
override def hintFor(clazz: Class[_]): String = custom.getOrElse(clazz, {
throw new IllegalArgumentException(s"No type hint mapping found for $clazz")
})
override def classFor(hint: String): Option[Class[_]] = reverse.get(hint)
}
}

View File

@ -31,13 +31,15 @@ import akka.http.scaladsl.model.ws.{Message, TextMessage}
import akka.http.scaladsl.server.directives.{Credentials, LoggingMagnet}
import akka.stream.{ActorMaterializer, OverflowStrategy}
import akka.stream.scaladsl.{BroadcastHub, Flow, Keep, Source}
import fr.acinq.eclair.api.JsonSupport.CustomTypeHints
import fr.acinq.eclair.io.NodeURI
import fr.acinq.eclair.payment.PaymentLifecycle.PaymentFailed
import fr.acinq.eclair.payment._
import grizzled.slf4j.Logging
import org.json4s.ShortTypeHints
import org.json4s.{ShortTypeHints, TypeHints}
import org.json4s.jackson.Serialization
import scodec.bits.ByteVector
import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration._
@ -51,13 +53,13 @@ trait Service extends Directives with Logging {
import JsonSupport.serialization
// used to send typed messages over the websocket
val formatsWithTypeHint = formats.withTypeHintFieldName("type") +
ShortTypeHints(List(
classOf[PaymentSent],
classOf[PaymentRelayed],
classOf[PaymentReceived],
classOf[PaymentSettlingOnChain],
classOf[PaymentFailed]))
CustomTypeHints(Map(
classOf[PaymentSent] -> "payment-sent",
classOf[PaymentRelayed] -> "payment-relayed",
classOf[PaymentReceived] -> "payment-received",
classOf[PaymentSettlingOnChain] -> "payment-settling-onchain",
classOf[PaymentFailed] -> "payment-failed"
))
def password: String

View File

@ -270,31 +270,31 @@ class ApiServiceSpec extends FunSuite with ScalatestRouteTest {
check {
val pf = PaymentFailed(ByteVector32.Zeroes, failures = Seq.empty)
val expectedSerializedPf = """{"type":"PaymentLifecycle$PaymentFailed","paymentHash":"0000000000000000000000000000000000000000000000000000000000000000","failures":[]}"""
val expectedSerializedPf = """{"type":"payment-failed","paymentHash":"0000000000000000000000000000000000000000000000000000000000000000","failures":[]}"""
Serialization.write(pf)(mockService.formatsWithTypeHint) === expectedSerializedPf
system.eventStream.publish(pf)
wsClient.expectMessage(expectedSerializedPf)
val ps = PaymentSent(amount = MilliSatoshi(21), feesPaid = MilliSatoshi(1), paymentHash = ByteVector32.Zeroes, paymentPreimage = ByteVector32.One, toChannelId = ByteVector32.Zeroes, timestamp = 1553784337711L)
val expectedSerializedPs = """{"type":"PaymentSent","amount":21,"feesPaid":1,"paymentHash":"0000000000000000000000000000000000000000000000000000000000000000","paymentPreimage":"0100000000000000000000000000000000000000000000000000000000000000","toChannelId":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":1553784337711}"""
val expectedSerializedPs = """{"type":"payment-sent","amount":21,"feesPaid":1,"paymentHash":"0000000000000000000000000000000000000000000000000000000000000000","paymentPreimage":"0100000000000000000000000000000000000000000000000000000000000000","toChannelId":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":1553784337711}"""
Serialization.write(ps)(mockService.formatsWithTypeHint) === expectedSerializedPs
system.eventStream.publish(ps)
wsClient.expectMessage(expectedSerializedPs)
val prel = PaymentRelayed(amountIn = MilliSatoshi(21), amountOut = MilliSatoshi(20), paymentHash = ByteVector32.Zeroes, fromChannelId = ByteVector32.Zeroes, ByteVector32.One, timestamp = 1553784963659L)
val expectedSerializedPrel = """{"type":"PaymentRelayed","amountIn":21,"amountOut":20,"paymentHash":"0000000000000000000000000000000000000000000000000000000000000000","fromChannelId":"0000000000000000000000000000000000000000000000000000000000000000","toChannelId":"0100000000000000000000000000000000000000000000000000000000000000","timestamp":1553784963659}"""
val expectedSerializedPrel = """{"type":"payment-relayed","amountIn":21,"amountOut":20,"paymentHash":"0000000000000000000000000000000000000000000000000000000000000000","fromChannelId":"0000000000000000000000000000000000000000000000000000000000000000","toChannelId":"0100000000000000000000000000000000000000000000000000000000000000","timestamp":1553784963659}"""
Serialization.write(prel)(mockService.formatsWithTypeHint) === expectedSerializedPrel
system.eventStream.publish(prel)
wsClient.expectMessage(expectedSerializedPrel)
val precv = PaymentReceived(amount = MilliSatoshi(21), paymentHash = ByteVector32.Zeroes, fromChannelId = ByteVector32.One, timestamp = 1553784963659L)
val expectedSerializedPrecv = """{"type":"PaymentReceived","amount":21,"paymentHash":"0000000000000000000000000000000000000000000000000000000000000000","fromChannelId":"0100000000000000000000000000000000000000000000000000000000000000","timestamp":1553784963659}"""
val expectedSerializedPrecv = """{"type":"payment-received","amount":21,"paymentHash":"0000000000000000000000000000000000000000000000000000000000000000","fromChannelId":"0100000000000000000000000000000000000000000000000000000000000000","timestamp":1553784963659}"""
Serialization.write(precv)(mockService.formatsWithTypeHint) === expectedSerializedPrecv
system.eventStream.publish(precv)
wsClient.expectMessage(expectedSerializedPrecv)
val pset = PaymentSettlingOnChain(amount = MilliSatoshi(21), paymentHash = ByteVector32.One, timestamp = 1553785442676L)
val expectedSerializedPset = """{"type":"PaymentSettlingOnChain","amount":21,"paymentHash":"0100000000000000000000000000000000000000000000000000000000000000","timestamp":1553785442676}"""
val expectedSerializedPset = """{"type":"payment-settling-onchain","amount":21,"paymentHash":"0100000000000000000000000000000000000000000000000000000000000000","timestamp":1553785442676}"""
Serialization.write(pset)(mockService.formatsWithTypeHint) === expectedSerializedPset
system.eventStream.publish(pset)
wsClient.expectMessage(expectedSerializedPset)

View File

@ -22,6 +22,7 @@ import fr.acinq.bitcoin.{MilliSatoshi, OutPoint}
import fr.acinq.eclair._
import fr.acinq.eclair.payment.{PaymentRequest, PaymentSettlingOnChain}
import fr.acinq.bitcoin.{ByteVector32, OutPoint}
import fr.acinq.eclair.api.JsonSupport.CustomTypeHints
import fr.acinq.eclair.payment.PaymentRequest
import fr.acinq.eclair.transactions.{IN, OUT}
import fr.acinq.eclair.wire.{NodeAddress, Tor2, Tor3}
@ -77,8 +78,8 @@ class JsonSerializersSpec extends FunSuite with Matchers {
}
test("type hints") {
implicit val formats = DefaultFormats.withTypeHintFieldName("type") + ShortTypeHints(List(classOf[PaymentSettlingOnChain])) + new MilliSatoshiSerializer
implicit val formats = DefaultFormats.withTypeHintFieldName("type") + CustomTypeHints(Map(classOf[PaymentSettlingOnChain] -> "payment-settling-onchain")) + new MilliSatoshiSerializer
val e1 = PaymentSettlingOnChain(MilliSatoshi(42), randomBytes32)
assert(Serialization.writePretty(e1).contains("\"type\" : \"PaymentSettlingOnChain\""))
assert(Serialization.writePretty(e1).contains("\"type\" : \"payment-settling-onchain\""))
}
}