akka.http.scaladsl.server.RejectionHandler Scala Examples

The following examples show how to use akka.http.scaladsl.server.RejectionHandler. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: JsonRpcServer.scala    From mantis   with Apache License 2.0 5 votes vote down vote up
package io.iohk.ethereum.jsonrpc.server

import java.security.SecureRandom

import akka.actor.ActorSystem
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.model.headers.HttpOriginRange
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{MalformedRequestContentRejection, RejectionHandler, Route}
import ch.megard.akka.http.cors.javadsl.CorsRejection
import ch.megard.akka.http.cors.scaladsl.CorsDirectives._
import ch.megard.akka.http.cors.scaladsl.settings.CorsSettings
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import io.iohk.ethereum.jsonrpc.{JsonRpcController, JsonRpcErrors, JsonRpcRequest, JsonRpcResponse}
import io.iohk.ethereum.utils.Logger
import org.json4s.JsonAST.JInt
import org.json4s.{DefaultFormats, native}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

trait JsonRpcServer extends Json4sSupport {
  val jsonRpcController: JsonRpcController

  implicit val serialization = native.Serialization

  implicit val formats = DefaultFormats

  def corsAllowedOrigins: HttpOriginRange

  val corsSettings = CorsSettings.defaultSettings.copy(
    allowGenericHttpRequests = true,
    allowedOrigins = corsAllowedOrigins
  )

  implicit def myRejectionHandler: RejectionHandler =
    RejectionHandler.newBuilder()
      .handle {
        case _: MalformedRequestContentRejection =>
          complete((StatusCodes.BadRequest, JsonRpcResponse("2.0", None, Some(JsonRpcErrors.ParseError), JInt(0))))
        case _: CorsRejection =>
          complete(StatusCodes.Forbidden)
      }
      .result()

  val route: Route = cors(corsSettings) {
    (pathEndOrSingleSlash & post) {
      entity(as[JsonRpcRequest]) { request =>
        handleRequest(request)
      } ~ entity(as[Seq[JsonRpcRequest]]) { request =>
        handleBatchRequest(request)
      }
    }
  }

  
  def run(): Unit

  private def handleRequest(request: JsonRpcRequest) = {
    complete(jsonRpcController.handleRequest(request))
  }

  private def handleBatchRequest(requests: Seq[JsonRpcRequest]) = {
    complete(Future.sequence(requests.map(request => jsonRpcController.handleRequest(request))))
  }
}

object JsonRpcServer extends Logger {

  def apply(jsonRpcController: JsonRpcController, config: JsonRpcServerConfig, secureRandom: SecureRandom)
           (implicit actorSystem: ActorSystem): Either[String, JsonRpcServer] = config.mode match {
    case "http" => Right(new JsonRpcHttpServer(jsonRpcController, config)(actorSystem))
    case "https" => Right(new JsonRpcHttpsServer(jsonRpcController, config, secureRandom)(actorSystem))
    case _ => Left(s"Cannot start JSON RPC server: Invalid mode ${config.mode} selected")
  }

  trait JsonRpcServerConfig {
    val mode: String
    val enabled: Boolean
    val interface: String
    val port: Int
    val certificateKeyStorePath: Option[String]
    val certificateKeyStoreType: Option[String]
    val certificatePasswordFile: Option[String]
    val corsAllowedOrigins: HttpOriginRange
  }


} 
Example 2
Source File: SidechainApiRejectionHandler.scala    From Sidechains-SDK   with MIT License 5 votes vote down vote up
package com.horizen.api.http

import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.RejectionHandler
import akka.http.scaladsl.server._

object SidechainApiRejectionHandler {

  implicit val rejectionHandler = RejectionHandler.newBuilder()
    .handle {

      case ValidationRejection(msg, _) =>
        SidechainApiError(StatusCodes.BadRequest, "Validation failed").complete(msg)

      case MissingFormFieldRejection(fieldName) =>
        SidechainApiError(StatusCodes.BadRequest, "Missing Form Field").complete(s"The required ($fieldName) was not found.")

      case MissingQueryParamRejection(param) =>
        SidechainApiError(StatusCodes.BadRequest, "Missing Parameter").complete(s"The required ($param) was not found.")

      case MalformedQueryParamRejection(param, _, _) =>
        SidechainApiError(StatusCodes.BadRequest, "Malformed Parameter").complete(s"The required ($param) was not found.")

      case MalformedRequestContentRejection(msg, _) =>
        SidechainApiError(StatusCodes.BadRequest, "Malformed Request").complete(msg)

      case MethodRejection(_) =>
        SidechainApiError(StatusCodes.MethodNotAllowed, "HTTP method not allowed.")

      case RequestEntityExpectedRejection =>
        SidechainApiError(StatusCodes.BadRequest, "Request entity expected but not supplied")

    }
    .handleNotFound {
      SidechainApiError(StatusCodes.NotFound, "NotFound").complete("The requested resource could not be found.")
    }
    .result()
} 
Example 3
Source File: Routes.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.storage.routes

