diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 85e63b36..15bf6a69 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,18 @@ Unreleased Breaking API Changes ~~~~~~~~~~~~~~~~~~~~ +* scrooge-generator: Dropped the generic (higher-kinded-types) service interface in scala-gen, + users are recommended to use YourService.MethodPerEndpoint, YourService.ServicePerEndpoint + and YourService.ReqRepServicePerEndpoint to represent Thrift service endpoints. Note, + `-finagle` option is required to generated finagle binding code. ``PHAB_ID=D747744`` + +* scrooge-generator: Removed YourService.FutureIface and YourService[Future] in scala-gen, + use $YourService.MethodPerEndpoint instead. Correspondingly, YourService$FinagleService and + related constructors taking MethodPerEndpoint as parameters. ``PHAB_ID=D747744`` + +* Scrooge-generator: Dropped ThriftServiceBuilder.build and MethodIfaceBuilder.newMethodIface. + ``PHAB_ID=D747744`` + * scrooge-generator: Add reserved keywords to ThriftParser. If your field names match these keywords, you may need to modify them. This change should not affect backwards and forwards compatiblility if using binary protocol for serde. ``PHAB_ID=D707116`` diff --git a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService$FinagleClient.scala b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService$FinagleClient.scala index 4a0bd128..0f204eb7 100644 --- a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService$FinagleClient.scala +++ b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService$FinagleClient.scala @@ -18,8 +18,7 @@ import org.apache.thrift.protocol._ class GoldService$FinagleClient( val service: com.twitter.finagle.Service[ThriftClientRequest, Array[Byte]], val clientParam: RichClientParam) - extends GoldService.MethodPerEndpoint - with GoldService.FutureIface { + extends GoldService.MethodPerEndpoint { @deprecated("Use com.twitter.finagle.thrift.RichClientParam", "2017-08-16") def this( diff --git a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService$FinagleService.scala b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService$FinagleService.scala index d7d3b2b0..248f1cb4 100644 --- a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService$FinagleService.scala +++ b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService$FinagleService.scala @@ -23,14 +23,14 @@ import org.apache.thrift.transport.TMemoryInputTransport @javax.annotation.Generated(value = Array("com.twitter.scrooge.Compiler")) class GoldService$FinagleService( - iface: GoldService[Future], + iface: GoldService.MethodPerEndpoint, serverParam: RichServerParam ) extends com.twitter.finagle.Service[Array[Byte], Array[Byte]] { import GoldService._ @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: GoldService[Future], + iface: GoldService.MethodPerEndpoint, protocolFactory: TProtocolFactory, stats: StatsReceiver = NullStatsReceiver, maxThriftBufferSize: Int = Thrift.param.maxThriftBufferSize, @@ -39,7 +39,7 @@ class GoldService$FinagleService( @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: GoldService[Future], + iface: GoldService.MethodPerEndpoint, protocolFactory: TProtocolFactory, stats: StatsReceiver, maxThriftBufferSize: Int @@ -47,7 +47,7 @@ class GoldService$FinagleService( @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: GoldService[Future], + iface: GoldService.MethodPerEndpoint, protocolFactory: TProtocolFactory ) = this(iface, protocolFactory, NullStatsReceiver, Thrift.param.maxThriftBufferSize) diff --git a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService.scala b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService.scala index 196d0302..c8e53af5 100644 --- a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService.scala +++ b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/GoldService.scala @@ -34,20 +34,6 @@ import scala.reflect.{ClassTag, classTag} @javax.annotation.Generated(value = Array("com.twitter.scrooge.Compiler")) -trait GoldService[+MM[_]] extends _root_.com.twitter.finagle.thrift.ThriftService { - /** Hello, I'm a comment. */ - def doGreatThings(request: com.twitter.scrooge.test.gold.thriftscala.Request): MM[com.twitter.scrooge.test.gold.thriftscala.Response] - - def noExceptionCall(request: com.twitter.scrooge.test.gold.thriftscala.Request): MM[com.twitter.scrooge.test.gold.thriftscala.Response] - - /** - * Used to close the underlying `Service`. - * Not a user-defined API. - */ - def asClosable: _root_.com.twitter.util.Closable = _root_.com.twitter.util.Closable.nop -} - - object GoldService extends _root_.com.twitter.finagle.thrift.GeneratedThriftService { self => val annotations: immutable$Map[String, String] = immutable$Map( @@ -1367,12 +1353,16 @@ object GoldService extends _root_.com.twitter.finagle.thrift.GeneratedThriftServ type noExceptionCall$result = NoExceptionCall.Result - trait MethodPerEndpoint - extends GoldService[Future] { + trait MethodPerEndpoint extends _root_.com.twitter.finagle.thrift.ThriftService { /** Hello, I'm a comment. */ def doGreatThings(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[com.twitter.scrooge.test.gold.thriftscala.Response] def noExceptionCall(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[com.twitter.scrooge.test.gold.thriftscala.Response] + /** + * Used to close the underlying `Service`. + * Not a user-defined API. + */ + def asClosable: _root_.com.twitter.util.Closable = _root_.com.twitter.util.Closable.nop } object MethodPerEndpoint { @@ -1425,7 +1415,7 @@ object GoldService extends _root_.com.twitter.finagle.thrift.GeneratedThriftServ @deprecated("Use MethodPerEndpoint", "2017-11-07") class MethodIface(serviceIface: BaseServiceIface) - extends FutureIface { + extends MethodPerEndpoint { def doGreatThings(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[com.twitter.scrooge.test.gold.thriftscala.Response] = serviceIface.doGreatThings(self.DoGreatThings.Args(request)) def noExceptionCall(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[com.twitter.scrooge.test.gold.thriftscala.Response] = @@ -1438,41 +1428,16 @@ object GoldService extends _root_.com.twitter.finagle.thrift.GeneratedThriftServ MethodPerEndpoint(servicePerEndpoint) } - @deprecated("Use MethodPerEndpointBuilder", "2018-01-12") - implicit object ThriftServiceBuilder - extends _root_.com.twitter.finagle.thrift.service.ThriftServiceBuilder[ServicePerEndpoint, GoldService[Future]] { - def build(servicePerEndpoint: ServicePerEndpoint): MethodPerEndpoint = - MethodPerEndpoint(servicePerEndpoint) - } - implicit object ReqRepMethodPerEndpointBuilder extends _root_.com.twitter.finagle.thrift.service.ReqRepMethodPerEndpointBuilder[ReqRepServicePerEndpoint, MethodPerEndpoint] { def methodPerEndpoint(servicePerEndpoint: ReqRepServicePerEndpoint): MethodPerEndpoint = ReqRepMethodPerEndpoint(servicePerEndpoint) } - @deprecated("Use MethodPerEndpointBuilder", "2017-11-07") - implicit object MethodIfaceBuilder - extends com.twitter.finagle.thrift.MethodIfaceBuilder[ServiceIface, GoldService[Future]] { - def newMethodIface(serviceIface: ServiceIface): MethodIface = - new MethodIface(serviceIface) - } - - @deprecated("Use MethodPerEndpoint", "2017-11-07") - trait FutureIface - extends MethodPerEndpoint - with GoldService[Future] { - /** Hello, I'm a comment. */ - def doGreatThings(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[com.twitter.scrooge.test.gold.thriftscala.Response] - - def noExceptionCall(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[com.twitter.scrooge.test.gold.thriftscala.Response] - } - class FinagledClient( service: com.twitter.finagle.Service[ThriftClientRequest, Array[Byte]], clientParam: RichClientParam) extends GoldService$FinagleClient(service, clientParam) - with FutureIface with MethodPerEndpoint { @deprecated("Use com.twitter.finagle.thrift.RichClientParam", "2017-08-16") @@ -1509,13 +1474,13 @@ object GoldService extends _root_.com.twitter.finagle.thrift.GeneratedThriftServ } class FinagledService( - iface: GoldService[Future], + iface: MethodPerEndpoint, serverParam: RichServerParam) extends GoldService$FinagleService(iface, serverParam) { @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: GoldService[Future], + iface: MethodPerEndpoint, protocolFactory: org.apache.thrift.protocol.TProtocolFactory, serviceName: String = "GoldService" ) = this(iface, RichServerParam(protocolFactory, serviceName)) diff --git a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService$FinagleClient.scala b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService$FinagleClient.scala index 7d2d59b4..2d9642dc 100644 --- a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService$FinagleClient.scala +++ b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService$FinagleClient.scala @@ -18,8 +18,7 @@ class PlatinumService$FinagleClient( override val service: com.twitter.finagle.Service[ThriftClientRequest, Array[Byte]], override val clientParam: RichClientParam) extends GoldService$FinagleClient(service, clientParam) - with PlatinumService.MethodPerEndpoint - with PlatinumService.FutureIface { + with PlatinumService.MethodPerEndpoint { @deprecated("Use com.twitter.finagle.thrift.RichClientParam", "2017-08-16") def this( diff --git a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService$FinagleService.scala b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService$FinagleService.scala index eae55f95..05a3f9da 100644 --- a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService$FinagleService.scala +++ b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService$FinagleService.scala @@ -20,14 +20,14 @@ import org.apache.thrift.protocol._ @javax.annotation.Generated(value = Array("com.twitter.scrooge.Compiler")) class PlatinumService$FinagleService( - iface: PlatinumService[Future], + iface: PlatinumService.MethodPerEndpoint, serverParam: RichServerParam ) extends GoldService$FinagleService(iface, serverParam) { import PlatinumService._ @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: PlatinumService[Future], + iface: PlatinumService.MethodPerEndpoint, protocolFactory: TProtocolFactory, stats: StatsReceiver = NullStatsReceiver, maxThriftBufferSize: Int = Thrift.param.maxThriftBufferSize, @@ -36,7 +36,7 @@ class PlatinumService$FinagleService( @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: PlatinumService[Future], + iface: PlatinumService.MethodPerEndpoint, protocolFactory: TProtocolFactory, stats: StatsReceiver, maxThriftBufferSize: Int @@ -44,7 +44,7 @@ class PlatinumService$FinagleService( @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: PlatinumService[Future], + iface: PlatinumService.MethodPerEndpoint, protocolFactory: TProtocolFactory ) = this(iface, protocolFactory, NullStatsReceiver, Thrift.param.maxThriftBufferSize) diff --git a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService.scala b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService.scala index 1361c7ea..f7743c3f 100644 --- a/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService.scala +++ b/scrooge-generator-tests/src/test/resources/gold_file_output_scala/com/twitter/scrooge/test/gold/thriftscala/PlatinumService.scala @@ -33,18 +33,6 @@ import scala.reflect.{ClassTag, classTag} @javax.annotation.Generated(value = Array("com.twitter.scrooge.Compiler")) -trait PlatinumService[+MM[_]] extends GoldService[MM] { - - def moreCoolThings(request: com.twitter.scrooge.test.gold.thriftscala.Request): MM[Int] - - /** - * Used to close the underlying `Service`. - * Not a user-defined API. - */ - override def asClosable: _root_.com.twitter.util.Closable = _root_.com.twitter.util.Closable.nop -} - - object PlatinumService extends _root_.com.twitter.finagle.thrift.GeneratedThriftService { self => val annotations: immutable$Map[String, String] = immutable$Map.empty @@ -936,11 +924,14 @@ object PlatinumService extends _root_.com.twitter.finagle.thrift.GeneratedThrift type moreCoolThings$result = MoreCoolThings.Result - trait MethodPerEndpoint - extends com.twitter.scrooge.test.gold.thriftscala.GoldService.MethodPerEndpoint - with PlatinumService[Future] { + trait MethodPerEndpoint extends com.twitter.scrooge.test.gold.thriftscala.GoldService.MethodPerEndpoint { def moreCoolThings(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[Int] + /** + * Used to close the underlying `Service`. + * Not a user-defined API. + */ + override def asClosable: _root_.com.twitter.util.Closable = _root_.com.twitter.util.Closable.nop } object MethodPerEndpoint { @@ -989,7 +980,7 @@ object PlatinumService extends _root_.com.twitter.finagle.thrift.GeneratedThrift @deprecated("Use MethodPerEndpoint", "2017-11-07") class MethodIface(serviceIface: BaseServiceIface) extends com.twitter.scrooge.test.gold.thriftscala.GoldService.MethodIface(serviceIface) - with FutureIface { + with MethodPerEndpoint { def moreCoolThings(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[Int] = serviceIface.moreCoolThings(self.MoreCoolThings.Args(request)) } @@ -1000,40 +991,16 @@ object PlatinumService extends _root_.com.twitter.finagle.thrift.GeneratedThrift MethodPerEndpoint(servicePerEndpoint) } - @deprecated("Use MethodPerEndpointBuilder", "2018-01-12") - implicit object ThriftServiceBuilder - extends _root_.com.twitter.finagle.thrift.service.ThriftServiceBuilder[ServicePerEndpoint, PlatinumService[Future]] { - def build(servicePerEndpoint: ServicePerEndpoint): MethodPerEndpoint = - MethodPerEndpoint(servicePerEndpoint) - } - implicit object ReqRepMethodPerEndpointBuilder extends _root_.com.twitter.finagle.thrift.service.ReqRepMethodPerEndpointBuilder[ReqRepServicePerEndpoint, MethodPerEndpoint] { def methodPerEndpoint(servicePerEndpoint: ReqRepServicePerEndpoint): MethodPerEndpoint = ReqRepMethodPerEndpoint(servicePerEndpoint) } - @deprecated("Use MethodPerEndpointBuilder", "2017-11-07") - implicit object MethodIfaceBuilder - extends com.twitter.finagle.thrift.MethodIfaceBuilder[ServiceIface, PlatinumService[Future]] { - def newMethodIface(serviceIface: ServiceIface): MethodIface = - new MethodIface(serviceIface) - } - - @deprecated("Use MethodPerEndpoint", "2017-11-07") - trait FutureIface - extends com.twitter.scrooge.test.gold.thriftscala.GoldService.FutureIface - with MethodPerEndpoint - with PlatinumService[Future] { - - def moreCoolThings(request: com.twitter.scrooge.test.gold.thriftscala.Request): Future[Int] - } - class FinagledClient( service: com.twitter.finagle.Service[ThriftClientRequest, Array[Byte]], clientParam: RichClientParam) extends PlatinumService$FinagleClient(service, clientParam) - with FutureIface with MethodPerEndpoint { @deprecated("Use com.twitter.finagle.thrift.RichClientParam", "2017-08-16") @@ -1070,13 +1037,13 @@ object PlatinumService extends _root_.com.twitter.finagle.thrift.GeneratedThrift } class FinagledService( - iface: PlatinumService[Future], + iface: MethodPerEndpoint, serverParam: RichServerParam) extends PlatinumService$FinagleService(iface, serverParam) { @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: PlatinumService[Future], + iface: MethodPerEndpoint, protocolFactory: org.apache.thrift.protocol.TProtocolFactory, serviceName: String = "PlatinumService" ) = this(iface, RichServerParam(protocolFactory, serviceName)) diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NamespaceSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NamespaceSpec.scala index 93cdb0c4..2caa9e05 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NamespaceSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NamespaceSpec.scala @@ -1,19 +1,22 @@ package com.twitter.scrooge.backend +import com.twitter.conversions.DurationOps._ import com.twitter.scrooge.testutil.Spec +import com.twitter.util.Await +import com.twitter.util.Future class NamespaceSpec extends Spec { "Scala Generator" should { import bar._ import com.fake._ "import from another namespace" in { - val service: Restaurant[Some] = new Restaurant[Some] { - def isOpen(whichDay: Weekday) = Some(whichDay != Weekday.Monday) + val service: Restaurant.MethodPerEndpoint = new Restaurant.MethodPerEndpoint { + def isOpen(whichDay: Weekday) = Future.value(whichDay != Weekday.Monday) def makeReservation(whichDay: Weekday, howMany: Int) = - Some(if (whichDay == Weekday.Monday) 0 else howMany) + Future.value(if (whichDay == Weekday.Monday) 0 else howMany) } - service.makeReservation(Weekday.Monday, 2) must be(Some(0)) - service.makeReservation(Weekday.Tuesday, 2) must be(Some(2)) + Await.result(service.makeReservation(Weekday.Monday, 2), 5.seconds) must equal(0) + Await.result(service.makeReservation(Weekday.Tuesday, 2), 5.seconds) must equal(2) } } } diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala deleted file mode 100644 index 3ddb216a..00000000 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/NonFinagleSpec.scala +++ /dev/null @@ -1,44 +0,0 @@ -package com.twitter.scrooge.backend - -import com.twitter.util.Try -import com.twitter.scrooge.testutil.Spec - -class NonFinagleSpec extends Spec { - "None Finagle Service " should { - "work in Scala" in { - import vanilla.test._ - import vanilla.test1._ - val chicago = Airport("ORD", "Chicago", Location(123, 321)) - val nyc = Airport("JFK", "New York", Location(789, 987)) - val service: ExtendedAirportService[Try] = new ExtendedAirportService[Try] { - def fetchAirportsInBounds(nw: Location, se: Location) = - Try { - Seq(chicago, nyc) - .filter { airport => inRegion(airport.loc, nw, se) } - } - def hasWifi(a: Airport) = - Try { - if (a.code == "ORD") - true - else if (a.code == "JFK") - false - else - throw AirportException(100) - } - - private[this] def inRegion(loc: Location, nw: Location, se: Location) = - loc.latitude < nw.latitude && - loc.latitude > se.latitude && - loc.longitude > nw.longitude && - loc.longitude < se.longitude - } - service.hasWifi(chicago).get() must be(true) - service.hasWifi(nyc).get() must be(false) - val sfo = Airport("SFO", "San Francisco", Location(10, 10)) - intercept[AirportException] { - service.hasWifi(sfo).get() - } - service.fetchAirportsInBounds(Location(500, 0), Location(0, 500))() must be(Seq(chicago)) - } - } -} diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala index a4863e69..e80818db 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ScalaGeneratorSpec.scala @@ -1,22 +1,29 @@ package com.twitter.scrooge.backend import com.twitter.conversions.DurationOps._ -import com.twitter.finagle.{Service, SourcedException} -import com.twitter.scrooge.backend.thriftscala.{ - ConstructorRequiredStruct, - ConstructorRequiredStructPackageProtected, - DeepValidationStruct, - DeepValidationUnion -} -import com.twitter.scrooge.testutil.{EvalHelper, JMockSpec} +import com.twitter.finagle.Service +import com.twitter.finagle.SourcedException +import com.twitter.scrooge.backend.thriftscala.ConstructorRequiredStruct +import com.twitter.scrooge.backend.thriftscala.ConstructorRequiredStructPackageProtected +import com.twitter.scrooge.backend.thriftscala.DeepValidationStruct +import com.twitter.scrooge.backend.thriftscala.DeepValidationUnion +import com.twitter.scrooge.testutil.EvalHelper +import com.twitter.scrooge.testutil.JMockSpec import com.twitter.scrooge._ -import com.twitter.scrooge.validation.{MissingConstructionRequiredField, MissingRequiredField} -import com.twitter.util.{Await, Future} -import inheritance.aaa.{Aaa, Box} +import com.twitter.scrooge.validation.MissingConstructionRequiredField +import com.twitter.scrooge.validation.MissingRequiredField +import com.twitter.util.Await +import com.twitter.util.Future +import inheritance.aaa.Aaa +import inheritance.aaa.Box import inheritance.bbb.Bbb -import inheritance.ccc.{Ccc, CccExtended} +import inheritance.ccc.Ccc +import inheritance.ccc.CccExtended import inheritance.ddd.Ddd -import java.io.{ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream} +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.ObjectInputStream +import java.io.ObjectOutputStream import java.nio.ByteBuffer import org.apache.thrift.protocol._ import org.apache.thrift.transport.TMemoryBuffer @@ -1090,10 +1097,10 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper { "hide internal helper function to avoid naming conflict" in { _ => import thrift.`def`.default._ - val impl = new NaughtyService[Some] { - def foo() = Some(FooResult("dummy message")) + val impl = new NaughtyService.MethodPerEndpoint { + def foo() = Future.value(FooResult("dummy message")) } - impl.foo().get.message must be("dummy message") + Await.result(impl.foo(), 5.seconds).message must be("dummy message") } "passthrough fields" should { diff --git a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala index 345ff600..1793d3aa 100644 --- a/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala +++ b/scrooge-generator-tests/src/test/scala/com/twitter/scrooge/backend/ServiceGeneratorSpec.scala @@ -2,24 +2,38 @@ package com.twitter.scrooge.backend import _root_.thrift.test.ExceptionalService._ import _root_.thrift.test._ -import collisions.dupes.thriftscala.{Aaa, Ccc} +import collisions.dupes.thriftscala.Aaa +import collisions.dupes.thriftscala.Ccc import com.twitter.conversions.DurationOps._ import com.twitter.finagle import com.twitter.finagle.param.Stats -import com.twitter.finagle.service.{ReqRep, ResponseClass, ResponseClassifier} +import com.twitter.finagle.service.ReqRep +import com.twitter.finagle.service.ResponseClass +import com.twitter.finagle.service.ResponseClassifier import com.twitter.finagle.stats.InMemoryStatsReceiver -import com.twitter.finagle.thrift.{RichClientParam, RichServerParam, ThriftClientRequest} +import com.twitter.finagle.thrift.RichClientParam +import com.twitter.finagle.thrift.RichServerParam +import com.twitter.finagle.thrift.ThriftClientRequest import com.twitter.finagle.{Service => finagleService, _} -import com.twitter.scrooge.testutil.{EvalHelper, JMockSpec} -import com.twitter.scrooge.{Request, Response, ThriftException} -import com.twitter.util.{Await, Future, Return, Time} -import java.net.{InetAddress, InetSocketAddress} +import com.twitter.scrooge.testutil.EvalHelper +import com.twitter.scrooge.testutil.JMockSpec +import com.twitter.scrooge.Request +import com.twitter.scrooge.Response +import com.twitter.scrooge.ThriftException +import com.twitter.util.Await +import com.twitter.util.Future +import com.twitter.util.Return +import com.twitter.util.Time +import java.net.InetAddress +import java.net.InetSocketAddress import java.util.concurrent.atomic.AtomicBoolean import org.apache.thrift.protocol._ import org.apache.thrift.transport.TMemoryInputTransport -import org.jmock.AbstractExpectations.{any, returnValue} +import org.jmock.AbstractExpectations.any +import org.jmock.AbstractExpectations.returnValue import org.jmock.lib.legacy.ClassImposteriser -import org.jmock.{Expectations, Mockery} +import org.jmock.Expectations +import org.jmock.Mockery import org.scalatest.concurrent.Eventually import scala.language.reflectiveCalls import scala.collection @@ -27,11 +41,11 @@ import scala.collection class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "ScalaGenerator service" should { "generate a service interface" in { _ => - val service: SimpleService[Some] = new SimpleService[Some] { - def deliver(where: String) = Some(3) + val service: SimpleService.MethodPerEndpoint = new SimpleService.MethodPerEndpoint { + def deliver(where: String) = Future.value(3) } - service.deliver("Boston") must be(Some(3)) + Await.result(service.deliver("Boston"), 5.seconds) must be(3) } "generate a future-based service interface" in { _ => @@ -258,10 +272,10 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "generate FinagleService" should { // use JMock manually - the scalatest JMock integration has trouble with - // the erasure for ExceptionalService[Future] + // the erasure for ExceptionalService.MethodPerEndpoint val context = new Mockery context.setImposteriser(ClassImposteriser.INSTANCE) - val impl = context.mock(classOf[ExceptionalService[Future]]) + val impl = context.mock(classOf[ExceptionalService.MethodPerEndpoint]) val service = new ExceptionalService$FinagleService(impl, RichServerParam()) "success" in { _ => @@ -383,7 +397,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "generate FinagledClient" should { val context = new Mockery context.setImposteriser(ClassImposteriser.INSTANCE) - val impl = context.mock(classOf[ExceptionalService[Future]]) + val impl = context.mock(classOf[ExceptionalService.MethodPerEndpoint]) val service = new ExceptionalService$FinagleService(impl, RichServerParam()) val clientService = new finagle.Service[ThriftClientRequest, Array[Byte]] { def apply(req: ThriftClientRequest) = service(req.message) @@ -482,7 +496,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "be closable MethodPerEndpoint" in { _ => val service = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new SimpleService[Future] { + new SimpleService.MethodPerEndpoint { def deliver(input: String) = Future.value(input.length) } ) @@ -505,7 +519,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "be closable ServicePerEndpoint" in { _ => val service = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new SimpleService[Future] { + new SimpleService.MethodPerEndpoint { def deliver(input: String) = Future.value(input.length) } ) @@ -528,7 +542,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val service = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new SimpleService[Future] { + new SimpleService.MethodPerEndpoint { def deliver(input: String) = Future.value(input.length) } ) @@ -558,7 +572,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "user can define close method and their own asClosable method" in { _ => val closableService = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new TestClosableService[Future] { + new TestClosableService.MethodPerEndpoint { def close() = Future.value("close") def asClosable() = Future.value("asClosable") } @@ -576,13 +590,13 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "correctly inherit traits across services" should { "generic" in { _ => - class BasicImpl extends ReadWriteService[Some] { - def getName() = Some("Rus") - def setName(name: String) = Some(()) + class BasicImpl extends ReadWriteService.MethodPerEndpoint { + def getName() = Future.value("Rus") + def setName(name: String) = Future.Unit } - new BasicImpl().isInstanceOf[ReadOnlyService[Some]] must be(true) - new BasicImpl().isInstanceOf[ReadWriteService[Some]] must be(true) + new BasicImpl().isInstanceOf[ReadOnlyService.MethodPerEndpoint] must be(true) + new BasicImpl().isInstanceOf[ReadWriteService.MethodPerEndpoint] must be(true) } "future-based" in { _ => @@ -601,8 +615,8 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val client = new ReadWriteService$FinagleClient(null, RichClientParam()) client.isInstanceOf[ReadOnlyService$FinagleClient] must be(true) - client.isInstanceOf[ReadOnlyService[Future]] must be(true) - client.isInstanceOf[ReadWriteService[Future]] must be(true) + client.isInstanceOf[ReadOnlyService.MethodPerEndpoint] must be(true) + client.isInstanceOf[ReadWriteService.MethodPerEndpoint] must be(true) } } @@ -619,7 +633,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val server = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new SimpleService[Future] { + new MethodPerEndpoint { def deliver(where: String) = Future.value(3) } ) @@ -639,7 +653,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { import ReadWriteService._ val server = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new ReadWriteService[Future] { + new ReadWriteService.MethodPerEndpoint { private[this] var name = "Initial name" def getName(): Future[String] = Future.value(name) @@ -679,7 +693,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { def serveExceptionalService(): ListeningServer = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new ExceptionalService[Future] { + new ExceptionalService.MethodPerEndpoint { private[this] var counter = 0 def deliver(where: String): Future[Int] = { @@ -715,7 +729,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { import ExceptionalService._ val server = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new ExceptionalService[Future] { + new ExceptionalService.MethodPerEndpoint { def deliver(input: String) = Future.value(input.length) def remove(id: Int): Future[Unit] = Future.Done } @@ -746,8 +760,11 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { } "work with retrying filters" in { _ => - import com.twitter.finagle.service.{RetryExceptionsFilter, RetryPolicy} - import com.twitter.util.{JavaTimer, Throw, Try} + import com.twitter.finagle.service.RetryExceptionsFilter + import com.twitter.finagle.service.RetryPolicy + import com.twitter.util.JavaTimer + import com.twitter.util.Throw + import com.twitter.util.Try val service = serveExceptionalService() val clientService = Thrift.client.servicePerEndpoint[ExceptionalService.ServicePerEndpoint]( @@ -793,7 +810,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val server = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new CamelCaseSnakeCaseService[Future] { + new CamelCaseSnakeCaseService.MethodPerEndpoint { def fooBar(fooBar: String): Future[String] = Future.value(fooBar) def bazQux(bazQux: String): Future[String] = Future.value(bazQux) } @@ -890,7 +907,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { "have correct stats with ResponseClassifier" in { _ => val server: ListeningServer = Thrift.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new SimpleService[Future] { + new SimpleService.MethodPerEndpoint { def deliver(where: String): Future[Int] = Future.value(where.length) } ) @@ -968,7 +985,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val server = ThriftMux.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new SimpleService[Future] { + new SimpleService.MethodPerEndpoint { def deliver(where: String) = Future.value(3) } ) @@ -991,7 +1008,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { import ReadWriteService._ val server = ThriftMux.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new ReadWriteService[Future] { + new ReadWriteService.MethodPerEndpoint { private[this] var name = "Initial name" def getName(): Future[String] = Future.value(name) @@ -1039,7 +1056,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { def serveExceptionalService(): ListeningServer = ThriftMux.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new ExceptionalService[Future] { + new ExceptionalService.MethodPerEndpoint { private[this] var counter = 0 def deliver(where: String): Future[Int] = { @@ -1076,7 +1093,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { import ExceptionalService._ val server = ThriftMux.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new ExceptionalService[Future] { + new ExceptionalService.MethodPerEndpoint { def deliver(input: String) = Future.value(input.length) def remove(id: Int): Future[Unit] = Future.Done } @@ -1107,8 +1124,11 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { } "work with retrying filters" in { _ => - import com.twitter.finagle.service.{RetryExceptionsFilter, RetryPolicy} - import com.twitter.util.{JavaTimer, Throw, Try} + import com.twitter.finagle.service.RetryExceptionsFilter + import com.twitter.finagle.service.RetryPolicy + import com.twitter.util.JavaTimer + import com.twitter.util.Throw + import com.twitter.util.Try val service = serveExceptionalService() val clientService = @@ -1156,7 +1176,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val server = ThriftMux.server.serveIface( new InetSocketAddress(InetAddress.getLoopbackAddress, 0), - new CamelCaseSnakeCaseService[Future] { + new CamelCaseSnakeCaseService.MethodPerEndpoint { def fooBar(fooBar: String): Future[String] = Future.value(fooBar) def bazQux(bazQux: String): Future[String] = Future.value(bazQux) } @@ -1281,7 +1301,7 @@ class ServiceGeneratorSpec extends JMockSpec with EvalHelper with Eventually { val context = new Mockery context.setImposteriser(ClassImposteriser.INSTANCE) - val impl = context.mock(classOf[_root_.thrift.test.Service[Future]]) + val impl = context.mock(classOf[_root_.thrift.test.Service.MethodPerEndpoint]) val service = new _root_.thrift.test.Service$FinagleService(impl, RichServerParam()) "allow generation and calls to eponymous FinagledService" in { _ => diff --git a/scrooge-generator/src/main/resources/scalagen/finagleClient.mustache b/scrooge-generator/src/main/resources/scalagen/finagleClient.mustache index 4505c4de..2bf00bab 100644 --- a/scrooge-generator/src/main/resources/scalagen/finagleClient.mustache +++ b/scrooge-generator/src/main/resources/scalagen/finagleClient.mustache @@ -15,8 +15,7 @@ class {{ServiceName}}$FinagleClient( {{#hasParent}}override {{/hasParent}}val service: com.twitter.finagle.Service[ThriftClientRequest, Array[Byte]], {{#hasParent}}override {{/hasParent}}val clientParam: RichClientParam) extends {{#hasParent}}{{finagleClientParent}}(service, clientParam) - with {{/hasParent}}{{ServiceName}}.MethodPerEndpoint - with {{ServiceName}}.FutureIface { + with {{/hasParent}}{{ServiceName}}.MethodPerEndpoint { @deprecated("Use com.twitter.finagle.thrift.RichClientParam", "2017-08-16") def this( diff --git a/scrooge-generator/src/main/resources/scalagen/finagleService.mustache b/scrooge-generator/src/main/resources/scalagen/finagleService.mustache index 8a659eeb..299847c2 100644 --- a/scrooge-generator/src/main/resources/scalagen/finagleService.mustache +++ b/scrooge-generator/src/main/resources/scalagen/finagleService.mustache @@ -21,7 +21,7 @@ import org.apache.thrift.transport.TMemoryInputTransport {{docstring}} @javax.annotation.Generated(value = Array("com.twitter.scrooge.Compiler")) class {{ServiceName}}$FinagleService( - iface: {{ServiceName}}[Future], + iface: {{ServiceName}}.MethodPerEndpoint, serverParam: RichServerParam ) extends {{finagleServiceParent}}{{#hasParent}}(iface, serverParam){{/hasParent}} { {{#hasMethodServices}} @@ -35,7 +35,7 @@ class {{ServiceName}}$FinagleService( @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: {{ServiceName}}[Future], + iface: {{ServiceName}}.MethodPerEndpoint, protocolFactory: TProtocolFactory, stats: StatsReceiver = NullStatsReceiver, maxThriftBufferSize: Int = Thrift.param.maxThriftBufferSize, @@ -44,7 +44,7 @@ class {{ServiceName}}$FinagleService( @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: {{ServiceName}}[Future], + iface: {{ServiceName}}.MethodPerEndpoint, protocolFactory: TProtocolFactory, stats: StatsReceiver, maxThriftBufferSize: Int @@ -52,7 +52,7 @@ class {{ServiceName}}$FinagleService( @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: {{ServiceName}}[Future], + iface: {{ServiceName}}.MethodPerEndpoint, protocolFactory: TProtocolFactory ) = this(iface, protocolFactory, NullStatsReceiver, Thrift.param.maxThriftBufferSize) diff --git a/scrooge-generator/src/main/resources/scalagen/service.mustache b/scrooge-generator/src/main/resources/scalagen/service.mustache index 49eabea3..e54dc31e 100644 --- a/scrooge-generator/src/main/resources/scalagen/service.mustache +++ b/scrooge-generator/src/main/resources/scalagen/service.mustache @@ -36,21 +36,6 @@ import scala.reflect.{ClassTag, classTag} {{docstring}} @javax.annotation.Generated(value = Array("com.twitter.scrooge.Compiler")) -trait {{ServiceName}}[+MM[_]] {{#genericParent}}extends {{genericParent}} {{/genericParent}}{ -{{#genericFunctions}} - {{>function}} -{{/genericFunctions}} - -{{#withAsClosable}} - /** - * Used to close the underlying `Service`. - * Not a user-defined API. - */ - {{#parent}}override {{/parent}}def asClosable: _root_.com.twitter.util.Closable = _root_.com.twitter.util.Closable.nop -{{/withAsClosable}} -} - -{{docstring}} object {{ServiceName}} {{#withFinagle}}extends _root_.com.twitter.finagle.thrift.GeneratedThriftService {{/withFinagle}}{ self => {{#annotations}} @@ -394,12 +379,17 @@ object {{ServiceName}} {{#withFinagle}}extends _root_.com.twitter.finagle.thrift {{/thriftFunctions}} {{#withFinagle}} - trait MethodPerEndpoint - extends {{#methodPerEndpointParent}}{{methodPerEndpointParent}} - with {{/methodPerEndpointParent}}{{ServiceName}}[Future] { + trait MethodPerEndpoint extends {{genericParent}} { {{#asyncFunctions}} {{>function}} {{/asyncFunctions}} +{{#withAsClosable}} + /** + * Used to close the underlying `Service`. + * Not a user-defined API. + */ + {{#parent}}override {{/parent}}def asClosable: _root_.com.twitter.util.Closable = _root_.com.twitter.util.Closable.nop +{{/withAsClosable}} } {{#generateServiceIface}} @@ -457,7 +447,7 @@ object {{ServiceName}} {{#withFinagle}}extends _root_.com.twitter.finagle.thrift @deprecated("Use MethodPerEndpoint", "2017-11-07") class MethodIface(serviceIface: BaseServiceIface) extends {{#parent}}{{parent}}.MethodIface(serviceIface) - with {{/parent}}FutureIface { + with {{/parent}}MethodPerEndpoint { {{#ownFunctions}} def {{funcName}}({{fieldParams}}): Future[{{typeName}}] = serviceIface.{{dedupedFuncName}}(self.{{funcObjectName}}.Args({{argNames}})){{^isVoid}}{{/isVoid}}{{#isVoid}}.unit{{/isVoid}} @@ -470,42 +460,17 @@ object {{ServiceName}} {{#withFinagle}}extends _root_.com.twitter.finagle.thrift MethodPerEndpoint(servicePerEndpoint) } - @deprecated("Use MethodPerEndpointBuilder", "2018-01-12") - implicit object ThriftServiceBuilder - extends _root_.com.twitter.finagle.thrift.service.ThriftServiceBuilder[ServicePerEndpoint, {{ServiceName}}[Future]] { - def build(servicePerEndpoint: ServicePerEndpoint): MethodPerEndpoint = - MethodPerEndpoint(servicePerEndpoint) - } - implicit object ReqRepMethodPerEndpointBuilder extends _root_.com.twitter.finagle.thrift.service.ReqRepMethodPerEndpointBuilder[ReqRepServicePerEndpoint, MethodPerEndpoint] { def methodPerEndpoint(servicePerEndpoint: ReqRepServicePerEndpoint): MethodPerEndpoint = ReqRepMethodPerEndpoint(servicePerEndpoint) } - - @deprecated("Use MethodPerEndpointBuilder", "2017-11-07") - implicit object MethodIfaceBuilder - extends com.twitter.finagle.thrift.MethodIfaceBuilder[ServiceIface, {{ServiceName}}[Future]] { - def newMethodIface(serviceIface: ServiceIface): MethodIface = - new MethodIface(serviceIface) - } {{/generateServiceIface}} - @deprecated("Use MethodPerEndpoint", "2017-11-07") - trait FutureIface - extends {{#futureIfaceParent}}{{futureIfaceParent}} - with {{/futureIfaceParent}}MethodPerEndpoint - with {{ServiceName}}[Future] { -{{#asyncFunctions}} - {{>function}} -{{/asyncFunctions}} - } - class FinagledClient( service: com.twitter.finagle.Service[ThriftClientRequest, Array[Byte]], clientParam: RichClientParam) extends {{ServiceName}}$FinagleClient(service, clientParam) - with FutureIface with MethodPerEndpoint { @deprecated("Use com.twitter.finagle.thrift.RichClientParam", "2017-08-16") @@ -542,13 +507,13 @@ object {{ServiceName}} {{#withFinagle}}extends _root_.com.twitter.finagle.thrift } class FinagledService( - iface: {{ServiceName}}[Future], + iface: MethodPerEndpoint, serverParam: RichServerParam) extends {{ServiceName}}$FinagleService(iface, serverParam) { @deprecated("Use com.twitter.finagle.thrift.RichServerParam", "2017-08-16") def this( - iface: {{ServiceName}}[Future], + iface: MethodPerEndpoint, protocolFactory: org.apache.thrift.protocol.TProtocolFactory, serviceName: String = "{{ServiceName}}" ) = this(iface, RichServerParam(protocolFactory, serviceName)) diff --git a/scrooge-generator/src/main/scala/com/twitter/scrooge/backend/ServiceTemplate.scala b/scrooge-generator/src/main/scala/com/twitter/scrooge/backend/ServiceTemplate.scala index 6bf77b98..6b2ec6d7 100644 --- a/scrooge-generator/src/main/scala/com/twitter/scrooge/backend/ServiceTemplate.scala +++ b/scrooge-generator/src/main/scala/com/twitter/scrooge/backend/ServiceTemplate.scala @@ -265,7 +265,7 @@ trait ServiceTemplate { self: TemplateGenerator => genQualifiedID(getServiceParentID(p), namespace).append(".FutureIface") }), "genericParent" -> service.parent - .map { p => genID(getServiceParentID(p)).append("[MM]") } + .map { p => genQualifiedID(getServiceParentID(p), namespace).append(".MethodPerEndpoint") } .getOrElse(v("_root_.com.twitter.finagle.thrift.ThriftService")), "syncFunctions" -> v(service.functions.map { f => functionDictionary(f, None) }), "asyncFunctions" -> v(service.functions.map { f => functionDictionary(f, Some("Future")) }),