org.apache.avro.util.Utf8 Scala Examples

The following examples show how to use org.apache.avro.util.Utf8. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: TupleEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import com.sksamuel.avro4s.{AvroSchema, Encoder}
import org.apache.avro.generic.GenericRecord
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

class TupleEncoderTest extends AnyFunSuite with Matchers {

  test("encode tuple2") {
    case class Test(z: (String, Option[Int]))
    val schema = AvroSchema[Test]
    val record = Encoder[Test].encode(Test("hello", Some(55))).asInstanceOf[GenericRecord]
    val z = record.get("z").asInstanceOf[GenericRecord]
    z.get("_1") shouldBe new Utf8("hello")
    z.get("_2") shouldBe 55
  }

  test("encode tuple3") {
    case class Test(z: (String, Option[Int], Long))
    val schema = AvroSchema[Test]
    val record = Encoder[Test].encode(Test("hello", Some(55), 9999999L)).asInstanceOf[GenericRecord]
    val z = record.get("z").asInstanceOf[GenericRecord]
    z.get("_1") shouldBe new Utf8("hello")
    z.get("_2") shouldBe 55
    z.get("_3") shouldBe 9999999L
  }

  test("encode tuple4") {
    case class Test(z: (String, Option[Int], Boolean, Double))
    val schema = AvroSchema[Test]
    val record = Encoder[Test].encode(Test("hello", Some(55), true, 0.24)).asInstanceOf[GenericRecord]
    val z = record.get("z").asInstanceOf[GenericRecord]
    z.get("_1") shouldBe new Utf8("hello")
    z.get("_2") shouldBe 55
    z.get("_3") shouldBe true
    z.get("_4") shouldBe 0.24
  }

  test("encode tuple5") {
    case class Test(z: (String, Option[Int], String, Boolean, String))
    val schema = AvroSchema[Test]
    val record = Encoder[Test].encode(Test("a", Some(55), "b", true, "c")).asInstanceOf[GenericRecord]
    val z = record.get("z").asInstanceOf[GenericRecord]
    z.get("_1") shouldBe new Utf8("a")
    z.get("_2") shouldBe 55
    z.get("_3") shouldBe new Utf8("b")
    z.get("_4") shouldBe true
    z.get("_5") shouldBe new Utf8("c")
  }
} 
Example 2
Source File: AvroMessageConverterTest.scala    From stream-reactor   with Apache License 2.0 5 votes vote down vote up
package com.datamountaineer.streamreactor.connect.sink.converters

import java.nio.ByteBuffer
import java.util.UUID

import com.datamountaineer.streamreactor.connect.jms.config.{JMSConfig, JMSSettings}
import com.datamountaineer.streamreactor.connect.jms.sink.converters.AvroMessageConverter
import com.datamountaineer.streamreactor.connect.sink.AvroDeserializer
import com.datamountaineer.streamreactor.connect.{TestBase, Using}
import io.confluent.connect.avro.AvroData
import javax.jms.BytesMessage
import org.apache.activemq.ActiveMQConnectionFactory
import org.apache.avro.generic.GenericData
import org.apache.avro.util.Utf8
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

import scala.collection.JavaConverters._
import scala.reflect.io.Path

class AvroMessageConverterTest extends AnyWordSpec with Matchers with Using with TestBase with BeforeAndAfterAll {
  val converter = new AvroMessageConverter()
  private lazy val avroData = new AvroData(128)
  val kafkaTopic1 = s"kafka-${UUID.randomUUID().toString}"
  val topicName = UUID.randomUUID().toString
  val queueName = UUID.randomUUID().toString

  val kcqlT = getKCQL(topicName, kafkaTopic1, "TOPIC")
  val kcqlQ = getKCQL(queueName, kafkaTopic1, "QUEUE")

  val props = getProps(s"$kcqlQ;$kcqlT", JMS_URL)
  val config = JMSConfig(props.asJava)
  val settings = JMSSettings(config, true)
  val setting = settings.settings.head

  override def afterAll(): Unit = {
    Path(AVRO_FILE).delete()
  }

  "AvroMessageConverter" should {
    "create a BytesMessage with avro payload" in {
      val connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false")

      using(connectionFactory.createConnection()) { connection =>
        using(connection.createSession(false, 1)) { session =>

          val record = getSinkRecords(kafkaTopic1).head
          val msg = converter.convert(record, session, setting)._2.asInstanceOf[BytesMessage]

          Option(msg).isDefined shouldBe true

          msg.reset()

          val size = msg.getBodyLength

          size > 0 shouldBe true
          val data = new Array[Byte](size.toInt)
          msg.readBytes(data)

          val avroRecord = AvroDeserializer(data, avroData.fromConnectSchema(record.valueSchema()))
          avroRecord.get("int8") shouldBe 12.toByte
          avroRecord.get("int16") shouldBe 12.toShort
          avroRecord.get("int32") shouldBe 12
          avroRecord.get("int64") shouldBe 12L
          avroRecord.get("float32") shouldBe 12.2f
          avroRecord.get("float64") shouldBe 12.2
          avroRecord.get("boolean") shouldBe true
          avroRecord.get("string").toString shouldBe "foo"
          avroRecord.get("bytes").asInstanceOf[ByteBuffer].array() shouldBe "foo".getBytes()
          val array = avroRecord.get("array").asInstanceOf[GenericData.Array[Utf8]]
          val iter = array.iterator()
          new Iterator[String] {
            override def hasNext: Boolean = iter.hasNext

            override def next(): String = iter.next().toString
          }.toSeq shouldBe Seq("a", "b", "c")
          val map = avroRecord.get("map").asInstanceOf[java.util.Map[Utf8, Int]].asScala
          map.size shouldBe 1
          map.keys.head.toString shouldBe "field"
          map.get(map.keys.head) shouldBe Some(1)

          val iterRecord = avroRecord.get("mapNonStringKeys").asInstanceOf[GenericData.Array[GenericData.Record]].iterator()
          iterRecord.hasNext shouldBe true
          val r = iterRecord.next()
          r.get("key") shouldBe 1
          r.get("value") shouldBe 1
        }
      }
    }
  }
} 
Example 3
Source File: SchemaForUtf8Test.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.schema

import com.sksamuel.avro4s.{AvroSchema, Encoder, FromRecord, ImmutableRecord, ToRecord}
import org.apache.avro.util.Utf8
import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers

class SchemaForUtf8Test extends AnyFunSpec with Matchers {

  describe("Serialization of objects containing Utf8 fields") {
    it("should serialize objects that contains simple Utf8 attributes") {
      case class Person(name: Utf8, alias: Utf8, age: Int)

      ToRecord[Person].to(Person(new Utf8("Name"), new Utf8("Alias"), 30))
    }

    it("should serialize objects that contains simple Utf8 attributes and one attribute has a default value") {
      case class Person(name: Utf8, alias: Utf8 = new Utf8("Not specified"), age: Int)

      ToRecord[Person].to(Person(name = new Utf8("Name"), age = 30))
    }

    it("should serialize objects that contains Optional Utf8 attributes") {
      case class Person(name: Utf8, alias: Option[Utf8], age: Int)

      ToRecord[Person].to(Person(new Utf8("Name"), Some(new Utf8("Alias")), 30))
      ToRecord[Person].to(Person(new Utf8("Name"), None, 30))
    }

    it("should serialize objects that contains Optional Utf8 attributes and one attribute has a default value") {
      case class Person(name: Utf8, alias: Option[Utf8] = Some(new Utf8("Not specified")), age: Int)

      ToRecord[Person].to(Person(new Utf8("Name"), Some(new Utf8("Alias")), 30))
      ToRecord[Person].to(Person(new Utf8("Name"), None, 30))
    }
  }

