rejection handling

This commit is contained in:
2019-10-31 22:23:03 +03:00
parent a84b947862
commit 2ad3600da5
9 changed files with 206 additions and 109 deletions

View File

@ -0,0 +1,27 @@
<included>
<appender name="application-base" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>[%-5level %d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%logger{50}]: %msg%n</pattern>
</encoder>
<file>application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<minIndex>1</minIndex>
<maxIndex>20</maxIndex>
<fileNamePattern>application.log.%i.gz</fileNamePattern>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>100MB</maxFileSize>
</triggeringPolicy>
</appender>
<appender name="application" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="application-base"/>
<queueSize>50000</queueSize>
<neverBlock>true</neverBlock>
</appender>
</included>

View File

@ -0,0 +1,27 @@
<included>
<appender name="http-base" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %marker %msg%n</pattern>
</encoder>
<file>http.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<minIndex>1</minIndex>
<maxIndex>20</maxIndex>
<fileNamePattern>http.log.%i.gz</fileNamePattern>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>100MB</maxFileSize>
</triggeringPolicy>
</appender>
<appender name="http" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="http-base"/>
<queueSize>50000</queueSize>
<neverBlock>true</neverBlock>
</appender>
</included>

View File

@ -1,5 +1,13 @@
<configuration>
<include resource="logback-application.xml" />
<include resource="logback-http.xml" />
<root level="debug">
<appender-ref ref="application" />
</root>
<logger name="me.arcanis.ffxivbis" level="DEBUG" />
<logger name="slick.jdbc.JdbcBackend.statement" level="DEBUG" />
</configuration>

View File

@ -29,7 +29,7 @@ import scala.util.{Failure, Success}
@Path("api/v1")
class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout)
extends BiSHelper(storage, ariyala) with Authorization with JsonSupport with HttpExceptionsHandler {
extends BiSHelper(storage, ariyala) with Authorization with JsonSupport with HttpHandler {
def route: Route = createBiS ~ getBiS ~ modifyBiS
@ -55,6 +55,7 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti
def createBiS: Route =
path("party" / Segment / "bis") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ =>
put {
@ -70,6 +71,7 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti
}
}
}
}
@GET
@Path("party/{partyId}/bis")
@ -95,6 +97,7 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti
def getBiS: Route =
path("party" / Segment / "bis") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
get {
@ -107,6 +110,8 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti
}
}
}
}
}
}
}
@ -133,6 +138,7 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti
def modifyBiS: Route =
path("party" / Segment / "bis") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ =>
post {
@ -149,3 +155,4 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti
}
}
}
}

View File

@ -1,16 +0,0 @@
package me.arcanis.ffxivbis.http.api.v1
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server._
import com.typesafe.scalalogging.StrictLogging
import me.arcanis.ffxivbis.http.api.v1.json._
trait HttpExceptionsHandler extends StrictLogging { this: JsonSupport =>
def exceptionHandler: ExceptionHandler = ExceptionHandler {
case other: Exception =>
logger.error("exception during request completion", other)
complete(StatusCodes.InternalServerError, ErrorResponse("unknown server error"))
}
}

View File

@ -0,0 +1,26 @@
package me.arcanis.ffxivbis.http.api.v1
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server._
import com.typesafe.scalalogging.StrictLogging
import me.arcanis.ffxivbis.http.api.v1.json._
import spray.json._
trait HttpHandler extends StrictLogging { this: JsonSupport =>
implicit def exceptionHandler: ExceptionHandler = ExceptionHandler {
case other: Exception =>
logger.error("exception during request completion", other)
complete(StatusCodes.InternalServerError, ErrorResponse("unknown server error"))
}
implicit def rejectionHandler: RejectionHandler =
RejectionHandler.default
.mapRejectionResponse {
case response @ HttpResponse(_, _, entity: HttpEntity.Strict, _) =>
val message = ErrorResponse(entity.data.utf8String).toJson
response.copy(entity = HttpEntity(ContentTypes.`application/json`, message.compactPrint))
case other => other
}
}

View File

@ -28,7 +28,7 @@ import scala.util.{Failure, Success}
@Path("api/v1")
class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
extends LootHelper(storage) with Authorization with JsonSupport with HttpExceptionsHandler {
extends LootHelper(storage) with Authorization with JsonSupport with HttpHandler {
def route: Route = getLoot ~ modifyLoot
@ -56,6 +56,7 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
def getLoot: Route =
path("party" / Segment / "loot") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
get {
@ -71,6 +72,7 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
}
}
}
}
@POST
@Consumes(value = Array("application/json"))
@ -94,6 +96,7 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
def modifyLoot: Route =
path("party" / Segment / "loot") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ =>
post {
@ -109,6 +112,7 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
}
}
}
}
@PUT
@Path("party/{partyId}/loot")
@ -136,6 +140,7 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
def suggestLoot: Route =
path("party" / Segment / "loot") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
put {
@ -151,3 +156,4 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
}
}
}
}

View File

@ -28,7 +28,7 @@ import scala.util.{Failure, Success}
@Path("api/v1")
class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout)
extends PlayerHelper(storage, ariyala) with Authorization with JsonSupport with HttpExceptionsHandler {
extends PlayerHelper(storage, ariyala) with Authorization with JsonSupport with HttpHandler {
def route: Route = getParty ~ modifyParty
@ -56,6 +56,7 @@ class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit
def getParty: Route =
path("party" / Segment) { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
get {
@ -71,6 +72,7 @@ class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit
}
}
}
}
@POST
@Path("party/{partyId}")
@ -94,6 +96,7 @@ class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit
def modifyParty: Route =
path("party" / Segment) { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ =>
entity(as[PlayerActionResponse]) { action =>
@ -108,3 +111,4 @@ class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit
}
}
}
}

View File

@ -28,7 +28,7 @@ import scala.util.{Failure, Success}
@Path("api/v1")
class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
extends UserHelper(storage) with Authorization with JsonSupport with HttpExceptionsHandler {
extends UserHelper(storage) with Authorization with JsonSupport with HttpHandler {
def route: Route = createParty ~ createUser ~ deleteUser ~ getUsers
@ -52,6 +52,7 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
def createParty: Route =
path("party" / Segment / "create") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
put {
entity(as[UserResponse]) { user =>
@ -65,6 +66,7 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
}
}
}
}
@POST
@Path("party/{partyId}/users")
@ -88,6 +90,7 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
def createUser: Route =
path("party" / Segment / "users") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ =>
post {
@ -103,6 +106,7 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
}
}
}
}
@DELETE
@Path("party/{partyId}/users/{username}")
@ -123,6 +127,7 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
def deleteUser: Route =
path("party" / Segment / "users" / Segment) { (partyId, username) =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ =>
delete {
@ -135,6 +140,7 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
}
}
}
}
@GET
@Path("party/{partyId}/users")
@ -158,6 +164,7 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
def getUsers: Route =
path("party" / Segment / "users") { partyId =>
handleExceptions(exceptionHandler) {
handleRejections(rejectionHandler) {
extractExecutionContext { implicit executionContext =>
authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ =>
get {
@ -171,3 +178,4 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout)
}
}
}
}