import akka.http.scaladsl.model.headers.{`WWW-Authenticate`, HttpChallenges}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{ExceptionHandler, RejectionHandler, Route}
import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClient.Caller
import ch.epfl.bluebrain.nexus.storage.StorageError._
import ch.epfl.bluebrain.nexus.storage.config.AppConfig
import ch.epfl.bluebrain.nexus.storage.config.AppConfig._
import ch.epfl.bluebrain.nexus.storage.routes.AuthDirectives._
import ch.epfl.bluebrain.nexus.storage.routes.PrefixDirectives._
import ch.epfl.bluebrain.nexus.storage.routes.instances._
import ch.epfl.bluebrain.nexus.storage.{AkkaSource, IamIdentitiesClient, Rejection, StorageError, Storages}
import com.typesafe.scalalogging.Logger
import monix.eval.Task

import scala.util.control.NonFatal

object Routes {

  private[this] val logger = Logger[this.type]

  
  def apply(
      storages: Storages[Task, AkkaSource]
  )(implicit config: AppConfig, identities: IamIdentitiesClient[Task]): Route =
    //TODO: Fetch Bearer token and verify identity
    wrap {
      concat(
        AppInfoRoutes(config.description).routes,
        (pathPrefix(config.http.prefix) & extractToken) { implicit token =>
          extractCaller.apply {
            case Caller(config.subject.subjectValue, _) => StorageRoutes(storages).routes
            case _                                      => failWith(AuthenticationFailed)
          }
        }
      )
    }

} 
Example 4
Source File: VinylDNSRouteTestHelper.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package vinyldns.api.route
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
import akka.http.scaladsl.server.Directives.{complete, extractUnmatchedPath}
import akka.http.scaladsl.server.{MalformedRequestContentRejection, RejectionHandler}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import org.json4s.MappingException

trait VinylDNSRouteTestHelper { this: ScalatestRouteTest =>
  import scala.concurrent.duration._
  import akka.http.scaladsl.testkit.RouteTestTimeout

  implicit val testTimeout = RouteTestTimeout(10.seconds)

  implicit def validationRejectionHandler: RejectionHandler =
    RejectionHandler
      .newBuilder()
      .handle {
        case MalformedRequestContentRejection(msg, MappingException(_, _)) =>
          complete(
            HttpResponse(
              status = StatusCodes.BadRequest,
              entity = HttpEntity(ContentTypes.`application/json`, msg)
            )
          )
      }
      .handleNotFound {
        extractUnmatchedPath { p =>
          complete((StatusCodes.NotFound, s"The requested path [$p] does not exist."))
        }
      }
      .result()
} 
Example 5
Source File: LoginResult.scala    From akka-http-extensions   with Mozilla Public License 2.0 5 votes vote down vote up
package akka.http.extensions.security

import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{Rejection, RejectionHandler}


case class LoggedIn(user: LoginInfo) extends LoginResult
case class UserDoesNotExist(username: String) extends LoginResult with Rejection
case class EmailDoesNotExist(email: String) extends LoginResult with Rejection
case class PasswordDoesNotMuch(username: String, password: String) extends LoginResult with Rejection
sealed trait LoginResult

trait WithLoginRejections{
  implicit def loginRejectionHandlers =
    RejectionHandler.newBuilder()
      .handle { case PasswordDoesNotMuch(username,password) ⇒
      complete(Forbidden, s"The password does not match") }
      .handle { case UserDoesNotExist(username) ⇒
      complete(Forbidden, s"You cannot login because the user $username does not exist") }
      .handle { case EmailDoesNotExist(email) ⇒
      complete(Forbidden, s"You cannot login because there is no user with  $email") }
      .result()
} 
Example 6
Source File: RegistrationResult.scala    From akka-http-extensions   with Mozilla Public License 2.0 5 votes vote down vote up
package akka.http.extensions.security

import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{Rejection, RejectionHandler}