  describe("Deserialization of objects containing Utf8 fields") {
    it("should deserialize objects that contains simple Utf8 attributes") {
      case class Person(name: Utf8, alias: Utf8, age: Int)

      val record = ImmutableRecord(AvroSchema[Person], Vector(new Utf8("Name"), new Utf8("Alias"), 30.asInstanceOf[AnyRef]))
      FromRecord[Person].from(record)
    }

    it("should deserialize objects that contains Optional Utf8 attributes") {
      case class Person(name: Utf8, familyName: Option[Utf8], alias: Option[Utf8], age: Int)

      val record = ImmutableRecord(AvroSchema[Person], Vector(new Utf8("Name"), None, Some(new Utf8("Alias")), 30.asInstanceOf[AnyRef]))
      FromRecord[Person].from(record)
    }
  }

} 
Example 4
Source File: BasicDecoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.decoder

import com.sksamuel.avro4s.examples.UppercasePkg.ClassInUppercasePackage
import com.sksamuel.avro4s.{AvroSchema, Decoder, DefaultFieldMapper, FieldMapper}
import org.apache.avro.generic.GenericData
import org.apache.avro.util.Utf8
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

case class FooString(str: String)
case class FooDouble(d: Double)
case class FooBoolean(b: Boolean)
case class FooFloat(f: Float)
case class FooLong(l: Long)
case class FooInt(i: Int)

class BasicDecoderTest extends AnyWordSpec with Matchers {

  "Decoder" should {
    "decode strings" in {
      val schema = AvroSchema[FooString]
      val record = new GenericData.Record(schema)
      record.put("str", "hello")
      Decoder[FooString].decode(record) shouldBe FooString("hello")
    }
    "decode longs" in {
      val schema = AvroSchema[FooLong]
      val record = new GenericData.Record(schema)
      record.put("l", 123456L)
      Decoder[FooLong].decode(record) shouldBe FooLong(123456L)
    }
    "decode doubles" in {
      val schema = AvroSchema[FooDouble]
      val record = new GenericData.Record(schema)
      record.put("d", 123.435D)
      Decoder[FooDouble].decode(record) shouldBe FooDouble(123.435D)
    }
    "decode booleans" in {
      val schema = AvroSchema[FooBoolean]
      val record = new GenericData.Record(schema)
      record.put("b", true)
      Decoder[FooBoolean].decode(record) shouldBe FooBoolean(true)
    }
    "decode floats" in {
      val schema = AvroSchema[FooFloat]
      val record = new GenericData.Record(schema)
      record.put("f", 123.435F)
      Decoder[FooFloat].decode(record) shouldBe FooFloat(123.435F)
    }
    "decode ints" in {
      val schema = AvroSchema[FooInt]
      val record = new GenericData.Record(schema)
      record.put("i", 123)
      Decoder[FooInt].decode(record) shouldBe FooInt(123)
    }
    "support uppercase packages" in {

      val schema = AvroSchema[ClassInUppercasePackage]
      val decoder = Decoder[ClassInUppercasePackage]

      val record = new GenericData.Record(schema)
      record.put("s", new Utf8("hello"))

      decoder.decode(record) shouldBe com.sksamuel.avro4s.examples.UppercasePkg.ClassInUppercasePackage("hello")
    }
  }
} 
Example 5
Source File: UUIDDecoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.decoder

import java.util.UUID

import com.sksamuel.avro4s.{AvroSchema, Decoder}
import org.apache.avro.generic.GenericData
import org.apache.avro.util.Utf8
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class UUIDDecoderTest extends AnyWordSpec with Matchers {

  import scala.collection.JavaConverters._

  "Decoder" should {
    "decode uuids" in {
      val uuid = UUID.randomUUID()
      val schema = AvroSchema[UUIDTest]
      val record = new GenericData.Record(schema)
      record.put("uuid", uuid.toString)
      Decoder[UUIDTest].decode(record) shouldBe UUIDTest(uuid)
    }
    "decode UUIDSs encoded as Utf8" in {
      val uuid = UUID.randomUUID()
      val schema = AvroSchema[UUIDTest]
      val record = new GenericData.Record(schema)
      record.put("uuid", new Utf8(uuid.toString))
      Decoder[UUIDTest].decode(record) shouldBe UUIDTest(uuid)
    }
    "decode seq of uuids" in {
      val schema = AvroSchema[UUIDSeq]

      val uuid1 = UUID.randomUUID()
      val uuid2 = UUID.randomUUID()

      val record = new GenericData.Record(schema)
      record.put("uuids", List(uuid1.toString, uuid2.toString).asJava)

      Decoder[UUIDSeq].decode(record) shouldBe UUIDSeq(List(uuid1, uuid2))
    }
    "decode Option[UUID]" in {
      val schema = AvroSchema[UUIDOption]

      val uuid = UUID.randomUUID()
      val record1 = new GenericData.Record(schema)
      record1.put("uuid", uuid.toString)

      Decoder[UUIDOption].decode(record1) shouldBe UUIDOption(Some(uuid))

      val record2 = new GenericData.Record(schema)
      record2.put("uuid", null)

      Decoder[UUIDOption].decode(record2) shouldBe UUIDOption(None)
    }
  }
}

case class UUIDTest(uuid: UUID)
case class UUIDSeq(uuids: Seq[UUID])
case class UUIDOption(uuid: Option[UUID]) 
Example 6
Source File: SchemaEvolutionTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.decoder

import java.io.{ByteArrayInputStream, ByteArrayOutputStream}

import com.sksamuel.avro4s._
import org.apache.avro.SchemaBuilder
import org.apache.avro.generic.GenericData
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

class SchemaEvolutionTest extends AnyFunSuite with Matchers {

  case class Version1(original: String)
  case class Version2(@AvroAlias("original") renamed: String)

  case class P1(name: String, age: Int = 18)
  case class P2(name: String)

  case class OptionalStringTest(a: String, b: Option[String])
  case class DefaultStringTest(a: String, b: String = "foo")

  ignore("@AvroAlias should be used when a reader schema has a field missing from the write schema") {

    val v1schema = AvroSchema[Version1]
    val v1 = Version1("hello")
    val baos = new ByteArrayOutputStream()
    val output = AvroOutputStream.data[Version1].to(baos).build()
    output.write(v1)
    output.close()

    // we load using a v2 schema
    val is = new AvroDataInputStream[Version2](new ByteArrayInputStream(baos.toByteArray), Some(v1schema))
    val v2 = is.iterator.toList.head

    v2.renamed shouldBe v1.original
  }

  test("when decoding, if the record and schema are missing a field and the target has a scala default, use that") {

    val f1 = RecordFormat[P1]
    val f2 = RecordFormat[P2]

    f1.from(f2.to(P2("foo"))) shouldBe P1("foo")
  }

  test("when decoding, if the record is missing a field that is present in the schema with a default, use the default from the schema") {
    val schema = SchemaBuilder.record("foo").fields().requiredString("a").endRecord()
    val record = new GenericData.Record(schema)
    record.put("a", new Utf8("hello"))
    Decoder[DefaultStringTest].decode(record) shouldBe DefaultStringTest("hello")
  }

  test("when decoding, if the record is missing a field that is present in the schema and the type is option, then set to None") {
    val schema1 = SchemaBuilder.record("foo").fields().requiredString("a").endRecord()
    val schema2 = SchemaBuilder.record("foo").fields().requiredString("a").optionalString("b").endRecord()
    val record = new GenericData.Record(schema1)
    record.put("a", new Utf8("hello"))
    Decoder[OptionalStringTest].decode(record) shouldBe OptionalStringTest("hello", None)
  }
} 
Example 7
Source File: ValueTypeDecoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.decoder

import com.sksamuel.avro4s.{AvroSchema, Decoder}
import org.apache.avro.generic.GenericData
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

class ValueTypeDecoderTest extends AnyFunSuite with Matchers {

  case class Test(foo: FooValueType)
  case class OptionTest(foo: Option[FooValueType])

  test("top level value types") {
    val actual = Decoder[FooValueType].decode("hello")
    actual shouldBe FooValueType("hello")
  }

  test("support fields that are value types") {
    val schema = AvroSchema[Test]

    val record1 = new GenericData.Record(schema)
    record1.put("foo", new Utf8("hello"))

    Decoder[Test].decode(record1) shouldBe Test(FooValueType("hello"))
  }

