├── project ├── plugins.sbt └── build.properties ├── activator-launch-1.3.7.jar ├── .gitignore ├── conf ├── evolutions │ └── default │ │ └── 1.sql ├── routes ├── logback.xml └── application.conf ├── activator.properties ├── app ├── models │ ├── entities │ │ └── Supplier.scala │ └── repos │ │ └── SupplierRepository.scala ├── util │ └── DBImplicits.scala ├── Module.scala └── controllers │ └── SuppliersController.scala ├── LICENSE ├── README.md ├── tutorial └── index.html ├── test └── ApplicationSpec.scala ├── activator.bat └── activator /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | // The Play plugin 2 | addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.12") 3 | -------------------------------------------------------------------------------- /activator-launch-1.3.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/play-slick-rest/HEAD/activator-launch-1.3.7.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | target 3 | /.idea 4 | /.idea_modules 5 | /.classpath 6 | /.project 7 | /.settings 8 | /RUNNING_PID 9 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | #Activator-generated Properties 2 | #Fri Mar 04 19:26:42 UTC 2016 3 | template.uuid=1c7228d8-76c3-4463-9912-bafe53ed6b37 4 | sbt.version=0.13.11 5 | -------------------------------------------------------------------------------- /conf/evolutions/default/1.sql: -------------------------------------------------------------------------------- 1 | # --- !Ups 2 | 3 | create table "SUPPLIERS" ("ID" BIGSERIAL NOT NULL PRIMARY KEY,"name" VARCHAR(254) NOT NULL,"desc" VARCHAR(254) NOT NULL); 4 | 5 | # --- !Downs 6 | ; 7 | drop table "SUPPLIERS"; -------------------------------------------------------------------------------- /activator.properties: -------------------------------------------------------------------------------- 1 | name=play-slick-rest 2 | title= Play Slick Rest 3 | tags=play,slick,rest,async 4 | description=The Play Slick Rest is a very simple json rest api showing one way of using Play Framework 2.5 with slick 3 library for database access. 5 | -------------------------------------------------------------------------------- /app/models/entities/Supplier.scala: -------------------------------------------------------------------------------- 1 | package models.entities 2 | 3 | import com.byteslounge.slickrepo.meta.{Entity, Keyed} 4 | 5 | case class Supplier(override val id: Option[Int], name: String, desc: String) extends Entity[Supplier, Int]{ 6 | def withId(id: Int): Supplier = this.copy(id = Some(id)) 7 | } -------------------------------------------------------------------------------- /conf/routes: -------------------------------------------------------------------------------- 1 | # Routes 2 | # This file defines all application routes (Higher priority routes first) 3 | # ~~~~ 4 | 5 | # An example controller showing how to write asynchronous code 6 | GET /supplier/:id controllers.SuppliersController.supplier(id : Int) 7 | POST /supplier controllers.SuppliersController.insertSupplier 8 | -------------------------------------------------------------------------------- /app/util/DBImplicits.scala: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import com.google.inject.Inject 4 | import play.api.db.slick.DatabaseConfigProvider 5 | import slick.dbio.DBIO 6 | import slick.jdbc.JdbcProfile 7 | import scala.concurrent.Future 8 | 9 | class DBImplicits @Inject()(dbConfigProvider: DatabaseConfigProvider) { 10 | implicit def executeOperation[T](databaseOperation: DBIO[T]): Future[T] = { 11 | dbConfigProvider.get[JdbcProfile].db.run(databaseOperation) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This software is licensed under the Apache 2 license, quoted below. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with 4 | the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 5 | 6 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an 7 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 8 | language governing permissions and limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # play-slick-rest 2 | The Play Slick Rest is a very simple json rest api showing one way of using Play Framework 2.5 with [slick 3](https://github.com/slick/slick) library for database access. 3 | 4 | 5 | It supports the following features: 6 | 7 | * Generic Data Access layer, using [slick-repo](https://github.com/gonmarques/slick-repo) 8 | 9 | The project was thought to be used as an activator template. 10 | 11 | #Running 12 | 13 | The database pre-configured is an h2, so you just have to: 14 | 15 | 16 | $ sbt run 17 | 18 | #Testing 19 | 20 | To run all tests (routes and persistence tests): 21 | 22 | 23 | $ sbt test 24 | 25 | #Using 26 | 27 | curl --request POST localhost:9000/supplier -H "Content-type: application/json" --data "{\"name\" : \"sup1\",\"desc\" : \"low prices\"}" 28 | 29 | curl localhost:9000/supplier/1 30 | 31 | 32 | #Credits 33 | 34 | To make this template, I just mixed tutorials and templates, so credits for play and slick guys and slick-repo owner. 35 | -------------------------------------------------------------------------------- /app/models/repos/SupplierRepository.scala: -------------------------------------------------------------------------------- 1 | package models.repos 2 | 3 | import com.byteslounge.slickrepo.meta.Keyed 4 | import com.byteslounge.slickrepo.repository.Repository 5 | import com.google.inject.Inject 6 | import models.entities.Supplier 7 | import play.api.db.slick.DatabaseConfigProvider 8 | import slick.ast.BaseTypedType 9 | import slick.jdbc.JdbcProfile 10 | 11 | class SupplierRepository @Inject()(dbConfigProvider: DatabaseConfigProvider) extends Repository[Supplier, Int](dbConfigProvider.get[JdbcProfile].profile) { 12 | import driver.api._ 13 | val pkType = implicitly[BaseTypedType[Int]] 14 | val tableQuery = TableQuery[Suppliers] 15 | type TableType = Suppliers 16 | 17 | class Suppliers(tag: slick.lifted.Tag) extends Table[Supplier](tag, "SUPPLIERS") with Keyed[Int] { 18 | def id = column[Int]("ID", O.PrimaryKey, O.AutoInc) 19 | def name = column[String]("name") 20 | def desc = column[String]("desc") 21 | def * = (id.?, name, desc) <> ((Supplier.apply _).tupled, Supplier.unapply) 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/Module.scala: -------------------------------------------------------------------------------- 1 | import com.google.inject.{AbstractModule, Inject, Provides} 2 | import java.time.Clock 3 | 4 | import models.repos.SupplierRepository 5 | import play.api.{Configuration, Environment} 6 | import util.DBImplicits 7 | 8 | import scala.concurrent.Future 9 | 10 | 11 | /** 12 | * This class is a Guice module that tells Guice how to bind several 13 | * different types. This Guice module is created when the Play 14 | * application starts. 15 | 16 | * Play will automatically use any class called `Module` that is in 17 | * the root package. You can create modules in other locations by 18 | * adding `play.modules.enabled` settings to the `application.conf` 19 | * configuration file. 20 | */ 21 | class Module (environment: Environment, 22 | configuration: Configuration) extends AbstractModule { 23 | 24 | override def configure() = { 25 | // Use the system clock as the default implementation of Clock 26 | bind(classOf[Clock]).toInstance(Clock.systemDefaultZone) 27 | bind(classOf[SupplierRepository]).asEagerSingleton() 28 | bind(classOf[DBImplicits]).asEagerSingleton() 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /app/controllers/SuppliersController.scala: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import javax.inject._ 4 | 5 | import models.entities.Supplier 6 | import models.repos.SupplierRepository 7 | import play.api.libs.json.{Json, Writes} 8 | import play.api.mvc._ 9 | import util.DBImplicits 10 | 11 | import scala.concurrent.Future 12 | import play.api.libs.concurrent.Execution.Implicits._ 13 | 14 | @Singleton 15 | class SuppliersController @Inject()(suppliersDAO : SupplierRepository, dbExecuter: DBImplicits) extends Controller { 16 | import dbExecuter.executeOperation 17 | 18 | implicit val supplierWrites = new Writes[Supplier] { 19 | def writes(sup: Supplier) = Json.obj( 20 | "id" -> sup.id, 21 | "name" -> sup.name, 22 | "desc" -> sup.desc 23 | ) 24 | } 25 | 26 | def supplier(id : Int) = Action.async { 27 | suppliersDAO.findOne(id) map { sup => sup.fold(NoContent)(sup => Ok(Json.toJson(sup))) } 28 | } 29 | 30 | def insertSupplier = Action.async(parse.json) { 31 | request => { 32 | for { 33 | name <- (request.body \ "name").asOpt[String] 34 | desc <- (request.body \ "desc").asOpt[String] 35 | } yield { 36 | suppliersDAO.save(Supplier(None, name, desc)).mapTo[Supplier] map { 37 | sup => Created("Id of Supplier Added : " + sup.id.getOrElse(0)) 38 | } recoverWith { 39 | case _ => Future { InternalServerError("Something wrong on server")} 40 | } 41 | } 42 | }.getOrElse(Future { 43 | BadRequest("Wrong json format") 44 | }) 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /conf/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ${application.home:-.}/logs/application.log 8 | 9 | %date [%level] from %logger in %thread - %message%n%xException 10 | 11 | 12 | 13 | 14 | 15 | %coloredLevel %logger{15} - %message%n%xException{10} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tutorial/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Slick Akka Http 5 | 6 | 7 |
8 |

