diff --git a/.travis.yml b/.travis.yml index f8341ad29a..d208d17f35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,12 +3,8 @@ sudo: false language: scala -scala: - - 2.11.11 - - 2.12.1 - env: - - JAVA_OPTS="-Dsbt.log.noformat=true" + - JAVA_OPTS="-DSKIP_FLAKY=true -Dsbt.log.noformat=true" # These directories are cached to S3 at the end of the build cache: @@ -22,6 +18,10 @@ before_cache: - find $HOME/.ivy2 -name "ivydata-*.properties" -delete - find $HOME/.sbt -name "*.lock" -delete +scala: + - 2.11.11 + - 2.12.1 + jdk: - oraclejdk8 diff --git a/CHANGELOG.md b/CHANGELOG.md index eb406f72e4..1c50f23c83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -All notable changes to this project will be documented in this file. Note that ``RB_ID=#`` and ``DIFF_ID=#`` correspond to associated message in commits. +All notable changes to this project will be documented in this file. Note that ``RB_ID=#`` and ``PHAB_ID=#`` correspond to associated message in commits. ## [Unreleased] @@ -12,6 +12,29 @@ All notable changes to this project will be documented in this file. Note that ` ### Closed +## [finatra-2.13.0](https://github.com/twitter/finatra/tree/finatra-2.13.0) (2017-09-06) + +### Added + +* inject-server: Add ability to fail embedded server startup on lint rule violation. + There is now a flag in the embedded servers that when set to true will fail + server startup if a lint rule violation is detected. This will then fail + the running test. ``PHAB_ID=D82399`` + +### Changed + +* finatra-http: No longer depend on bijection-util. ``PHAB_ID=D86640`` + +* finatra-jackson: Deprecate c.t.finatra.json.utils.CamelCasePropertyNamingStrategy. + This object was created to reduce ambiguity with previous releases of Jackson in which + the default PropertyNamingStrategy was an abstract class with a default of camel case. + Users are encouraged to use the Jackson PropertyNamingStrategy + constants directly. ``PHAB_ID=D81707`` + +### Fixed + +### Closed + ## [finatra-2.12.0](https://github.com/twitter/finatra/tree/finatra-2.12.0) (2017-08-15) ### Added @@ -147,7 +170,7 @@ All notable changes to this project will be documented in this file. Note that ` * inject-core: Move Logging from grizzled-slf4j to util/util-slf4j-api. `c.t.inject.Logger` is now deprecated in favor of `c.t.util.logging.Logger` - in util. ``DIFF_ID=D29713`` + in util. ``PHAB_ID=D29713`` * finatra-httpclient: Update framework tests to FunSuite ScalaTest testing style. ``RB_ID=909526`` @@ -208,12 +231,12 @@ All notable changes to this project will be documented in this file. Note that ` test helpers which mix in the recommended FunSuite. Thus it will look like your tests are broken as you will need to update to change to use the new "WordSpec" classes or changed your testing style to the recommended `FunSuite` style. - ``DIFF_ID=D19822`` + ``PHAB_ID=D19822`` * inject-core: Remove JUnitRunner from `c.t.inject.Test`. This was only necessary for internal building with pants and is no longer required. The sbt build uses the ScalaTest runner and is thus not affected. Additionally, update specs2 to 2.4.17 and - to depend on just the `specs2-mock` dependency where needed. ``DIFF_ID=D18011`` + to depend on just the `specs2-mock` dependency where needed. ``PHAB_ID=D18011`` ### Fixed diff --git a/benchmarks/src/test/scala/BUILD b/benchmarks/src/test/scala/BUILD index 74df80c2b3..e0566071bc 100644 --- a/benchmarks/src/test/scala/BUILD +++ b/benchmarks/src/test/scala/BUILD @@ -30,4 +30,5 @@ junit_tests( ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/build.sbt b/build.sbt index 64393a7277..be5fded7de 100644 --- a/build.sbt +++ b/build.sbt @@ -4,7 +4,7 @@ import scoverage.ScoverageKeys concurrentRestrictions in Global += Tags.limit(Tags.Test, 1) -lazy val projectVersion = "2.12.0" +lazy val projectVersion = "2.13.0" lazy val buildSettings = Seq( version := projectVersion, @@ -15,11 +15,19 @@ lazy val buildSettings = Seq( javaOptions in Test ++= travisTestJavaOptions ) +lazy val noPublishSettings = Seq( + publish := {}, + publishLocal := {}, + publishArtifact := false +) + def travisTestJavaOptions: Seq[String] = { // When building on travis-ci, we want to suppress logging to error level only. val travisBuild = sys.env.getOrElse("TRAVIS", "false").toBoolean if (travisBuild) { Seq( + "-DSKIP_FLAKY=true", + "-Dsbt.log.noformat=true", "-Dorg.slf4j.simpleLogger.defaultLogLevel=error", "-Dcom.twitter.inject.test.logging.disabled", // Needed to avoid cryptic EOFException crashes in forked tests @@ -27,7 +35,10 @@ def travisTestJavaOptions: Seq[String] = { // See https://github.com/sbt/sbt/issues/653 // and https://github.com/travis-ci/travis-ci/issues/3775 "-Xmx3G") - } else Seq.empty + } else { + Seq( + "-DSKIP_FLAKY=true") + } } lazy val versions = new { @@ -38,12 +49,11 @@ lazy val versions = new { val suffix = if (branch == "master" || travisBranch == "master") "" else "-SNAPSHOT" // Use SNAPSHOT versions of Twitter libraries on non-master branches - val finagleVersion = "7.0.0" + suffix - val scroogeVersion = "4.19.0" + suffix - val twitterserverVersion = "1.31.0" + suffix - val utilVersion = "7.0.0" + suffix + val finagleVersion = "7.1.0" + suffix + val scroogeVersion = "4.20.0" + suffix + val twitterserverVersion = "1.32.0" + suffix + val utilVersion = "7.1.0" + suffix - val bijectionVersion = "0.9.5" val commonsCodec = "1.9" val commonsFileupload = "1.3.1" val commonsIo = "2.4" @@ -98,6 +108,8 @@ lazy val baseSettings = Seq( scalaCompilerOptions, javacOptions in (Compile, compile) ++= Seq("-source", "1.8", "-target", "1.8", "-Xlint:unchecked"), javacOptions in doc ++= Seq("-source", "1.8"), + // -a: print stack traces for failing asserts + testOptions += Tests.Argument(TestFrameworks.JUnit, "-a"), // broken in 2.12 due to: https://issues.scala-lang.org/browse/SI-10134 scalacOptions in (Compile, doc) ++= { if (scalaVersion.value.startsWith("2.12")) Seq("-no-java-comments") @@ -237,7 +249,7 @@ lazy val root = (project in file(".")) .enablePlugins(ScalaUnidocPlugin) .settings(baseSettings) .settings(buildSettings) - .settings(publishSettings) + .settings(noPublishSettings) .settings( organization := "com.twitter", moduleName := "finatra-root", @@ -586,8 +598,7 @@ lazy val http = project moduleName := "finatra-http", ScoverageKeys.coverageExcludedPackages := ";.*ScalaObjectHandler.*;.*NonValidatingHttpHeadersResponse.*;com\\.twitter\\.finatra\\..*package.*;.*ThriftExceptionMapper.*;.*HttpResponseExceptionMapper.*;.*HttpResponseException.*", libraryDependencies ++= Seq( - "com.github.spullara.mustache.java" % "compiler" % versions.mustache, - "com.twitter" %% "bijection-util" % versions.bijectionVersion, + "com.github.spullara.mustache.java" % "compiler" % versions.mustache exclude("com.google.guava", "guava"), "com.twitter" %% "finagle-exp" % versions.finagleVersion, "com.twitter" %% "finagle-http" % versions.finagleVersion, "commons-fileupload" % "commons-fileupload" % versions.commonsFileupload, diff --git a/doc/src/sphinx/user-guide/http/requests.rst b/doc/src/sphinx/user-guide/http/requests.rst index 2ee0fcc8ea..04c64a0155 100644 --- a/doc/src/sphinx/user-guide/http/requests.rst +++ b/doc/src/sphinx/user-guide/http/requests.rst @@ -153,7 +153,7 @@ An example of testing this endpoint: def deserializeRequest(name: String) = { val requestBytes = IOUtils.toByteArray(getClass.getResourceAsStream(name)) - Request.decodeBytes(requestBytes) + HttpCodec.decodeBytesToRequest(requestBytes) } "post multipart" in { diff --git a/doc/src/sphinx/user-guide/json/index.rst b/doc/src/sphinx/user-guide/json/index.rst index 565c7e44c8..a8d5400c1b 100644 --- a/doc/src/sphinx/user-guide/json/index.rst +++ b/doc/src/sphinx/user-guide/json/index.rst @@ -83,7 +83,7 @@ For example, override val serializationInclusion = Include.NON_EMPTY - override val propertyNamingStrategy = CamelCasePropertyNamingStrategy + override val propertyNamingStrategy = PropertyNamingStrategy.LOWER_CAMEL_CASE override def additionalMapperConfiguration(mapper: ObjectMapper) { mapper.configure(Feature.WRITE_NUMBERS_AS_STRINGS, true) diff --git a/examples/benchmark-server/build.sbt b/examples/benchmark-server/build.sbt index dc3f0e89a9..25c063200d 100644 --- a/examples/benchmark-server/build.sbt +++ b/examples/benchmark-server/build.sbt @@ -1,11 +1,11 @@ name := "benchmark-server" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val logback = "1.1.7" } diff --git a/examples/benchmark-server/src/main/scala/BUILD b/examples/benchmark-server/src/main/scala/BUILD index b7e2c0079a..3509ef3236 100644 --- a/examples/benchmark-server/src/main/scala/BUILD +++ b/examples/benchmark-server/src/main/scala/BUILD @@ -1,19 +1,21 @@ scala_library( dependencies=[ - '3rdparty/jvm/org/slf4j:slf4j-nop', '3rdparty/jvm/com/fasterxml/jackson/core:jackson-databind', '3rdparty/jvm/com/fasterxml/jackson/datatype:jackson-datatype-joda', '3rdparty/jvm/com/fasterxml/jackson/module:jackson-module-scala', '3rdparty/jvm/com/google/inject:guice', + '3rdparty/jvm/org/slf4j:slf4j-nop', 'finagle/finagle-core/src/main/scala', 'finagle/finagle-http/src/main/scala', 'finatra/http/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-server/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', 'util/util-stats/src/main/scala', @@ -23,4 +25,5 @@ scala_library( ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/benchmark-server/src/test/scala/BUILD b/examples/benchmark-server/src/test/scala/BUILD index bc1397e0d6..7fdeee503a 100644 --- a/examples/benchmark-server/src/test/scala/BUILD +++ b/examples/benchmark-server/src/test/scala/BUILD @@ -4,12 +4,14 @@ junit_tests( '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-http/src/main/scala', 'finatra/examples/benchmark-server/src/main/scala', + 'finatra/examples/benchmark-server/src/test/resources', 'finatra/http/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-server/src/main/scala:scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/benchmark-server/src/test/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/hello-world-heroku/build.sbt b/examples/hello-world-heroku/build.sbt index 4af18241d0..fb37d32eb0 100644 --- a/examples/hello-world-heroku/build.sbt +++ b/examples/hello-world-heroku/build.sbt @@ -3,13 +3,13 @@ import com.typesafe.sbt.SbtNativePackager._ packageArchetype.java_application name := "hello-world-heroku" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" fork in run := true parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" val finagleMetrics = "0.0.3" diff --git a/examples/hello-world-heroku/src/main/scala/BUILD b/examples/hello-world-heroku/src/main/scala/BUILD index c58fe19de3..d61b833248 100644 --- a/examples/hello-world-heroku/src/main/scala/BUILD +++ b/examples/hello-world-heroku/src/main/scala/BUILD @@ -4,20 +4,23 @@ scala_library( '3rdparty/jvm/com/google/inject:guice', '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-http/src/main/scala', + 'finatra/examples/hello-world-heroku/src/main/resources', 'finatra/http/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-server/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/hello-world-heroku/src/main/resources', ], excludes = [ exclude(org='org.slf4j', name='slf4j-jdk14') ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/hello-world/build.sbt b/examples/hello-world/build.sbt index 76f520fff3..7108288b8a 100644 --- a/examples/hello-world/build.sbt +++ b/examples/hello-world/build.sbt @@ -1,11 +1,11 @@ name := "hello-world" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" } diff --git a/examples/hello-world/pom.xml b/examples/hello-world/pom.xml index 91204d447e..763c455ad5 100644 --- a/examples/hello-world/pom.xml +++ b/examples/hello-world/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.twitter hello-world - 2.12.0 + 2.13.0 1.8 @@ -12,7 +12,7 @@ UTF-8 2.12.1 2.12 - 2.12.0 + 2.13.0 com.twitter.hello.HelloWorldServerMain com.twitter.hello diff --git a/examples/hello-world/src/main/scala/BUILD b/examples/hello-world/src/main/scala/BUILD index 8c108d3b05..cfa3e16e2d 100644 --- a/examples/hello-world/src/main/scala/BUILD +++ b/examples/hello-world/src/main/scala/BUILD @@ -4,20 +4,23 @@ scala_library( '3rdparty/jvm/com/google/inject:guice', '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-http/src/main/scala', + 'finatra/examples/hello-world/src/main/resources', 'finatra/http/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-server/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/hello-world/src/main/resources', ], excludes = [ exclude(org='org.slf4j', name='slf4j-jdk14') ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/hello-world/src/test/scala/BUILD b/examples/hello-world/src/test/scala/BUILD index 80cf1cc5f2..d2c04f637b 100644 --- a/examples/hello-world/src/test/scala/BUILD +++ b/examples/hello-world/src/test/scala/BUILD @@ -9,13 +9,15 @@ junit_tests( '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-http/src/main/scala', 'finatra/examples/hello-world/src/main/scala', + 'finatra/examples/hello-world/src/test/resources', 'finatra/http/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-server/src/main/scala:scala', 'finatra/inject/inject-server/src/test/scala:test-deps', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/hello-world/src/test/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/java-http-server/build.sbt b/examples/java-http-server/build.sbt index 8d7be96952..979c0f852a 100644 --- a/examples/java-http-server/build.sbt +++ b/examples/java-http-server/build.sbt @@ -1,6 +1,6 @@ name := "java-http-server" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" parallelExecution in ThisBuild := false publishMavenStyle := true @@ -16,7 +16,7 @@ javacOptions ++= Seq( mainClass in (Compile, packageBin) := Some("com.twitter.hello.server.HelloWorldServerMain") lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" val junit = "4.12" diff --git a/examples/java-server/build.sbt b/examples/java-server/build.sbt index 2edd94e61e..d92fd6456e 100644 --- a/examples/java-server/build.sbt +++ b/examples/java-server/build.sbt @@ -1,6 +1,6 @@ name := "java-server" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" parallelExecution in ThisBuild := false publishMavenStyle := true @@ -10,7 +10,7 @@ autoScalaLibrary := false mainClass in (Compile, packageBin) := Some("com.twitter.hello.server.HelloWorldServerMain") lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" } diff --git a/examples/java-thrift-server/build.sbt b/examples/java-thrift-server/build.sbt index 71191c1ddf..17b3d5b132 100644 --- a/examples/java-thrift-server/build.sbt +++ b/examples/java-thrift-server/build.sbt @@ -3,7 +3,7 @@ import sbt.Keys._ parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" val mockito = "1.9.5" @@ -14,7 +14,7 @@ lazy val versions = new { } lazy val baseSettings = Seq( - version := "2.12.0", + version := "2.13.0", scalaVersion := "2.12.1", ivyScala := ivyScala.value.map(_.copy(overrideScalaVersion = true)), libraryDependencies ++= Seq( diff --git a/examples/streaming-example/build.sbt b/examples/streaming-example/build.sbt index 7dd9eb54ae..5fa58854bc 100644 --- a/examples/streaming-example/build.sbt +++ b/examples/streaming-example/build.sbt @@ -1,11 +1,11 @@ name := "streaming-example" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" } diff --git a/examples/streaming-example/src/main/scala/BUILD b/examples/streaming-example/src/main/scala/BUILD index c3bea24d2f..72aa11338a 100644 --- a/examples/streaming-example/src/main/scala/BUILD +++ b/examples/streaming-example/src/main/scala/BUILD @@ -3,20 +3,23 @@ scala_library( '3rdparty/jvm/ch/qos/logback:logback-classic', '3rdparty/jvm/com/google/inject:guice', '3rdparty/jvm/org/slf4j:slf4j-api', + 'finatra/examples/streaming-example/src/main/resources', 'finatra/http/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-server/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/streaming-example/src/main/resources', ], excludes = [ exclude(org='org.slf4j', name='slf4j-jdk14') ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/streaming-example/src/test/scala/BUILD b/examples/streaming-example/src/test/scala/BUILD index 3cd1c667aa..91bb0bc019 100644 --- a/examples/streaming-example/src/test/scala/BUILD +++ b/examples/streaming-example/src/test/scala/BUILD @@ -4,15 +4,18 @@ junit_tests( '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-http/src/main/scala', 'finatra/examples/streaming-example/src/main/scala', + 'finatra/examples/streaming-example/src/test/resources', 'finatra/http/src/test/scala:test-deps', 'finatra/httpclient/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-server/src/main/scala:scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'finatra/jackson/src/main/scala:scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/streaming-example/src/test/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/thrift-server/build.sbt b/examples/thrift-server/build.sbt index fa5b56a938..f8f1f0c27d 100644 --- a/examples/thrift-server/build.sbt +++ b/examples/thrift-server/build.sbt @@ -3,7 +3,7 @@ import sbt.Keys._ parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" val mockito = "1.9.5" @@ -13,7 +13,7 @@ lazy val versions = new { } lazy val baseSettings = Seq( - version := "2.12.0", + version := "2.13.0", scalaVersion := "2.12.1", ivyScala := ivyScala.value.map(_.copy(overrideScalaVersion = true)), libraryDependencies ++= Seq( diff --git a/examples/thrift-server/thrift-example-server/src/main/scala/BUILD b/examples/thrift-server/thrift-example-server/src/main/scala/BUILD index 1ef33ab1fa..37e7e32247 100644 --- a/examples/thrift-server/thrift-example-server/src/main/scala/BUILD +++ b/examples/thrift-server/thrift-example-server/src/main/scala/BUILD @@ -8,20 +8,25 @@ scala_library( '3rdparty/jvm/net/codingwell:scala-guice', '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-core/src/main/scala', + 'finagle/finagle-http/src/main/scala:scala', + 'finagle/finagle-thriftmux/src/main/scala:scala', 'finatra/examples/thrift-server/thrift-example-idl/src/main/thrift:thrift-scala', + 'finatra/examples/thrift-server/thrift-example-server/src/main/resources', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-server/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/thrift/src/main/scala', 'finatra/thrift/src/main/thrift:thrift-scala', 'scrooge/scrooge-core/src/main/scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/thrift-server/thrift-example-server/src/main/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/thrift-server/thrift-example-server/src/test/scala/BUILD b/examples/thrift-server/thrift-example-server/src/test/scala/BUILD index 7721ba2706..9d8503737e 100644 --- a/examples/thrift-server/thrift-example-server/src/test/scala/BUILD +++ b/examples/thrift-server/thrift-example-server/src/test/scala/BUILD @@ -9,15 +9,18 @@ junit_tests( '3rdparty/jvm/org/slf4j:slf4j-api', 'finatra/examples/thrift-server/thrift-example-idl/src/main/thrift:thrift-scala', 'finatra/examples/thrift-server/thrift-example-server/src/main/scala', + 'finatra/examples/thrift-server/thrift-example-server/src/test/resources', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-server/src/main/scala:scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'finatra/thrift/src/main/scala', 'finatra/thrift/src/main/thrift:thrift-scala', 'finatra/thrift/src/test/scala:test-deps', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/thrift-server/thrift-example-server/src/test/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/tiny-url/build.sbt b/examples/tiny-url/build.sbt index cfa8e5cbc3..066caedefa 100644 --- a/examples/tiny-url/build.sbt +++ b/examples/tiny-url/build.sbt @@ -3,13 +3,13 @@ import com.typesafe.sbt.SbtNativePackager._ packageArchetype.java_application name := "tiny-url" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" fork in run := true parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" val redis = "2.7.2" diff --git a/examples/tiny-url/src/main/scala/BUILD b/examples/tiny-url/src/main/scala/BUILD index c3e05ad0ed..a6dac1545d 100644 --- a/examples/tiny-url/src/main/scala/BUILD +++ b/examples/tiny-url/src/main/scala/BUILD @@ -15,21 +15,24 @@ scala_library( '3rdparty/jvm/org/slf4j:slf4j-api', ':jedis', 'finagle/finagle-http/src/main/scala', + 'finatra/examples/tiny-url/src/main/resources', 'finatra/http/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-server/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/jackson/src/main/scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/tiny-url/src/main/resources', ], excludes = [ exclude(org='org.slf4j', name='slf4j-jdk14') ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/tiny-url/src/test/scala/BUILD b/examples/tiny-url/src/test/scala/BUILD index c9d5918cb6..2fabeac140 100644 --- a/examples/tiny-url/src/test/scala/BUILD +++ b/examples/tiny-url/src/test/scala/BUILD @@ -11,13 +11,15 @@ junit_tests( 'finagle/finagle-http/src/main/scala', 'finatra/examples/tiny-url/src/main/scala', 'finatra/examples/tiny-url/src/main/scala:jedis', + 'finatra/examples/tiny-url/src/test/resources', 'finatra/http/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-server/src/main/scala:scala', 'finatra/inject/inject-server/src/test/scala:test-deps', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/tiny-url/src/test/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/twitter-clone/build.sbt b/examples/twitter-clone/build.sbt index e168302380..df5b9a062a 100644 --- a/examples/twitter-clone/build.sbt +++ b/examples/twitter-clone/build.sbt @@ -1,11 +1,11 @@ name := "twitter-clone" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" } diff --git a/examples/twitter-clone/src/main/scala/BUILD b/examples/twitter-clone/src/main/scala/BUILD index 8b62d5d1b8..b697fd43a4 100644 --- a/examples/twitter-clone/src/main/scala/BUILD +++ b/examples/twitter-clone/src/main/scala/BUILD @@ -13,24 +13,27 @@ scala_library( '3rdparty/jvm/net/codingwell:scala-guice', '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-http/src/main/scala', + 'finatra/examples/twitter-clone/src/main/resources', 'finatra/http/src/main/scala', 'finatra/httpclient/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-server/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-utils/src/main/scala', 'finatra/jackson/src/main/scala', 'finatra/utils/src/main/scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/twitter-clone/src/main/resources', ], excludes = [ exclude(org='org.slf4j', name='slf4j-jdk14') ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/twitter-clone/src/test/scala/BUILD b/examples/twitter-clone/src/test/scala/BUILD index 8c9e14799e..6de4ed37b5 100644 --- a/examples/twitter-clone/src/test/scala/BUILD +++ b/examples/twitter-clone/src/test/scala/BUILD @@ -13,14 +13,17 @@ junit_tests( '3rdparty/jvm/org/specs2:mock', 'finagle/finagle-http/src/main/scala', 'finatra/examples/twitter-clone/src/main/scala', + 'finatra/examples/twitter-clone/src/test/resources', 'finatra/http/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-server/src/main/scala:scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'finatra/jackson/src/main/scala:scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/twitter-clone/src/test/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/examples/web-dashboard/build.sbt b/examples/web-dashboard/build.sbt index a849c6a27e..ecfc2db20c 100644 --- a/examples/web-dashboard/build.sbt +++ b/examples/web-dashboard/build.sbt @@ -2,12 +2,12 @@ import sbt.Keys._ name := "web-dashboard" organization := "com.twitter" -version := "2.12.0" +version := "2.13.0" scalaVersion := "2.12.1" parallelExecution in ThisBuild := false lazy val versions = new { - val finatra = "2.12.0" + val finatra = "2.13.0" val guice = "4.0" val logback = "1.1.7" } diff --git a/examples/web-dashboard/src/main/scala/BUILD b/examples/web-dashboard/src/main/scala/BUILD index 2481220217..b6d8146ea3 100644 --- a/examples/web-dashboard/src/main/scala/BUILD +++ b/examples/web-dashboard/src/main/scala/BUILD @@ -9,21 +9,23 @@ scala_library( '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-http/src/main/scala', 'finagle/finagle-zipkin/src/main/scala', + 'finatra/examples/web-dashboard/src/main/resources', + 'finatra/examples/web-dashboard/src/main/webapp', 'finatra/http/src/main/java', 'finatra/http/src/main/scala', 'finatra/httpclient/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-server/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-thrift-client/src/main/scala', 'finatra/inject/inject-utils/src/main/scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/web-dashboard/src/main/resources', - 'finatra/examples/web-dashboard/src/main/webapp', ], fatal_warnings=True, sources=globs( @@ -31,4 +33,5 @@ scala_library( 'com/twitter/web/dashboard/controllers/*.scala', 'com/twitter/web/dashboard/views/*.scala', ), + strict_deps=True, ) diff --git a/examples/web-dashboard/src/test/scala/BUILD b/examples/web-dashboard/src/test/scala/BUILD index 010eaf5a9c..ace24886ab 100644 --- a/examples/web-dashboard/src/test/scala/BUILD +++ b/examples/web-dashboard/src/test/scala/BUILD @@ -11,16 +11,18 @@ junit_tests( '3rdparty/jvm/org/specs2:mock', 'finagle/finagle-http/src/main/scala', 'finatra/examples/web-dashboard/src/main/scala', + 'finatra/examples/web-dashboard/src/test/resources', 'finatra/http/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-server/src/main/scala:scala', 'finatra/inject/inject-server/src/test/scala:test-deps', 'util/util-slf4j-api/src/main/scala', - 'finatra/examples/web-dashboard/src/test/resources', ], excludes=[ exclude(org='org.slf4j', name='slf4j-jdk14') ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/http/src/main/scala/BUILD b/http/src/main/scala/BUILD index 6434c5c108..2faebb0b8c 100644 --- a/http/src/main/scala/BUILD +++ b/http/src/main/scala/BUILD @@ -16,7 +16,6 @@ scala_library( '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', '3rdparty/jvm/com/google/inject/extensions:guice-multibindings', '3rdparty/jvm/com/google/inject:guice', - '3rdparty/jvm/com/twitter/bijection:util', '3rdparty/jvm/commons-fileupload', '3rdparty/jvm/commons-io', '3rdparty/jvm/commons-lang:commons-lang', @@ -29,10 +28,13 @@ scala_library( '3rdparty/jvm/org/slf4j:jul-to-slf4j', '3rdparty/jvm/org/slf4j:log4j-over-slf4j', '3rdparty/jvm/org/slf4j:slf4j-api', + 'finagle/finagle-base-http/src/main/scala:scala', 'finagle/finagle-core/src/main/scala', 'finagle/finagle-exp/src/main/scala', 'finagle/finagle-http/src/main/scala', + 'finagle/finagle-netty3/src/main/scala:scala', 'finatra/http/src/main/java', + 'finatra/http/src/main/resources', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-modules/src/main/scala', @@ -46,15 +48,23 @@ scala_library( 'util/util-app/src/main/scala', 'util/util-collection/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', 'util/util-stats/src/main/scala', - 'finatra/http/src/main/resources', - 'finagle/finagle-base-http/src/main/scala:scala', - 'finagle/finagle-netty3/src/main/scala:scala', - 'util/util-lint/src/main/scala:scala', ], fatal_warnings=True, sources=rglobs('*.scala'), strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + 'finagle/finagle-base-http/src/main/scala:scala', + 'finagle/finagle-core/src/main/scala:scala', + 'finagle/finagle-http/src/main/scala:scala', + 'finatra/inject/inject-app/src/main/scala:scala', + 'finatra/utils/src/main/java:java', + 'finatra/utils/src/main/scala', + 'util/util-app/src/main/scala:scala', + 'util/util-core/src/main/scala:scala', + ] ) diff --git a/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/CallbackConverter.scala b/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/CallbackConverter.scala index 9e1aa7b634..1709a5d90d 100644 --- a/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/CallbackConverter.scala +++ b/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/CallbackConverter.scala @@ -1,17 +1,15 @@ package com.twitter.finatra.http.internal.marshalling -import com.twitter.bijection.Conversion._ -import com.twitter.bijection.twitter_util.TwitterExecutionContext -import com.twitter.bijection.twitter_util.UtilBijections.twitter2ScalaFuture import com.twitter.concurrent.AsyncStream import com.twitter.finagle.http._ import com.twitter.finatra.http.response.{ResponseBuilder, StreamingResponse} import com.twitter.finatra.json.FinatraObjectMapper import com.twitter.finatra.json.internal.streaming.JsonStreamParser import com.twitter.io.Buf -import com.twitter.util.{Future, FuturePool} +import com.twitter.util.{FuturePool, Promise, Future} import javax.inject.Inject -import scala.concurrent.{Future => ScalaFuture} +import scala.concurrent.{Future => ScalaFuture, ExecutionContext => ScalaExecutionContext} +import scala.util.{Success, Failure} private[http] class CallbackConverter @Inject()( messageBodyManager: MessageBodyManager, @@ -110,16 +108,17 @@ private[http] class CallbackConverter @Inject()( response.headerMap.add(Fields.ContentType, responseBuilder.jsonContentType) Future.value(response) } else if (runtimeClassEq[ResponseType, ScalaFuture[_]]) { - implicit val ec = immediatePoolEc - def toTwitterFuture[A](in: ScalaFuture[A]) = in.as[Future[A]] - if (isScalaFutureOption[ResponseType]) { val fn = (request: Request) => - toTwitterFuture(requestCallback.asInstanceOf[Request => ScalaFuture[Option[_]]](request)) + toTwitterFuture( + requestCallback + .asInstanceOf[Request => ScalaFuture[Option[_]]](request))(immediatePoolExcCtx) createResponseCallback(fn) } else { val fn = (request: Request) => - toTwitterFuture(requestCallback.asInstanceOf[Request => ScalaFuture[_]](request)) + toTwitterFuture( + requestCallback + .asInstanceOf[Request => ScalaFuture[_]](request))(immediatePoolExcCtx) createResponseCallback(fn) } } else { request: Request => @@ -181,9 +180,41 @@ private[http] class CallbackConverter @Inject()( typeArgs.head.runtimeClass == classOf[Option[_]] } - // Ideally, it would be up to the user to determine where next to run their code but exposing that explicitly would be very difficult - // just for addressing this case. By using the `c.t.util.FuturePool.immediatePool`, the user will still have control over the thread - // pool at least tangentially in that whatever thread satisfied the Future (Promise) is where the bijection conversion will be run - // (and presumably whatever comes after since we use a thread local scheduler by default). - private[this] val immediatePoolEc = new TwitterExecutionContext(FuturePool.immediatePool) + private def toTwitterFuture[A](scalaFuture: ScalaFuture[A]) + (implicit executor: ScalaExecutionContext): Future[A] = { + val p = new Promise[A]() + scalaFuture.onComplete { + case Success(value) => p.setValue(value) + case Failure(exception) => p.setException(exception) + } + p + } + + // Ideally, it would be up to the user to determine where next to run their code + // but exposing that explicitly would be very difficult just for addressing this case. + // By using the `c.t.util.FuturePool.immediatePool`, the user will still have control + // over the thread pool at least tangentially in that whatever thread satisfied the + // Future (Promise) is where the Future conversion will be run (and presumably whatever comes + // after since we use a thread local scheduler by default). + private[this] val immediatePoolExcCtx = new ExecutionContext(FuturePool.immediatePool) + + /** ExecutionContext adapter using a FuturePool; see bijection/TwitterExecutionContext */ + private[this] class ExecutionContext( + pool: FuturePool, + report: Throwable => Unit + ) extends ScalaExecutionContext { + def this(pool: FuturePool) = this(pool, ExecutionContext.ignore) + override def execute(runnable: Runnable): Unit = { + pool(runnable.run()) + () + } + + override def reportFailure(t: Throwable): Unit = report(t) + } + + private[this] object ExecutionContext { + private def ignore(throwable: Throwable): Unit = { + // do nothing + } + } } diff --git a/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/MessageBodyManager.scala b/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/MessageBodyManager.scala index e6ea1dc1a7..d7a9e4f4ad 100644 --- a/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/MessageBodyManager.scala +++ b/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/MessageBodyManager.scala @@ -4,12 +4,12 @@ import com.twitter.finagle.http.Request import com.twitter.finatra.http.marshalling._ import com.twitter.inject.Injector import com.twitter.inject.TypeUtils.singleTypeParam +import com.twitter.inject.conversions.map._ import java.lang.annotation.Annotation import java.lang.reflect.Type import java.util.concurrent.ConcurrentHashMap import javax.inject.{Inject, Singleton} import net.codingwell.scalaguice._ -import scala.collection.JavaConverters._ import scala.collection.mutable import scala.reflect.ScalaSignature @@ -25,8 +25,8 @@ class MessageBodyManager @Inject()( private val annotationTypeToWriter = mutable.Map[Type, MessageBodyWriter[Any]]() private val readerCache = - new ConcurrentHashMap[Manifest[_], Option[MessageBodyReader[Any]]]().asScala - private val writerCache = new ConcurrentHashMap[Any, MessageBodyWriter[Any]]().asScala + new ConcurrentHashMap[Manifest[_], Option[MessageBodyReader[Any]]]() + private val writerCache = new ConcurrentHashMap[Any, MessageBodyWriter[Any]]() /* Public (Config methods called during server startup) */ @@ -69,7 +69,7 @@ class MessageBodyManager @Inject()( def read[T: Manifest](request: Request): T = { val requestManifest = manifest[T] - readerCache.getOrElseUpdate(requestManifest, { + readerCache.atomicGetOrElseUpdate(requestManifest, { val objType = typeLiteral(requestManifest).getType classTypeToReader.get(objType) orElse findReaderBySuperType(objType) }) match { @@ -91,7 +91,7 @@ class MessageBodyManager @Inject()( // Note: writerCache is bounded on the number of unique classes returned from controller routes */ def writer(obj: Any): MessageBodyWriter[Any] = { val objClass = obj.getClass - writerCache.getOrElseUpdate(objClass, { + writerCache.atomicGetOrElseUpdate(objClass, { (classTypeToWriter .get(objClass) orElse classAnnotationToWriter(objClass)) getOrElse defaultMessageBodyWriter }) diff --git a/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/mustache/MustacheTemplateNameLookup.scala b/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/mustache/MustacheTemplateNameLookup.scala index 6ef0668615..d0f31e6b0a 100644 --- a/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/mustache/MustacheTemplateNameLookup.scala +++ b/http/src/main/scala/com/twitter/finatra/http/internal/marshalling/mustache/MustacheTemplateNameLookup.scala @@ -2,14 +2,14 @@ package com.twitter.finatra.http.internal.marshalling.mustache import com.twitter.finatra.http.marshalling.mustache.MustacheBodyComponent import com.twitter.finatra.response.Mustache +import com.twitter.inject.conversions.map._ import java.util.concurrent.ConcurrentHashMap import javax.inject.Singleton -import scala.collection.JavaConverters._ @Singleton private[finatra] class MustacheTemplateNameLookup { - private val classToTemplateNameCache = new ConcurrentHashMap[Class[_], String]().asScala + private val classToTemplateNameCache = new ConcurrentHashMap[Class[_], String]() /* Public */ @@ -24,7 +24,7 @@ private[finatra] class MustacheTemplateNameLookup { /* Private */ private def lookupViaAnnotation(viewObj: Any): String = { - classToTemplateNameCache.getOrElseUpdate(viewObj.getClass, { + classToTemplateNameCache.atomicGetOrElseUpdate(viewObj.getClass, { val mustacheAnnotation = viewObj.getClass.getAnnotation(classOf[Mustache]) mustacheAnnotation.value + ".mustache" }) diff --git a/http/src/main/scala/com/twitter/finatra/http/response/StreamingResponse.scala b/http/src/main/scala/com/twitter/finatra/http/response/StreamingResponse.scala index 9f81b5f90e..2f830654c8 100644 --- a/http/src/main/scala/com/twitter/finatra/http/response/StreamingResponse.scala +++ b/http/src/main/scala/com/twitter/finatra/http/response/StreamingResponse.scala @@ -102,8 +102,7 @@ class StreamingResponse[T] private ( /* Orphan the future which writes to our response thread */ (for { _ <- writePrefix(writer) - bufs = asyncStream().map(toBuf) - _ <- addSeparatorIfPresent(bufs).foreachF(writer.write) + _ <- addSeparatorIfPresent(asyncStream().map(toBuf)).foreachF(writer.write) result <- writeSuffix(writer) } yield result) onSuccess { r => debug("Success writing to chunked response") @@ -128,13 +127,13 @@ class StreamingResponse[T] private ( case None => Future.Unit } - private[this] def addSeparatorIfPresent(stream: AsyncStream[Buf]): AsyncStream[Buf] = + private[this] def addSeparatorIfPresent(stream: => AsyncStream[Buf]): AsyncStream[Buf] = separator match { case Some(sep) => addSeparator(stream, sep) case None => stream } - private[this] def addSeparator(stream: AsyncStream[Buf], separator: Buf): AsyncStream[Buf] = { + private[this] def addSeparator(stream: => AsyncStream[Buf], separator: Buf): AsyncStream[Buf] = { stream.take(1) ++ (stream.drop(1).map { buf => separator.concat(buf) }) @@ -146,3 +145,4 @@ class StreamingResponse[T] private ( } } } + diff --git a/http/src/test/java/BUILD b/http/src/test/java/BUILD index 0bfcce6c10..590f5845ed 100644 --- a/http/src/test/java/BUILD +++ b/http/src/test/java/BUILD @@ -10,6 +10,7 @@ junit_tests( 'finagle/finagle-http/src/main/scala', 'finatra/http/src/main/java', 'finatra/http/src/main/scala', + 'finatra/http/src/test/resources', 'finatra/http/src/test/scala:test-deps', 'finatra/httpclient/src/main/scala', 'finatra/inject/inject-app/src/main/scala', @@ -26,11 +27,11 @@ junit_tests( 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', 'util/util-stats/src/main/scala', - 'finatra/http/src/test/resources', ], fatal_warnings=False, sources=rglobs( 'com/twitter/finatra/http/*.java', 'com/twitter/finatra/test/*.java', ), + strict_deps=True, ) diff --git a/http/src/test/scala/BUILD b/http/src/test/scala/BUILD index 7006e4a9a4..b44929b9df 100644 --- a/http/src/test/scala/BUILD +++ b/http/src/test/scala/BUILD @@ -30,7 +30,9 @@ junit_tests( 'finatra/http/src/main/java', 'finatra/http/src/main/scala', 'finatra/http/src/test/java', + 'finatra/http/src/test/resources', 'finatra/http/src/test/scala:test-deps', + 'finatra/http/src/test/webapp', 'finatra/httpclient/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-app/src/test/scala:test-deps', @@ -41,6 +43,7 @@ junit_tests( 'finatra/inject/inject-request-scope/src/main/scala', 'finatra/inject/inject-server/src/main/scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-utils/src/main/scala', 'finatra/jackson/src/main/scala', 'finatra/jackson/src/test/scala:test-deps', @@ -49,15 +52,15 @@ junit_tests( 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', 'util/util-stats/src/main/scala', - 'finatra/http/src/test/resources', - 'finatra/http/src/test/webapp', ], sources=rglobs( 'com/twitter/finatra/http/tests/*.scala', - ) + ), + strict_deps=True, ) scala_library(name="test-deps", @@ -88,6 +91,7 @@ scala_library(name="test-deps", 'finatra/inject/inject-server/src/test/scala:test-deps', 'finatra/jackson/src/main/scala', 'finatra/jackson/src/test/scala:test-deps', + 'twitter-server/src/main/scala:scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', ], @@ -95,4 +99,9 @@ scala_library(name="test-deps", sources=globs( 'com/twitter/finatra/http/*.scala' ), + strict_deps=True, + exports=[ + 'finatra/http/src/main/scala', + 'finatra/inject/inject-server/src/test/scala:test-deps', + ], ) diff --git a/http/src/test/scala/com/twitter/finatra/http/EmbeddedHttpServer.scala b/http/src/test/scala/com/twitter/finatra/http/EmbeddedHttpServer.scala index 0045a89ca0..0def10f0bb 100644 --- a/http/src/test/scala/com/twitter/finatra/http/EmbeddedHttpServer.scala +++ b/http/src/test/scala/com/twitter/finatra/http/EmbeddedHttpServer.scala @@ -39,6 +39,7 @@ import scala.util.control.NonFatal * @param disableTestLogging Disable all logging emitted from the test infrastructure. * @param maxStartupTimeSeconds Maximum seconds to wait for embedded server to start. If exceeded a * [[com.twitter.inject.app.StartupTimeoutException]] is thrown. + * @param failOnLintViolation If server startup should fail due (and thus the test) to a detected lint rule issue after startup. */ class EmbeddedHttpServer( val twitterServer: Ports, @@ -54,7 +55,8 @@ class EmbeddedHttpServer( streamResponse: Boolean = false, verbose: Boolean = false, disableTestLogging: Boolean = false, - maxStartupTimeSeconds: Int = 60 + maxStartupTimeSeconds: Int = 60, + failOnLintViolation: Boolean = false ) extends EmbeddedTwitterServer( twitterServer = twitterServer, flags = flags + (httpPortFlag -> ephemeralLoopback), @@ -66,7 +68,8 @@ class EmbeddedHttpServer( streamResponse = streamResponse, verbose = verbose, disableTestLogging = disableTestLogging, - maxStartupTimeSeconds = maxStartupTimeSeconds + maxStartupTimeSeconds = maxStartupTimeSeconds, + failOnLintViolation = failOnLintViolation ) { /* Additional Constructors */ diff --git a/http/src/test/scala/com/twitter/finatra/http/tests/integration/doeverything/test/DoEverythingServerFeatureTest.scala b/http/src/test/scala/com/twitter/finatra/http/tests/integration/doeverything/test/DoEverythingServerFeatureTest.scala index a6d91a49ba..6660d4eb4f 100644 --- a/http/src/test/scala/com/twitter/finatra/http/tests/integration/doeverything/test/DoEverythingServerFeatureTest.scala +++ b/http/src/test/scala/com/twitter/finatra/http/tests/integration/doeverything/test/DoEverythingServerFeatureTest.scala @@ -8,6 +8,7 @@ import com.twitter.finagle.http.Method._ import com.twitter.finagle.http.Status._ import com.twitter.finagle.http._ import com.twitter.finatra.http.EmbeddedHttpServer +import com.twitter.finagle.http.codec.HttpCodec import com.twitter.finatra.http.tests.integration.doeverything.main.DoEverythingServer import com.twitter.finatra.http.tests.integration.doeverything.main.domain.SomethingStreamedResponse import com.twitter.finatra.http.tests.integration.doeverything.main.services.DoEverythingService @@ -30,7 +31,7 @@ class DoEverythingServerFeatureTest extends FeatureTest { def deserializeRequest(name: String) = { val requestBytes = IOUtils.toByteArray(getClass.getResourceAsStream(name)) - Request.decodeBytes(requestBytes) + HttpCodec.decodeBytesToRequest(requestBytes) } def counter(key: String): Long = { diff --git a/http/src/test/scala/com/twitter/finatra/http/tests/request/MultiParamsTest.scala b/http/src/test/scala/com/twitter/finatra/http/tests/request/MultiParamsTest.scala index 7a155e3e1a..091abba1ea 100644 --- a/http/src/test/scala/com/twitter/finatra/http/tests/request/MultiParamsTest.scala +++ b/http/src/test/scala/com/twitter/finatra/http/tests/request/MultiParamsTest.scala @@ -2,6 +2,7 @@ package com.twitter.finatra.http.tests.request import com.twitter.finagle.http.{Method, Request} import com.twitter.finagle.{http => finagle} +import com.twitter.finagle.http.codec.HttpCodec import com.twitter.finatra.http.fileupload.MultipartItem import com.twitter.finatra.http.request.RequestUtils import com.twitter.inject.Test @@ -28,7 +29,7 @@ class MultiParamsTest extends Test with Mockito { val fileUploadFileBytes = resourceAsBytes("/multipart/dealwithit.gif") val requestAsBytes = resourceAsBytes("/multipart/upload.bytes") - val finagleRequest = finagle.Request.decodeBytes(requestAsBytes) + val finagleRequest = HttpCodec.decodeBytesToRequest(requestAsBytes) val expectedMultiParams = Map[String, MultipartItem]( "type" -> MultipartItem( @@ -68,7 +69,7 @@ class MultiParamsTest extends Test with Mockito { test("handle MS Surface Upload with quoted boundary") { val fileUploadFileBytes = resourceAsBytes("/multipart/TempProfileImageCrop.png") val requestAsBytes = resourceAsBytes("/multipart/ms-surface.bytes") - val finagleRequest = finagle.Request.decodeBytes(requestAsBytes) + val finagleRequest = HttpCodec.decodeBytesToRequest(requestAsBytes) val expectedMultiParams = Map[String, MultipartItem]( "banner" -> MultipartItem( @@ -89,7 +90,7 @@ class MultiParamsTest extends Test with Mockito { test("handle Iphone Upload with multiple boundaries") { val fileUploadFileBytes = resourceAsBytes("/multipart/image.jpg") val requestAsBytes = resourceAsBytes("/multipart/request-POST-iphone.bytes") - val finagleRequest = finagle.Request.decodeBytes(requestAsBytes) + val finagleRequest = HttpCodec.decodeBytesToRequest(requestAsBytes) val expectedMultiParams = Map[String, MultipartItem]( "offset_top" -> MultipartItem( @@ -153,7 +154,7 @@ class MultiParamsTest extends Test with Mockito { test("Android Upload with multiple boundaries") { val fileUploadFileBytes = resourceAsBytes("/multipart/kM1K5C4p") val requestAsBytes = resourceAsBytes("/multipart/request-POST-android.bytes") - val finagleRequest = finagle.Request.decodeBytes(requestAsBytes) + val finagleRequest = HttpCodec.decodeBytesToRequest(requestAsBytes) val expectedMultiParams = Map[String, MultipartItem]( "banner" -> MultipartItem( @@ -177,7 +178,7 @@ class MultiParamsTest extends Test with Mockito { test("invalid upload data") { val requestAsBytes = resourceAsBytes("/multipart/request-POST-android.bytes") - val finagleRequest = finagle.Request.decodeBytes(requestAsBytes) + val finagleRequest = HttpCodec.decodeBytesToRequest(requestAsBytes) finagleRequest.setContentType("text/html; bounfoodary=foo; charset=UTF-8\"") assertMultiParamsEmpty(finagleRequest) diff --git a/httpclient/src/main/scala/BUILD b/httpclient/src/main/scala/BUILD index f600a4b78b..fa4ea26e47 100644 --- a/httpclient/src/main/scala/BUILD +++ b/httpclient/src/main/scala/BUILD @@ -5,6 +5,7 @@ scala_library( repo = artifactory, ), dependencies=[ + '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', '3rdparty/jvm/com/google/guava:guava', '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', '3rdparty/jvm/com/google/inject/extensions:guice-multibindings', @@ -16,11 +17,17 @@ scala_library( 'finagle/finagle-core/src/main/scala', 'finagle/finagle-http/src/main/scala', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-utils/src/main/scala', 'finatra/jackson/src/main/scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', ], fatal_warnings=True, - sources=rglobs('*.scala') + sources=rglobs('*.scala'), + strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + '3rdparty/jvm/net/codingwell:scala-guice', + ] ) diff --git a/httpclient/src/main/scala/com/twitter/finatra/httpclient/HttpClient.scala b/httpclient/src/main/scala/com/twitter/finatra/httpclient/HttpClient.scala index a1337899e4..5cd76c1d39 100644 --- a/httpclient/src/main/scala/com/twitter/finatra/httpclient/HttpClient.scala +++ b/httpclient/src/main/scala/com/twitter/finatra/httpclient/HttpClient.scala @@ -10,7 +10,14 @@ import com.twitter.inject.utils.RetryUtils import com.twitter.util.{Future, Try} /** - * A simple HTTP client + * A simple HTTP client. + * + * @note Some servers won't handle requests properly if the Host header is not set + * @param hostname the hostname that will be used for the Host header. Leave as default or set as "" to not set a Host header + * @param httpService underlying `com.twitter.finagle.Service` + * @param retryPolicy optional retry policy if the service fails to get a successful response + * @param defaultHeaders headers to add to every request + * @param mapper object mapper [[com.twitter.finatra.json.FinatraObjectMapper]] */ class HttpClient( hostname: String = "", diff --git a/httpclient/src/main/scala/com/twitter/finatra/httpclient/modules/HttpClientModule.scala b/httpclient/src/main/scala/com/twitter/finatra/httpclient/modules/HttpClientModule.scala index 5214280745..81b8f82228 100644 --- a/httpclient/src/main/scala/com/twitter/finatra/httpclient/modules/HttpClientModule.scala +++ b/httpclient/src/main/scala/com/twitter/finatra/httpclient/modules/HttpClientModule.scala @@ -14,6 +14,7 @@ abstract class HttpClientModule extends TwitterModule { def dest: String + // override and set to a non-empty value if the dest requires a Host header def hostname: String = "" def retryPolicy: Option[RetryPolicy[Try[Response]]] = None diff --git a/httpclient/src/test/scala/BUILD b/httpclient/src/test/scala/BUILD index f5d0c199e0..f56bd3ece1 100644 --- a/httpclient/src/test/scala/BUILD +++ b/httpclient/src/test/scala/BUILD @@ -15,6 +15,7 @@ junit_tests( 'finagle/finagle-core/src/main/scala', 'finagle/finagle-http/src/main/scala', 'finatra/httpclient/src/main/scala', + 'finatra/httpclient/src/test/resources', 'finatra/httpclient/src/test/scala:test-deps', 'finatra/inject/inject-app/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', @@ -23,11 +24,11 @@ junit_tests( 'twitter-server/src/main/scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/httpclient/src/test/resources', ], sources=globs( 'com/twitter/finatra/httpclient/*.scala' ), + strict_deps=True, ) scala_library(name="test-deps", @@ -43,6 +44,7 @@ scala_library(name="test-deps", 'finatra/inject/inject-app/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', ], @@ -50,4 +52,5 @@ scala_library(name="test-deps", sources=globs( 'com/twitter/finatra/httpclient/test/*.scala' ), + strict_deps=True, ) diff --git a/inject-thrift-client-http-mapper/src/main/scala/BUILD b/inject-thrift-client-http-mapper/src/main/scala/BUILD index d4a2ae8ef3..24b6cdd375 100644 --- a/inject-thrift-client-http-mapper/src/main/scala/BUILD +++ b/inject-thrift-client-http-mapper/src/main/scala/BUILD @@ -14,6 +14,7 @@ scala_library( 'finagle/finagle-http/src/main/scala', 'finatra/http/src/main/scala', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-thrift-client/src/main/scala', 'finatra/inject/inject-utils/src/main/scala', 'scrooge/scrooge-core/src/main/scala', @@ -21,4 +22,9 @@ scala_library( ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + '3rdparty/jvm/net/codingwell:scala-guice', + ], ) diff --git a/inject-thrift-client-http-mapper/src/test/scala/BUILD b/inject-thrift-client-http-mapper/src/test/scala/BUILD index d324e486eb..04e01898e6 100644 --- a/inject-thrift-client-http-mapper/src/test/scala/BUILD +++ b/inject-thrift-client-http-mapper/src/test/scala/BUILD @@ -13,16 +13,20 @@ junit_tests( '3rdparty/jvm/org/specs2:mock', 'finagle/finagle-core/src/main/scala', 'finagle/finagle-http/src/main/scala', + 'finagle/finagle-thrift/src/main/scala:scala', + 'finagle/finagle-thriftmux/src/main/scala:scala', 'finatra/http/src/main/scala', 'finatra/http/src/test/scala:test-deps', 'finatra/httpclient/src/main/scala', 'finatra/inject-thrift-client-http-mapper/src/main/scala', + 'finatra/inject-thrift-client-http-mapper/src/test/resources', 'finatra/inject-thrift-client-http-mapper/src/test/thrift:thrift-scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', 'finatra/inject/inject-server/src/main/scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-thrift-client/src/main/scala', 'finatra/jackson/src/main/scala', 'finatra/thrift/src/main/scala', @@ -32,11 +36,12 @@ junit_tests( 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', 'util/util-stats/src/main/scala', - 'finatra/inject-thrift-client-http-mapper/src/test/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/inject/inject-app/src/main/scala/BUILD b/inject/inject-app/src/main/scala/BUILD index 3c8c417969..88ce877bf1 100644 --- a/inject/inject-app/src/main/scala/BUILD +++ b/inject/inject-app/src/main/scala/BUILD @@ -15,10 +15,10 @@ scala_library( '3rdparty/jvm/org/joda:joda-convert', '3rdparty/jvm/org/slf4j:slf4j-api', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/inject/inject-slf4j/src/main/scala:scala', ], fatal_warnings=True, sources=rglobs('*.scala'), @@ -26,4 +26,9 @@ scala_library( 'finatra/inject/inject-app/src/main/java', ], strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + '3rdparty/jvm/net/codingwell:scala-guice', + ] + ) diff --git a/inject/inject-app/src/test/scala/BUILD b/inject/inject-app/src/test/scala/BUILD index 06e5c6fbdf..ab2b08e816 100644 --- a/inject/inject-app/src/test/scala/BUILD +++ b/inject/inject-app/src/test/scala/BUILD @@ -14,6 +14,7 @@ junit_tests( 'finatra/inject/inject-app/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', @@ -23,6 +24,7 @@ junit_tests( 'com/twitter/inject/app/tests/*.scala', 'com/twitter/inject/app/tests/internal/*.scala' ), + strict_deps=True, ) scala_library(name="test-deps", @@ -33,18 +35,18 @@ scala_library(name="test-deps", ), dependencies=[ '//:scala-reflect', + '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', '3rdparty/jvm/com/google/inject/extensions:guice-multibindings', '3rdparty/jvm/com/google/inject/extensions:guice-testlib', '3rdparty/jvm/com/google/inject:guice', '3rdparty/jvm/net/codingwell:scala-guice', + '3rdparty/jvm/org/slf4j:jcl-over-slf4j', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'util/util-app/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/inject/inject-slf4j/src/main/scala:scala', - '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', - '3rdparty/jvm/org/slf4j:jcl-over-slf4j', ], fatal_warnings=True, sources=globs( diff --git a/inject/inject-core/src/main/scala/BUILD b/inject/inject-core/src/main/scala/BUILD index 8175973189..1f722acaf1 100644 --- a/inject/inject-core/src/main/scala/BUILD +++ b/inject/inject-core/src/main/scala/BUILD @@ -5,6 +5,8 @@ scala_library( repo = artifactory, ), dependencies=[ + '//:scala-reflect', + '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', '3rdparty/jvm/com/google/inject/extensions:guice-multibindings', '3rdparty/jvm/com/google/inject:guice', @@ -15,9 +17,14 @@ scala_library( 'finatra/inject/inject-slf4j/src/main/scala', 'util/util-app/src/main/scala', 'util/util-slf4j-api/src/main/scala', - '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', ], fatal_warnings=True, sources=rglobs('*.scala'), strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + '3rdparty/jvm/net/codingwell:scala-guice', + 'finatra/inject/inject-slf4j/src/main/scala', + 'util/util-app/src/main/scala:scala', + ] ) diff --git a/inject/inject-core/src/test/scala/BUILD b/inject/inject-core/src/test/scala/BUILD index 8871810b3f..36fea97d1f 100644 --- a/inject/inject-core/src/test/scala/BUILD +++ b/inject/inject-core/src/test/scala/BUILD @@ -19,7 +19,8 @@ junit_tests( fatal_warnings=True, sources=rglobs( 'com/twitter/inject/tests/*.scala', - ) + ), + strict_deps=True, ) scala_library(name="test-deps", @@ -41,6 +42,7 @@ scala_library(name="test-deps", '3rdparty/jvm/org/slf4j:slf4j-api', '3rdparty/jvm/org/specs2:mock', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', ], @@ -51,5 +53,14 @@ scala_library(name="test-deps", ), java_sources=[ 'finatra/inject/inject-core/src/test/java' + ], + strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + '3rdparty/jvm/joda-time:joda-time', + '3rdparty/jvm/junit:junit', + '3rdparty/jvm/org/scalatest:scalatest', + '3rdparty/jvm/org/specs2:mock', + 'util/util-core/src/main/scala:scala', ] ) diff --git a/inject/inject-modules/src/main/scala/BUILD b/inject/inject-modules/src/main/scala/BUILD index ec0b8b5f77..b009be5426 100644 --- a/inject/inject-modules/src/main/scala/BUILD +++ b/inject/inject-modules/src/main/scala/BUILD @@ -5,6 +5,7 @@ scala_library( repo = artifactory, ), dependencies=[ + '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', '3rdparty/jvm/com/google/inject/extensions:guice-multibindings', '3rdparty/jvm/com/google/inject:guice', @@ -12,14 +13,17 @@ scala_library( '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-core/src/main/scala', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', + 'util/util-app/src/main/scala:scala', 'util/util-slf4j-api/src/main/scala', 'util/util-slf4j-jul-bridge/src/main/scala', 'util/util-stats/src/main/scala', - 'finatra/inject/inject-slf4j/src/main/scala:scala', - '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', - 'util/util-app/src/main/scala:scala', ], fatal_warnings=True, sources=rglobs('*.scala'), strict_deps=True, + exports=[ + '3rdparty/jvm/net/codingwell:scala-guice', + ] + ) diff --git a/inject/inject-modules/src/test/scala/BUILD b/inject/inject-modules/src/test/scala/BUILD index 9846c51d02..4ce45eda0a 100644 --- a/inject/inject-modules/src/test/scala/BUILD +++ b/inject/inject-modules/src/test/scala/BUILD @@ -20,6 +20,7 @@ junit_tests( sources=globs( 'com/twitter/inject/modules/tests/*.scala', ), + strict_deps=True, ) scala_library(name="test-deps", @@ -41,5 +42,6 @@ scala_library(name="test-deps", fatal_warnings=True, sources=globs( 'com/twitter/inject/modules/*.scala', - ) + ), + strict_deps=True, ) diff --git a/inject/inject-request-scope/src/main/scala/BUILD b/inject/inject-request-scope/src/main/scala/BUILD index 7457f793a7..7538be0f27 100644 --- a/inject/inject-request-scope/src/main/scala/BUILD +++ b/inject/inject-request-scope/src/main/scala/BUILD @@ -5,6 +5,7 @@ scala_library( repo = artifactory, ), dependencies=[ + '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', '3rdparty/jvm/com/google/inject/extensions:guice-multibindings', '3rdparty/jvm/com/google/inject:guice', @@ -13,11 +14,10 @@ scala_library( '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-core/src/main/scala', 'finatra/inject/inject-core/src/main/scala', - 'util/util-core/src/main/scala', - 'util/util-slf4j-api/src/main/scala', 'finatra/inject/inject-slf4j/src/main/scala:scala', - '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', 'util/util-app/src/main/scala:scala', + 'util/util-core/src/main/scala', + 'util/util-slf4j-api/src/main/scala', ], fatal_warnings=True, sources=rglobs('*.scala'), @@ -25,4 +25,9 @@ scala_library( 'finatra/inject/inject-request-scope/src/main/java', ], strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + '3rdparty/jvm/net/codingwell:scala-guice', + ] + ) diff --git a/inject/inject-request-scope/src/test/scala/BUILD b/inject/inject-request-scope/src/test/scala/BUILD index 972d573f20..ca5405b885 100644 --- a/inject/inject-request-scope/src/test/scala/BUILD +++ b/inject/inject-request-scope/src/test/scala/BUILD @@ -13,10 +13,11 @@ junit_tests( 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', 'finatra/inject/inject-request-scope/src/main/scala', + 'finatra/inject/inject-request-scope/src/test/resources', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/inject/inject-request-scope/src/test/resources', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/inject/inject-server/src/main/scala/BUILD b/inject/inject-server/src/main/scala/BUILD index 189df17e47..15d76fc9bb 100644 --- a/inject/inject-server/src/main/scala/BUILD +++ b/inject/inject-server/src/main/scala/BUILD @@ -5,30 +5,38 @@ scala_library( repo = artifactory, ), dependencies=[ + '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', '3rdparty/jvm/com/google/inject/extensions:guice-multibindings', '3rdparty/jvm/com/google/inject:guice', '3rdparty/jvm/net/codingwell:scala-guice', '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-core/src/main/scala', + 'finagle/finagle-http/src/main/scala:scala', 'finagle/finagle-stats/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-modules/src/main/scala', + 'finatra/inject/inject-server/src/main/resources', 'finatra/inject/inject-slf4j/src/main/scala', 'finatra/inject/inject-utils/src/main/scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', 'util/util-stats/src/main/scala', - 'finatra/inject/inject-server/src/main/resources', - '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', - 'finagle/finagle-http/src/main/scala:scala', - 'util/util-lint/src/main/scala:scala', ], fatal_warnings=True, sources=rglobs('*.scala'), strict_deps=True, + exports=[ + '3rdparty/jvm/net/codingwell:scala-guice', + 'finatra/inject/inject-app/src/main/scala', + 'finatra/inject/inject-utils/src/main/scala:scala', + 'twitter-server/src/main/scala', + 'util/util-app/src/main/scala:scala', + 'util/util-core/src/main/scala:scala', + ] ) diff --git a/inject/inject-server/src/test/scala/BUILD b/inject/inject-server/src/test/scala/BUILD index c0a782c2b1..921d3373ee 100644 --- a/inject/inject-server/src/test/scala/BUILD +++ b/inject/inject-server/src/test/scala/BUILD @@ -19,9 +19,11 @@ junit_tests( 'finatra/inject/inject-core/src/test/scala:test-deps', 'finatra/inject/inject-server/src/main/scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-registry/src/main/scala', 'util/util-slf4j-api/src/main/scala', @@ -30,6 +32,7 @@ junit_tests( sources=globs( 'com/twitter/server/tests/*.scala', 'com/twitter/inject/server/tests/*.scala'), + strict_deps=True, ) scala_library(name="test-deps", @@ -69,4 +72,8 @@ scala_library(name="test-deps", ], fatal_warnings=True, sources=globs('com/twitter/inject/server/*.scala'), + strict_deps=True, + exports=[ + 'util/util-core/src/main/scala:scala', + ] ) diff --git a/inject/inject-server/src/test/scala/com/twitter/inject/server/EmbeddedTwitterServer.scala b/inject/inject-server/src/test/scala/com/twitter/inject/server/EmbeddedTwitterServer.scala index 3d418be037..7998a8bb94 100644 --- a/inject/inject-server/src/test/scala/com/twitter/inject/server/EmbeddedTwitterServer.scala +++ b/inject/inject-server/src/test/scala/com/twitter/inject/server/EmbeddedTwitterServer.scala @@ -4,11 +4,12 @@ import com.google.common.net.{HttpHeaders, MediaType} import com.google.inject.Stage import com.twitter.conversions.time._ import com.twitter.finagle.builder.ClientBuilder -import com.twitter.finagle.http.{Http => _, _} +import com.twitter.finagle.http._ +import com.twitter.finagle.http.codec.HttpCodec import com.twitter.finagle.service.Backoff._ import com.twitter.finagle.service.RetryPolicy import com.twitter.finagle.service.RetryPolicy._ -import com.twitter.finagle.stats.{InMemoryStatsReceiver, NullStatsReceiver, StatsReceiver} +import com.twitter.finagle.stats.{InMemoryStatsReceiver, StatsReceiver} import com.twitter.finagle.{ChannelClosedException, Http, Service} import com.twitter.inject.PoolUtils import com.twitter.inject.app.{ @@ -21,6 +22,7 @@ import com.twitter.inject.modules.InMemoryStatsReceiverModule import com.twitter.inject.server.EmbeddedTwitterServer._ import com.twitter.inject.server.PortUtils._ import com.twitter.server.AdminHttpServer +import com.twitter.util.lint.{Rule, GlobalRules} import com.twitter.util.{Await, Duration, Future, Stopwatch, Try} import java.lang.annotation.Annotation import java.net.{InetSocketAddress, URI} @@ -68,6 +70,7 @@ object EmbeddedTwitterServer { * @param disableTestLogging Disable all logging emitted from the test infrastructure. * @param maxStartupTimeSeconds Maximum seconds to wait for embedded server to start. If exceeded a * [[com.twitter.inject.app.StartupTimeoutException]] is thrown. + * @param failOnLintViolation If server startup should fail due (and thus the test) to a detected lint rule issue after startup. */ class EmbeddedTwitterServer( twitterServer: com.twitter.server.TwitterServer, @@ -80,7 +83,8 @@ class EmbeddedTwitterServer( streamResponse: Boolean = false, verbose: Boolean = false, disableTestLogging: Boolean = false, - maxStartupTimeSeconds: Int = 60 + maxStartupTimeSeconds: Int = 60, + failOnLintViolation: Boolean = false ) extends Matchers { /* Additional Constructors */ @@ -149,7 +153,6 @@ class EmbeddedTwitterServer( * @param instance - to bind instance. * @tparam T - type of the instance to bind. * @return this [[EmbeddedTwitterServer]]. - * * @see https://twitter.github.io/finatra/user-guide/testing/index.html#feature-tests */ def bind[T: TypeTag](instance: T): EmbeddedTwitterServer = { @@ -166,7 +169,6 @@ class EmbeddedTwitterServer( * @tparam T - type of the instance to bind. * @tparam A - type of the Annotation used to bind the instance. * @return this [[EmbeddedTwitterServer]]. - * * @see https://twitter.github.io/finatra/user-guide/testing/index.html#feature-tests */ def bind[T: TypeTag, A <: Annotation: TypeTag](instance: T): EmbeddedTwitterServer = { @@ -413,7 +415,7 @@ class EmbeddedTwitterServer( val host = new InetSocketAddress(PortUtils.loopbackAddress, port) val builder = ClientBuilder() - .name(name) + .name(s"$name:$port") .stack(Http.client.withStreaming(streamResponse)) .tcpConnectTimeout(tcpConnectTimeout) .connectTimeout(connectTimeout) @@ -421,7 +423,7 @@ class EmbeddedTwitterServer( .hosts(host) .hostConnectionLimit(75) .retryPolicy(retryPolicy) - .reportTo(NullStatsReceiver) + .reportTo(inMemoryStatsReceiver) .failFast(false) .daemon(true) @@ -509,7 +511,7 @@ class EmbeddedTwitterServer( } private def receivedResponseStr(response: Response): String = { - "\n\nReceived Response:\n" + response.encodeString() + "\n\nReceived Response:\n" + HttpCodec.encodeResponseToString(response) } private def handleRequest(request: Request, client: Service[Request, Response]): Response = { @@ -625,16 +627,29 @@ class EmbeddedTwitterServer( } } + private def throwStartupFailedException(): Unit = { + println(s"\nEmbedded server $name failed to startup") + throw startupFailedThrowable.get + } + private def waitForServerStarted(): Unit = { for (i <- 1 to maxStartupTimeSeconds) { info("Waiting for warmup phases to complete...") if (startupFailedThrowable.isDefined) { - println(s"\nEmbedded server $name failed to startup") - throw startupFailedThrowable.get + throwStartupFailedException() } - if ((isInjectable && injectableServer.started) || (!isInjectable && nonInjectableServerStarted)) { + if ((isInjectable && injectableServer.started) + || (!isInjectable && nonInjectableServerStarted)) { + /* TODO: RUN AND WARN ALWAYS + For now only run if failOnValidation = true until + we allow for a better way to isolate the server startup + in feature tests */ + if (failOnLintViolation) { + checkStartupLintIssues() + } + started = true logStartup() return @@ -643,7 +658,34 @@ class EmbeddedTwitterServer( Thread.sleep(1000) } throw new StartupTimeoutException( - s"App: $name failed to startup within $maxStartupTimeSeconds seconds." + s"Embedded server: $name failed to startup within $maxStartupTimeSeconds seconds." ) } + + private def checkStartupLintIssues(): Unit = { + val failures: Map[Rule, Seq[String]] = computeLintIssues + val numIssues = failures.map(_._2.size).sum + val issueString = if (numIssues == 1) "Issue" else "Issues" + if (failures.nonEmpty) { + info(s"Warning: $numIssues Linter $issueString Found!") + failures.foreach { case (rule, issues) => + info(s"\t* Rule: ${rule.name} - ${rule.description}") + issues.foreach(issue => info(s"\t - $issue")) + } + info("After addressing these issues, consider enabling failOnLintViolation mode to prevent future issues from reaching production.") + if (failOnLintViolation) { + val e = new Exception(s"failOnLintViolation is enabled and $numIssues Linter ${issueString.toLowerCase()} found.") + startupFailedThrowable = Some(e) + throwStartupFailedException() + } + } + } + + private def computeLintIssues: Map[Rule, Seq[String]] = { + val rules = GlobalRules.get.iterable.toSeq + rules + .map(rule => rule -> rule().map(_.details.replace("\n", " ").trim)) + .filterNot(_._2.isEmpty) + .toMap + } } diff --git a/inject/inject-server/src/test/scala/com/twitter/inject/server/tests/EmbeddedTwitterServerIntegrationTest.scala b/inject/inject-server/src/test/scala/com/twitter/inject/server/tests/EmbeddedTwitterServerIntegrationTest.scala index 425ba34092..5fe7186142 100644 --- a/inject/inject-server/src/test/scala/com/twitter/inject/server/tests/EmbeddedTwitterServerIntegrationTest.scala +++ b/inject/inject-server/src/test/scala/com/twitter/inject/server/tests/EmbeddedTwitterServerIntegrationTest.scala @@ -1,19 +1,72 @@ package com.twitter.inject.server.tests -import com.twitter.finagle.http.Status +import com.twitter.finagle.{Http, Service} +import com.twitter.finagle.http.{Request, Response, Status} import com.twitter.inject.server.{EmbeddedTwitterServer, TwitterServer} import com.twitter.inject.{Logging, Test, TwitterModule} +import com.twitter.util.{Future, Await} +import com.twitter.util.lint.{Rules, RulesImpl, GlobalRules, Rule, Issue, Category} +import com.twitter.util.registry.{GlobalRegistry, SimpleRegistry} +import org.apache.commons.lang.RandomStringUtils class EmbeddedTwitterServerIntegrationTest extends Test { + private [this] def generateTestRuleName: String = { + s"TestRule-${RandomStringUtils.randomAlphabetic(12).toUpperCase()}" + } + + private def mkRules(rules: Rule*): Rules = { + val toReturn = new RulesImpl() + rules.foreach(rule => toReturn.add(rule)) + toReturn + } + + private val alwaysRule1 = + Rule( + Category.Configuration, + generateTestRuleName, + "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") { + Seq( + Issue("Etiam nisi metus, commodo in erat id, sagittis luctus purus."), + Issue("Vestibulum sagittis justo a ex suscipit, sit amet efficitur mi varius."), + Issue("Maecenas eu condimentum nulla, non porta tortor.")) + } + private val alwaysRule2 = + Rule( + Category.Configuration, + generateTestRuleName, + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquam eu ante et auctor. " + + "Vestibulum sagittis justo a ex suscipit, sit amet efficitur mi varius. Maecenas egestas " + + "viverra arcu, id volutpat magna molestie sit amet.") { + Seq(Issue("Duis blandit orci mi, sit amet euismod magna maximus eu.")) + } + private val alwaysRule3 = + Rule( + Category.Configuration, + generateTestRuleName, + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquam eu ante et auctor. " + + "Vestibulum sagittis justo a ex suscipit, sit amet efficitur mi varius. Maecenas egestas " + + "viverra arcu, id volutpat magna molestie sit amet.") { + Seq(Issue("This is just a test.")) + } + private val neverRule = + Rule( + Category.Configuration, + generateTestRuleName, + "Donec ligula nibh, accumsan a tempor a, consequat sit amet enim.") { + Seq.empty + } + test("server#start") { val twitterServer = new TwitterServer {} twitterServer.addFrameworkOverrideModules(new TwitterModule {}) val embeddedServer = new EmbeddedTwitterServer(twitterServer) - embeddedServer.httpGetAdmin("/health", andExpect = Status.Ok, withBody = "OK\n") - - embeddedServer.close() + try { + embeddedServer.httpGetAdmin("/health", andExpect = Status.Ok, withBody = "OK\n") + } finally { + embeddedServer.close() + } } test("server#fail if server is a singleton") { @@ -33,24 +86,179 @@ class EmbeddedTwitterServerIntegrationTest extends Test { val server = new EmbeddedTwitterServer(new TwitterServer {}) .bind[String]("helloworld") - server.injector.instance[String] should be("helloworld") - server.close() + try { + server.injector.instance[String] should be("helloworld") + } finally { + server.close() + } } test("server#fail because of unknown flag") { val server = new EmbeddedTwitterServer(new TwitterServer {}, flags = Map("foo.bar" -> "true")) - val e = intercept[Exception] { - server.assertHealthy() + try { + val e = intercept[Exception] { + server.assertHealthy() + } + e.getMessage.contains("Error parsing flag \"foo.bar\": flag undefined") should be(true) + } finally { + server.close() + } + } + + // Currently fails in sbt + ignore("server#fail startup because of linting violations") { + val rules = mkRules(alwaysRule1, alwaysRule2, neverRule) + + GlobalRegistry.withRegistry(new SimpleRegistry) { + GlobalRules.withRules(rules) { + val server = new EmbeddedTwitterServer(new TwitterServer {}, failOnLintViolation = true) + try { + val e = intercept[Exception] { + server.assertHealthy() + } + e.getMessage.contains("and 4 Linter issues found") should be(true) + } finally { + server.close() + } + } + } + } + + // Currently fails in sbt + ignore("server#starts when there is an artificial rule but no violations and failOnLintViolation = true") { + val rules = mkRules(neverRule) + + GlobalRegistry.withRegistry(new SimpleRegistry) { + GlobalRules.withRules(rules) { + val server = new EmbeddedTwitterServer(new TwitterServer {}, failOnLintViolation = true) + + try { + server.assertHealthy() + } finally { + server.close() + } + } + } + } + + // Currently fails in sbt + ignore("server#starts when there are no lint rule violations and failOnLintViolation = true") { + val rules = mkRules() + + GlobalRegistry.withRegistry(new SimpleRegistry) { + GlobalRules.withRules(rules) { + val server = new EmbeddedTwitterServer(new TwitterServer {}, failOnLintViolation = true) + + try { + server.assertHealthy() + } finally { + server.close() + } + } + } + } + + // Currently fails in sbt + ignore("server#starts when there are linting violations and failOnLintViolation = false") { + val rules = mkRules(alwaysRule1, alwaysRule2, alwaysRule3) + + GlobalRegistry.withRegistry(new SimpleRegistry) { + GlobalRules.withRules(rules) { + val server = new EmbeddedTwitterServer(new TwitterServer {}) + + try { + server.assertHealthy() + } finally { + server.close() + } + } + } + } + + // Currently fails in sbt + ignore("server#non-injectable server fail startup because linting violation and failOnLintViolation = true") { + val rules = mkRules(alwaysRule3) + + GlobalRegistry.withRegistry(new SimpleRegistry) { + GlobalRules.withRules(rules) { + val server = new EmbeddedTwitterServer(new NonInjectableServer, failOnLintViolation = true) + try { + val e = intercept[Exception] { + server.assertHealthy() + } + e.getMessage.contains("and 1 Linter issue found") should be(true) + } finally { + server.close() + } + } + } + } + + // Currently fails in sbt + ignore("server#non-injectable server starts when there are linting violations and failOnLintViolation = false") { + val rules = mkRules(alwaysRule3) + + GlobalRegistry.withRegistry(new SimpleRegistry) { + GlobalRules.withRules(rules) { + val server = new EmbeddedTwitterServer(new NonInjectableServer) + try { + server.assertHealthy() + } finally { + server.close() + } + } + } + } + + // Currently fails in sbt + ignore("server#non-injectable server starts when there are no linting violations and and failOnLintViolation = false") { + val rules = mkRules() + + GlobalRegistry.withRegistry(new SimpleRegistry) { + GlobalRules.withRules(rules) { + val server = new EmbeddedTwitterServer(new NonInjectableServer) + try { + server.assertHealthy() + } finally { + server.close() + } + } + } + } + + // Currently fails in sbt + ignore("server#non-injectable server starts when there are no linting violations and and failOnLintViolation = true") { + val rules = mkRules() + + GlobalRegistry.withRegistry(new SimpleRegistry) { + GlobalRules.withRules(rules) { + val server = new EmbeddedTwitterServer(new NonInjectableServer, failOnLintViolation = true) + try { + server.assertHealthy() + } finally { + server.close() + } + } } - e.getMessage.contains("Error parsing flag \"foo.bar\": flag undefined") should be(true) - server.close() } } class NonInjectableServer extends com.twitter.server.TwitterServer with Logging { - def main(): Unit = { - info("Hello World") + val service = new Service[Request, Response] { + def apply(request: Request) = { + val response = Response(request.version, Status.Ok) + response.contentString = "hello" + Future.value(response) + } + } + + def main() { + val server = Http.serve(":8888", service) + onExit { + server.close() + } + Await.ready(server) } } diff --git a/inject/inject-slf4j/src/main/scala/BUILD b/inject/inject-slf4j/src/main/scala/BUILD index 78f0a8e33d..7f9d8c142a 100644 --- a/inject/inject-slf4j/src/main/scala/BUILD +++ b/inject/inject-slf4j/src/main/scala/BUILD @@ -15,6 +15,8 @@ scala_library( 'util/util-slf4j-api/src/main/scala', ], exports=[ + '3rdparty/jvm/com/fasterxml/jackson/core:jackson-annotations', + 'util/util-core/src/main/scala:scala', 'util/util-slf4j-api/src/main/scala', ], excludes=[ diff --git a/inject/inject-thrift-client/src/main/scala/BUILD b/inject/inject-thrift-client/src/main/scala/BUILD index 3c9b9b5265..0e35f7f8f2 100644 --- a/inject/inject-thrift-client/src/main/scala/BUILD +++ b/inject/inject-thrift-client/src/main/scala/BUILD @@ -20,6 +20,7 @@ scala_library( 'finagle/finagle-thriftmux/src/main/scala', 'finatra/inject/inject-app/src/main/scala', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-thrift/src/main/scala', 'finatra/inject/inject-utils/src/main/scala', 'scrooge/scrooge-core/src/main/scala', @@ -33,4 +34,12 @@ scala_library( java_sources=[ 'finatra/inject/inject-thrift-client/src/main/java' ], + strict_deps=True, + exports=[ + '3rdparty/jvm/com/github/nscala_time:nscala_time', + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + 'finagle/finagle-core/src/main/scala:scala', + 'finatra/inject/inject-app/src/main/scala:scala', + 'scrooge/scrooge-core/src/main/scala:scala', + ], ) diff --git a/inject/inject-thrift-client/src/test/scala/BUILD b/inject/inject-thrift-client/src/test/scala/BUILD index 24fa7b95bd..e414081ff6 100644 --- a/inject/inject-thrift-client/src/test/scala/BUILD +++ b/inject/inject-thrift-client/src/test/scala/BUILD @@ -13,6 +13,7 @@ junit_tests( '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-core/src/main/scala', 'finagle/finagle-http/src/main/scala', + 'finagle/finagle-thrift/src/main/scala:scala', 'finagle/finagle-thriftmux/src/main/scala', 'finatra/http/src/main/scala', 'finatra/http/src/test/scala:test-deps', @@ -23,16 +24,20 @@ junit_tests( 'finatra/inject/inject-modules/src/main/scala', 'finatra/inject/inject-server/src/main/scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-thrift-client/src/main/scala', 'finatra/inject/inject-thrift-client/src/test/thrift:greeter-thrift-scala', + 'finatra/inject/inject-thrift/src/main/scala:scala', 'finatra/thrift/src/test/scala:test-deps', 'scrooge/scrooge-core/src/main/scala', 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', ], fatal_warnings=True, sources=rglobs('com/twitter/inject/thrift/*.scala'), + strict_deps=True, ) diff --git a/inject/inject-thrift/src/main/scala/BUILD b/inject/inject-thrift/src/main/scala/BUILD index ada93f290e..bdd4a02253 100644 --- a/inject/inject-thrift/src/main/scala/BUILD +++ b/inject/inject-thrift/src/main/scala/BUILD @@ -13,4 +13,5 @@ scala_library( ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, ) diff --git a/inject/inject-thrift/src/test/scala/BUILD b/inject/inject-thrift/src/test/scala/BUILD index 4109e7372a..da1b83ab1b 100644 --- a/inject/inject-thrift/src/test/scala/BUILD +++ b/inject/inject-thrift/src/test/scala/BUILD @@ -16,4 +16,5 @@ junit_tests( sources=globs( 'com/twitter/inject/tests/exceptions/*.scala', 'com/twitter/inject/tests/thrift/utils/*.scala'), + strict_deps=True, ) diff --git a/inject/inject-utils/src/main/scala/BUILD b/inject/inject-utils/src/main/scala/BUILD index d4a4a37165..6912d34221 100644 --- a/inject/inject-utils/src/main/scala/BUILD +++ b/inject/inject-utils/src/main/scala/BUILD @@ -5,6 +5,7 @@ scala_library( repo = artifactory, ), dependencies=[ + '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', '3rdparty/jvm/com/github/nscala_time:nscala_time', '3rdparty/jvm/commons-lang', '3rdparty/jvm/joda-time:joda-time', @@ -12,13 +13,16 @@ scala_library( 'finagle/finagle-core/src/main/scala', 'finagle/finagle-mux/src/main/scala', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', + 'finatra/inject/inject-utils/src/main/resources', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/inject/inject-utils/src/main/resources', - 'finatra/inject/inject-slf4j/src/main/scala:scala', - '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', ], fatal_warnings=True, sources=rglobs('*.scala'), strict_deps=True, + exports=[ + '3rdparty/jvm/com/github/nscala_time:nscala_time', + ] + ) diff --git a/inject/inject-utils/src/main/scala/com/twitter/inject/conversions/map.scala b/inject/inject-utils/src/main/scala/com/twitter/inject/conversions/map.scala index b3a185e80c..9033c4e84c 100644 --- a/inject/inject-utils/src/main/scala/com/twitter/inject/conversions/map.scala +++ b/inject/inject-utils/src/main/scala/com/twitter/inject/conversions/map.scala @@ -1,6 +1,7 @@ package com.twitter.inject.conversions import com.twitter.inject.conversions.tuple._ +import java.util.concurrent.ConcurrentHashMap import scala.collection.{SortedMap, immutable, mutable} object map { @@ -102,4 +103,15 @@ object map { }).toSortedMap } } + + implicit class RichConcurrentMap[A, B](val map: ConcurrentHashMap[A, B]) + extends AnyVal { + def atomicGetOrElseUpdate(key: A, op: => B): B = { + map.computeIfAbsent(key, new java.util.function.Function[A, B]() { + override def apply(key: A): B = { + op + } + }) + } + } } diff --git a/inject/inject-utils/src/test/scala/BUILD b/inject/inject-utils/src/test/scala/BUILD index 4d6b2ab067..a1f31085f4 100644 --- a/inject/inject-utils/src/test/scala/BUILD +++ b/inject/inject-utils/src/test/scala/BUILD @@ -1,6 +1,7 @@ junit_tests( dependencies=[ '3rdparty/jvm/ch/qos/logback:logback-classic', + '3rdparty/jvm/joda-time:joda-time', '3rdparty/jvm/org/scalatest:scalatest', '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-core/src/main/scala', @@ -8,13 +9,14 @@ junit_tests( 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', 'finatra/inject/inject-utils/src/main/scala', + 'finatra/inject/inject-utils/src/test/resources', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/inject/inject-utils/src/test/resources', ], fatal_warnings=True, sources=globs( 'com/twitter/inject/tests/*.scala', 'com/twitter/inject/tests/conversions/*.scala', 'com/twitter/inject/tests/exceptions/*.scala'), + strict_deps=True, ) diff --git a/inject/inject-utils/src/test/scala/com/twitter/inject/tests/conversions/MapsConversionsTest.scala b/inject/inject-utils/src/test/scala/com/twitter/inject/tests/conversions/MapsConversionsTest.scala index f3e14b2252..08d1d70b1e 100644 --- a/inject/inject-utils/src/test/scala/com/twitter/inject/tests/conversions/MapsConversionsTest.scala +++ b/inject/inject-utils/src/test/scala/com/twitter/inject/tests/conversions/MapsConversionsTest.scala @@ -2,6 +2,7 @@ package com.twitter.inject.tests.conversions import com.twitter.inject.conversions.map._ import com.twitter.inject.Test +import java.util.concurrent.ConcurrentHashMap import scala.collection.SortedMap class MapsConversionsTest extends Test { @@ -59,4 +60,12 @@ class MapsConversionsTest extends Test { Map(1 -> "a", 2 -> "a", 3 -> "b") filterNotKeys { _ == 3 } should equal(Map(1 -> "a", 2 -> "a")) } + + test("RichConcurrentMap#atomicGetOrElseUpdate") { + val map = new ConcurrentHashMap[String, Int]() + map.atomicGetOrElseUpdate("1", 1) should equal(1) + map.get("1") should equal(1) + map.atomicGetOrElseUpdate("1", 2) should equal(1) + map.get("1") should equal(1) + } } diff --git a/jackson/README.md b/jackson/README.md index d99cdbe93d..06bb79f517 100644 --- a/jackson/README.md +++ b/jackson/README.md @@ -44,7 +44,7 @@ object CustomJacksonModule extends FinatraJacksonModule { override val serializationInclusion = Include.NON_EMPTY - override val propertyNamingStrategy = CamelCasePropertyNamingStrategy + override val propertyNamingStrategy = PropertyNamingStrategy.LOWER_CAMEL_CASE override def additionalMapperConfiguration(mapper: ObjectMapper) { mapper.configure(Feature.WRITE_NUMBERS_AS_STRINGS, true) diff --git a/jackson/src/main/java/BUILD b/jackson/src/main/java/BUILD index c17506ff22..c4861276db 100644 --- a/jackson/src/main/java/BUILD +++ b/jackson/src/main/java/BUILD @@ -4,5 +4,10 @@ java_library( 'finatra/jackson/src/main/scala', ], fatal_warnings=False, - sources=rglobs('*.java') + sources=rglobs('*.java'), + exports=[ + '3rdparty/jvm/com/google/inject:guice', + 'finatra/jackson/src/main/scala:scala', + ] + ) diff --git a/jackson/src/main/scala/BUILD b/jackson/src/main/scala/BUILD index 74b803aa04..b91465b565 100644 --- a/jackson/src/main/scala/BUILD +++ b/jackson/src/main/scala/BUILD @@ -26,12 +26,12 @@ scala_library( '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-http/src/main/scala', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-utils/src/main/scala', - 'util/util-core/src/main/scala', - 'util/util-slf4j-api/src/main/scala', 'finatra/jackson/src/main/resources', - 'finatra/inject/inject-slf4j/src/main/scala:scala', 'util/util-app/src/main/scala:scala', + 'util/util-core/src/main/scala', + 'util/util-slf4j-api/src/main/scala', ], fatal_warnings=True, sources=rglobs('*.scala'), @@ -39,4 +39,9 @@ scala_library( 'finatra/jackson/src/main/java' ], strict_deps=True, + exports=[ + '3rdparty/jvm/com/fasterxml/jackson/module:jackson-module-scala', + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + ] + ) diff --git a/jackson/src/main/scala/com/twitter/finatra/json/internal/caseclass/jackson/FinatraCaseClassDeserializer.scala b/jackson/src/main/scala/com/twitter/finatra/json/internal/caseclass/jackson/FinatraCaseClassDeserializer.scala index d420daad8b..00b538a544 100644 --- a/jackson/src/main/scala/com/twitter/finatra/json/internal/caseclass/jackson/FinatraCaseClassDeserializer.scala +++ b/jackson/src/main/scala/com/twitter/finatra/json/internal/caseclass/jackson/FinatraCaseClassDeserializer.scala @@ -11,7 +11,6 @@ import com.fasterxml.jackson.databind.exc.InvalidFormatException import com.twitter.finatra.json.internal.caseclass.exceptions._ import com.twitter.finatra.json.internal.caseclass.exceptions.CaseClassValidationException.PropertyPath import com.twitter.finatra.json.internal.caseclass.validation.ValidationProvider -import com.twitter.finatra.json.utils.CamelCasePropertyNamingStrategy import com.twitter.finatra.response.JsonCamelCase import com.twitter.finatra.validation.ErrorCode import com.twitter.finatra.validation.ValidationResult._ @@ -251,7 +250,7 @@ private[finatra] class FinatraCaseClassDeserializer( private def propertyNamingStrategy = { if (javaType.getRawClass.isAnnotationPresent(classOf[JsonCamelCase])) - CamelCasePropertyNamingStrategy + PropertyNamingStrategy.LOWER_CAMEL_CASE else config.getPropertyNamingStrategy } diff --git a/jackson/src/main/scala/com/twitter/finatra/json/modules/FinatraJacksonModule.scala b/jackson/src/main/scala/com/twitter/finatra/json/modules/FinatraJacksonModule.scala index 83e412cae0..02f38ec97a 100644 --- a/jackson/src/main/scala/com/twitter/finatra/json/modules/FinatraJacksonModule.scala +++ b/jackson/src/main/scala/com/twitter/finatra/json/modules/FinatraJacksonModule.scala @@ -13,7 +13,6 @@ import com.twitter.finatra.json.FinatraObjectMapper import com.twitter.finatra.json.internal.caseclass.guice.GuiceInjectableValues import com.twitter.finatra.json.internal.caseclass.jackson.FinatraCaseClassModule import com.twitter.finatra.json.internal.serde.{FinatraSerDeSimpleModule, LongKeyDeserializers} -import com.twitter.finatra.json.utils.CamelCasePropertyNamingStrategy import com.twitter.inject.TwitterModule import javax.inject.Singleton import scala.collection.JavaConverters._ @@ -53,7 +52,7 @@ class FinatraJacksonModule extends TwitterModule { objectMapper: ObjectMapper with ScalaObjectMapper ): FinatraObjectMapper = { val objectMapperCopy = copy(objectMapper) - objectMapperCopy.setPropertyNamingStrategy(CamelCasePropertyNamingStrategy) + objectMapperCopy.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CAMEL_CASE) new FinatraObjectMapper(objectMapperCopy) } diff --git a/jackson/src/main/scala/com/twitter/finatra/json/utils/CamelCasePropertyNamingStrategy.scala b/jackson/src/main/scala/com/twitter/finatra/json/utils/CamelCasePropertyNamingStrategy.scala index 322e2adb6b..d529793e4d 100644 --- a/jackson/src/main/scala/com/twitter/finatra/json/utils/CamelCasePropertyNamingStrategy.scala +++ b/jackson/src/main/scala/com/twitter/finatra/json/utils/CamelCasePropertyNamingStrategy.scala @@ -3,4 +3,11 @@ package com.twitter.finatra.json.utils import com.fasterxml.jackson.databind.PropertyNamingStrategy /* By default PropertyNamingStrategy uses CamelCase */ +@deprecated( + "This was needed with previous versions of Jackson in which the " + + "PropertyNamingStrategy was an abstract class with a non-obvious " + + "default of camel case. Please use " + + "PropertyNamingStrategy#LOWER_CAMEL_CASE directly.", + "2017-08-15" +) object CamelCasePropertyNamingStrategy extends PropertyNamingStrategy diff --git a/jackson/src/test/scala/BUILD b/jackson/src/test/scala/BUILD index c03ff0b519..b81d4c8356 100644 --- a/jackson/src/test/scala/BUILD +++ b/jackson/src/test/scala/BUILD @@ -40,6 +40,8 @@ junit_tests( 'com/twitter/finatra/json/tests/*.scala', 'com/twitter/finatra/json/tests/*.java', ), + strict_deps=True, + ) scala_library(name="test-deps", @@ -70,4 +72,9 @@ scala_library(name="test-deps", 'com/twitter/finatra/validation/*.scala', 'com/twitter/finatra/validation/*.java', ), + strict_deps=True, + exports=[ + 'finatra/jackson/src/main/scala:scala', + ] + ) diff --git a/jackson/src/test/scala/com/twitter/finatra/json/tests/internal/caseclass/jackson/CaseClassFieldTest.scala b/jackson/src/test/scala/com/twitter/finatra/json/tests/internal/caseclass/jackson/CaseClassFieldTest.scala index 77a0be06d2..4a932e4c94 100644 --- a/jackson/src/test/scala/com/twitter/finatra/json/tests/internal/caseclass/jackson/CaseClassFieldTest.scala +++ b/jackson/src/test/scala/com/twitter/finatra/json/tests/internal/caseclass/jackson/CaseClassFieldTest.scala @@ -1,5 +1,6 @@ package com.twitter.finatra.json.tests.internal.caseclass.jackson +import com.fasterxml.jackson.databind.PropertyNamingStrategy import com.fasterxml.jackson.databind.`type`.TypeFactory import com.twitter.finatra.json.internal.caseclass.jackson.CaseClassField import com.twitter.finatra.json.tests.internal.{ @@ -7,7 +8,6 @@ import com.twitter.finatra.json.tests.internal.{ WithNonemptyJsonProperty, WithoutJsonPropertyAnnotation } -import com.twitter.finatra.json.utils.CamelCasePropertyNamingStrategy import com.twitter.inject.Test class CaseClassFieldTest extends Test { @@ -15,7 +15,7 @@ class CaseClassFieldTest extends Test { test("CaseClassField.createFields have field name foo") { val fields = CaseClassField.createFields( classOf[WithEmptyJsonProperty], - CamelCasePropertyNamingStrategy, + PropertyNamingStrategy.LOWER_CAMEL_CASE, TypeFactory.defaultInstance ) @@ -26,7 +26,7 @@ class CaseClassFieldTest extends Test { test("CaseClassField.createFields also have field name foo") { val fields = CaseClassField.createFields( classOf[WithoutJsonPropertyAnnotation], - CamelCasePropertyNamingStrategy, + PropertyNamingStrategy.LOWER_CAMEL_CASE, TypeFactory.defaultInstance ) @@ -37,7 +37,7 @@ class CaseClassFieldTest extends Test { test("CaseClassField.createFields have field name bar") { val fields = CaseClassField.createFields( classOf[WithNonemptyJsonProperty], - CamelCasePropertyNamingStrategy, + PropertyNamingStrategy.LOWER_CAMEL_CASE, TypeFactory.defaultInstance ) diff --git a/project/plugins.sbt b/project/plugins.sbt index 543c9b2e37..778bc29b8d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,7 +5,7 @@ resolvers ++= Seq( ) val branch = Process("git" :: "rev-parse" :: "--abbrev-ref" :: "HEAD" :: Nil).!!.trim -val scroogeSbtPluginVersionPrefix = "4.19.0" +val scroogeSbtPluginVersionPrefix = "4.20.0" val scroogeSbtPluginVersion = if (branch == "master") scroogeSbtPluginVersionPrefix else scroogeSbtPluginVersionPrefix + "-SNAPSHOT" diff --git a/thrift/src/main/scala/BUILD b/thrift/src/main/scala/BUILD index 6d990ed356..a85411e690 100644 --- a/thrift/src/main/scala/BUILD +++ b/thrift/src/main/scala/BUILD @@ -21,6 +21,7 @@ scala_library( '3rdparty/jvm/org/yaml:snakeyaml', 'finagle/finagle-core/src/main/scala', 'finagle/finagle-exp/src/main/scala', + 'finagle/finagle-http/src/main/scala:scala', 'finagle/finagle-thrift/src/main/scala', 'finagle/finagle-thriftmux/src/main/scala', 'finatra/inject/inject-app/src/main/scala', @@ -36,10 +37,21 @@ scala_library( 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', 'util/util-stats/src/main/scala', ], fatal_warnings=True, sources=rglobs('*.scala'), + strict_deps=True, + exports=[ + '3rdparty/jvm/com/github/nscala_time:nscala_time', + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + 'finagle/finagle-core/src/main/scala:scala', + 'finatra/utils/src/main/java:java', + 'scrooge/scrooge-core/src/main/scala:scala', + 'util/util-app/src/main/scala:scala', + 'util/util-core/src/main/scala:scala', + ], ) diff --git a/thrift/src/test/scala/BUILD b/thrift/src/test/scala/BUILD index 4c3a375bbf..bbf5019116 100644 --- a/thrift/src/test/scala/BUILD +++ b/thrift/src/test/scala/BUILD @@ -9,15 +9,20 @@ junit_tests( '3rdparty/jvm/org/scalatest:scalatest', '3rdparty/jvm/org/slf4j:slf4j-api', 'finagle/finagle-core/src/main/scala', + 'finagle/finagle-http/src/main/scala:scala', + 'finagle/finagle-thrift/src/main/scala:scala', 'finagle/finagle-thriftmux/src/main/scala', 'finatra/inject/inject-app/src/main/scala', + 'finatra/inject/inject-app/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', 'finatra/inject/inject-server/src/main/scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-utils/src/main/scala', 'finatra/thrift/src/main/scala', 'finatra/thrift/src/main/thrift:thrift-scala', + 'finatra/thrift/src/test/resources', 'finatra/thrift/src/test/scala:test-deps', 'finatra/thrift/src/test/thrift:doeverything-thrift-scala', 'finatra/utils/src/main/java', @@ -26,13 +31,14 @@ junit_tests( 'twitter-server/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', + 'util/util-lint/src/main/scala:scala', 'util/util-logging/src/main/scala', 'util/util-slf4j-api/src/main/scala', 'util/util-stats/src/main/scala', - 'finatra/thrift/src/test/resources', ], fatal_warnings=True, sources=rglobs('com/twitter/finatra/thrift/tests/*.scala'), + strict_deps=True, ) scala_library(name="test-deps", @@ -52,8 +58,13 @@ scala_library(name="test-deps", 'finagle/finagle-thriftmux/src/main/scala', 'finatra/inject/inject-server/src/main/scala', 'finatra/inject/inject-server/src/test/scala:test-deps', + 'twitter-server/src/main/scala:scala', 'util/util-stats/src/main/scala', ], fatal_warnings=True, - sources=globs('com/twitter/finatra/thrift/*.scala') + sources=globs('com/twitter/finatra/thrift/*.scala'), + strict_deps=True, + exports=[ + '3rdparty/jvm/net/codingwell:scala-guice', + ] ) diff --git a/thrift/src/test/scala/com/twitter/finatra/thrift/EmbeddedThriftServer.scala b/thrift/src/test/scala/com/twitter/finatra/thrift/EmbeddedThriftServer.scala index c61d03015c..b99934df2f 100644 --- a/thrift/src/test/scala/com/twitter/finatra/thrift/EmbeddedThriftServer.scala +++ b/thrift/src/test/scala/com/twitter/finatra/thrift/EmbeddedThriftServer.scala @@ -25,6 +25,7 @@ import scala.reflect.runtime.universe._ * @param verbose Enable verbose logging during test runs. * @param disableTestLogging Disable all logging emitted from the test infrastructure. * @param maxStartupTimeSeconds Maximum seconds to wait for embedded server to start. If exceeded an Exception is thrown. + * @param failOnLintViolation If server startup should fail due (and thus the test) to a detected lint rule issue after startup. */ class EmbeddedThriftServer( override val twitterServer: Ports, @@ -36,7 +37,8 @@ class EmbeddedThriftServer( override val thriftPortFlag: String = "thrift.port", verbose: Boolean = false, disableTestLogging: Boolean = false, - maxStartupTimeSeconds: Int = 60 + maxStartupTimeSeconds: Int = 60, + failOnLintViolation: Boolean = false ) extends EmbeddedTwitterServer( twitterServer, flags + (thriftPortFlag -> ephemeralLoopback), @@ -46,7 +48,8 @@ class EmbeddedThriftServer( useSocksProxy, verbose = verbose, disableTestLogging = disableTestLogging, - maxStartupTimeSeconds = maxStartupTimeSeconds + maxStartupTimeSeconds = maxStartupTimeSeconds, + failOnLintViolation = failOnLintViolation ) with ThriftClient { diff --git a/utils/src/main/java/BUILD b/utils/src/main/java/BUILD index 186a221ed5..36a60d8cec 100644 --- a/utils/src/main/java/BUILD +++ b/utils/src/main/java/BUILD @@ -8,5 +8,9 @@ java_library( '3rdparty/jvm/com/google/inject:guice', ], fatal_warnings=False, - sources=rglobs('*.java') + sources=rglobs('*.java'), + exports=[ + '3rdparty/jvm/com/google/inject:guice', + ] + ) diff --git a/utils/src/main/scala/BUILD b/utils/src/main/scala/BUILD index a633863517..088ef87ad4 100644 --- a/utils/src/main/scala/BUILD +++ b/utils/src/main/scala/BUILD @@ -5,6 +5,7 @@ scala_library( repo = artifactory, ), dependencies=[ + '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', '3rdparty/jvm/com/google/inject/extensions:guice-multibindings', '3rdparty/jvm/com/google/inject:guice', @@ -17,12 +18,11 @@ scala_library( 'finagle/finagle-core/src/main/scala', 'finagle/finagle-http/src/main/scala', 'finatra/inject/inject-core/src/main/scala', + 'finatra/inject/inject-slf4j/src/main/scala:scala', 'finatra/inject/inject-utils/src/main/scala', 'util/util-app/src/main/scala', 'util/util-core/src/main/scala', 'util/util-slf4j-api/src/main/scala', - 'finatra/inject/inject-slf4j/src/main/scala:scala', - '3rdparty/jvm/com/fasterxml/jackson:jackson-annotations', ], fatal_warnings=True, sources=rglobs('*.scala'), @@ -30,4 +30,9 @@ scala_library( 'finatra/utils/src/main/java', ], strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + '3rdparty/jvm/net/codingwell:scala-guice', + ] + ) diff --git a/utils/src/test/scala/BUILD b/utils/src/test/scala/BUILD index ebe514acdc..d1a0ad15ee 100644 --- a/utils/src/test/scala/BUILD +++ b/utils/src/test/scala/BUILD @@ -11,14 +11,18 @@ junit_tests( 'finatra/inject/inject-app/src/test/scala:test-deps', 'finatra/inject/inject-core/src/main/scala', 'finatra/inject/inject-core/src/test/scala:test-deps', + 'finatra/inject/inject-slf4j/src/main/scala:scala', + 'finatra/inject/inject-utils/src/main/scala:scala', 'finatra/utils/src/main/scala', 'finatra/utils/src/test/scala:test-deps', 'util/util-core/src/main/scala', + 'util/util-logging/src/main/scala:scala', 'util/util-slf4j-api/src/main/scala', ], sources=rglobs( 'com/twitter/finatra/tests/*.scala', ), + strict_deps=True, ) scala_library(name="test-deps", @@ -46,5 +50,10 @@ scala_library(name="test-deps", sources=globs( 'com/twitter/finatra/modules/*.scala', 'com/twitter/finatra/test/*.scala' - ) + ), + strict_deps=True, + exports=[ + '3rdparty/jvm/com/google/inject/extensions:guice-assistedinject', + '3rdparty/jvm/net/codingwell:scala-guice', + ] )