  test("support value types inside Options") {
    val schema = AvroSchema[OptionTest]

    val record1 = new GenericData.Record(schema)
    record1.put("foo", new Utf8("hello"))

    Decoder[OptionTest].decode(record1) shouldBe OptionTest(Some(FooValueType("hello")))
  }
}

case class FooValueType(s: String) extends AnyVal 
Example 8
Source File: EitherDecoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.decoder

import com.sksamuel.avro4s._
import org.apache.avro.SchemaBuilder
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

case class Test(either: Either[String, Double])
case class Goo(s: String)
case class Foo(b: Boolean)
case class Test2(either: Either[Goo, Foo])

class EitherDecoderTest extends AnyFunSuite with Matchers {

  case class Voo(s: String)
  case class Woo(b: Boolean)
  case class Test3(either: Either[Voo, Woo])

  @AvroName("w")
  case class Wobble(s: String)

  @AvroName("t")
  case class Topple(b: Boolean)

  case class Test4(either: Either[Wobble, Topple])

  @AvroNamespace("market")
  case class Apple(s: String)

  @AvroNamespace("market")
  case class Orange(b: Boolean)

  case class Test5(either: Either[Apple, Orange])

  test("decode union:T,U for Either[T,U] of primitives") {
    val schema = AvroSchema[Test]
    Decoder[Test].decode(ImmutableRecord(schema, Vector(new Utf8("foo")))) shouldBe Test(Left("foo"))
    Decoder[Test].decode(ImmutableRecord(schema, Vector(java.lang.Double.valueOf(234.4D)))) shouldBe Test(Right(234.4D))
  }

  test("decode union:T,U for Either[T,U] of top level classes") {
    val schema = AvroSchema[Test2]
    Decoder[Test2].decode(ImmutableRecord(schema, Vector(ImmutableRecord(AvroSchema[Goo], Vector(new Utf8("zzz")))))) shouldBe Test2(Left(Goo("zzz")))
    Decoder[Test2].decode(ImmutableRecord(schema, Vector(ImmutableRecord(AvroSchema[Foo], Vector(java.lang.Boolean.valueOf(true)))))) shouldBe Test2(Right(Foo(true)))
  }

  test("decode union:T,U for Either[T,U] of nested classes") {
    val schema = AvroSchema[Test3]
    Decoder[Test3].decode(ImmutableRecord(schema, Vector(ImmutableRecord(AvroSchema[Voo], Vector(new Utf8("zzz")))))) shouldBe Test3(Left(Voo("zzz")))
    Decoder[Test3].decode(ImmutableRecord(schema, Vector(ImmutableRecord(AvroSchema[Woo], Vector(java.lang.Boolean.valueOf(true)))))) shouldBe Test3(Right(Woo(true)))
  }

  test("use @AvroName defined on a class when choosing which Either to decode") {

    val wschema = SchemaBuilder.record("w").namespace("com.sksamuel.avro4s.record.decoder.EitherDecoderTest").fields().requiredBoolean("s").endRecord()
    val tschema = SchemaBuilder.record("t").namespace("com.sksamuel.avro4s.record.decoder.EitherDecoderTest").fields().requiredString("b").endRecord()
    val union = SchemaBuilder.unionOf().`type`(wschema).and().`type`(tschema).endUnion()
    val schema = SchemaBuilder.record("Test4").fields().name("either").`type`(union).noDefault().endRecord()

    Decoder[Test4].decode(ImmutableRecord(schema, Vector(ImmutableRecord(tschema, Vector(java.lang.Boolean.valueOf(true)))))) shouldBe Test4(Right(Topple(true)))
    Decoder[Test4].decode(ImmutableRecord(schema, Vector(ImmutableRecord(wschema, Vector(new Utf8("zzz")))))) shouldBe Test4(Left(Wobble("zzz")))
  }

  test("use @AvroNamespace when choosing which Either to decode") {

    val appleschema = SchemaBuilder.record("Apple").namespace("market").fields().requiredBoolean("s").endRecord()
    val orangeschema = SchemaBuilder.record("Orange").namespace("market").fields().requiredString("b").endRecord()
    val union = SchemaBuilder.unionOf().`type`(appleschema).and().`type`(orangeschema).endUnion()
    val schema = SchemaBuilder.record("Test5").fields().name("either").`type`(union).noDefault().endRecord()

    Decoder[Test5].decode(ImmutableRecord(schema, Vector(ImmutableRecord(orangeschema, Vector(java.lang.Boolean.valueOf(true)))))) shouldBe Test5(Right(Orange(true)))
    Decoder[Test5].decode(ImmutableRecord(schema, Vector(ImmutableRecord(appleschema, Vector(new Utf8("zzz")))))) shouldBe Test5(Left(Apple("zzz")))
  }
} 
Example 9
Source File: CoproductDecoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.decoder

import com.sksamuel.avro4s.record.decoder.CPWrapper.{ISBG, ISCB}
import com.sksamuel.avro4s.{AvroSchema, Decoder}
import org.apache.avro.generic.GenericData
import org.apache.avro.util.Utf8
import shapeless.{:+:, CNil, Coproduct}
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

import scala.collection.JavaConverters._

class CoproductDecoderTest extends AnyFunSuite with Matchers {

  test("coproducts with primitives") {
    val decoder = Decoder[CPWrapper]
    val record = new GenericData.Record(decoder.schema)
    record.put("u", new Utf8("wibble"))
    decoder.decode(record) shouldBe CPWrapper(Coproduct[CPWrapper.ISBG]("wibble"))
  }

  test("coproducts with case classes") {
    val decoder = Decoder[CPWrapper]
    val gimble = new GenericData.Record(AvroSchema[Gimble])
    gimble.put("x", new Utf8("foo"))
    val record = new GenericData.Record(decoder.schema)
    record.put("u", gimble)
    decoder.decode(record) shouldBe CPWrapper(Coproduct[CPWrapper.ISBG](Gimble("foo")))
  }

  test("coproducts with options") {
    val codec = Decoder[CPWithOption]
    val gimble = new GenericData.Record(AvroSchema[Gimble])
    gimble.put("x", new Utf8("foo"))
    val record = new GenericData.Record(codec.schema)
    record.put("u", gimble)
    codec.decode(record) shouldBe CPWithOption(Some(Coproduct[CPWrapper.ISBG](Gimble("foo"))))
  }

  test("coproduct with array") {
    val schema = AvroSchema[CPWithArray]
    val array = new GenericData.Array(AvroSchema[Seq[String]], List(new Utf8("a"), new Utf8("b")).asJava)
    val record = new GenericData.Record(schema)
    record.put("u", array)
    Decoder[CPWithArray].decode(record) shouldBe CPWithArray(Coproduct[CPWrapper.SSI](Seq("a", "b")))
  }

  test("coproduct with array of coproducts") {
    val coproduct = CoproductWithArrayOfCoproduct(Coproduct[ISCB](Seq(Coproduct[ISBG](3), Coproduct[ISBG]("three"))))
    val array = new GenericData.Array(AvroSchema[Seq[ISBG]], List(3, new Utf8("three")).asJava)
    val record = new GenericData.Record(AvroSchema[CoproductWithArrayOfCoproduct])
    record.put("union", array)
    Decoder[CoproductWithArrayOfCoproduct].decode(record) shouldBe coproduct
  }

  test("coproducts") {
    val schema = AvroSchema[Coproducts]
    val record = new GenericData.Record(schema)
    record.put("union", new Utf8("foo"))
    val coproduct = Coproduct[Int :+: String :+: Boolean :+: CNil]("foo")
    Decoder[Coproducts].decode(record) shouldBe Coproducts(coproduct)
  }

  test("coproducts of coproducts") {
    val schema = AvroSchema[CoproductsOfCoproducts]
    val record = new GenericData.Record(schema)
    record.put("union", new Utf8("foo"))
    val coproduct = Coproduct[(Int :+: String :+: CNil) :+: Boolean :+: CNil](Coproduct[Int :+: String :+: CNil]("foo"))
    Decoder[CoproductsOfCoproducts].decode(record) shouldBe CoproductsOfCoproducts(coproduct)
  }
}

case class CPWithArray(u: CPWrapper.SSI)