Intro

9 | 10 |

The Play Slick Rest is a very simple json rest api showing one way of using Play 2.5 with Slick 3.1 for database access. 11 |

12 | 13 |

Running

14 | 15 |

16 | The project was thought to be used as a seed for creating akka-http projects with slick, so the implementation is minimal. The model is very simple, is a supplier with a name and description. 17 |

18 | The rest api has a get and a post (json), a get for get all the suppliers, and a post to add suppliers. You should view this info in swagger with more detail. 19 |

20 | For running the project go to section run, and run it. 21 |

22 | For running the project in sbt: 23 | 24 |


25 |     $ sbt
26 |     > run
27 |     
28 |     
29 | 30 |
31 | 32 | 33 | 34 |
35 |

Slick 3

36 |

Models as case classes and slick 3 schemas extending from a BaseEntity and BaseTable

37 | 38 |
 case class Supplier(name: String,desc: String)  extends BaseEntity 
39 | 40 | 41 |

42 |     class SuppliersTable(tag: Tag) extends BaseTable[Supplier](tag, "suppliers") {
43 |       def name = column[String]("name")
44 |       def desc = column[String]("desc")
45 |       def * = (id, name, desc) <> (Supplier.tupled, Supplier.unapply)
46 |     }
47 | 48 | 49 |

