├── public ├── stylesheets │ └── main.css ├── images │ └── favicon.png └── javascripts │ └── hello.js ├── project ├── build.properties └── plugins.sbt ├── README.md ├── conf ├── logger-configurator.properties ├── log4j2.xml ├── routes └── application.conf ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── scripts ├── test-sbt ├── script-helper └── test-gradle ├── NOTICE ├── app ├── views │ ├── index.scala.html │ └── main.scala.html ├── controllers │ ├── HomeController.scala │ ├── CountController.scala │ └── AsyncController.scala ├── services │ ├── Counter.scala │ └── ApplicationTimer.scala ├── Module.scala ├── Filters.scala ├── filters │ └── ExampleFilter.scala └── Log4J2LoggerConfigurator.scala ├── test ├── IntegrationSpec.scala └── ApplicationSpec.scala ├── .mergify.yml ├── .travis.yml ├── gradlew.bat ├── .github └── settings.yml ├── gradlew └── LICENSE /public/stylesheets/main.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.2.8 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MOVED TO https://github.com/playframework/play-samples 2 | -------------------------------------------------------------------------------- /conf/logger-configurator.properties: -------------------------------------------------------------------------------- 1 | play.logger.configurator=Log4J2LoggerConfigurator 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | // The Play plugin 2 | addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.0") 3 | -------------------------------------------------------------------------------- /public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/playframework/play-scala-log4j2-example/2.7.x/public/images/favicon.png -------------------------------------------------------------------------------- /public/javascripts/hello.js: -------------------------------------------------------------------------------- 1 | if (window.console) { 2 | console.log("Welcome to your Play application's JavaScript!"); 3 | } 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/playframework/play-scala-log4j2-example/2.7.x/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | logs 3 | target 4 | /.idea 5 | /.idea_modules 6 | /.classpath 7 | /.gradle 8 | /.project 9 | /.settings 10 | /RUNNING_PID 11 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStorePath=wrapper/dists 5 | zipStoreBase=GRADLE_USER_HOME 6 | -------------------------------------------------------------------------------- /scripts/test-sbt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | . "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/script-helper" 4 | 5 | echo "+----------------------------+" 6 | echo "| Executing tests using sbt |" 7 | echo "+----------------------------+" 8 | sbt ++$TRAVIS_SCALA_VERSION test 9 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Written by Lightbend 2 | 3 | To the extent possible under law, the author(s) have dedicated all copyright and 4 | related and neighboring rights to this software to the public domain worldwide. 5 | This software is distributed without any warranty. 6 | 7 | You should have received a copy of the CC0 Public Domain Dedication along with 8 | this software. If not, see . 9 | -------------------------------------------------------------------------------- /conf/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /scripts/script-helper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | java_version=$(java -version 2>&1 | java -version 2>&1 | awk -F '"' '/version/ {print $2}') 7 | 8 | if [[ $java_version = 1.8* ]] ; then 9 | echo "The build is using Java 8 ($java_version). No addional JVM params needed." 10 | else 11 | echo "The build is using Java 9+ ($java_version). We need additional JVM parameters" 12 | export _JAVA_OPTIONS="$_JAVA_OPTIONS --add-modules=java.xml.bind" 13 | fi 14 | -------------------------------------------------------------------------------- /app/views/index.scala.html: -------------------------------------------------------------------------------- 1 | @* 2 | * This template takes a single argument, a String containing a 3 | * message to display. 4 | *@ 5 | @(message: String) 6 | 7 | @* 8 | * Call the the `main` template with two arguments. The first 9 | * argument is a `String` with the title of the page, the second 10 | * argument is an `Html` object containing the body of the page. 11 | *@ 12 | @main("Welcome to Play") { 13 |

Welcome to PlayFramework!

14 |

Your new application is ready.