case class Gimble(x: String)
case class CPWrapper(u: CPWrapper.ISBG)
case class CPWithOption(u: Option[CPWrapper.ISBG])

object CPWrapper {
  type ISBG = Int :+: String :+: Boolean :+: Gimble :+: CNil
  type SSI = Seq[String] :+: Int :+: CNil
  type ISCB = Int :+: Seq[ISBG] :+: String :+: CNil
}

case class Coproducts(union: Int :+: String :+: Boolean :+: CNil)
case class CoproductsOfCoproducts(union: (Int :+: String :+: CNil) :+: Boolean :+: CNil)
case class CoproductWithArrayOfCoproduct(union: CPWrapper.ISCB) 
Example 10
Source File: CoproductEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import com.sksamuel.avro4s._
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
import shapeless.{:+:, CNil, Coproduct}

class CoproductEncoderTest extends AnyFunSuite with Matchers {

  test("coproducts with primitives") {
    val encoder = Encoder[CPWrapper]
    encoder.encode(CPWrapper(Coproduct[CPWrapper.ISBG](4))) shouldBe ImmutableRecord(encoder.schema, Vector(java.lang.Integer.valueOf(4)))
    encoder.encode(CPWrapper(Coproduct[CPWrapper.ISBG]("wibble"))) shouldBe ImmutableRecord(encoder.schema, Vector(new Utf8("wibble")))
    encoder.encode(CPWrapper(Coproduct[CPWrapper.ISBG](true))) shouldBe ImmutableRecord(encoder.schema, Vector(java.lang.Boolean.valueOf(true)))
  }

  test("coproducts with case classes") {
    val gschema = AvroSchema[Gimble]
    val encoder = Encoder[CPWrapper]
    encoder.encode(CPWrapper(Coproduct[CPWrapper.ISBG](Gimble("foo")))) shouldBe ImmutableRecord(encoder.schema, Vector(ImmutableRecord(gschema, Vector(new Utf8("foo")))))
  }

  test("options of coproducts") {
    val schema = AvroSchema[CPWithOption]
    Encoder[CPWithOption].encode(CPWithOption(Some(Coproduct[CPWrapper.ISBG]("foo")))) shouldBe ImmutableRecord(schema, Vector(new Utf8("foo")))
    Encoder[CPWithOption].encode(CPWithOption(None)) shouldBe ImmutableRecord(schema, Vector(null))
  }

  test("coproducts with arrays") {
    val schema = AvroSchema[CPWithArray]
    Encoder[CPWithArray].encode(CPWithArray(Coproduct[CPWrapper.SSI](Seq("foo", "bar")))) shouldBe ImmutableRecord(schema, Vector(java.util.Arrays.asList(new Utf8("foo"), new Utf8("bar"))))
    Encoder[CPWithArray].encode(CPWithArray(Coproduct[CPWrapper.SSI](4))) shouldBe ImmutableRecord(schema, Vector(java.lang.Integer.valueOf(4)))
  }
}

case class CPWithArray(u: CPWrapper.SSI)

case class Gimble(x: String)
case class CPWrapper(u: CPWrapper.ISBG)
case class CPWithOption(u: Option[CPWrapper.ISBG])

object CPWrapper {
  type ISBG = Int :+: String :+: Boolean :+: Gimble :+: CNil
  type SSI = Seq[String] :+: Int :+: CNil
}

case class Coproducts(union: Int :+: String :+: Boolean :+: CNil)
case class CoproductsOfCoproducts(union: (Int :+: String :+: CNil) :+: Boolean :+: CNil) 
Example 11
Source File: BasicEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import com.sksamuel.avro4s.examples.UppercasePkg.ClassInUppercasePackage
import com.sksamuel.avro4s._
import org.apache.avro.Schema
import org.apache.avro.generic.{GenericFixed, GenericRecord}
import org.apache.avro.util.Utf8
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class BasicEncoderTest extends AnyWordSpec with Matchers {

  "Encoder" should {
    "encode strings as UTF8" in {
      case class Foo(s: String)
      val schema = AvroSchema[Foo]
      val record = Encoder[Foo].encode(Foo("hello"))
      record shouldBe ImmutableRecord(schema, Vector(new Utf8("hello")))
    }
    "encode strings as GenericFixed and pad bytes when schema is fixed" in {
      case class Foo(s: String)

      val fixedSchema = SchemaFor[String](Schema.createFixed("FixedString", null, null, 7))
      implicit val fixedStringEncoder: Encoder[String] = Encoder.StringEncoder.withSchema(fixedSchema)

      val record = Encoder[Foo].encode(Foo("hello")).asInstanceOf[GenericRecord]
      record.get("s").asInstanceOf[GenericFixed].bytes().toList shouldBe Seq(104, 101, 108, 108, 111, 0, 0)
      // the fixed should have the right size
      record.get("s").asInstanceOf[GenericFixed].bytes().length shouldBe 7
    }
    "encode longs" in {
      case class Foo(l: Long)
      val schema = AvroSchema[Foo]
      Encoder[Foo].encode(Foo(123456L)) shouldBe ImmutableRecord(schema, Vector(java.lang.Long.valueOf(123456L)))
    }
    "encode doubles" in {
      case class Foo(d: Double)
      val schema = AvroSchema[Foo]
      Encoder[Foo].encode(Foo(123.435)) shouldBe ImmutableRecord(schema, Vector(java.lang.Double.valueOf(123.435D)))
    }
    "encode booleans" in {
      case class Foo(d: Boolean)
      val schema = AvroSchema[Foo]
      Encoder[Foo].encode(Foo(true)) shouldBe ImmutableRecord(schema, Vector(java.lang.Boolean.valueOf(true)))
    }
    "encode floats" in {
      case class Foo(d: Float)
      val schema = AvroSchema[Foo]
      Encoder[Foo].encode(Foo(123.435F)) shouldBe ImmutableRecord(schema, Vector(java.lang.Float.valueOf(123.435F)))
    }
    "encode ints" in {
      case class Foo(i: Int)
      val schema = AvroSchema[Foo]
      Encoder[Foo].encode(Foo(123)) shouldBe ImmutableRecord(schema, Vector(java.lang.Integer.valueOf(123)))
    }
    "support uppercase packages" in {
      val schema = AvroSchema[ClassInUppercasePackage]
      val t = com.sksamuel.avro4s.examples.UppercasePkg.ClassInUppercasePackage("hello")
      schema.getFullName shouldBe "com.sksamuel.avro4s.examples.UppercasePkg.ClassInUppercasePackage"
      Encoder[ClassInUppercasePackage].encode(t) shouldBe ImmutableRecord(schema, Vector(new Utf8("hello")))
    }
  }
} 
Example 12
Source File: StructEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import com.sksamuel.avro4s.{AvroSchema, Encoder, ImmutableRecord}
import org.apache.avro.util.Utf8
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

case class County(name: String, towns: Seq[Town], ceremonial: Boolean, lat: Double, long: Double)
case class Town(name: String, population: Int)

class StructEncoderTest extends AnyWordSpec with Matchers {

  import scala.collection.JavaConverters._

  "RecordEncoder" should {
    "encode structs" in {
      val countySchema = AvroSchema[County]
      val townSchema = AvroSchema[Town]
      val count = County("Bucks", Seq(Town("Hardwick", 123), Town("Weedon", 225)), true, 12.34, 0.123)
      val result = Encoder[County].encode(count)

      val hardwick = ImmutableRecord(townSchema, Vector(new Utf8("Hardwick"), java.lang.Integer.valueOf(123)))
      val weedon = ImmutableRecord(townSchema, Vector(new Utf8("Weedon"), java.lang.Integer.valueOf(225)))
      result shouldBe ImmutableRecord(countySchema, Vector(new Utf8("Bucks"), List(hardwick, weedon).asJava, java.lang.Boolean.valueOf(true), java.lang.Double.valueOf(12.34), java.lang.Double.valueOf(0.123)))
    }
  }
} 
Example 13
Source File: NestedStructEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import com.sksamuel.avro4s.{AvroSchema, Encoder, ImmutableRecord}
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

class NestedStructEncoderTest extends AnyFunSuite with Matchers {

