Skip to content

Commit

Permalink
#39 Support PrimitiveTypeSerializer to handle multi-part form data
Browse files Browse the repository at this point in the history
  • Loading branch information
parthbond180 committed Jul 14, 2022
1 parent f04ee3f commit e30758d
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ class CordaptorAPITestSuite(
val req = client.POST("$baseUrl/node/reference/TestFileFlow")

val multiPartContentProvider = MultiPartContentProvider()
multiPartContentProvider.addFieldPart("testString", StringContentProvider("test"), null)
multiPartContentProvider.addFieldPart("testInt", StringContentProvider("2"), null)
multiPartContentProvider.addFilePart("file", "testData.csv",
PathContentProvider(Paths.get(CordaptorAPITestSuite::class.java.classLoader.getResource("testData.csv").toURI())), null)
multiPartContentProvider.close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,16 @@
"file": {
"type": "string",
"format": "binary"
},
"testInt": {
"type": "number",
"format": "int32"
},
"testString": {
"type": "string"
}
},
"required": ["file"]
"required": ["file", "testInt", "testString"]
},
"CordaFlowProgress": {
"type": "object",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ data class TestFileFlowResult(
@StartableByService
@Suppress("UNUSED")
class TestFileFlow(
private val file: ByteArray
private val file: ByteArray,
private val testInt: Int,
private val testString: String
) : FlowLogic<TestFileFlowResult>() {

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ class BigDecimalSerializer
override fun toJson(obj: BigDecimal, generator: JsonGenerator) {
generator.write(obj)
}

override fun fromMultiPartFormValue(formValue: FormData.FormValue): BigDecimal {
return when(formValue.value.isNotEmpty()) {
true -> formValue.value.toBigDecimal()
false -> BigDecimal(0)
}
}
}

class CordaNodeAttachmentSerializer : MultiPartFormDataSerializer<CordaNodeAttachment> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ class SerializationFactory(
val map = ConcurrentHashMap<SerializerKey, JsonSerializer<Any>>()

map[SerializerKey(String::class.java)] = StringSerializer as JsonSerializer<Any>
map[SerializerKey(ByteArray::class.java)] = ByteArraySerializer as JsonSerializer<Any>
map[SerializerKey(Int::class.java)] = IntSerializer as JsonSerializer<Any>
map[SerializerKey(Long::class.java)] = LongSerializer as JsonSerializer<Any>
map[SerializerKey(Double::class.java)] = DoubleSerializer as JsonSerializer<Any>
Expand Down Expand Up @@ -137,6 +136,8 @@ class SerializationFactory(

override val valueType = SerializerKey.fromSuperclassTypeArgument(PrimitiveTypeSerializer::class, this::class)
override fun generateSchema(generator: JsonSchemaGenerator) = schema

abstract fun fromMultiPartFormValue(formValue: FormData.FormValue) : T
}

/** Built-in serializer for atomic value of type [String] */
Expand All @@ -156,25 +157,13 @@ class SerializationFactory(
override fun toJson(obj: String, generator: JsonGenerator) {
generator.write(obj)
}
}

/** Built-in serializer for atomic value of type [ByteArray] */
object ByteArraySerializer : PrimitiveTypeSerializer<ByteArray>("string") {
override fun fromJson(value: JsonValue): ByteArray {
return when (value.valueType) {
// provide limited number of type conversions
JsonValue.ValueType.TRUE -> true.toString().base64ToByteArray()
JsonValue.ValueType.FALSE -> false.toString().base64ToByteArray()
JsonValue.ValueType.NULL -> "".base64ToByteArray()
JsonValue.ValueType.NUMBER -> value.toString().base64ToByteArray()
JsonValue.ValueType.STRING -> (value as JsonString).string.base64ToByteArray()
else -> throw AssertionError("Expected string, got ${value.valueType} with value $value")
override fun fromMultiPartFormValue(formValue: FormData.FormValue): String {
return when(formValue.value.isNotEmpty()) {
true -> formValue.value
false -> ""
}
}

override fun toJson(obj: ByteArray, generator: JsonGenerator) {
generator.write(String(obj))
}
}

/** Built-in serializer for atomic value of type [Int] */
Expand All @@ -191,6 +180,13 @@ class SerializationFactory(
override fun toJson(obj: Int, generator: JsonGenerator) {
generator.write(obj)
}

override fun fromMultiPartFormValue(formValue: FormData.FormValue): Int {
return when(formValue.value.isNotEmpty()) {
true -> Integer.parseInt(formValue.value)
false -> 0
}
}
}

/** Built-in serializer for atomic value of type [Long] */
Expand All @@ -207,6 +203,13 @@ class SerializationFactory(
override fun toJson(obj: Long, generator: JsonGenerator) {
generator.write(obj)
}

override fun fromMultiPartFormValue(formValue: FormData.FormValue): Long {
return when(formValue.value.isNotEmpty()) {
true -> formValue.value.toLong()
false -> 0
}
}
}

/** Built-in serializer for atomic value of type [Double] */
Expand All @@ -223,6 +226,13 @@ class SerializationFactory(
override fun toJson(obj: Double, generator: JsonGenerator) {
generator.write(obj)
}

override fun fromMultiPartFormValue(formValue: FormData.FormValue): Double {
return when(formValue.value.isNotEmpty()) {
true -> formValue.value.toDouble()
false -> 0.0
}
}
}

/** Built-in serializer for atomic value of type [Float] */
Expand All @@ -239,6 +249,13 @@ class SerializationFactory(
override fun toJson(obj: Float, generator: JsonGenerator) {
generator.write(obj.toDouble())
}

override fun fromMultiPartFormValue(formValue: FormData.FormValue): Float {
return when(formValue.value.isNotEmpty()) {
true -> formValue.value.toFloat()
false -> 0.0.toFloat()
}
}
}

/** Built-in serializer for atomic value of type [Boolean] */
Expand All @@ -255,6 +272,13 @@ class SerializationFactory(
override fun toJson(obj: Boolean, generator: JsonGenerator) {
generator.write(obj)
}

override fun fromMultiPartFormValue(formValue: FormData.FormValue): Boolean {
return when (formValue.value.isNotEmpty()) {
true -> formValue.value.toBoolean()
else -> throw AssertionError("Expected , boolean got ${formValue.value}")
}
}
}

/** Serializer for Kotlin type [Unit] */
Expand All @@ -269,6 +293,13 @@ class SerializationFactory(
override fun toJson(obj: Unit, generator: JsonGenerator) {
generator.write(obj.toString())
}

override fun fromMultiPartFormValue(formValue: FormData.FormValue) {
return when (formValue.value.isNullOrEmpty()) {
true -> Unit
else -> throw AssertionError("Expected unit, got ${formValue.value}")
}
}
}

// FIXME use url format for the schema
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ abstract class StructuredObjectSerializer<T: Any>(
is MultiPartFormValueSerializer -> {
prop.serializer.fromMultiPartFormValue(it.first)
}
is SerializationFactory.PrimitiveTypeSerializer -> {
prop.serializer.fromMultiPartFormValue(it.first)
}
is MultiPartFormTransformValueSerializer<*,*> -> {
prop.serializer.transformValue(it.first)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,10 @@ class CordaTypesTest : KoinTest {
fun `test multi part form data corda flow instruction serialization`() {
val serializer = getKoin().getSerializer(CordaFlowInstruction::class, TestFileFlow::class) as MultiPartFormDataSerializer
val testPath = Paths.get(CordaTypesTest::class.java.classLoader.getResource("testData.csv").toURI())
val formData = FormData(1)
val formData = FormData(3)
formData.add("file", testPath, "testData.csv", null)

formData.add("testString", "test")
formData.add("testInt", "2")
println("Serializer Schema: " + serializer.generateRecursiveSchema(getKoin().get()))

assertTrue { testPath.toFile().readBytes().contentEquals(
Expand Down Expand Up @@ -412,6 +413,8 @@ data class TestNonComposableFlow(

data class TestFileFlow(
val file: ByteArray,
val testInt: Int,
val testString: String,
override val progressTracker: ProgressTracker
) : FlowLogic<ByteArray>() {

Expand Down

0 comments on commit e30758d

Please sign in to comment.