case class UserRegistered(user:LoginInfo) extends RegistrationResult
case class UserAlreadyExists(user:LoginInfo) extends RegistrationResult with Rejection
case class BadEmail(user:LoginInfo,message:String) extends RegistrationResult with Rejection
case class BadPassword(user:LoginInfo,message:String) extends RegistrationResult with Rejection
sealed trait RegistrationResult

trait WithRegistrationRejections{
  implicit def registerRejectionHandlers =
    RejectionHandler.newBuilder()
      .handle { case UserAlreadyExists(user) ⇒
      complete(Forbidden, s"You cannot register, as user ${user.username} already exists") }
      .handle { case BadEmail(user,message) ⇒
      complete(Forbidden, s"The email of ${user.username} is wrong, because: $message") }
      .handle { case BadPassword(user,message) ⇒
      complete(Forbidden, s"The password of ${user.username} is wrong, because: $message") }
      .result()
} 
Example 7
Source File: HttpUi.scala    From mist   with Apache License 2.0 5 votes vote down vote up
package io.hydrosphere.mist.master.interfaces.http

import akka.http.scaladsl.model._
import akka.http.scaladsl.server.directives.ContentTypeResolver.Default
import akka.http.scaladsl.server.{Directives, RejectionHandler, Route}


  private val fallbackToSpa = RejectionHandler.newBuilder()
    .handleNotFound(getFromFile(index))
    .result()

  val route: Route = {
    pathPrefix("ui") {
      get {
        pathEnd {
          redirect("/ui/", PermanentRedirect)
        } ~
        pathSingleSlash {
          getFromFile(index)
        } ~
        handleRejections(fallbackToSpa) {
          getFromDirectory(path)
        }
      }
    }
  }

} 
Example 8
Source File: TestRoute.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.testkit

import akka.actor.{Actor, ActorSystem}
import akka.http.scaladsl.server.directives.PathDirectives._
import akka.http.scaladsl.server.{ExceptionHandler, RejectionHandler, Route}
import akka.http.scaladsl.settings.RoutingSettings
import akka.testkit.TestActorRef
import org.squbs.unicomplex.{RouteDefinition, WithActorContext, WithWebContext}

import scala.reflect.ClassTag


  def apply[T <: RouteDefinition: ClassTag](webContext: String)(implicit system: ActorSystem): Route = {
    val clazz = implicitly[ClassTag[T]].runtimeClass
    implicit val actorContext = TestActorRef[TestRouteActor].underlyingActor.context
    val routeDef =
      WithWebContext(webContext) {
        WithActorContext {
          clazz.asSubclass(classOf[RouteDefinition]).newInstance()
        }
      }

    implicit val routingSettings = RoutingSettings(system.settings.config)
    implicit val rejectionHandler:RejectionHandler = routeDef.rejectionHandler.getOrElse(RejectionHandler.default)
    implicit val exceptionHandler:ExceptionHandler = routeDef.exceptionHandler.orNull

    if (webContext.length > 0) pathPrefix(separateOnSlashes(webContext)) { Route.seal(routeDef.route) }
    else { Route.seal(routeDef.route) }
  }

  private[testkit] class TestRouteActor extends Actor {
    def receive = {
      case _ =>
    }
  }
} 
Example 9
Source File: GenericAPIHandlers.scala    From marvin-engine-executor   with Apache License 2.0 5 votes vote down vote up
package org.marvin.executor.api

import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{ExceptionHandler, MissingQueryParamRejection, RejectionHandler}
import grizzled.slf4j.Logger
import org.marvin.exception.MarvinEExecutorException
import spray.json.DefaultJsonProtocol._

import scala.concurrent.TimeoutException

case class ErrorResponse(errorMessage: String)

object GenericAPIHandlers {

  lazy val logger = Logger[this.type]

  implicit val errorFormatter = jsonFormat1(ErrorResponse)

  val exceptions: ExceptionHandler =
    ExceptionHandler {
      case ex: IllegalArgumentException => {
        logger.debug("Endpoint thrown illegal argument exception.", ex)

        val error = ErrorResponse(errorMessage = ex.getMessage)
        complete(HttpResponse(StatusCodes.BadRequest, entity = toResponseEntityJson(error)))
      }
      case ex: TimeoutException => {
        logger.debug("Endpoint thrown timeout exception", ex)

        val error = ErrorResponse(errorMessage = "The engine was not able to provide a response within the specified timeout.")
        complete(HttpResponse(StatusCodes.InternalServerError, entity = toResponseEntityJson(error)))
      }
      case ex: MarvinEExecutorException => {
        logger.debug("Endpoint thrown Marvin EExecutor Exception", ex)

        val error = ErrorResponse(errorMessage = ex.getMessage())
        complete(HttpResponse(StatusCodes.ServiceUnavailable, entity = toResponseEntityJson(error)))
      }
      case _ => {
        val error = ErrorResponse(errorMessage = "Unexpected error.")
        complete(HttpResponse(StatusCodes.InternalServerError, entity = toResponseEntityJson(error)))
      }
    }