  test("encode nested structs") {

    case class Foo(s: String)
    case class Fooo(foo: Foo)
    case class Foooo(fooo: Fooo)

    Encoder[Foooo].encode(Foooo(Fooo(Foo("a")))) shouldBe
      ImmutableRecord(
        AvroSchema[Foooo],
        Vector(
          ImmutableRecord(
            AvroSchema[Fooo],
            Vector(
              ImmutableRecord(
                AvroSchema[Foo],
                Vector(new Utf8("a"))))
          )
        )
      )
  }
} 
Example 14
Source File: UUIDEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import java.util.UUID

import com.sksamuel.avro4s.{AvroSchema, Encoder, ImmutableRecord}
import org.apache.avro.util.Utf8
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class UUIDEncoderTest extends AnyWordSpec with Matchers {

  import scala.collection.JavaConverters._

  "Encoder" should {
    "encode uuids" in {
      val uuid = UUID.randomUUID()
      val schema = AvroSchema[UUIDTest]
      Encoder[UUIDTest].encode(UUIDTest(uuid)) shouldBe ImmutableRecord(schema, Vector(new Utf8(uuid.toString)))
    }
    "encode seq of uuids" in {
      val uuid1 = UUID.randomUUID()
      val uuid2 = UUID.randomUUID()
      val schema = AvroSchema[UUIDSeq]
      Encoder[UUIDSeq].encode(UUIDSeq(Seq(uuid1, uuid2))) shouldBe ImmutableRecord(schema, Vector(List(new Utf8(uuid1.toString), new Utf8(uuid2.toString)).asJava))
    }
    "encode UUIDs with defaults" in {
      val uuid = UUID.randomUUID()
      val schema = AvroSchema[UUIDDefault]
      Encoder[UUIDDefault].encode(UUIDDefault(uuid)) shouldBe ImmutableRecord(schema, Vector(new Utf8(uuid.toString)))
    }
    "encode Option[UUID]" in {
      val uuid = UUID.randomUUID()
      val schema = AvroSchema[UUIDOption]
      Encoder[UUIDOption].encode(UUIDOption(Some(uuid))) shouldBe ImmutableRecord(schema, Vector(new Utf8(uuid.toString)))
      Encoder[UUIDOption].encode(UUIDOption(None)) shouldBe ImmutableRecord(schema, Vector(null))
    }
  }
}

case class UUIDTest(uuid: UUID)
case class UUIDSeq(uuids: Seq[UUID])
case class UUIDDefault(uuid: UUID = UUID.fromString("86da265c-95bd-443c-8860-9381efca059d"))
case class UUIDOption(uuid: Option[UUID]) 
Example 15
Source File: EitherEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import com.sksamuel.avro4s.{AvroSchema, Encoder, ImmutableRecord}
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

class EitherEncoderTest extends AnyFunSuite with Matchers {

  test("generate union:T,U for Either[T,U] of primitives") {
    case class Test(either: Either[String, Double])
    Encoder[Test].encode(Test(Left("foo"))) shouldBe ImmutableRecord(AvroSchema[Test], Vector(new Utf8("foo")))
    Encoder[Test].encode(Test(Right(234.4D))) shouldBe ImmutableRecord(AvroSchema[Test], Vector(java.lang.Double.valueOf(234.4D)))
  }

  test("generate union:T,U for Either[T,U] of records") {
    case class Goo(s: String)
    case class Foo(b: Boolean)
    case class Test(either: Either[Goo, Foo])
    Encoder[Test].encode(Test(Left(Goo("zzz")))) shouldBe ImmutableRecord(AvroSchema[Test], Vector(ImmutableRecord(AvroSchema[Goo], Vector(new Utf8("zzz")))))
    Encoder[Test].encode(Test(Right(Foo(true)))) shouldBe ImmutableRecord(AvroSchema[Test], Vector(ImmutableRecord(AvroSchema[Foo], Vector(java.lang.Boolean.valueOf(true)))))
  }
} 
Example 16
Source File: AvroDeserializer.scala    From eel-sdk   with Apache License 2.0 5 votes vote down vote up
package io.eels.component.avro

import com.typesafe.config.ConfigFactory
import io.eels.Row
import io.eels.schema.StructType
import org.apache.avro.Schema.Field
import org.apache.avro.generic.GenericRecord
import org.apache.avro.util.Utf8

import scala.collection.JavaConverters._


class AvroDeserializer(useJavaString: Boolean = ConfigFactory.load().getBoolean("eel.avro.java.string")) {

  val config = ConfigFactory.load()
  val deserializeAsNullable = config.getBoolean("eel.avro.deserializeAsNullable")
  var schema: StructType = null
  var fields: Array[Field] = null
  var range: Range = null

  def toScala(value: Any): Any = {
    value match {
      case record: GenericRecord => toValues(record)
      case utf8: Utf8 if useJavaString => value.asInstanceOf[Utf8].toString
      case col: java.util.Collection[Any] => col.asScala.toVector.map(toScala)
      case map: java.util.Map[_, _] => map.asScala.toMap.map { case (k, v) => toScala(k) -> toScala(v) }
      case other => other
    }
  }

  def toValues(record: GenericRecord): Vector[Any] = {
    val vector = Vector.newBuilder[Any]
    for (k <- 0 until record.getSchema.getFields.size) {
      val value = record.get(k)
      vector += toScala(value)
    }
    vector.result
  }

  def toRow(record: GenericRecord): Row = {
    // take the schema from the first record
    if (schema == null) {
      schema = AvroSchemaFns.fromAvroSchema(record.getSchema, deserializeAsNullable)
    }
    Row(schema, toValues(record))
  }
} 
Example 17
Source File: OptionEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import com.sksamuel.avro4s.{AvroSchema, Encoder, ImmutableRecord}
import org.apache.avro.util.Utf8
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class OptionEncoderTest extends AnyWordSpec with Matchers {

  "Encoder" should {
    "support String options" in {
      case class Test(s: Option[String])
      val schema = AvroSchema[Test]
      Encoder[Test].encode(Test(Option("qwe"))) shouldBe ImmutableRecord(schema, Vector(new Utf8("qwe")))
      Encoder[Test].encode(Test(None)) shouldBe ImmutableRecord(schema, Vector(null))
    }
    "support boolean options" in {
      case class Test(b: Option[Boolean])
      val schema = AvroSchema[Test]
      Encoder[Test].encode(Test(Option(true))) shouldBe ImmutableRecord(schema, Vector(java.lang.Boolean.valueOf(true)))
      Encoder[Test].encode(Test(None)) shouldBe ImmutableRecord(schema, Vector(null))
    }
    "support options of case classes" in {
      case class Foo(s: String)
      case class Test(b: Option[Foo])
      val schema = AvroSchema[Test]
      val fooSchema = AvroSchema[Foo]
      Encoder[Test].encode(Test(Option(Foo("hello")))) shouldBe ImmutableRecord(schema, Vector(ImmutableRecord(fooSchema, Vector(new Utf8("hello")))))
      Encoder[Test].encode(Test(None)) shouldBe ImmutableRecord(schema, Vector(null))
    }
  }
} 
Example 18
Source File: ValueTypeEncoderTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.record.encoder

import com.sksamuel.avro4s.{AvroSchema, Encoder, ImmutableRecord}
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

class ValueTypeEncoderTest extends AnyFunSuite with Matchers {

  test("top level value types") {
    val schema = AvroSchema[FooValueType]
    Encoder[FooValueType].encode(FooValueType("hello")) shouldBe new Utf8("hello")
  }

  test("support fields that are value types") {
    case class Test(foo: FooValueType)
    val schema = AvroSchema[Test]
    Encoder[Test].encode(Test(FooValueType("hello"))) shouldBe ImmutableRecord(schema, Vector(new Utf8("hello")))
  }

  test("support value types inside Options") {
    case class Test(foo: Option[FooValueType])
    val schema = AvroSchema[Test]
    val record = Encoder[Test].encode(Test(Some(FooValueType("hello"))))
    record shouldBe ImmutableRecord(schema, Vector(new Utf8("hello")))
  }
}

