Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the scalapb json marshaller for sealed-oneof messages #3342

Merged
merged 8 commits into from Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .appveyor.build.sh
@@ -1,8 +1,8 @@
#!/bin/bash
set -eo pipefail

JRE8_URL='https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u242-b08/OpenJDK8U-jre_x64_linux_hotspot_8u242b08.tar.gz'
JRE8_VERSION='AdoptOpenJDK-8u242b08'
JRE8_URL='https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u282-b08/OpenJDK8U-jre_x64_linux_hotspot_8u282b08.tar.gz'
JRE8_VERSION='AdoptOpenJDK-8u282b08'
JRE11_URL='https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.6%2B10/OpenJDK11U-jre_x64_linux_hotspot_11.0.6_10.tar.gz'
JRE11_VERSION='AdoptOpenJDK-11.0.6_10'
JDK14_URL='https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14%2B36/OpenJDK14U-jdk_x64_linux_hotspot_14_36.tar.gz'
Expand Down
18 changes: 16 additions & 2 deletions core/src/main/resources/com/linecorp/armeria/public_suffixes.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions scalapb/scalapb_2.12/build.gradle
Expand Up @@ -34,6 +34,18 @@ tasks.scaladoc.source "${scalapbProject}/src/main/scala"
compileScala.targetCompatibility = 1.8
ScalaCompileOptions.metaClass.useAnt = false

tasks.withType(Test) {
useJUnitPlatform {
// A workaround for 'java.lang.InternalError: Malformed class name'
// when testing scalapb module with Java 8. This bug was fixed in Java 9.
// - https://github.com/gradle/gradle/issues/8432
// - https://bugs.openjdk.java.net/browse/JDK-8057919
if (System.env.TEST_JAVA_VERSION == '8') {
exclude("**/*\$*\$*.class")
}
}
}

task aggregatedScaladocs(
type: ScalaDoc,
description: 'Generate scaladocs from all child projects',
Expand Down
12 changes: 12 additions & 0 deletions scalapb/scalapb_2.13/build.gradle
Expand Up @@ -25,6 +25,18 @@ tasks.withType(ScalaCompile) {
}
}

tasks.withType(Test) {
useJUnitPlatform {
// A workaround for 'java.lang.InternalError: Malformed class name'
// when testing scalapb module with Java 8. This bug was fixed in Java 9.
// - https://github.com/gradle/gradle/issues/8432
// - https://bugs.openjdk.java.net/browse/JDK-8057919
if (System.env.TEST_JAVA_VERSION == '8') {
exclude("**/*\$*\$*.class")
}
}
}

sourceSets {
test {
scala {
Expand Down
Expand Up @@ -28,7 +28,7 @@ import java.io.{InputStream, OutputStream}
import java.util.concurrent.ConcurrentMap
import scala.io.{Codec, Source}
import scalapb.json4s.{Parser, Printer}
import scalapb.{GeneratedMessage, GeneratedMessageCompanion}
import scalapb.{GeneratedMessage, GeneratedMessageCompanion, GeneratedSealedOneof}

/**
* A [[com.linecorp.armeria.common.grpc.GrpcJsonMarshaller]] that serializes and deserializes
Expand All @@ -39,13 +39,16 @@ final class ScalaPbJsonMarshaller private (
jsonParser: Parser = jsonDefaultParser
) extends GrpcJsonMarshaller {

override def serializeMessage[A](marshaller: Marshaller[A], message: A, os: OutputStream): Unit = {
if (!message.isInstanceOf[GeneratedMessage])
throw new IllegalStateException(
s"Unexpected message type: ${message.getClass} (expected: ${classOf[GeneratedMessage]})")
val msg = message.asInstanceOf[GeneratedMessage]
os.write(jsonPrinter.print(msg).getBytes())
}
override def serializeMessage[A](marshaller: Marshaller[A], message: A, os: OutputStream): Unit =
message match {
case msg: GeneratedSealedOneof =>
os.write(jsonPrinter.print(msg.asMessage).getBytes())
ikhoon marked this conversation as resolved.
Show resolved Hide resolved
case msg: GeneratedMessage =>
os.write(jsonPrinter.print(msg).getBytes())
case _ =>
throw new IllegalStateException(
s"Unexpected message type: ${message.getClass} (expected: ${classOf[GeneratedMessage]})")
}

override def deserializeMessage[A](marshaller: Marshaller[A], in: InputStream): A = {
val companion = getMessageCompanion(marshaller)
Expand Down
17 changes: 17 additions & 0 deletions scalapb/scalapb_2.13/src/test/proto/messages.proto
Expand Up @@ -27,3 +27,20 @@ message SimpleResponse {
string message = 1;
int32 status = 2;
}

// Copied from https://scalapb.github.io/docs/sealed-oneofs/
message Expr {
oneof sealed_value {
Literal lit = 1;
Add add = 2;
}
}

message Literal {
int32 value = 1;
}

message Add {
Expr left = 1;
Expr right = 2;
}
@@ -0,0 +1,43 @@
package com.linecorp.armeria.common.scalapb

import com.linecorp.armeria.scalapb.testing.messages.{Add, Literal}
import java.io.ByteArrayOutputStream
import net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import scalapb.GeneratedSealedOneof

class ScalaPbJsonMarshallerTest {

@Test
def serializeOneOf(): Unit = {
val marshaller = ScalaPbJsonMarshaller()
val os = new ByteArrayOutputStream()

val literal = Literal(10)
assertThat(literal).isInstanceOf(classOf[GeneratedSealedOneof])
marshaller.serializeMessage(null, literal, os)
assertThatJson(new String(os.toByteArray))
.isEqualTo("""
|{
| "lit": { "value": 10 }
|}""".stripMargin)

os.reset()
val add = Add(Literal(1), Literal(2))
assertThat(add).isInstanceOf(classOf[GeneratedSealedOneof])
marshaller.serializeMessage(null, add, os)
assertThatJson(new String(os.toByteArray))
.isEqualTo("""
|{
| "add": {
| "left": {
| "lit": { "value": 1 }
| },
| "right":{
| "lit":{ "value": 2 }
| }
| }
|}""".stripMargin)
}
}