  val rejections: RejectionHandler =
    RejectionHandler.newBuilder().handle {
      case rj: MissingQueryParamRejection => {
        logger.debug("Missing query parameters.")

        val error = ErrorResponse(errorMessage = s"Missing query parameter. [${rj.parameterName}]")
        complete(HttpResponse(StatusCodes.BadRequest, entity = toResponseEntityJson(error)))
      }
    }.result()

  def toResponseEntityJson(error: ErrorResponse): ResponseEntity = {
    HttpEntity(ContentTypes.`application/json`, errorFormatter.write(error).toString())
  }
} 
Example 10
Source File: AkkaHttpClient.scala    From sttp   with Apache License 2.0 5 votes vote down vote up
package sttp.client.akkahttp

import akka.actor.ActorSystem
import akka.event.LoggingAdapter
import akka.http.scaladsl.model.ws.{Message, WebSocketRequest, WebSocketUpgradeResponse}
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.server.{ExceptionHandler, RejectionHandler, Route, RoutingLog}
import akka.http.scaladsl.settings.{ClientConnectionSettings, ConnectionPoolSettings, ParserSettings, RoutingSettings}
import akka.http.scaladsl.{Http, HttpsConnectionContext}
import akka.stream.Materializer
import akka.stream.scaladsl.Flow

import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, Future}

trait AkkaHttpClient {
  def singleRequest(
      request: HttpRequest,
      settings: ConnectionPoolSettings
  ): Future[HttpResponse]

  def singleWebsocketRequest[WS_RESULT](
      request: WebSocketRequest,
      clientFlow: Flow[Message, Message, WS_RESULT],
      settings: ClientConnectionSettings
  )(implicit ec: ExecutionContext, mat: Materializer): Future[(WebSocketUpgradeResponse, WS_RESULT)]
}

object AkkaHttpClient {
  def default(
      system: ActorSystem,
      connectionContext: Option[HttpsConnectionContext],
      customLog: Option[LoggingAdapter]
  ): AkkaHttpClient =
    new AkkaHttpClient {
      private val http = Http()(system)

      override def singleRequest(
          request: HttpRequest,
          settings: ConnectionPoolSettings
      ): Future[HttpResponse] = {
        http.singleRequest(
          request,
          connectionContext.getOrElse(http.defaultClientHttpsContext),
          settings,
          customLog.getOrElse(system.log)
        )
      }

      override def singleWebsocketRequest[WS_RESULT](
          request: WebSocketRequest,
          clientFlow: Flow[Message, Message, WS_RESULT],
          settings: ClientConnectionSettings
      )(implicit ec: ExecutionContext, mat: Materializer): Future[(WebSocketUpgradeResponse, WS_RESULT)] = {
        val (wsResponse, wsResult) = http.singleWebSocketRequest(
          request,
          clientFlow,
          connectionContext.getOrElse(http.defaultClientHttpsContext),
          None,
          settings,
          customLog.getOrElse(system.log)
        )
        wsResponse.map((_, wsResult))
      }
    }

  def stubFromAsyncHandler(run: HttpRequest => Future[HttpResponse]): AkkaHttpClient =
    new AkkaHttpClient {
      def singleRequest(request: HttpRequest, settings: ConnectionPoolSettings): Future[HttpResponse] =
        run(request)

      override def singleWebsocketRequest[WS_RESULT](
          request: WebSocketRequest,
          clientFlow: Flow[Message, Message, WS_RESULT],
          settings: ClientConnectionSettings
      )(implicit ec: ExecutionContext, mat: Materializer): Future[(WebSocketUpgradeResponse, WS_RESULT)] =
        Future.failed(new RuntimeException("Websockets are not supported"))
    }

  def stubFromRoute(route: Route)(implicit
      routingSettings: RoutingSettings,
      parserSettings: ParserSettings,
      materializer: Materializer,
      routingLog: RoutingLog,
      executionContext: ExecutionContextExecutor = null,
      rejectionHandler: RejectionHandler = RejectionHandler.default,
      exceptionHandler: ExceptionHandler = null
  ): AkkaHttpClient = stubFromAsyncHandler(Route.asyncHandler(route))
}