case class FooValueType(s: String) extends AnyVal 
Example 19
Source File: OptionOutputStreamTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.streams.output

import org.apache.avro.generic.GenericRecord
import org.apache.avro.util.Utf8

class OptionOutputStreamTest extends OutputStreamTest {

  test("options of booleans") {
    case class Test(z: Option[Boolean])
    writeRead(Test(Some(true))) { record =>
      record.get("z") shouldBe true
    }
    writeRead(Test(None)) { record =>
      record.get("z") shouldBe null
    }
  }

  test("options of ints") {
    case class Test(z: Option[Int])
    writeRead(Test(Some(43242))) { record =>
      record.get("z") shouldBe 43242
    }
    writeRead(Test(None)) { record =>
      record.get("z") shouldBe null
    }
  }

  test("options of longs") {
    case class Test(z: Option[Long])
    writeRead(Test(Some(43242L))) { record =>
      record.get("z") shouldBe 43242L
    }
    writeRead(Test(None)) { record =>
      record.get("z") shouldBe null
    }
  }

  test("options of doubles") {
    case class Test(z: Option[Double])
    writeRead(Test(Some(123.34))) { record =>
      record.get("z") shouldBe java.lang.Double.valueOf(123.34)
    }
    writeRead(Test(None)) { record =>
      record.get("z") shouldBe null
    }
  }

  test("options of strings") {
    case class Test(z: Option[String])
    writeRead(Test(Some("hello"))) { record =>
      record.get("z") shouldBe new Utf8("hello")
    }
    writeRead(Test(None)) { record =>
      record.get("z") shouldBe null
    }
  }

  test("options of classes") {
    case class Foo(s: String)
    case class Test(z: Option[Foo])
    writeRead(Test(Some(Foo("hello")))) { record =>
      record.get("z").asInstanceOf[GenericRecord].get("s") shouldBe new Utf8("hello")
    }
    writeRead(Test(None)) { record =>
      record.get("z") shouldBe null
    }
  }
} 
Example 20
Source File: EitherOutputStreamTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.streams.output

import java.util

import com.sksamuel.avro4s.schema.Wine
import org.apache.avro.AvroRuntimeException
import org.apache.avro.generic.{GenericData, GenericRecord}
import org.apache.avro.util.Utf8

class EitherOutputStreamTest extends OutputStreamTest {

  import scala.collection.JavaConverters._

  test("write out either of primitives") {
    case class Test(z: Either[String, Int])
    writeRead(Test(Left("hello"))) { record =>
      record.get("z") shouldBe new Utf8("hello")
    }
    writeRead(Test(Right(45))) { record =>
      record.get("z") shouldBe 45
    }
  }

  test("write out either of Array") {
    case class Test(z: Either[Array[Int], String])
    writeRead(Test(Left(Array(1, 3, 4)))) { record =>
      record.get("z").asInstanceOf[GenericData.Array[Int]].asScala shouldBe List(1, 3, 4)
    }
  }

  test("write out either of Seq") {
    case class Test(z: Either[String, Seq[String]])
    writeRead(Test(Right(Seq("c", "d")))) { record =>
      record.get("z").asInstanceOf[GenericData.Array[String]].asScala shouldBe List(new Utf8("c"), new Utf8("d"))
    }
  }

  test("write out either of enum") {
    case class Test(z: Either[Wine, Seq[String]])
    writeRead(Test(Left(Wine.Malbec))) { record =>
      record.get("z").asInstanceOf[GenericData.EnumSymbol].toString shouldBe "Malbec"
    }
  }

  test("write out either of Maps") {
    case class Test(z: Either[Array[Int], Map[String, Boolean]])
    writeRead(Test(Right(Map("a" -> true, "b" -> false)))) { record =>
      record.get("z").asInstanceOf[util.HashMap[String, Boolean]].asScala shouldBe Map(new Utf8("a") -> true, new Utf8("b") -> false)
    }
  }

  test("write out case classes") {
    case class Foo(a: String)
    case class Bar(b: Boolean)
    case class Test(z: Either[Foo, Bar])
    writeRead(Test(Left(Foo("hello")))) { record =>
      record.get("z").asInstanceOf[GenericRecord].get("a") shouldBe new Utf8("hello")
    }
    writeRead(Test(Right(Bar(true)))) { record =>
      record.get("z").asInstanceOf[GenericRecord].get("b") shouldBe true
    }
  }

  test("throw an exception if trying to use two collection types in an either") {
    intercept[AvroRuntimeException] {
      case class Test(z: Either[Seq[String], List[Int]])
      writeRead(Test(Left(Seq("hello")))) { record =>
      }
    }
  }
} 
Example 21
Source File: BasicOutputStreamTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.streams.output

import com.sksamuel.avro4s.{Encoder, SchemaFor}
import org.apache.avro.Schema.Parser
import org.apache.avro.generic.{GenericRecord, GenericRecordBuilder}
import org.apache.avro.util.Utf8

class BasicOutputStreamTest extends OutputStreamTest {

  test("write out booleans") {
    case class Test(z: Boolean)
    writeRead(Test(true)) { record =>
      record.get("z") shouldBe true
    }
  }

  test("write out strings") {
    case class Test(z: String)
    writeRead(Test("Hello world")) { record =>
      record.get("z") shouldBe new Utf8("Hello world")
    }
  }

  test("write out longs") {
    case class Test(z: Long)
    writeRead(Test(65653L)) { record =>
      record.get("z") shouldBe 65653L
    }
  }

  test("write out ints") {
    case class Test(z: Int)
    writeRead(Test(44)) { record =>
      record.get("z") shouldBe 44
    }
  }

  test("write out doubles") {
    case class Test(z: Double)
    writeRead(Test(3.235)) { record =>
      record.get("z") shouldBe 3.235
    }
  }

  test("write out floats") {
    case class Test(z: Float)
    writeRead(Test(3.4F)) { record =>
      record.get("z") shouldBe 3.4F
    }
  }

  test("write out generic record") {
    val recordSchema = new Parser().parse(
      """{"type":"record","name":"Test","fields":[{"name":"field","type":"string"}]}"""
    )
    implicit val recordSchemaFor: SchemaFor[GenericRecord] = SchemaFor(recordSchema)

    implicit val encoder: Encoder[GenericRecord] = new Encoder[GenericRecord] {
      def schemaFor = recordSchemaFor

      def encode(value: GenericRecord): AnyRef = value
    }


    val record: GenericRecord = new GenericRecordBuilder(recordSchema).set("field", "value").build()

    writeRead(record) { rec =>
      rec.get("field") shouldBe new Utf8("value")
    }
  }
} 
Example 22
Source File: ValueTypeOutputStreamTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.streams.output

import com.sksamuel.avro4s.record.encoder.FooValueType
import org.apache.avro.util.Utf8

class ValueTypeOutputStreamTest extends OutputStreamTest {

  test("value type") {
    case class Test(foo: FooValueType)
    writeRead(Test(FooValueType("abc"))) { record =>
      record.get("foo") shouldBe new Utf8("abc")
    }
  }

  test("value types inside Options") {
    case class Test(foo: Option[FooValueType])
    writeRead(Test(Some(FooValueType("abc")))) { record =>
      record.get("foo") shouldBe new Utf8("abc")
    }
    writeRead(Test(None)) { record =>
      record.get("foo") shouldBe null
    }
  }
} 
Example 23
Source File: UUIDOutputStreamTest.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.streams.output

import java.util.UUID

import org.apache.avro.generic.GenericData
import org.apache.avro.util.Utf8

class UUIDOutputStreamTest extends OutputStreamTest {

  import scala.collection.JavaConverters._

  test("write out uuids") {
    val a = UUID.randomUUID()
    case class Test(z: UUID)
    writeRead(Test(a)) { record =>
      record.get("z") shouldBe new Utf8(a.toString)
    }
  }

  test("write out seq of UUIDS") {
    case class Test(z: Seq[UUID])
    val a = UUID.randomUUID()
    val b = UUID.randomUUID()
    val c = UUID.randomUUID()
    writeRead(Test(Seq(a, b, c))) { record =>
      record.get("z").asInstanceOf[GenericData.Array[Utf8]].asScala shouldBe Seq(a, b, c).map(_.toString).map(new Utf8(_))
    }
  }

