Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Sep 17 22:52
    edma2 added as member
  • Sep 17 22:52
    edma2 removed as member
  • Sep 17 22:51
    edma2 added as member
  • Sep 17 22:51
    edma2 removed as member
  • Jun 13 2020 03:21

    finaglehelper on develop

    finatra: Support for injecting … (compare)

  • Jun 12 2020 22:21

    finaglehelper on develop

    finatra-thrift: Reduce complexi… (compare)

  • Jun 12 2020 02:44

    finaglehelper on develop

    finatra-thrift: Use correct dat… (compare)

  • Jun 11 2020 07:32

    finaglehelper on develop

    finatra-thrift: CommonThriftLog… (compare)

  • Jun 10 2020 19:31

    finaglehelper on develop

    finagle, finatra, ts: Keep `inc… (compare)

  • Jun 10 2020 19:05
    ihasfrozen commented #522
  • Jun 09 2020 00:46

    finaglehelper on develop

    finatra: Add comments for optim… (compare)

  • Jun 08 2020 18:23

    finaglehelper on develop

    finatra-doc: Add missing import… (compare)

  • Jun 05 2020 03:18

    finaglehelper on develop

    inject-core: Remove finagle-cor… (compare)

  • Jun 04 2020 22:33

    finaglehelper on develop

    finatra: Use permanent links fo… (compare)

  • May 29 2020 21:31
    cacoco closed #511
  • May 29 2020 21:31
    cacoco commented #511
  • May 29 2020 21:31
    cacoco closed #524
  • May 29 2020 21:31
    cacoco commented #524
  • May 28 2020 22:31

    finaglehelper on develop

    util|scrooge|finagle|twitter-se… (compare)

  • May 28 2020 00:41

    finaglehelper on develop

    finatra: Update testing docs P… (compare)

Deenar Toraskar
@deenar
Thank you for your help @cacoco
Christopher Coco
@cacoco
Ok glad you got it figured out, @deenar
Deenar Toraskar
@deenar
@cacoco Hi Chris, I was wondering how does one go about serialing Option[LocalDateTime] or Option[LocalDate]?
Christopher Coco
@cacoco
@deenar we include the DefaultScalaModule which should allow for serializing Options which should then proxy to the right serializer for LocalDate LocalDateTime if you have one
The Scala Module supports serialization and limited deserialization of Scala Case Classes, Sequences, Maps, Tuples, Options, and Enumerations.
Deenar Toraskar
@deenar
@cacoco thanks I have a couple of other question 1) i would like to return HTML via moustache if Accept header contained text/html or JSON otherwise, what is the idiomatic way of doing this
is there an Oauth2 filter implementation available somewhere?
Christopher Coco
@cacoco
@deenar we don’t have an OAuth2 Filter anywhere though I believe there is a finagle-oauth2 project here: https://github.com/finagle/finagle-oauth2 which should work. For your first question, if you want to content-negotiation like this you have several choices. Most simply is to switch on the accept header — we have a utility that may help here: https://github.com/twitter/finatra/blob/develop/http/src/main/scala/com/twitter/finatra/http/request/RequestUtils.scala#L31
Deenar Toraskar
@deenar
Thank you
Deenar Toraskar
@deenar
Hi All, I wanted to write some test on Finatra Request parsing and Response writing for some of the application classes we have, but am stuck. I saw com.twitter.finatra.http.tests.marshalling.MessageBodyManagerTest, but it only seems to test overwritten read and write behaviour not the default one.
Christopher Coco
@cacoco
@deenar not sure what you mean.
Do you have example of what you’re trying to do or what you’re running into?
Deenar Toraskar
@deenar
''' test("Test PaymentRuleTest writer ") {
val testCase = ParseRules.getSampleTestCase()
val writerResponse = defaultMessageBodyWriter.write(testCase.inputMessage)
writerResponse.contentType should equal(MediaType.JsonUtf8)
mapper.parsePaymentRuleTest should equal(testCase)
}'''
something along the lines of given a case class wanted to assert it's JSON encoding on the way out is as expected and a given JSON request is mapped correctly on the way in
Christopher Coco
@cacoco
@deenar its not intended that you need to interact with the message body manager at all to test this
you would issue a request to the server and expect the returned JSON is as expected
Deenar Toraskar
@deenar
so I should just use FeatureTests
for what you’re describing: "something along the lines of given a case class wanted to assert it's JSON encoding on the way out is as expected and a given JSON request is mapped correctly on the way in”, yes a FeatureTest
I mean you are free to test the message body writer directly…if you really want to but you’re just testing our machinery and not your logic (and you should assume we test our machinery)
Deenar Toraskar
@deenar
I do have FeatureTests, but was wondering if there was a way just to check the serialisation and deserialisation of individual case classe
Christopher Coco
@cacoco
meaning what exactly
test what mechanism
testing serialization an deserialization of a case class is effectively writing tests of the framework which is again, great, but ultimately useless for testing anything related to your logic.
ok
Christopher Coco
@cacoco
right you are free to right more tests for our object mapper — but does that help you test anything for your code?
Christopher Coco
@cacoco

If you just want to test json mapping, then yeah you can follow what happens in the Jackson tests:
https://github.com/twitter/finatra/blob/develop/jackson/src/test/scala/com/twitter/finatra/jackson/ScalaObjectMapperTest.scala

https://github.com/twitter/finatra/blob/develop/jackson/src/test/scala/com/twitter/finatra/jackson/ScalaObjectMapperFromInjectorTest.scala

https://github.com/twitter/finatra/blob/develop/jackson/src/test/scala/com/twitter/finatra/jackson/AbstractScalaObjectMapperTest.scala

Or if you want to test how object mapping interacts with HTTP requests, then you can build a minimal injector like in the MessageBodyManagerTest (https://github.com/twitter/finatra/blob/develop/http/src/test/scala/com/twitter/finatra/http/tests/marshalling/MessageBodyManagerTest.scala#L72) and get references to the DefaultMessageBodyReader and DefaultMessageBodyWriter (which are supersets of logic and end up deferring to the ScalaObjectMapper for JSON serialization): https://github.com/twitter/finatra/blob/develop/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/DefaultMessageBodyWriterImpl.scala#L68

But I’m not sure that tells you anything about your code built on top of this.

that it, this is what I was after, I can test all kinds of expected inputs quicker
the feature test covers the logic, but is expensive to do the same for fields which are just pass through
thanks
Hamdi Allam
@hamdiallam
Hey folks, the 20.9.0 release is out! https://finagle.github.io/blog/2020/09/25/release-notes/
Christopher Coco
@cacoco
@deenar I wanted to add that I was not speaking only about FeatureTests earlier (there are several types of testing concepts that we espouse in Finatra: https://twitter.github.io/finatra/user-guide/testing/index.html#types-of-tests). If a use case is “expensive” to add into your tests it is possible that your system isn’t modularized well enough to allow easy testing of various components. Yes, you can always add some simple unit tests of the direct features provided by the framework (as mentioned before) especially if you’re trying to use them as regression tests against your specific data (in this case you want to always know that your case classes can be serialized/deserialized as they are perhaps unique) — but I would argue these are somewhat secondary tests and should not replace testing your higher-level logic on top of the framework of which, there are several ways to do so. Hope that helps. Thanks.
Deenar Toraskar
@deenar
@cacoco thanks for this, i was more using it as a stub during development to see how new model classes would serialize/deserialise out of the box
jyanJing
@jyanJing
Deenar Toraskar
@deenar
@jyanJing Thanks, will check it out
Matthieu Totet
@totetmatt

Oy Folks,
Happy user of Finatra here for some time now. Just asking for an advice. We use finatra for some REST services let's say /api/A and /api/B with some custom request.
And that works great, but all theses services has some common parameters let's say userId so it looks like that :

trait UserTrait{ @QueryParam("user.id")  val userId:String}
case class GetAReQuest(@QueryParam a:String, @QueryParam("user.id") userId:String) extends UserTrait
get("/api/A") { aRequest: GetARequest => /* Magic here*/ }

case class GetBReQuest(@QueryParam b:Int, @QueryParam("user.id") userId:String) extends UserTrait
get("/api/B") { bRequest: GetBRequest => /* Magic here*/ }

It works but I'm not fan of doing copy paste of the trait all the time (and I don't know how to make the @QueryParam used automatically if I extends the case class ) and would like to have a better mechanism to "compose" the requests object.

TL;DR I tried Request Context but at the end if I understand I need to "parse manually" the requests to my object. But I'm wondering if it would be possible to use
objectMapper.parseMessageBody[UserCaseClass](request)
without the exception
Injecting request attributes (e.g. QueryParam, Header, etc) not supported when explicitly calling ScalaObjectMapper.parse. Instead use a 'case class' input parameter on a Controller callback (e.g. get('/') { r: ClassWithRequestAttributes => ... } ).
so I just declare the case class and parsing is done automatically ?

Thanks by advance !

Christopher Coco
@cacoco

@totetmatt defining the @QueryParam should only be necessary on the field in the trait. You should not need to redefine the field nor the annotation in the case class implementations like in your example. E.g. your classes should just be defined like so:

trait UserTrait{ @QueryParam("user.id")  val userId:String}
case class GetAReQuest(@QueryParam a:String) extends UserTrait
case class GetBReQuest(@QueryParam b:Int) extends UserTrait

However, if you wanted to do this manually, you would use the DefaultMessageBodyReader#parse method here (not the ScalaObjectMapper#parseMessageBody): https://github.com/twitter/finatra/blob/develop/http/src/main/scala/com/twitter/finatra/http/marshalling/DefaultMessageBodyReader.scala#L59

The ScalaObjectMapper doesn’t know anything about HTTP, even though there’s an implicit that adds the parseMessageBody function — that doesn’t know how to interpet the annotations. Only the MessageBodyReader in the HTTP package has that ability.
Matthieu Totet
@totetmatt

Hey @cacoco thanks for the insights !

I actually tried what you explain before but if I do so, scala complain as

class GetAReQuest needs to be abstract, since value userId in trait Usertrait of type String is not defined

And then, even if I add userId:String to the case class, the @QueryParam won't be propagated : "user_id: field is required"

But, if on the trait I declare the attributes as def then it works, Needs to repeat the field, but then @QueryParam looks "propagated".

trait UserTrait { @QueryParam("user.id")  def userId:String}
                                       //  ^---- use of def instead of val 

case class GetAReQuest(@QueryParam a:String, userId:String) extends UserTrait
case class GetBReQuest(@QueryParam b:Int, userId:String) extends UserTrait
                                       // ^----- Repeat the trait attributes but no need to repeat @QueryParam or any other @Annotation

I don't really know what are the implication or even if it's correct to do this way, but so far it's acceptable for my use case.

Thanks also for the explaination about the ScalaObjectMapper & MessageBodyReader, was quite confuse on what was happening here.
But then if I understand there is no real way to parse a request "ad-hoc" like :
case class UserData([...])
case class QueryData([...])
case class XYZData([...])
get("/api/") { req:Requests =>
    val userData:UserData   = req.asInstanceOf[UserData]
    val queryData:QueryData = req.asInstanceOf[QueryData]
    val xyzData:XYZData     = req.asInstanceOf[XYZData]
                        ^----- Or any other magical method ?
// Yeah I know feels weird but just want to know for knowledge
}
Christopher Coco
@cacoco
@totetmatt It seems like you have a pretty standard case for inheritence and you’re just fighting Scala. Case classes can be a bit funny but there’s no magic here and we have plenty of test cases if you look around that highlight the behavior of annotated inherited fields as it pertains to custom request case class parsing. But yeah, you’re right, you need to define the field as a def in the trait and in the case class repeat it as a field (but you don’t need to redefine the annotation). This just Scala. For your second question, I’m not sure I understand what you mean by “ad-hoc” here. You have a type so it’s not really ad-hoc? If you manually want to parse the JSON body of a request, then you would just use an http Request as the callback type and then parse the content string into some object like here.
awu
@awu
hey folks, x-posting from twitter/finagle: i'm trying to use inject-mdc and MDCInitializer from finatra in a finagle(finch) service, but for some reason the mdc keys aren't showing up in logs. anyone have an idea? the filter is pretty much the exact same as the LoggingMDCFilter and it's the very first filter.
4 replies
Marwan Rabbâa
@waghanza
Hello,
We want to introduce finatra in the-benchmarker/web-frameworks#3835
@cacoco do you (or any core team member) consent (or is no opposed) on such a thing ?