15 | } 16 | -------------------------------------------------------------------------------- /scripts/test-gradle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | . "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/script-helper" 4 | 5 | # Using cut because TRAVIS_SCALA_VERSION is the full Scala 6 | # version (for example 2.12.4), but Gradle expects just the 7 | # binary version (for example 2.12) 8 | scala_binary_version=$(echo $TRAVIS_SCALA_VERSION | cut -c1-4) 9 | 10 | echo "+------------------------------+" 11 | echo "| Executing tests using Gradle |" 12 | echo "+------------------------------+" 13 | ./gradlew -Dscala.binary.version=$scala_binary_version check -i --stacktrace 14 | -------------------------------------------------------------------------------- /test/IntegrationSpec.scala: -------------------------------------------------------------------------------- 1 | import org.scalatestplus.play._ 2 | import org.scalatestplus.play.guice.GuiceOneServerPerTest 3 | 4 | /** 5 | * add your integration spec here. 6 | * An integration test will fire up a whole play application in a real (or headless) browser 7 | */ 8 | class IntegrationSpec extends PlaySpec with GuiceOneServerPerTest with OneBrowserPerTest with HtmlUnitFactory { 9 | 10 | "Application" should { 11 | 12 | "work from within a browser" in { 13 | 14 | go to ("http://localhost:" + port) 15 | 16 | pageSource must include ("Your new application is ready.") 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /conf/routes: -------------------------------------------------------------------------------- 1 | # Routes 2 | # This file defines all application routes (Higher priority routes first) 3 | # ~~~~ 4 | 5 | # An example controller showing a sample home page 6 | GET / controllers.HomeController.index 7 | # An example controller showing how to use dependency injection 8 | GET /count controllers.CountController.count 9 | # An example controller showing how to write asynchronous code 10 | GET /message controllers.AsyncController.message 11 | 12 | # Map static resources from the /public folder to the /assets URL path 13 | GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) 14 | -------------------------------------------------------------------------------- /app/controllers/HomeController.scala: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import javax.inject._ 4 | import play.api._ 5 | import play.api.mvc._ 6 | 7 | /** 8 | * This controller creates an `Action` to handle HTTP requests to the 9 | * application's home page. 10 | */ 11 | @Singleton 12 | class HomeController @Inject() (val controllerComponents: ControllerComponents) extends BaseController { 13 | 14 | /** 15 | * Create an Action to render an HTML page with a welcome message. 16 | * The configuration in the `routes` file means that this method 17 | * will be called when the application receives a `GET` request with 18 | * a path of `/`. 19 | */ 20 | def index = Action { 21 | Ok(views.html.index("Your new application is ready.")) 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /app/controllers/CountController.scala: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import javax.inject._ 4 | import play.api._ 5 | import play.api.mvc._ 6 | 7 | import services.Counter 8 | 9 | /** 10 | * This controller demonstrates how to use dependency injection to 11 | * bind a component into a controller class. The class creates an 12 | * `Action` that shows an incrementing count to users. The [[Counter]] 13 | * object is injected by the Guice dependency injection system. 14 | */ 15 | @Singleton 16 | class CountController @Inject() (val controllerComponents: ControllerComponents, counter: Counter) extends BaseController { 17 | 18 | /** 19 | * Create an action that responds with the [[Counter]]'s current 20 | * count. The result is plain text. This `Action` is mapped to 21 | * `GET /count` requests by an entry in the `routes` config file. 22 | */ 23 | def count = Action { Ok(counter.nextCount().toString) } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: Merge PRs that are ready 3 | conditions: 4 | - status-success=Travis CI - Pull Request 5 | - status-success=typesafe-cla-validator 6 | - "#approved-reviews-by>=1" 7 | - "#review-requested=0" 8 | - "#changes-requested-reviews-by=0" 9 | - label!=status:block-merge 10 | actions: 11 | merge: 12 | method: squash 13 | strict: smart 14 | 15 | - name: Merge TemplateControl's PRs that are ready 16 | conditions: 17 | - status-success=Travis CI - Pull Request 18 | - "#review-requested=0" 19 | - "#changes-requested-reviews-by=0" 20 | - label!=status:block-merge 21 | - label=status:merge-when-green 22 | - label!=status:block-merge 23 | actions: 24 | merge: 25 | method: squash 26 | strict: smart 27 | 28 | - name: Delete the PR branch after merge 29 | conditions: 30 | - merged 31 | actions: 32 | delete_head_branch: {} 33 | -------------------------------------------------------------------------------- /app/services/Counter.scala: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import java.util.concurrent.atomic.AtomicInteger 4 | import javax.inject._ 5 | 6 | /** 7 | * This trait demonstrates how to create a component that is injected 8 | * into a controller. The trait represents a counter that returns a 9 | * incremented number each time it is called. 10 | */ 11 | trait Counter { 12 | def nextCount(): Int 13 | } 14 | 15 | /** 16 | * This class is a concrete implementation of the [[Counter]] trait. 17 | * It is configured for Guice dependency injection in the [[Module]] 18 | * class. 19 | * 20 | * This class has a `Singleton` annotation because we need to make 21 | * sure we only use one counter per application. Without this 22 | * annotation we would get a new instance every time a [[Counter]] is 23 | * injected. 24 | */ 25 | @Singleton 26 | class AtomicCounter extends Counter { 27 | private val atomicCounter = new AtomicInteger() 28 | override def nextCount(): Int = atomicCounter.getAndIncrement() 29 | } 30 | -------------------------------------------------------------------------------- /app/views/main.scala.html: -------------------------------------------------------------------------------- 1 | @* 2 | * This template is called from the `index` template. This template 3 | * handles the rendering of the page header and body tags. It takes 4 | * two arguments, a `String` for the title of the page and an `Html` 5 | * object to insert into the body of the page. 6 | *@ 7 | @(title: String)(content: Html) 8 | 9 | 10 | 11 | 12 | @* Here's where we render the page title `String`. *@ 13 | @title 14 | 15 | 16 | 17 | 18 | 19 | @* And here's where we render the `Html` object containing 20 | * the page content. *@ 21 | @content 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/Module.scala: -------------------------------------------------------------------------------- 1 | import com.google.inject.AbstractModule 2 | import java.time.Clock 3 | 4 | import services.{ApplicationTimer, AtomicCounter, Counter} 5 | 6 | /** 7 | * This class is a Guice module that tells Guice how to bind several 8 | * different types. This Guice module is created when the Play 9 | * application starts. 10 | 11 | * Play will automatically use any class called `Module` that is in 12 | * the root package. You can create modules in other locations by 13 | * adding `play.modules.enabled` settings to the `application.conf` 14 | * configuration file. 15 | */ 16 | class Module extends AbstractModule { 17 | 18 | override def configure() = { 19 | // Use the system clock as the default implementation of Clock 20 | bind(classOf[Clock]).toInstance(Clock.systemDefaultZone) 21 | // Ask Guice to create an instance of ApplicationTimer when the 22 | // application starts. 23 | bind(classOf[ApplicationTimer]).asEagerSingleton 24 | // Set AtomicCounter as the implementation for Counter. 25 | bind(classOf[Counter]).to(classOf[AtomicCounter]) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/Filters.scala: -------------------------------------------------------------------------------- 1 | import javax.inject._ 2 | import play.api._ 3 | import play.api.http.HttpFilters 4 | import play.api.mvc._ 5 | 6 | import filters.ExampleFilter 7 | 8 | /** 9 | * This class configures filters that run on every request. This 10 | * class is queried by Play to get a list of filters. 11 | * 12 | * Play will automatically use filters from any class called 13 | * `Filters` that is placed the root package. You can load filters 14 | * from a different class by adding a `play.http.filters` setting to 15 | * the `application.conf` configuration file. 16 | * 17 | * @param env Basic environment settings for the current application. 18 | * @param exampleFilter A demonstration filter that adds a header to 19 | * each response. 20 | */ 21 | @Singleton 22 | class Filters @Inject() ( 23 | env: Environment, 24 | exampleFilter: ExampleFilter) extends HttpFilters { 25 | 26 | override val filters = { 27 | // Use the example filter if we're running development mode. If 28 | // we're running in production or test mode then don't use any 29 | // filters at all. 30 | if (env.mode == Mode.Dev) Seq(exampleFilter) else Seq.empty 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/filters/ExampleFilter.scala: -------------------------------------------------------------------------------- 1 | package filters 2 | 3 | import akka.stream.Materializer 4 | import javax.inject._ 5 | import play.api.mvc._ 6 | import scala.concurrent.{ExecutionContext, Future} 7 | 8 | /** 9 | * This is a simple filter that adds a header to all requests. It's 10 | * added to the application's list of filters by the 11 | * [[ExampleFilter]] class. 12 | * 13 | * @param mat This object is needed to handle streaming of requests 14 | * and responses. 15 | * @param exec This class is needed to execute code asynchronously. 16 | * It is used below by the `map` method. 17 | */ 18 | @Singleton 19 | class ExampleFilter @Inject()( 20 | implicit override val mat: Materializer, 21 | exec: ExecutionContext) extends Filter { 22 | 23 | override def apply(nextFilter: RequestHeader => Future[Result]) 24 | (requestHeader: RequestHeader): Future[Result] = { 25 | // Run the next filter in the chain. This will call other filters 26 | // and eventually call the action. Take the result and modify it 27 | // by adding a new header. 28 | nextFilter(requestHeader).map { result => 29 | result.withHeaders("X-ExampleFilter" -> "foo") 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | scala: 2.12.8 3 | script: $SCRIPT 4 | 5 | env: 6 | matrix: 7 | - SCRIPT=scripts/test-sbt TRAVIS_JDK=adopt@1.8.202-08 8 | - SCRIPT=scripts/test-sbt TRAVIS_JDK=adopt@1.11.0-2 9 | - SCRIPT=scripts/test-gradle TRAVIS_JDK=adopt@1.8.202-08 10 | - SCRIPT=scripts/test-gradle TRAVIS_JDK=adopt@1.11.0-2 11 | 12 | matrix: 13 | fast_finish: true 14 | allow_failures: 15 | - env: SCRIPT=scripts/test-gradle TRAVIS_JDK=adopt@1.8.202-08 # current gradle doesn't support play 2.7 16 | - env: SCRIPT=scripts/test-gradle TRAVIS_JDK=adopt@1.11.0-2 # current gradle doesn't support play 2.7 17 | - env: SCRIPT=scripts/test-sbt TRAVIS_JDK=adopt@1.11.0-2 # not fully supported but allows problem discovery 18 | 19 | before_install: curl -Ls https://git.io/jabba | bash && . ~/.jabba/jabba.sh 20 | install: jabba install "$TRAVIS_JDK" && jabba use "$_" && java -Xmx32m -version 21 | 22 | cache: 23 | directories: 24 | - "$HOME/.gradle/caches" 25 | - "$HOME/.ivy2/cache" 26 | - "$HOME/.jabba/jdk" 27 | - "$HOME/.sbt" 28 | 29 | before_cache: 30 | - find $HOME/.ivy2 -name "ivydata-*.properties" -delete 31 | - find $HOME/.sbt -name "*.lock" -delete 32 | -------------------------------------------------------------------------------- /test/ApplicationSpec.scala: -------------------------------------------------------------------------------- 1 | import org.scalatestplus.play._ 2 | import org.scalatestplus.play.guice.GuiceOneAppPerTest 3 | import play.api.test._ 4 | import play.api.test.Helpers._ 5 | 6 | /** 7 | * Add your spec here. 8 | * You can mock out a whole application including requests, plugins etc. 9 | * For more information, consult the wiki. 10 | */ 11 | class ApplicationSpec extends PlaySpec with GuiceOneAppPerTest { 12 | 13 | "Routes" should { 14 | 15 | "send 404 on a bad request" in { 16 | route(app, FakeRequest(GET, "/boum")).map(status) mustBe Some(NOT_FOUND) 17 | } 18 | 19 | } 20 | 21 | "HomeController" should { 22 | 23 | "render the index page" in { 24 | val home = route(app, FakeRequest(GET, "/")).get 25 | 26 | status(home) mustBe OK 27 | contentType(home) mustBe Some("text/html") 28 | contentAsString(home) must include ("Your new application is ready.") 29 | } 30 | 31 | } 32 | 33 | "CountController" should { 34 | 35 | "return an increasing count" in { 36 | contentAsString(route(app, FakeRequest(GET, "/count")).get) mustBe "0" 37 | contentAsString(route(app, FakeRequest(GET, "/count")).get) mustBe "1" 38 | contentAsString(route(app, FakeRequest(GET, "/count")).get) mustBe "2" 39 | } 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /app/controllers/AsyncController.scala: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import akka.actor.ActorSystem 4 | import javax.inject._ 5 | import play.api._ 6 | import play.api.mvc._ 7 | import scala.concurrent.{ExecutionContext, Future, Promise} 8 | import scala.concurrent.duration._ 9 | 10 | /** 11 | * This controller creates an `Action` that demonstrates how to write 12 | * simple asychronous code in a controller. It uses a timer to 13 | * asynchronously delay sending a response for 1 second. 14 | * 15 | * @param actorSystem We need the `ActorSystem`'s `Scheduler` to 16 | * run code after a delay. 17 | * @param exec We need an `ExecutionContext` to execute our 18 | * asynchronous code. 19 | */ 20 | @Singleton 21 | class AsyncController @Inject() (val controllerComponents: ControllerComponents, actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends BaseController { 22 | 23 | /** 24 | * Create an Action that returns a plain text message after a delay 25 | * of 1 second. 26 | * 27 | * The configuration in the `routes` file means that this method 28 | * will be called when the application receives a `GET` request with 29 | * a path of `/message`. 30 | */ 31 | def message = Action.async { 32 | getFutureMessage(1.second).map { msg => Ok(msg) } 33 | } 34 | 35 | private def getFutureMessage(delayTime: FiniteDuration): Future[String] = { 36 | val promise: Promise[String] = Promise[String]() 37 | actorSystem.scheduler.scheduleOnce(delayTime) { promise.success("Hi!") } 38 | promise.future 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /app/services/ApplicationTimer.scala: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import java.time.{Clock, Instant} 4 | 5 | import javax.inject._ 6 | import org.slf4j.LoggerFactory 7 | import play.api.inject._ 8 | 9 | import scala.concurrent.Future 10 | 11 | /** 12 | * This class demonstrates how to run code when the 13 | * application starts and stops. It starts a timer when the 14 | * application starts. When the application stops it prints out how 15 | * long the application was running for. 16 | * 17 | * This class is registered for Guice dependency injection in the 18 | * [[Module]] class. We want the class to start when the application 19 | * starts, so it is registered as an "eager singleton". See the code 20 | * in the [[Module]] class to see how this happens. 21 | * 22 | * This class needs to run code when the server stops. It uses the 23 | * application's [[ApplicationLifecycle]] to register a stop hook. 24 | */ 25 | @Singleton 26 | class ApplicationTimer @Inject() (clock: Clock, appLifecycle: ApplicationLifecycle) { 27 | 28 | private val logger = LoggerFactory.getLogger(classOf[ApplicationTimer]) 29 | 30 | // This code is called when the application starts. 31 | private val start: Instant = clock.instant 32 | logger.info(s"ApplicationTimer demo: Starting application at $start.") 33 | 34 | // When the application starts, register a stop hook with the 35 | // ApplicationLifecyle object. The code inside the stop hook wil 36 | // be run when the application stops. 37 | appLifecycle.addStopHook { () => 38 | val stop: Instant = clock.instant 39 | val runningTime: Long = stop.getEpochSecond - start.getEpochSecond 40 | logger.info(s"ApplicationTimer demo: Stopping application at ${clock.instant} after ${runningTime}s.") 41 | Future.successful(()) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Log4J2LoggerConfigurator.scala: -------------------------------------------------------------------------------- 1 | import java.io.File 2 | import java.net.URL 3 | 4 | import org.apache.logging.log4j.LogManager 5 | import org.apache.logging.log4j.core.LoggerContext 6 | import org.apache.logging.log4j.core.config.Configurator 7 | import org.slf4j.ILoggerFactory 8 | import play.api.{Configuration, Environment, LoggerConfigurator, Mode} 9 | 10 | class Log4J2LoggerConfigurator extends LoggerConfigurator { 11 | 12 | private lazy val factory: ILoggerFactory = org.slf4j.impl.StaticLoggerBinder.getSingleton.getLoggerFactory 13 | 14 | override def init(rootPath: File, mode: Mode): Unit = { 15 | val properties = Map("application.home" -> rootPath.getAbsolutePath) 16 | val resourceName = "log4j2.xml" 17 | val resourceUrl = Option(this.getClass.getClassLoader.getResource(resourceName)) 18 | configure(properties, resourceUrl) 19 | } 20 | 21 | override def shutdown(): Unit = { 22 | val context = LogManager.getContext().asInstanceOf[LoggerContext] 23 | Configurator.shutdown(context) 24 | } 25 | 26 | override def configure(env: Environment): Unit = { 27 | val properties = LoggerConfigurator.generateProperties(env, Configuration.empty, Map.empty) 28 | val resourceUrl = env.resource("log4j2.xml") 29 | configure(properties, resourceUrl) 30 | } 31 | 32 | override def configure(env: Environment, configuration: Configuration, optionalProperties: Map[String, String]): Unit = { 33 | // LoggerConfigurator.generateProperties enables play.logger.includeConfigProperties=true 34 | val properties = LoggerConfigurator.generateProperties(env, configuration, optionalProperties) 35 | val resourceUrl = env.resource("log4j2.xml") 36 | configure(properties, resourceUrl) 37 | } 38 | 39 | override def configure(properties: Map[String, String], config: Option[URL]): Unit = { 40 | val context = LogManager.getContext(false).asInstanceOf[LoggerContext] 41 | context.setConfigLocation(config.get.toURI) 42 | } 43 | 44 | override def loggerFactory: ILoggerFactory = factory 45 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /.github/settings.yml: -------------------------------------------------------------------------------- 1 | # These settings are synced to GitHub by https://probot.github.io/apps/settings/ 2 | repository: 3 | homepage: "https://developer.lightbend.com/start/?group=play" 4 | topics: playframework, example, example-project, sample, sample-app, jvm, webapp 5 | private: false 6 | has_issues: true 7 | # We don't need projects in sample projects 8 | has_projects: false 9 | # We don't need wiki in sample projects 10 | has_wiki: false 11 | has_downloads: true 12 | default_branch: 2.7.x 13 | allow_squash_merge: true 14 | allow_merge_commit: false 15 | allow_rebase_merge: false 16 | 17 | teams: 18 | - name: core 19 | permission: admin 20 | - name: integrators 21 | permission: write 22 | - name: write-bots 23 | permission: write 24 | 25 | branches: 26 | - name: "[0-9].*.x" 27 | protection: 28 | # We don't require reviews for sample applications because they are mainly 29 | # updated by template-control, which is an automated process 30 | required_pull_request_reviews: null 31 | # Required. Require status checks to pass before merging. Set to null to disable 32 | required_status_checks: 33 | # Required. The list of status checks to require in order to merge into this branch 34 | contexts: ["Travis CI - Pull Request", "typesafe-cla-validator"] 35 | 36 | # Labels: tailored list of labels to be used by sample applications 37 | labels: 38 | - color: f9d0c4 39 | name: "closed:declined" 40 | - color: f9d0c4 41 | name: "closed:duplicated" 42 | oldname: duplicate 43 | - color: f9d0c4 44 | name: "closed:invalid" 45 | oldname: invalid 46 | - color: f9d0c4 47 | name: "closed:question" 48 | oldname: question 49 | - color: f9d0c4 50 | name: "closed:wontfix" 51 | oldname: wontfix 52 | - color: 7057ff 53 | name: "good first issue" 54 | - color: 7057ff 55 | name: "Hacktoberfest" 56 | - color: 7057ff 57 | name: "help wanted" 58 | - color: cceecc 59 | name: "status:backlog" 60 | oldname: backlog 61 | - color: b60205 62 | name: "status:block-merge" 63 | oldname: block-merge 64 | - color: b60205 65 | name: "status:blocked" 66 | - color: 0e8a16 67 | name: "status:in-progress" 68 | - color: 0e8a16 69 | name: "status:merge-when-green" 70 | oldname: merge-when-green 71 | - color: fbca04 72 | name: "status:needs-backport" 73 | - color: fbca04 74 | name: "status:needs-forwardport" 75 | - color: fbca04 76 | name: "status:needs-info" 77 | - color: fbca04 78 | name: "status:needs-verification" 79 | - color: 0e8a16 80 | name: "status:ready" 81 | - color: fbca04 82 | name: "status:to-review" 83 | oldname: review 84 | - color: c5def5 85 | name: "topic:build/tests" 86 | - color: c5def5 87 | name: "topic:dev-environment" 88 | - color: c5def5 89 | name: "topic:documentation" 90 | - color: c5def5 91 | name: "topic:jdk-next" 92 | - color: b60205 93 | name: "type:defect" 94 | oldname: bug 95 | - color: 0052cc 96 | name: "type:feature" 97 | - color: 0052cc 98 | name: "type:improvement" 99 | oldname: enhancement 100 | - color: 0052cc 101 | name: "type:updates" 102 | - color: bf0d92 103 | name: "type:template-control" 104 | oldname: template-control 105 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /conf/application.conf: -------------------------------------------------------------------------------- 1 | # This is the main configuration file for the application. 2 | # https://www.playframework.com/documentation/latest/ConfigFile 3 | # ~~~~~ 4 | # Play uses HOCON as its configuration file format. HOCON has a number 5 | # of advantages over other config formats, but there are two things that 6 | # can be used when modifying settings. 7 | # 8 | # You can include other configuration files in this main application.conf file: 9 | #include "extra-config.conf" 10 | # 11 | # You can declare variables and substitute for them: 12 | #mykey = ${some.value} 13 | # 14 | # And if an environment variable exists when there is no other subsitution, then 15 | # HOCON will fall back to substituting environment variable: 16 | #mykey = ${JAVA_HOME} 17 | 18 | ## Akka 19 | # https://www.playframework.com/documentation/latest/ScalaAkka#Configuration 20 | # https://www.playframework.com/documentation/latest/JavaAkka#Configuration 21 | # ~~~~~ 22 | # Play uses Akka internally and exposes Akka Streams and actors in Websockets and 23 | # other streaming HTTP responses. 24 | akka { 25 | # "akka.log-config-on-start" is extraordinarly useful because it log the complete 26 | # configuration at INFO level, including defaults and overrides, so it s worth 27 | # putting at the very top. 28 | # 29 | # Put the following in your conf/logback.xml file: 30 | # 31 | # 32 | # 33 | # And then uncomment this line to debug the configuration. 34 | # 35 | #log-config-on-start = true 36 | } 37 | 38 | ## Secret key 39 | # http://www.playframework.com/documentation/latest/ApplicationSecret 40 | # ~~~~~ 41 | # The secret key is used to sign Play's session cookie. 42 | # This must be changed for production, but we don't recommend you change it in this file. 43 | play.http.secret.key = "changeme" 44 | 45 | ## Modules 46 | # https://www.playframework.com/documentation/latest/Modules 47 | # ~~~~~ 48 | # Control which modules are loaded when Play starts. Note that modules are 49 | # the replacement for "GlobalSettings", which are deprecated in 2.5.x. 50 | # Please see https://www.playframework.com/documentation/latest/GlobalSettings 51 | # for more information. 52 | # 53 | # You can also extend Play functionality by using one of the publically available 54 | # Play modules: https://playframework.com/documentation/latest/ModuleDirectory 55 | play.modules { 56 | # By default, Play will load any class called Module that is defined 57 | # in the root package (the "app" directory), or you can define them 58 | # explicitly below. 59 | # If there are any built-in modules that you want to disable, you can list them here. 60 | #enabled += my.application.Module 61 | 62 | # If there are any built-in modules that you want to disable, you can list them here. 63 | #disabled += "" 64 | } 65 | 66 | ## Internationalisation 67 | # https://www.playframework.com/documentation/latest/JavaI18N 68 | # https://www.playframework.com/documentation/latest/ScalaI18N 69 | # ~~~~~ 70 | # Play comes with its own i18n settings, which allow the user's preferred language 71 | # to map through to internal messages, or allow the language to be stored in a cookie. 72 | play.i18n { 73 | # The application languages 74 | langs = [ "en" ] 75 | 76 | # Whether the language cookie should be secure or not 77 | #langCookieSecure = true 78 | 79 | # Whether the HTTP only attribute of the cookie should be set to true 80 | #langCookieHttpOnly = true 81 | } 82 | 83 | ## Play HTTP settings 84 | # ~~~~~ 85 | play.http { 86 | ## Router 87 | # https://www.playframework.com/documentation/latest/JavaRouting 88 | # https://www.playframework.com/documentation/latest/ScalaRouting 89 | # ~~~~~ 90 | # Define the Router object to use for this application. 91 | # This router will be looked up first when the application is starting up, 92 | # so make sure this is the entry point. 93 | # Furthermore, it's assumed your route file is named properly. 94 | # So for an application router like `my.application.Router`, 95 | # you may need to define a router file `conf/my.application.routes`. 96 | # Default to Routes in the root package (aka "apps" folder) (and conf/routes) 97 | #router = my.application.Router 98 | 99 | ## Action Creator 100 | # https://www.playframework.com/documentation/latest/JavaActionCreator 101 | # ~~~~~ 102 | #actionCreator = null 103 | 104 | ## ErrorHandler 105 | # https://www.playframework.com/documentation/latest/JavaRouting 106 | # https://www.playframework.com/documentation/latest/ScalaRouting 107 | # ~~~~~ 108 | # If null, will attempt to load a class called ErrorHandler in the root package, 109 | #errorHandler = null 110 | 111 | ## Filters 112 | # https://www.playframework.com/documentation/latest/ScalaHttpFilters 113 | # https://www.playframework.com/documentation/latest/JavaHttpFilters 114 | # ~~~~~ 115 | # Filters run code on every request. They can be used to perform 116 | # common logic for all your actions, e.g. adding common headers. 117 | # Defaults to "Filters" in the root package (aka "apps" folder) 118 | # Alternatively you can explicitly register a class here. 119 | #filters += my.application.Filters 120 | 121 | ## Session & Flash 122 | # https://www.playframework.com/documentation/latest/JavaSessionFlash 123 | # https://www.playframework.com/documentation/latest/ScalaSessionFlash 124 | # ~~~~~ 125 | session { 126 | # Sets the cookie to be sent only over HTTPS. 127 | #secure = true 128 | 129 | # Sets the cookie to be accessed only by the server. 130 | #httpOnly = true 131 | 132 | # Sets the max-age field of the cookie to 5 minutes. 133 | # NOTE: this only sets when the browser will discard the cookie. Play will consider any 134 | # cookie value with a valid signature to be a valid session forever. To implement a server side session timeout, 135 | # you need to put a timestamp in the session and check it at regular intervals to possibly expire it. 136 | #maxAge = 300 137 | 138 | # Sets the domain on the session cookie. 139 | #domain = "example.com" 140 | } 141 | 142 | flash { 143 | # Sets the cookie to be sent only over HTTPS. 144 | #secure = true 145 | 146 | # Sets the cookie to be accessed only by the server. 147 | #httpOnly = true 148 | } 149 | } 150 | 151 | ## Netty Provider 152 | # https://www.playframework.com/documentation/latest/SettingsNetty 153 | # ~~~~~ 154 | play.server.netty { 155 | # Whether the Netty wire should be logged 156 | #log.wire = true 157 | 158 | # If you run Play on Linux, you can use Netty's native socket transport 159 | # for higher performance with less garbage. 160 | #transport = "native" 161 | } 162 | 163 | ## WS (HTTP Client) 164 | # https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS 165 | # ~~~~~ 166 | # The HTTP client primarily used for REST APIs. The default client can be 167 | # configured directly, but you can also create different client instances 168 | # with customized settings. You must enable this by adding to build.sbt: 169 | # 170 | # libraryDependencies += ws // or javaWs if using java 171 | # 172 | play.ws { 173 | # Sets HTTP requests not to follow 302 requests 174 | #followRedirects = false 175 | 176 | # Sets the maximum number of open HTTP connections for the client. 177 | #ahc.maxConnectionsTotal = 50 178 | 179 | ## WS SSL 180 | # https://www.playframework.com/documentation/latest/WsSSL 181 | # ~~~~~ 182 | ssl { 183 | # Configuring HTTPS with Play WS does not require programming. You can 184 | # set up both trustManager and keyManager for mutual authentication, and 185 | # turn on JSSE debugging in development with a reload. 186 | #debug.handshake = true 187 | #trustManager = { 188 | # stores = [ 189 | # { type = "JKS", path = "exampletrust.jks" } 190 | # ] 191 | #} 192 | } 193 | } 194 | 195 | ## Cache 196 | # https://www.playframework.com/documentation/latest/JavaCache 197 | # https://www.playframework.com/documentation/latest/ScalaCache 198 | # ~~~~~ 199 | # Play comes with an integrated cache API that can reduce the operational 200 | # overhead of repeated requests. You must enable this by adding to build.sbt: 201 | # 202 | # libraryDependencies += cache 203 | # 204 | play.cache { 205 | # If you want to bind several caches, you can bind the individually 206 | #bindCaches = ["db-cache", "user-cache", "session-cache"] 207 | } 208 | 209 | ## Filters 210 | # https://www.playframework.com/documentation/latest/Filters 211 | # ~~~~~ 212 | # There are a number of built-in filters that can be enabled and configured 213 | # to give Play greater security. You must enable this by adding to build.sbt: 214 | # 215 | # libraryDependencies += filters 216 | # 217 | play.filters { 218 | ## CORS filter configuration 219 | # https://www.playframework.com/documentation/latest/CorsFilter 220 | # ~~~~~ 221 | # CORS is a protocol that allows web applications to make requests from the browser 222 | # across different domains. 223 | # NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has 224 | # dependencies on CORS settings. 225 | cors { 226 | # Filter paths by a whitelist of path prefixes 227 | #pathPrefixes = ["/some/path", ...] 228 | 229 | # The allowed origins. If null, all origins are allowed. 230 | #allowedOrigins = ["http://www.example.com"] 231 | 232 | # The allowed HTTP methods. If null, all methods are allowed 233 | #allowedHttpMethods = ["GET", "POST"] 234 | } 235 | 236 | ## CSRF Filter 237 | # https://www.playframework.com/documentation/latest/ScalaCsrf#Applying-a-global-CSRF-filter 238 | # https://www.playframework.com/documentation/latest/JavaCsrf#Applying-a-global-CSRF-filter 239 | # ~~~~~ 240 | # Play supports multiple methods for verifying that a request is not a CSRF request. 241 | # The primary mechanism is a CSRF token. This token gets placed either in the query string 242 | # or body of every form submitted, and also gets placed in the users session. 243 | # Play then verifies that both tokens are present and match. 244 | csrf { 245 | # Sets the cookie to be sent only over HTTPS 246 | #cookie.secure = true 247 | 248 | # Defaults to CSRFErrorHandler in the root package. 249 | #errorHandler = MyCSRFErrorHandler 250 | } 251 | 252 | ## Security headers filter configuration 253 | # https://www.playframework.com/documentation/latest/SecurityHeaders 254 | # ~~~~~ 255 | # Defines security headers that prevent XSS attacks. 256 | # If enabled, then all options are set to the below configuration by default: 257 | headers { 258 | # The X-Frame-Options header. If null, the header is not set. 259 | #frameOptions = "DENY" 260 | 261 | # The X-XSS-Protection header. If null, the header is not set. 262 | #xssProtection = "1; mode=block" 263 | 264 | # The X-Content-Type-Options header. If null, the header is not set. 265 | #contentTypeOptions = "nosniff" 266 | 267 | # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set. 268 | #permittedCrossDomainPolicies = "master-only" 269 | 270 | # The Content-Security-Policy header. If null, the header is not set. 271 | #contentSecurityPolicy = "default-src 'self'" 272 | } 273 | 274 | ## Allowed hosts filter configuration 275 | # https://www.playframework.com/documentation/latest/AllowedHostsFilter 276 | # ~~~~~ 277 | # Play provides a filter that lets you configure which hosts can access your application. 278 | # This is useful to prevent cache poisoning attacks. 279 | hosts { 280 | # Allow requests to example.com, its subdomains, and localhost:9000. 281 | #allowed = [".example.com", "localhost:9000"] 282 | } 283 | } 284 | 285 | ## Evolutions 286 | # https://www.playframework.com/documentation/latest/Evolutions 287 | # ~~~~~ 288 | # Evolutions allows database scripts to be automatically run on startup in dev mode 289 | # for database migrations. You must enable this by adding to build.sbt: 290 | # 291 | # libraryDependencies += evolutions 292 | # 293 | play.evolutions { 294 | # You can disable evolutions for a specific datasource if necessary 295 | #db.default.enabled = false 296 | } 297 | 298 | ## Database Connection Pool 299 | # https://www.playframework.com/documentation/latest/SettingsJDBC 300 | # ~~~~~ 301 | # Play doesn't require a JDBC database to run, but you can easily enable one. 302 | # 303 | # libraryDependencies += jdbc 304 | # 305 | play.db { 306 | # The combination of these two settings results in "db.default" as the 307 | # default JDBC pool: 308 | #config = "db" 309 | #default = "default" 310 | 311 | # Play uses HikariCP as the default connection pool. You can override 312 | # settings by changing the prototype: 313 | prototype { 314 | # Sets a fixed JDBC connection pool size of 50 315 | #hikaricp.minimumIdle = 50 316 | #hikaricp.maximumPoolSize = 50 317 | } 318 | } 319 | 320 | ## JDBC Datasource 321 | # https://www.playframework.com/documentation/latest/JavaDatabase 322 | # https://www.playframework.com/documentation/latest/ScalaDatabase 323 | # ~~~~~ 324 | # Once JDBC datasource is set up, you can work with several different 325 | # database options: 326 | # 327 | # Slick (Scala preferred option): https://www.playframework.com/documentation/latest/PlaySlick 328 | # JPA (Java preferred option): https://playframework.com/documentation/latest/JavaJPA 329 | # EBean: https://playframework.com/documentation/latest/JavaEbean 330 | # Anorm: https://www.playframework.com/documentation/latest/ScalaAnorm 331 | # 332 | db { 333 | # You can declare as many datasources as you want. 334 | # By convention, the default datasource is named `default` 335 | 336 | # https://www.playframework.com/documentation/latest/Developing-with-the-H2-Database 337 | #default.driver = org.h2.Driver 338 | #default.url = "jdbc:h2:mem:play" 339 | #default.username = sa 340 | #default.password = "" 341 | 342 | # You can turn on SQL logging for any datasource 343 | # https://www.playframework.com/documentation/latest/Highlights25#Logging-SQL-statements 344 | #default.logSql=true 345 | } 346 | --------------------------------------------------------------------------------