  test("write out Some[UUID]") {
    val a = UUID.randomUUID()
    case class Test(z: Option[UUID])
    writeRead(Test(Some(a))) { record =>
      record.get("z") shouldBe new Utf8(a.toString)
    }
  }

  test("write out None[UUID]") {
    case class Test(z: Option[UUID])
    writeRead(Test(None)) { record =>
      record.get("z") shouldBe null
    }
  }

  test("write out UUID with default value") {
    case class Test(z: UUID = UUID.fromString("86da265c-95bd-443c-8860-9381efca059d"))
    writeRead(Test()) { record =>
      record.get("z") shouldBe new Utf8("86da265c-95bd-443c-8860-9381efca059d")
    }
  }

} 
Example 24
Source File: GithubIssue485.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.github

import java.io.{ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream}

import com.sksamuel.avro4s.record.decoder.CPWrapper
import com.sksamuel.avro4s.{AvroSchema, Decoder, DefaultFieldMapper}
import org.apache.avro.generic.GenericData
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
import shapeless.Coproduct

class GithubIssue485 extends AnyFunSuite with Matchers {

  test("Serializable Coproduct Decoder #485") {
    val baos = new ByteArrayOutputStream()
    val oos = new ObjectOutputStream(baos)
    oos.writeObject(Decoder[CPWrapper])
    oos.close()

    val decoder =
      new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray)).readObject().asInstanceOf[Decoder[CPWrapper]]

    val schema = AvroSchema[CPWrapper]
    val record = new GenericData.Record(schema)
    record.put("u", new Utf8("wibble"))
    decoder.decode(record) shouldBe CPWrapper(Coproduct[CPWrapper.ISBG]("wibble"))
  }
} 
Example 25
Source File: GithubIssue191.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s.github

import java.io.ByteArrayOutputStream

import com.sksamuel.avro4s.{AvroOutputStream, AvroSchema}
import org.apache.avro.file.{DataFileReader, SeekableByteArrayInput}
import org.apache.avro.generic.{GenericDatumReader, GenericRecord}
import org.apache.avro.util.Utf8
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

final case class SN(value: String) extends AnyVal
final case class SimpleUser(name: String, sn: Option[SN])

class GithubIssue191 extends AnyFunSuite with Matchers {

  test("writing out AnyVal in an option") {
    implicit val schema = AvroSchema[SimpleUser]
    val bytes = new ByteArrayOutputStream
    val out = AvroOutputStream.data[SimpleUser].to(bytes).build()
    out.write(SimpleUser("Tom", Some(SN("123"))))
    out.close()

    val datumReader = new GenericDatumReader[GenericRecord](schema)
    val dataFileReader = new DataFileReader[GenericRecord](new SeekableByteArrayInput(bytes.toByteArray), datumReader)
    val record = new Iterator[GenericRecord] {
      override def hasNext: Boolean = dataFileReader.hasNext
      override def next(): GenericRecord = dataFileReader.next
    }.toList.head
    record.getSchema shouldBe schema
    record.get("name") shouldBe new Utf8("Tom")
    record.get("sn") shouldBe new Utf8("123")
  }
} 
Example 26
Source File: TypeGuardedDecoding.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s

import org.apache.avro.generic.GenericContainer
import org.apache.avro.util.Utf8

import scala.reflect.runtime.universe._

object TypeGuardedDecoding {

  def guard[T: WeakTypeTag](decoder: Decoder[T]): PartialFunction[Any, T] = {
    import scala.reflect.runtime.universe.typeOf

    val tpe = implicitly[WeakTypeTag[T]].tpe

    if (tpe <:< typeOf[java.lang.String]) stringDecoder(decoder)
    else if (tpe <:< typeOf[Boolean]) booleanDecoder(decoder)
    else if (tpe <:< typeOf[Int]) intDecoder(decoder)
    else if (tpe <:< typeOf[Long]) longDecoder(decoder)
    else if (tpe <:< typeOf[Double]) doubleDecoder(decoder)
    else if (tpe <:< typeOf[Float]) floatDecoder(decoder)
    else if (tpe <:< typeOf[Array[_]] || tpe <:< typeOf[java.util.Collection[_]] || tpe <:< typeOf[Iterable[_]]) {
      arrayDecoder(decoder)
    } else if (tpe <:< typeOf[java.util.Map[_, _]] || tpe <:< typeOf[Map[_, _]]) {
      mapDecoder(decoder)
    } else if (tpe <:< typeOf[shapeless.Coproduct]) {
      coproductDecoder(decoder)
    } else {
      recordDecoder(decoder.schema.getFullName, decoder)
    }
  }

  private def stringDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: Utf8   => decoder.decode(v)
    case v: String => decoder.decode(v)
  }

  private def booleanDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: Boolean => decoder.decode(v)
  }

  private def intDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: Int => decoder.decode(v)
  }

  private def longDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: Long => decoder.decode(v)
  }

  private def doubleDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: Double => decoder.decode(v)
  }

  private def floatDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: Float => decoder.decode(v)
  }

  private def arrayDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: Array[_]                => decoder.decode(v)
    case v: java.util.Collection[_] => decoder.decode(v)
    case v: Iterable[_]             => decoder.decode(v)
  }

  private def mapDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: java.util.Map[_, _] => decoder.decode(v)
  }

  private def coproductDecoder[T](decoder: Decoder[T]): PartialFunction[Any, T] = scala.Function.unlift { value =>
    // this is only sort of safe because we will call TypeGuardedDecoding again in the decoder
    util.Try(decoder.decode(value)) match {
      case util.Success(cp) => Some(cp)
      case _                => None
    }
  }

  private def recordDecoder[T](typeName: String, decoder: Decoder[T]): PartialFunction[Any, T] = {
    case v: GenericContainer if v.getSchema.getFullName == typeName => decoder.decode(v)
  }
} 
Example 27
Source File: DefaultResolver.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s

import java.nio.ByteBuffer
import java.util.UUID

import org.apache.avro.LogicalTypes.Decimal
import org.apache.avro.generic.{GenericEnumSymbol, GenericFixed}
import org.apache.avro.util.Utf8
import org.apache.avro.{Conversions, Schema}
import CustomDefaults._
import scala.collection.JavaConverters._


object DefaultResolver {

  def apply(value: Any, schema: Schema): AnyRef = value match {
    case Some(x) => apply(x, schema)
    case u: Utf8 => u.toString
    case uuid: UUID => uuid.toString
    case enum: GenericEnumSymbol[_] => enum.toString
    case fixed: GenericFixed => fixed.bytes()
    case bd: BigDecimal => bd.toString()
    case byteBuffer: ByteBuffer if schema.getLogicalType.isInstanceOf[Decimal] =>
      val decimalConversion = new Conversions.DecimalConversion
      val bd = decimalConversion.fromBytes(byteBuffer, schema, schema.getLogicalType)
      java.lang.Double.valueOf(bd.doubleValue)
    case byteBuffer: ByteBuffer => byteBuffer.array()
    case x: scala.Long => java.lang.Long.valueOf(x)
    case x: scala.Boolean => java.lang.Boolean.valueOf(x)
    case x: scala.Int => java.lang.Integer.valueOf(x)
    case x: scala.Double => java.lang.Double.valueOf(x)
    case x: scala.Float => java.lang.Float.valueOf(x)
    case x: Map[_,_] => x.asJava
    case x: Seq[_] => x.asJava
    case shapeless.Inl(x) => apply(x, schema)
    case p: Product => customDefault(p, schema)
    case v if isScalaEnumeration(v) => customScalaEnumDefault(value)
    case _ =>
      value.asInstanceOf[AnyRef]
  }

} 
Example 28
Source File: StringToGenericRecord.scala    From hydra   with Apache License 2.0 5 votes vote down vote up
package hydra.avro.convert

import java.util.UUID