BaseEntity and BaseTable provide Id for the class and table.

50 | 51 |
52 | 53 |
54 |

Generic DAO

55 |

This seed has a generic slick DAO that can be used to implement a crud for an entity.

56 |

The generic DAO is used to create a suppliers DAO in Module:

57 | 58 |

59 |     @Provides
60 |     def provideSuppliersDAO : AbstractBaseDAO[SuppliersTable,Supplier] = new BaseDAO[SuppliersTable,Supplier]{
61 |           override protected val tableQ: dbConfig.driver.api.TableQuery[SuppliersTable] = SlickTables.suppliersTableQ
62 |     }
63 |     
64 | 65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /test/ApplicationSpec.scala: -------------------------------------------------------------------------------- 1 | import java.time.Clock 2 | 3 | import com.google.inject.{AbstractModule, Provides} 4 | import models.entities.Supplier 5 | import models.repos.SupplierRepository 6 | import play.api.inject.guice.GuiceApplicationBuilder 7 | import play.api.test._ 8 | import org.specs2.execute.Results 9 | import org.specs2.matcher.Matchers 10 | import org.specs2.mock.Mockito 11 | import play.api.libs.json.{JsObject, JsString} 12 | import slick.dbio.DBIOAction 13 | import play.api.libs.concurrent.Execution.Implicits._ 14 | import slick.SlickException 15 | 16 | import scala.concurrent.{ExecutionContext, Future} 17 | 18 | class ApplicationSpec extends PlaySpecification with Results with Matchers with Mockito{ 19 | sequential 20 | 21 | val daoMock = mock[SupplierRepository] 22 | 23 | val application = new GuiceApplicationBuilder().overrides(new AbstractModule { 24 | override def configure() = { 25 | bind(classOf[Clock]).toInstance(Clock.systemDefaultZone) 26 | } 27 | @Provides 28 | def suppliersDAO : SupplierRepository = daoMock 29 | }).build 30 | 31 | "Routes" should { 32 | 33 | "send 404 on a bad request" in { 34 | route(application, FakeRequest(GET, "/boum")).map(status(_)) shouldEqual Some(NOT_FOUND) 35 | } 36 | 37 | "send 204 when there isn't a /supplier/1" in { 38 | daoMock.findOne(0).returns(DBIOAction.from(Future{None})) 39 | route(application, FakeRequest(GET, "/supplier/0")).map( 40 | status(_)) shouldEqual Some(NO_CONTENT) 41 | } 42 | 43 | "send 200 when there is a /supplier/1" in { 44 | daoMock.findOne(1).returns(DBIOAction.from(Future{ Some(Supplier(Some(1),"name","desc")) })) 45 | route(application, FakeRequest(GET, "/supplier/1")).map( 46 | status(_)) shouldEqual Some(OK) 47 | } 48 | 49 | "send 415 when post to create a supplier without json type" in { 50 | route(application, FakeRequest(POST, "/supplier")).map( 51 | status(_)) shouldEqual Some(UNSUPPORTED_MEDIA_TYPE) 52 | } 53 | 54 | "send 400 when post to create a supplier with empty json" in { 55 | route(application, 56 | FakeRequest(POST, "/supplier", FakeHeaders(("Content-type","application/json") :: Nil),JsObject(Seq()))).map( 57 | status(_)) shouldEqual Some(BAD_REQUEST) 58 | } 59 | 60 | "send 400 when post to create a supplier with wrong json" in { 61 | route(application, 62 | FakeRequest(POST, "/supplier", FakeHeaders(("Content-type","application/json") :: Nil),JsObject(Seq("wrong" -> JsString("wrong"))))).map( 63 | status(_)) shouldEqual Some(BAD_REQUEST) 64 | } 65 | 66 | "send 201 when post to create a supplier with valid json" in { 67 | val (name,desc) = ("Apple","Shut up and take my money") 68 | val supplier = Supplier(None, name, desc) 69 | daoMock.save(supplier).returns(DBIOAction.from(Future{supplier.copy(id = Some(1))})) 70 | route(application, 71 | FakeRequest(POST, "/supplier", FakeHeaders(("Content-type","application/json") :: Nil), 72 | JsObject(Seq("name" -> JsString(name),"desc" -> JsString(desc))))).map( 73 | status(_)) shouldEqual Some(CREATED) 74 | } 75 | 76 | "send 500 when post to create a supplier with valid json" in { 77 | val (name,desc) = ("Apple","Shut up and take my money") 78 | val supplier = Supplier(None, name, desc) 79 | daoMock.save(supplier).returns(DBIOAction.failed(new SlickException("test"))) 80 | route(application, 81 | FakeRequest(POST, "/supplier", FakeHeaders(("Content-type","application/json") :: Nil), 82 | JsObject(Seq("name" -> JsString(name),"desc" -> JsString(desc))))).map( 83 | status(_)) shouldEqual Some(INTERNAL_SERVER_ERROR) 84 | } 85 | 86 | } 87 | 88 | } 89 | 90 | -------------------------------------------------------------------------------- /activator.bat: -------------------------------------------------------------------------------- 1 | @REM activator launcher script 2 | @REM 3 | @REM Environment: 4 | @REM In order for Activator to work you must have Java available on the classpath 5 | @REM JAVA_HOME - location of a JDK home dir (optional if java on path) 6 | @REM CFG_OPTS - JVM options (optional) 7 | @REM Configuration: 8 | @REM activatorconfig.txt found in the ACTIVATOR_HOME or ACTIVATOR_HOME/ACTIVATOR_VERSION 9 | @setlocal enabledelayedexpansion 10 | 11 | @echo off 12 | 13 | set "var1=%~1" 14 | if defined var1 ( 15 | if "%var1%"=="help" ( 16 | echo. 17 | echo Usage activator [options] [command] 18 | echo. 19 | echo Commands: 20 | echo ui Start the Activator UI 21 | echo new [name] [template-id] Create a new project with [name] using template [template-id] 22 | echo list-templates Print all available template names 23 | echo help Print this message 24 | echo. 25 | echo Options: 26 | echo -jvm-debug [port] Turn on JVM debugging, open at the given port. Defaults to 9999 if no port given. 27 | echo. 28 | echo Environment variables ^(read from context^): 29 | echo JAVA_OPTS Environment variable, if unset uses "" 30 | echo SBT_OPTS Environment variable, if unset uses "" 31 | echo ACTIVATOR_OPTS Environment variable, if unset uses "" 32 | echo. 33 | echo Please note that in order for Activator to work you must have Java available on the classpath 34 | echo. 35 | goto :end 36 | ) 37 | ) 38 | 39 | if "%ACTIVATOR_HOME%"=="" ( 40 | set "ACTIVATOR_HOME=%~dp0" 41 | @REM remove trailing "\" from path 42 | set ACTIVATOR_HOME=!ACTIVATOR_HOME:~0,-1! 43 | ) 44 | 45 | set ERROR_CODE=0 46 | set APP_VERSION=1.3.7 47 | set ACTIVATOR_LAUNCH_JAR=activator-launch-%APP_VERSION%.jar 48 | 49 | rem Detect if we were double clicked, although theoretically A user could 50 | rem manually run cmd /c 51 | for %%x in (%cmdcmdline%) do if %%~x==/c set DOUBLECLICKED=1 52 | 53 | rem FIRST we load a config file of extra options (if there is one) 54 | set "CFG_FILE_HOME=%UserProfile%\.activator\activatorconfig.txt" 55 | set "CFG_FILE_VERSION=%UserProfile%\.activator\%APP_VERSION%\activatorconfig.txt" 56 | set CFG_OPTS= 57 | if exist %CFG_FILE_VERSION% ( 58 | FOR /F "tokens=* eol=# usebackq delims=" %%i IN ("%CFG_FILE_VERSION%") DO ( 59 | set DO_NOT_REUSE_ME=%%i 60 | rem ZOMG (Part #2) WE use !! here to delay the expansion of 61 | rem CFG_OPTS, otherwise it remains "" for this loop. 62 | set CFG_OPTS=!CFG_OPTS! !DO_NOT_REUSE_ME! 63 | ) 64 | ) 65 | if "%CFG_OPTS%"=="" ( 66 | if exist %CFG_FILE_HOME% ( 67 | FOR /F "tokens=* eol=# usebackq delims=" %%i IN ("%CFG_FILE_HOME%") DO ( 68 | set DO_NOT_REUSE_ME=%%i 69 | rem ZOMG (Part #2) WE use !! here to delay the expansion of 70 | rem CFG_OPTS, otherwise it remains "" for this loop. 71 | set CFG_OPTS=!CFG_OPTS! !DO_NOT_REUSE_ME! 72 | ) 73 | ) 74 | ) 75 | 76 | rem We use the value of the JAVACMD environment variable if defined 77 | set _JAVACMD=%JAVACMD% 78 | 79 | if "%_JAVACMD%"=="" ( 80 | if not "%JAVA_HOME%"=="" ( 81 | if exist "%JAVA_HOME%\bin\java.exe" set "_JAVACMD=%JAVA_HOME%\bin\java.exe" 82 | 83 | rem if there is a java home set we make sure it is the first picked up when invoking 'java' 84 | SET "PATH=%JAVA_HOME%\bin;%PATH%" 85 | ) 86 | ) 87 | 88 | if "%_JAVACMD%"=="" set _JAVACMD=java 89 | 90 | rem Detect if this java is ok to use. 91 | for /F %%j in ('"%_JAVACMD%" -version 2^>^&1') do ( 92 | if %%~j==java set JAVAINSTALLED=1 93 | if %%~j==openjdk set JAVAINSTALLED=1 94 | ) 95 | 96 | rem Detect the same thing about javac 97 | if "%_JAVACCMD%"=="" ( 98 | if not "%JAVA_HOME%"=="" ( 99 | if exist "%JAVA_HOME%\bin\javac.exe" set "_JAVACCMD=%JAVA_HOME%\bin\javac.exe" 100 | ) 101 | ) 102 | if "%_JAVACCMD%"=="" set _JAVACCMD=javac 103 | for /F %%j in ('"%_JAVACCMD%" -version 2^>^&1') do ( 104 | if %%~j==javac set JAVACINSTALLED=1 105 | ) 106 | 107 | rem BAT has no logical or, so we do it OLD SCHOOL! Oppan Redmond Style 108 | set JAVAOK=true 109 | if not defined JAVAINSTALLED set JAVAOK=false 110 | if not defined JAVACINSTALLED set JAVAOK=false 111 | 112 | if "%JAVAOK%"=="false" ( 113 | echo. 114 | echo A Java JDK is not installed or can't be found. 115 | if not "%JAVA_HOME%"=="" ( 116 | echo JAVA_HOME = "%JAVA_HOME%" 117 | ) 118 | echo. 119 | echo Please go to 120 | echo http://www.oracle.com/technetwork/java/javase/downloads/index.html 121 | echo and download a valid Java JDK and install before running Activator. 122 | echo. 123 | echo If you think this message is in error, please check 124 | echo your environment variables to see if "java.exe" and "javac.exe" are 125 | echo available via JAVA_HOME or PATH. 126 | echo. 127 | if defined DOUBLECLICKED pause 128 | exit /B 1 129 | ) 130 | 131 | rem Check what Java version is being used to determine what memory options to use 132 | for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do ( 133 | set JAVA_VERSION=%%g 134 | ) 135 | 136 | rem Strips away the " characters 137 | set JAVA_VERSION=%JAVA_VERSION:"=% 138 | 139 | rem TODO Check if there are existing mem settings in JAVA_OPTS/CFG_OPTS and use those instead of the below 140 | for /f "delims=. tokens=1-3" %%v in ("%JAVA_VERSION%") do ( 141 | set MAJOR=%%v 142 | set MINOR=%%w 143 | set BUILD=%%x 144 | 145 | set META_SIZE=-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=256M 146 | if "!MINOR!" LSS "8" ( 147 | set META_SIZE=-XX:PermSize=64M -XX:MaxPermSize=256M 148 | ) 149 | 150 | set MEM_OPTS=!META_SIZE! 151 | ) 152 | 153 | rem We use the value of the JAVA_OPTS environment variable if defined, rather than the config. 154 | set _JAVA_OPTS=%JAVA_OPTS% 155 | if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=%CFG_OPTS% 156 | 157 | set DEBUG_OPTS= 158 | 159 | rem Loop through the arguments, building remaining args in args variable 160 | set args= 161 | :argsloop 162 | if not "%~1"=="" ( 163 | rem Checks if the argument contains "-D" and if true, adds argument 1 with 2 and puts an equal sign between them. 164 | rem This is done since batch considers "=" to be a delimiter so we need to circumvent this behavior with a small hack. 165 | set arg1=%~1 166 | if "!arg1:~0,2!"=="-D" ( 167 | set "args=%args% "%~1"="%~2"" 168 | shift 169 | shift 170 | goto argsloop 171 | ) 172 | 173 | if "%~1"=="-jvm-debug" ( 174 | if not "%~2"=="" ( 175 | rem This piece of magic somehow checks that an argument is a number 176 | for /F "delims=0123456789" %%i in ("%~2") do ( 177 | set var="%%i" 178 | ) 179 | if defined var ( 180 | rem Not a number, assume no argument given and default to 9999 181 | set JPDA_PORT=9999 182 | ) else ( 183 | rem Port was given, shift arguments 184 | set JPDA_PORT=%~2 185 | shift 186 | ) 187 | ) else ( 188 | set JPDA_PORT=9999 189 | ) 190 | shift 191 | 192 | set DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=!JPDA_PORT! 193 | goto argsloop 194 | ) 195 | rem else 196 | set "args=%args% "%~1"" 197 | shift 198 | goto argsloop 199 | ) 200 | 201 | :run 202 | 203 | if "!args!"=="" ( 204 | if defined DOUBLECLICKED ( 205 | set CMDS="ui" 206 | ) else set CMDS=!args! 207 | ) else set CMDS=!args! 208 | 209 | rem We add a / in front, so we get file:///C: instead of file://C: 210 | rem Java considers the later a UNC path. 211 | rem We also attempt a solid effort at making it URI friendly. 212 | rem We don't even bother with UNC paths. 213 | set JAVA_FRIENDLY_HOME_1=/!ACTIVATOR_HOME:\=/! 214 | set JAVA_FRIENDLY_HOME=/!JAVA_FRIENDLY_HOME_1: =%%20! 215 | 216 | rem Checks if the command contains spaces to know if it should be wrapped in quotes or not 217 | set NON_SPACED_CMD=%_JAVACMD: =% 218 | if "%_JAVACMD%"=="%NON_SPACED_CMD%" %_JAVACMD% %DEBUG_OPTS% %MEM_OPTS% %ACTIVATOR_OPTS% %SBT_OPTS% %_JAVA_OPTS% "-Dactivator.home=%JAVA_FRIENDLY_HOME%" -jar "%ACTIVATOR_HOME%\%ACTIVATOR_LAUNCH_JAR%" %CMDS% 219 | if NOT "%_JAVACMD%"=="%NON_SPACED_CMD%" "%_JAVACMD%" %DEBUG_OPTS% %MEM_OPTS% %ACTIVATOR_OPTS% %SBT_OPTS% %_JAVA_OPTS% "-Dactivator.home=%JAVA_FRIENDLY_HOME%" -jar "%ACTIVATOR_HOME%\%ACTIVATOR_LAUNCH_JAR%" %CMDS% 220 | 221 | if ERRORLEVEL 1 goto error 222 | goto end 223 | 224 | :error 225 | set ERROR_CODE=1 226 | 227 | :end 228 | 229 | @endlocal 230 | 231 | exit /B %ERROR_CODE% 232 | -------------------------------------------------------------------------------- /activator: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ### ------------------------------- ### 4 | ### Helper methods for BASH scripts ### 5 | ### ------------------------------- ### 6 | 7 | realpath () { 8 | ( 9 | TARGET_FILE="$1" 10 | 11 | cd "$(dirname "$TARGET_FILE")" 12 | TARGET_FILE=$(basename "$TARGET_FILE") 13 | 14 | COUNT=0 15 | while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ] 16 | do 17 | TARGET_FILE=$(readlink "$TARGET_FILE") 18 | cd "$(dirname "$TARGET_FILE")" 19 | TARGET_FILE=$(basename "$TARGET_FILE") 20 | COUNT=$(($COUNT + 1)) 21 | done 22 | 23 | if [ "$TARGET_FILE" == "." -o "$TARGET_FILE" == ".." ]; then 24 | cd "$TARGET_FILE" 25 | TARGET_FILEPATH= 26 | else 27 | TARGET_FILEPATH=/$TARGET_FILE 28 | fi 29 | 30 | # make sure we grab the actual windows path, instead of cygwin's path. 31 | if ! is_cygwin; then 32 | echo "$(pwd -P)/$TARGET_FILE" 33 | else 34 | echo $(cygwinpath "$(pwd -P)/$TARGET_FILE") 35 | fi 36 | ) 37 | } 38 | 39 | # TODO - Do we need to detect msys? 40 | 41 | # Uses uname to detect if we're in the odd cygwin environment. 42 | is_cygwin() { 43 | local os=$(uname -s) 44 | case "$os" in 45 | CYGWIN*) return 0 ;; 46 | *) return 1 ;; 47 | esac 48 | } 49 | 50 | # This can fix cygwin style /cygdrive paths so we get the 51 | # windows style paths. 52 | cygwinpath() { 53 | local file="$1" 54 | if is_cygwin; then 55 | echo $(cygpath -w $file) 56 | else 57 | echo $file 58 | fi 59 | } 60 | 61 | # Make something URI friendly 62 | make_url() { 63 | url="$1" 64 | local nospaces=${url// /%20} 65 | if is_cygwin; then 66 | echo "/${nospaces//\\//}" 67 | else 68 | echo "$nospaces" 69 | fi 70 | } 71 | 72 | # Detect if we should use JAVA_HOME or just try PATH. 73 | get_java_cmd() { 74 | if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then 75 | echo "$JAVA_HOME/bin/java" 76 | else 77 | echo "java" 78 | fi 79 | } 80 | 81 | echoerr () { 82 | echo 1>&2 "$@" 83 | } 84 | vlog () { 85 | [[ $verbose || $debug ]] && echoerr "$@" 86 | } 87 | dlog () { 88 | [[ $debug ]] && echoerr "$@" 89 | } 90 | execRunner () { 91 | # print the arguments one to a line, quoting any containing spaces 92 | [[ $verbose || $debug ]] && echo "# Executing command line:" && { 93 | for arg; do 94 | if printf "%s\n" "$arg" | grep -q ' '; then 95 | printf "\"%s\"\n" "$arg" 96 | else 97 | printf "%s\n" "$arg" 98 | fi 99 | done 100 | echo "" 101 | } 102 | 103 | exec "$@" 104 | } 105 | addJava () { 106 | dlog "[addJava] arg = '$1'" 107 | java_args=( "${java_args[@]}" "$1" ) 108 | } 109 | addApp () { 110 | dlog "[addApp] arg = '$1'" 111 | sbt_commands=( "${app_commands[@]}" "$1" ) 112 | } 113 | addResidual () { 114 | dlog "[residual] arg = '$1'" 115 | residual_args=( "${residual_args[@]}" "$1" ) 116 | } 117 | addDebugger () { 118 | addJava "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" 119 | } 120 | addConfigOpts () { 121 | dlog "[addConfigOpts] arg = '$*'" 122 | for item in $* 123 | do 124 | addJava "$item" 125 | done 126 | } 127 | # a ham-fisted attempt to move some memory settings in concert 128 | # so they need not be messed around with individually. 129 | get_mem_opts () { 130 | local mem=${1:-1024} 131 | local meta=$(( $mem / 4 )) 132 | (( $meta > 256 )) || meta=256 133 | (( $meta < 1024 )) || meta=1024 134 | 135 | # default is to set memory options but this can be overridden by code section below 136 | memopts="-Xms${mem}m -Xmx${mem}m" 137 | if [[ "${java_version}" > "1.8" ]]; then 138 | extmemopts="-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=${meta}m" 139 | else 140 | extmemopts="-XX:PermSize=64m -XX:MaxPermSize=${meta}m" 141 | fi 142 | 143 | if [[ "${java_opts}" == *-Xmx* ]] || [[ "${java_opts}" == *-Xms* ]] || [[ "${java_opts}" == *-XX:MaxPermSize* ]] || [[ "${java_opts}" == *-XX:ReservedCodeCacheSize* ]] || [[ "${java_opts}" == *-XX:MaxMetaspaceSize* ]]; then 144 | # if we detect any of these settings in ${java_opts} we need to NOT output our settings. 145 | # The reason is the Xms/Xmx, if they don't line up, cause errors. 146 | memopts="" 147 | extmemopts="" 148 | fi 149 | 150 | echo "${memopts} ${extmemopts}" 151 | } 152 | require_arg () { 153 | local type="$1" 154 | local opt="$2" 155 | local arg="$3" 156 | if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then 157 | die "$opt requires <$type> argument" 158 | fi 159 | } 160 | is_function_defined() { 161 | declare -f "$1" > /dev/null 162 | } 163 | 164 | # If we're *not* running in a terminal, and we don't have any arguments, then we need to add the 'ui' parameter 165 | detect_terminal_for_ui() { 166 | [[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && { 167 | addResidual "ui" 168 | } 169 | # SPECIAL TEST FOR MAC 170 | [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && { 171 | echo "Detected MAC OSX launched script...." 172 | echo "Swapping to UI" 173 | addResidual "ui" 174 | } 175 | } 176 | 177 | # Processes incoming arguments and places them in appropriate global variables. called by the run method. 178 | process_args () { 179 | while [[ $# -gt 0 ]]; do 180 | case "$1" in 181 | -h|-help) usage; exit 1 ;; 182 | -v|-verbose) verbose=1 && shift ;; 183 | -d|-debug) debug=1 && shift ;; 184 | -mem) require_arg integer "$1" "$2" && app_mem="$2" && shift 2 ;; 185 | -jvm-debug) 186 | if echo "$2" | grep -E ^[0-9]+$ > /dev/null; then 187 | addDebugger "$2" && shift 188 | else 189 | addDebugger 9999 190 | fi 191 | shift ;; 192 | -java-home) require_arg path "$1" "$2" && java_cmd="$2/bin/java" && shift 2 ;; 193 | -D*) addJava "$1" && shift ;; 194 | -J*) addJava "${1:2}" && shift ;; 195 | *) addResidual "$1" && shift ;; 196 | esac 197 | done 198 | 199 | is_function_defined process_my_args && { 200 | myargs=("${residual_args[@]}") 201 | residual_args=() 202 | process_my_args "${myargs[@]}" 203 | } 204 | } 205 | 206 | # Actually runs the script. 207 | run() { 208 | # TODO - check for sane environment 209 | 210 | # process the combined args, then reset "$@" to the residuals 211 | process_args "$@" 212 | detect_terminal_for_ui 213 | set -- "${residual_args[@]}" 214 | argumentCount=$# 215 | 216 | #check for jline terminal fixes on cygwin 217 | if is_cygwin; then 218 | stty -icanon min 1 -echo > /dev/null 2>&1 219 | addJava "-Djline.terminal=jline.UnixTerminal" 220 | addJava "-Dsbt.cygwin=true" 221 | fi 222 | 223 | # run sbt 224 | execRunner "$java_cmd" \ 225 | "-Dactivator.home=$(make_url "$activator_home")" \ 226 | $(get_mem_opts $app_mem) \ 227 | ${java_opts[@]} \ 228 | ${java_args[@]} \ 229 | -jar "$app_launcher" \ 230 | "${app_commands[@]}" \ 231 | "${residual_args[@]}" 232 | 233 | local exit_code=$? 234 | if is_cygwin; then 235 | stty icanon echo > /dev/null 2>&1 236 | fi 237 | exit $exit_code 238 | } 239 | 240 | # Loads a configuration file full of default command line options for this script. 241 | loadConfigFile() { 242 | cat "$1" | sed '/^\#/d' 243 | } 244 | 245 | ### ------------------------------- ### 246 | ### Start of customized settings ### 247 | ### ------------------------------- ### 248 | usage() { 249 | cat < [options] 251 | 252 | Command: 253 | ui Start the Activator UI 254 | new [name] [template-id] Create a new project with [name] using template [template-id] 255 | list-templates Print all available template names 256 | -h | -help Print this message 257 | 258 | Options: 259 | -v | -verbose Make this runner chattier 260 | -d | -debug Set sbt log level to debug 261 | -mem Set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem)) 262 | -jvm-debug Turn on JVM debugging, open at the given port. 263 | 264 | # java version (default: java from PATH, currently $(java -version 2>&1 | grep version)) 265 | -java-home Alternate JAVA_HOME 266 | 267 | # jvm options and output control 268 | -Dkey=val Pass -Dkey=val directly to the java runtime 269 | -J-X Pass option -X directly to the java runtime 270 | (-J is stripped) 271 | 272 | # environment variables (read from context) 273 | JAVA_OPTS Environment variable, if unset uses "" 274 | SBT_OPTS Environment variable, if unset uses "" 275 | ACTIVATOR_OPTS Environment variable, if unset uses "" 276 | 277 | In the case of duplicated or conflicting options, the order above 278 | shows precedence: environment variables lowest, command line options highest. 279 | EOM 280 | } 281 | 282 | ### ------------------------------- ### 283 | ### Main script ### 284 | ### ------------------------------- ### 285 | 286 | declare -a residual_args 287 | declare -a java_args 288 | declare -a app_commands 289 | declare -r real_script_path="$(realpath "$0")" 290 | declare -r activator_home="$(realpath "$(dirname "$real_script_path")")" 291 | declare -r app_version="1.3.7" 292 | 293 | declare -r app_launcher="${activator_home}/activator-launch-${app_version}.jar" 294 | declare -r script_name=activator 295 | java_cmd=$(get_java_cmd) 296 | declare -r java_opts=( "${ACTIVATOR_OPTS[@]}" "${SBT_OPTS[@]}" "${JAVA_OPTS[@]}" "${java_opts[@]}" ) 297 | userhome="$HOME" 298 | if is_cygwin; then 299 | # cygwin sets home to something f-d up, set to real windows homedir 300 | userhome="$USERPROFILE" 301 | fi 302 | declare -r activator_user_home_dir="${userhome}/.activator" 303 | declare -r java_opts_config_home="${activator_user_home_dir}/activatorconfig.txt" 304 | declare -r java_opts_config_version="${activator_user_home_dir}/${app_version}/activatorconfig.txt" 305 | 306 | # Now check to see if it's a good enough version 307 | declare -r java_version=$("$java_cmd" -version 2>&1 | awk -F '"' '/version/ {print $2}') 308 | if [[ "$java_version" == "" ]]; then 309 | echo 310 | echo No java installations was detected. 311 | echo Please go to http://www.java.com/getjava/ and download 312 | echo 313 | exit 1 314 | elif [[ ! "$java_version" > "1.6" ]]; then 315 | echo 316 | echo The java installation you have is not up to date 317 | echo Activator requires at least version 1.6+, you have 318 | echo version $java_version 319 | echo 320 | echo Please go to http://www.java.com/getjava/ and download 321 | echo a valid Java Runtime and install before running Activator. 322 | echo 323 | exit 1 324 | fi 325 | 326 | # if configuration files exist, prepend their contents to the java args so it can be processed by this runner 327 | # a "versioned" config trumps one on the top level 328 | if [[ -f "$java_opts_config_version" ]]; then 329 | addConfigOpts $(loadConfigFile "$java_opts_config_version") 330 | elif [[ -f "$java_opts_config_home" ]]; then 331 | addConfigOpts $(loadConfigFile "$java_opts_config_home") 332 | fi 333 | 334 | run "$@" 335 | -------------------------------------------------------------------------------- /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.crypto.secret = "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 = true 296 | autoApply=true 297 | } 298 | 299 | ## Database Connection Pool 300 | # https://www.playframework.com/documentation/latest/SettingsJDBC 301 | # ~~~~~ 302 | # Play doesn't require a JDBC database to run, but you can easily enable one. 303 | # 304 | # libraryDependencies += jdbc 305 | # 306 | play.db { 307 | # The combination of these two settings results in "db.default" as the 308 | # default JDBC pool: 309 | #config = "db" 310 | #default = "default" 311 | 312 | # Play uses HikariCP as the default connection pool. You can override 313 | # settings by changing the prototype: 314 | prototype { 315 | # Sets a fixed JDBC connection pool size of 50 316 | #hikaricp.minimumIdle = 50 317 | #hikaricp.maximumPoolSize = 50 318 | } 319 | } 320 | 321 | ## JDBC Datasource 322 | # https://www.playframework.com/documentation/latest/JavaDatabase 323 | # https://www.playframework.com/documentation/latest/ScalaDatabase 324 | # ~~~~~ 325 | # Once JDBC datasource is set up, you can work with several different 326 | # database options: 327 | # 328 | # Slick (Scala preferred option): https://www.playframework.com/documentation/latest/PlaySlick 329 | # JPA (Java preferred option): https://playframework.com/documentation/latest/JavaJPA 330 | # EBean: https://playframework.com/documentation/latest/JavaEbean 331 | # Anorm: https://www.playframework.com/documentation/latest/ScalaAnorm 332 | # 333 | db { 334 | # You can declare as many datasources as you want. 335 | # By convention, the default datasource is named `default` 336 | 337 | # https://www.playframework.com/documentation/latest/Developing-with-the-H2-Database 338 | #default.driver = org.h2.Driver 339 | #default.url = "jdbc:h2:mem:play" 340 | #default.username = sa 341 | #default.password = "" 342 | 343 | # You can turn on SQL logging for any datasource 344 | # https://www.playframework.com/documentation/latest/Highlights25#Logging-SQL-statements 345 | #default.logSql=true 346 | } 347 | 348 | slick.dbs.default.driver="slick.driver.H2Driver$" 349 | slick.dbs.default.db.driver="org.h2.Driver" 350 | slick.dbs.default.db.url="jdbc:h2:mem:test" 351 | --------------------------------------------------------------------------------