import org.apache.avro.{LogicalTypes, Schema}
import org.apache.avro.generic.{GenericDatumReader, GenericRecord}
import org.apache.avro.io.DecoderFactory
import cats.implicits._
import org.apache.avro.util.Utf8

import scala.util.{Failure, Success, Try}

object StringToGenericRecord {

  final case class ValidationExtraFieldsError(fields: Set[String]) extends RuntimeException(
    s"Extra fields ${fields.mkString(",")} found with Strict Validation Strategy"
  )

  final case class InvalidLogicalTypeError(expected: String, received: AnyRef) extends RuntimeException(
    s"Invalid logical type. Expected $expected but received $received"
  )

  implicit class ConvertToGenericRecord(s: String) {

    private def isUuidValid(s: String): Boolean =
      Try(UUID.fromString(s)).isSuccess

    private def checkLogicalTypes(record: GenericRecord): Try[Unit] = {
      import collection.JavaConverters._
      def checkAll(avroField: AnyRef, fieldSchema: Option[Schema]): Try[Unit] = avroField match {
        case g: GenericRecord => g.getSchema.getFields.asScala.toList
          .traverse(f => checkAll(g.get(f.name), f.schema.some)).void
        case u: Utf8 if fieldSchema.exists(f => Option(f.getLogicalType).exists(_.getName == LogicalTypes.uuid.getName)) =>
          if (isUuidValid(u.toString)) Success(()) else Failure(InvalidLogicalTypeError("UUID", u.toString))
        case _ => Success(())
      }
      val fields = record.getSchema.getFields.asScala.toList
      fields.traverse(f => checkAll(record.get(f.name), f.schema.some)).void
    }

    private def getAllPayloadFieldNames: Set[String] = {
      import spray.json._
      def loop(cur: JsValue, extraName: Option[String]): Set[String] = cur match {
        case JsObject(f) => f.flatMap { case (k: String, v: JsValue) =>
          loop(v, k.some) ++ Set(extraName.getOrElse("") + k)
        }.toSet
        case _ => Set.empty
      }
      loop(s.parseJson, None)
    }

    private def getAllSchemaFieldNames(schema: Schema): Set[String] = {
      import Schema.Type._
      import collection.JavaConverters._
      def loop(sch: Schema, extraName: Option[String]): Set[String] = sch.getType match {
        case RECORD => sch.getFields.asScala.toSet.flatMap { f: Schema.Field =>
          loop(f.schema, f.name.some) ++ Set(extraName.getOrElse("") + f.name)
        }
        case _ => Set.empty
      }
      loop(schema, None)
    }

    def toGenericRecord(schema: Schema, useStrictValidation: Boolean): Try[GenericRecord] = Try {
      if (useStrictValidation) {
        val diff = getAllPayloadFieldNames diff getAllSchemaFieldNames(schema)
        if (diff.nonEmpty) throw ValidationExtraFieldsError(diff)
      }
      val decoderFactory = new DecoderFactory
      val decoder = decoderFactory.jsonDecoder(schema, s)
      val reader = new GenericDatumReader[GenericRecord](schema)
      reader.read(null, decoder)
    }.flatTap(checkLogicalTypes)
  }

} 
Example 29
Source File: AvroParquetReaderFnTest.scala    From eel-sdk   with Apache License 2.0 5 votes vote down vote up
package io.eels.component.parquet

import java.util.UUID

import io.eels.component.avro.AvroSchemaFns
import io.eels.component.parquet.avro.AvroParquetReaderFn
import io.eels.schema.{DoubleType, Field, LongType, StructType}
import org.apache.avro.SchemaBuilder
import org.apache.avro.generic.{GenericData, GenericRecord}
import org.apache.avro.util.Utf8
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.parquet.avro.AvroParquetWriter
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec}

class AvroParquetReaderFnTest extends WordSpec with Matchers with BeforeAndAfterAll {

  private implicit val conf = new Configuration()
  private implicit val fs = FileSystem.get(new Configuration())

  private val path = new Path(UUID.randomUUID().toString())

  override def afterAll(): Unit = {
    val fs = FileSystem.get(new Configuration())
    fs.delete(path, false)
  }

  private val avroSchema = SchemaBuilder.record("com.chuckle").fields()
    .requiredString("str").requiredLong("looong").requiredDouble("dooble").endRecord()

  private val writer = AvroParquetWriter.builder[GenericRecord](path)
    .withSchema(avroSchema)
    .build()

  private val record = new GenericData.Record(avroSchema)
  record.put("str", "wibble")
  record.put("looong", 999L)
  record.put("dooble", 12.34)
  writer.write(record)
  writer.close()

  val schema = StructType(Field("str"), Field("looong", LongType(true), true), Field("dooble", DoubleType, true))

  "AvroParquetReaderFn" should {
    "support projections on doubles" in {

      val reader = AvroParquetReaderFn(path, None, Option(AvroSchemaFns.toAvroSchema(schema.removeField("looong"))))
      val record = reader.read()
      reader.close()

      record.get("str").asInstanceOf[Utf8].toString shouldBe "wibble"
      record.get("dooble") shouldBe 12.34
    }
    "support projections on longs" in {

      val reader = AvroParquetReaderFn(path, None, Option(AvroSchemaFns.toAvroSchema(schema.removeField("str"))))
      val record = reader.read()
      reader.close()

      record.get("looong") shouldBe 999L
    }
    "support full projections" in {

      val reader = AvroParquetReaderFn(path, None, Option(AvroSchemaFns.toAvroSchema(schema)))
      val record = reader.read()
      reader.close()

      record.get("str").asInstanceOf[Utf8].toString shouldBe "wibble"
      record.get("looong") shouldBe 999L
      record.get("dooble") shouldBe 12.34

    }
    "support non projections" in {

      val reader = AvroParquetReaderFn(path, None, None)
      val group = reader.read()
      reader.close()

      group.get("str").asInstanceOf[Utf8].toString shouldBe "wibble"
      group.get("looong") shouldBe 999L
      group.get("dooble") shouldBe 12.34

    }
  }
} 
Example 30
Source File: AvroSourceTest.scala    From eel-sdk   with Apache License 2.0 5 votes vote down vote up
package io.eels.component.avro

import java.nio.file.Paths

import com.typesafe.config.ConfigFactory
import io.eels.schema.{Field, StructType}
import org.apache.avro.util.Utf8
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.FileSystem
import org.scalatest.{Matchers, WordSpec}

class AvroSourceTest extends WordSpec with Matchers {

  private implicit val conf = new Configuration()
  private implicit val fs = FileSystem.get(new Configuration())

  "AvroSource" should {
    "read schema" in {
      val people = AvroSource(Paths.get(getClass.getResource("/test.avro").toURI).toAbsolutePath)
      people.schema shouldBe StructType(Field("name", nullable = false), Field("job", nullable = false), Field("location", nullable = false))
    }
    "read strings as java.lang.String when eel.avro.java.string is true" in {
      System.setProperty("eel.avro.java.string", "true")
      ConfigFactory.invalidateCaches()
      val people = AvroSource(Paths.get(getClass.getResource("/test.avro").toURI).toAbsolutePath).toDataStream().toSet
      people.map(_.values) shouldBe Set(
        List("clint eastwood", "actor", "carmel"),
        List("elton john", "musician", "pinner"),
        List("issac newton", "scientist", "heaven")
      )
      System.setProperty("eel.avro.java.string", "false")
      ConfigFactory.invalidateCaches()
    }
    "read strings as utf8 when eel.avro.java.string is false" in {
      System.setProperty("eel.avro.java.string", "false")
      ConfigFactory.invalidateCaches()
      val people = AvroSource(Paths.get(getClass.getResource("/test.avro").toURI).toAbsolutePath).toDataStream().toSet
      people.map(_.values) shouldBe Set(
        List(new Utf8("clint eastwood"), new Utf8("actor"), new Utf8("carmel")),
        List(new Utf8("elton john"), new Utf8("musician"), new Utf8("pinner")),
        List(new Utf8("issac newton"), new Utf8("scientist"), new Utf8("heaven"))
      )
      System.setProperty("eel.avro.java.string", "true")
      ConfigFactory.invalidateCaches()
    }
  }
}