play.api.routing.Router Scala Examples

The following examples show how to use play.api.routing.Router. 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: Components.scala    From gbf-raidfinder   with MIT License 6 votes vote down vote up
package walfie.gbf.raidfinder.server

import akka.actor.ActorSystem
import akka.stream.Materializer
import com.trueaccord.scalapb.json.JsonFormat
import monix.execution.Scheduler
import play.api.BuiltInComponents
import play.api.http.{ContentTypes, DefaultHttpErrorHandler}
import play.api.libs.json.Json
import play.api.Mode.Mode
import play.api.mvc._
import play.api.routing.Router
import play.api.routing.sird._
import play.core.server._
import play.filters.cors.{CORSConfig, CORSFilter}
import play.filters.gzip.GzipFilterComponents
import scala.concurrent.duration.FiniteDuration
import scala.concurrent.Future
import walfie.gbf.raidfinder.protocol.{RaidBossesResponse, BinaryProtobuf}
import walfie.gbf.raidfinder.RaidFinder
import walfie.gbf.raidfinder.server.controller._
import walfie.gbf.raidfinder.server.syntax.ProtocolConverters.RaidBossDomainOps

class Components(
  raidFinder:                 RaidFinder[BinaryProtobuf],
  translator:                 BossNameTranslator,
  port:                       Int,
  mode:                       Mode,
  websocketKeepAliveInterval: FiniteDuration,
  metricsCollector:           MetricsCollector
) extends NettyServerComponents
  with BuiltInComponents with GzipFilterComponents with Controller {

  override lazy val serverConfig = ServerConfig(port = Some(port), mode = mode)

  private val corsFilter = new CORSFilter(corsConfig = CORSConfig().withAnyOriginAllowed)
  override lazy val httpFilters = List(gzipFilter, corsFilter)

  lazy val websocketController = new WebsocketController(
    raidFinder, translator, websocketKeepAliveInterval, metricsCollector
  )(actorSystem, materializer, Scheduler.Implicits.global)

  // The charset isn't necessary, but without it, Chrome displays Japanese incorrectly
  // if you try to view the JSON directly.
  // https://bugs.chromium.org/p/chromium/issues/detail?id=438464
  private val ContentTypeJsonWithUtf8 = "application/json; charset=utf-8"

  lazy val router = Router.from {
    case GET(p"/") =>
      controllers.Assets.at(path = "/public", "index.html")

    case GET(p"/api/bosses.json" ? q_s"name=$names") =>
      val bosses = if (names.nonEmpty) {
        val knownBossesMap = raidFinder.getKnownBosses
        names.collect(knownBossesMap)
      } else raidFinder.getKnownBosses.values

      val responseProtobuf = RaidBossesResponse(
        raidBosses = bosses.map(_.toProtocol(translator)).toSeq
      )
      val responseJson = JsonFormat.toJsonString(responseProtobuf)
      Action(Ok(responseJson).as(ContentTypeJsonWithUtf8))

    case GET(p"/api/metrics.json") =>
      val activeUsers = metricsCollector.getActiveWebSocketCount()
      val json = Json.obj("activeUsers" -> activeUsers)
      Action(Ok(json))

    case GET(p"/ws/raids" ? q_o"keepAlive=${ bool(keepAlive) }") =>
      websocketController.raids(keepAlive = keepAlive.getOrElse(false))

    case GET(p"/$file*") =>
      controllers.Assets.at(path = "/public", file = file)
  }

  override lazy val httpErrorHandler = new ErrorHandler

  override def serverStopHook = () => Future.successful {
    actorSystem.terminate()
  }
} 
Example 2
Source File: PlaySpecs2Spec.scala    From play-grpc   with Apache License 2.0 5 votes vote down vote up
package play.grpc.specs2

import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner

import play.api.inject.bind
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.libs.ws.WSClient
import play.api.libs.ws.WSRequest
import play.api.routing.Router
import play.api.test._

import akka.grpc.internal.GrpcProtocolNative

import example.myapp.helloworld.grpc.helloworld._

import io.grpc.Status


@RunWith(classOf[JUnitRunner])
class PlaySpecs2Spec extends ForServer with ServerGrpcClient with PlaySpecification with ApplicationFactories {

  protected def applicationFactory: ApplicationFactory =
    withGuiceApp(GuiceApplicationBuilder().overrides(bind[Router].to[GreeterServiceImpl]))

  // RICH: Still need to work out how to make WSClient work properly with endpoints
  def wsUrl(path: String)(implicit running: RunningServer): WSRequest = {
    val ws  = running.app.injector.instanceOf[WSClient]
    val url = running.endpoints.httpEndpoint.get.pathUrl(path)
    ws.url(url)
  }

  "A Play server bound to a gRPC router" should {
    "give a 404 when routing a non-gRPC request" >> { implicit rs: RunningServer =>
      val result = await(wsUrl("/").get)
      result.status must ===(404) // Maybe should be a 426, see #396
    }
    "give a 415 error when not using a gRPC content-type" >> { implicit rs: RunningServer =>
      val result = await(wsUrl(s"/${GreeterService.name}/FooBar").get)
      result.status must ===(415) // Maybe should be a 426, see #396
    }
    "give a grpc UNIMPLEMENTED when routing a non-existent gRPC method" >> { implicit rs: RunningServer =>
      val result = await(
        wsUrl(s"/${GreeterService.name}/FooBar")
          .addHttpHeaders("Content-Type" -> GrpcProtocolNative.contentType.toString)
          .get,
      )
      result.status must ===(200) // Maybe should be a 426, see #396
      result.header("grpc-status") must beSome(Status.Code.UNIMPLEMENTED.value().toString)
    }
    "give a grpc INVALID_ARGUMENT error when routing an empty request to a gRPC method" >> {
      implicit rs: RunningServer =>
        val result = await(
          wsUrl(s"/${GreeterService.name}/SayHello")
            .addHttpHeaders("Content-Type" -> GrpcProtocolNative.contentType.toString)
            .get,
        )
        result.status must ===(200) // Maybe should be a 426, see #396

        // grpc-status 3 means INVALID_ARGUMENT error. See https://developers.google.com/maps-booking/reference/grpc-api/status_codes
        result.header("grpc-status") must beSome(Status.Code.INVALID_ARGUMENT.value().toString)
    }
    "work with a gRPC client" >> { implicit rs: RunningServer =>
      withGrpcClient[GreeterServiceClient] { client: GreeterServiceClient =>
        val reply = await(client.sayHello(HelloRequest("Alice")))
        reply.message must ===("Hello, Alice!")
      }
    }
  }
} 
Example 3
Source File: TestRouters.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.it.routers

import javax.inject.Inject
import play.api.mvc
import play.api.mvc._
import play.api.routing.Router.Routes
import play.api.routing.Router
import play.api.routing.SimpleRouterImpl
import play.core.j.JavaRouterAdapter

import scala.concurrent.ExecutionContext
import scala.concurrent.Future


object FixedResponseRouter {
  def apply(msg: String) =
    new SimpleRouterImpl({
      case _ =>
        new Action[Unit] {
          override def parser: BodyParser[Unit] = mvc.BodyParsers.utils.empty

          override def apply(request: Request[Unit]): Future[Result] =
            Future.successful(Results.Ok(msg))

          override def executionContext: ExecutionContext =
            scala.concurrent.ExecutionContext.global
        }
    })

  def newInstanceJava(msg: String) = new JavaRouterAdapter(FixedResponseRouter(msg))
} 
Example 4
Source File: AdditionalRouter.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.javadsl.server

import java.util

import play.api.inject.Injector
import play.api.routing.Router
import play.core.j.JavaRouterAdapter

import scala.collection.JavaConverters._
import scala.collection.immutable

trait AdditionalRouter {
  def prefix: Option[String]
  def withPrefix(path: String): AdditionalRouter
}

final case class ClassBased[R <: Router](classType: Class[R], prefix: Option[String]) extends AdditionalRouter {
  def this(classType: Class[R]) = this(classType, None)

  def withPrefix(path: String): ClassBased[R] = copy(prefix = AdditionalRouter.appendPrefix(prefix, path))
}

final case class InstanceBased(router: Router, prefix: Option[String]) extends AdditionalRouter {
  def this(classType: Router) = this(classType, None)

  def withPrefix(path: String): InstanceBased = copy(prefix = AdditionalRouter.appendPrefix(prefix, path))
}

object AdditionalRouter {

  
  private[lagom] def appendPrefix(prefix: Option[String], newPrefix: String) = {
    prefix
      .map(oldPrefix => newPrefix + "/" + oldPrefix)
      .orElse(Option(newPrefix))
  }
  private[lagom] def wireRouters(
      injector: Injector,
      additionalRouters: util.List[AdditionalRouter]
  ): util.List[Router] = {
    // modifies the Router in case a prefix is defined
    // otherwise returns the router as is
    def applyPrefix(router: Router, prefix: Option[String]): Router =
      prefix.map(router.withPrefix).getOrElse(router)

    additionalRouters.asScala
      .foldLeft(immutable.Seq.empty[Router]) { (routers, ar) =>
        ar match {
          case ar: InstanceBased =>
            routers :+ applyPrefix(ar.router, ar.prefix)

          case ar: ClassBased[_] =>
            val ins = injector.instanceOf(ar.classType)
            routers :+ applyPrefix(ins, ar.prefix)
        }
      }
      .asJava
  }
} 
Example 5
Source File: AppLoader.scala    From slim-play   with MIT License 5 votes vote down vote up
import play.api.ApplicationLoader.Context
import play.api._
import play.api.mvc.Results._
import play.api.routing.Router
import play.api.routing.sird._

import scala.concurrent.Future

class AppComponents(context: Context) extends BuiltInComponentsFromContext(context) {

  val httpFilters     = Nil
  override val Action = defaultActionBuilder

  val router: Router = Router.from {

    // Essentially copied verbatim from the SIRD example
    case GET(p"/hello/$to") =>
      Action {
        Ok(s"Hello $to")
      }

    
    case GET(p"/sqrt/${double(num)}") =>
      Action.async {
        Future {
          Ok(Math.sqrt(num).toString)
        }
      }

  }

}

class AppLoader extends ApplicationLoader {
  def load(context: Context) = new AppComponents(context).application
} 
Example 6
Source File: ArticleComponents.scala    From scala-play-realworld-example-app   with MIT License 5 votes vote down vote up
package articles

import com.softwaremill.macwire.wire
import commons.config.{WithControllerComponents, WithExecutionContextComponents}
import commons.models._
import articles.controllers.{ArticleController, CommentController, TagController}
import articles.models._
import articles.repositories._
import articles.services._
import commons.CommonsComponents
import users.UserComponents
import play.api.routing.Router
import play.api.routing.sird._
import users.controllers.AuthenticatedActionBuilder

trait ArticleComponents
  extends WithControllerComponents
    with UserComponents
    with CommonsComponents
    with WithExecutionContextComponents {

  def authenticatedAction: AuthenticatedActionBuilder

  lazy val articleController: ArticleController = wire[ArticleController]
  lazy val articleWriteService: ArticleWriteService = wire[ArticleWriteService]
  lazy val articleReadService: ArticleReadService = wire[ArticleReadService]
  lazy val articleRepo: ArticleRepo = wire[ArticleRepo]

  lazy val commentController: CommentController = wire[CommentController]
  lazy val commentService: CommentService = wire[CommentService]
  lazy val commentWithAuthorRepo: CommentWithAuthorRepo = wire[CommentWithAuthorRepo]
  lazy val commentRepo: CommentRepo = wire[CommentRepo]

  lazy val tagController: TagController = wire[TagController]
  lazy val tagService: TagService = wire[TagService]
  lazy val tagRepo: TagRepo = wire[TagRepo]

  lazy val articleTagRepo: ArticleTagAssociationRepo = wire[ArticleTagAssociationRepo]
  lazy val articleWithTagsRepo: ArticleWithTagsRepo = wire[ArticleWithTagsRepo]

  lazy val favoriteAssociationRepo: FavoriteAssociationRepo = wire[FavoriteAssociationRepo]

  val articleRoutes: Router.Routes = {
    case GET(p"/articles" ? q_o"limit=${long(maybeLimit)}" &
      q_o"offset=${long(maybeOffset)}" &
      q_o"tag=$maybeTag" &
      q_o"author=$maybeAuthor" &
      q_o"favorited =$maybeFavorited") =>

      articleController.findAll(maybeTag, maybeAuthor, maybeFavorited, maybeLimit, maybeOffset)
    case GET(p"/articles/feed" ? q_o"limit=${long(limit)}" & q_o"offset=${long(offset)}") =>
      articleController.findFeed(limit, offset)
    case GET(p"/articles/$slug") =>
      articleController.findBySlug(slug)
    case POST(p"/articles") =>
      articleController.create
    case PUT(p"/articles/$slug") =>
      articleController.update(slug)
    case DELETE(p"/articles/$slug") =>
      articleController.delete(slug)
    case POST(p"/articles/$slug/comments") =>
      commentController.create(slug)
    case GET(p"/articles/$slug/comments") =>
      commentController.findByArticleSlug(slug)
    case POST(p"/articles/$slug/favorite") =>
      articleController.favorite(slug)
    case DELETE(p"/articles/$slug/favorite") =>
      articleController.unfavorite(slug)
    case DELETE(p"/articles/$_/comments/${long(id)}") =>
      commentController.delete(CommentId(id))
    case GET(p"/tags") =>
      tagController.findAll
  }

} 
Example 7
Source File: UserComponents.scala    From scala-play-realworld-example-app   with MIT License 5 votes vote down vote up
package users

import com.softwaremill.macwire.wire
import commons.config.{WithControllerComponents, WithExecutionContextComponents}
import commons.models.Username
import _root_.authentication.AuthenticationComponents
import play.api.routing.Router
import play.api.routing.sird._
import users.controllers._
import users.repositories.{FollowAssociationRepo, ProfileRepo, UserRepo}
import users.services._

trait UserComponents extends AuthenticationComponents with WithControllerComponents with WithExecutionContextComponents {
  lazy val userController: UserController = wire[UserController]
  lazy val userService: UserService = wire[UserService]
  lazy val userRepo: UserRepo = wire[UserRepo]
  lazy val userRegistrationService: UserRegistrationService = wire[UserRegistrationService]
  lazy val userRegistrationValidator: UserRegistrationValidator = wire[UserRegistrationValidator]
  lazy val userUpdateValidator: UserUpdateValidator = wire[UserUpdateValidator]

  lazy val passwordValidator: PasswordValidator = wire[PasswordValidator]
  lazy val usernameValidator: UsernameValidator = wire[UsernameValidator]
  lazy val emailValidator: EmailValidator = wire[EmailValidator]

  lazy val profileController: ProfileController = wire[ProfileController]
  lazy val profileService: ProfileService = wire[ProfileService]
  lazy val profileRepo: ProfileRepo = wire[ProfileRepo]

  lazy val followAssociationRepo: FollowAssociationRepo = wire[FollowAssociationRepo]

  lazy val loginController: LoginController = wire[LoginController]

  lazy val authenticatedAction: AuthenticatedActionBuilder = wire[JwtAuthenticatedActionBuilder]
  lazy val optionallyAuthenticatedAction: OptionallyAuthenticatedActionBuilder =
    wire[JwtOptionallyAuthenticatedActionBuilder]

  val userRoutes: Router.Routes = {
    case POST(p"/users") =>
      userController.register
    case GET(p"/user") =>
      userController.getCurrentUser
    case POST(p"/users/login") =>
      loginController.login
    case PUT(p"/user") =>
      userController.update
    case GET(p"/profiles/$rawUsername") =>
      profileController.findByUsername(Username(rawUsername))
    case POST(p"/profiles/$rawUsername/follow") =>
      profileController.follow(Username(rawUsername))
    case DELETE(p"/profiles/$rawUsername/follow") =>
      profileController.unfollow(Username(rawUsername))
  }
} 
Example 8
package config

import java.util.UUID

import _root_.controllers.AssetsComponents
import articles.ArticleComponents
import authentication.AuthenticationComponents
import users.UserComponents
import play.api.ApplicationLoader.Context
import play.api._
import play.api.cache.AsyncCacheApi
import play.api.cache.ehcache.EhCacheComponents
import play.api.db.evolutions.{DynamicEvolutions, EvolutionsComponents}
import play.api.db.slick._
import play.api.db.slick.evolutions.SlickEvolutionsComponents
import play.api.i18n._
import play.api.libs.ws.ahc.AhcWSComponents
import play.api.mvc._
import play.api.routing.Router
import play.filters.cors.{CORSConfig, CORSFilter}
import slick.basic.{BasicProfile, DatabaseConfig}

class RealWorldApplicationLoader extends ApplicationLoader {
  def load(context: Context): Application = new RealWorldComponents(context).application
}

class RealWorldComponents(context: Context) extends BuiltInComponentsFromContext(context)
  with SlickComponents
  with SlickEvolutionsComponents
  with AssetsComponents
  with I18nComponents
  with EvolutionsComponents
  with AhcWSComponents
  with AuthenticationComponents
  with  UserComponents
  with ArticleComponents
  with EhCacheComponents {

  override lazy val slickApi: SlickApi =
    new DefaultSlickApi(environment, configuration, applicationLifecycle)(executionContext)

  override lazy val databaseConfigProvider: DatabaseConfigProvider = new DatabaseConfigProvider {
    def get[P <: BasicProfile]: DatabaseConfig[P] = slickApi.dbConfig[P](DbName("default"))
  }

  override lazy val dynamicEvolutions: DynamicEvolutions = new DynamicEvolutions

  def onStart(): Unit = {
    // applicationEvolutions is a val and requires evaluation
    applicationEvolutions
  }

  onStart()

  // set up logger
  LoggerConfigurator(context.environment.classLoader).foreach {
    _.configure(context.environment, context.initialConfiguration, Map.empty)
  }

  protected lazy val routes: PartialFunction[RequestHeader, Handler] = userRoutes.orElse(articleRoutes)

  override lazy val router: Router = Router.from(routes)

  override lazy val defaultCacheApi: AsyncCacheApi = cacheApi(UUID.randomUUID().toString)

  private lazy val corsFilter: CORSFilter = {
    val corsConfig = CORSConfig.fromConfiguration(configuration)

    CORSFilter(corsConfig)
  }

  override def httpFilters: Seq[EssentialFilter] = List(corsFilter)
} 
Example 9
Source File: AuthenticationTest.scala    From scala-play-realworld-example-app   with MIT License 5 votes vote down vote up
package users.controllers

import authentication.exceptions.MissingOrInvalidCredentialsCode
import com.softwaremill.macwire.wire
import commons_test.test_helpers.RealWorldWithServerAndTestConfigBaseTest.RealWorldWithTestConfig
import commons_test.test_helpers.{ProgrammaticDateTimeProvider, RealWorldWithServerAndTestConfigBaseTest, WithUserTestHelper}
import play.api.ApplicationLoader.Context
import play.api.http.HeaderNames
import play.api.libs.json._
import play.api.mvc._
import play.api.routing.Router
import play.api.routing.sird._
import users.models.UserDetailsWithToken
import users.test_helpers.UserRegistrations

import scala.concurrent.ExecutionContext

class AuthenticationTest extends RealWorldWithServerAndTestConfigBaseTest with WithUserTestHelper {

  val fakeApiPath: String = "test"

  val accessTokenJsonAttrName: String = "access_token"

  val programmaticDateTimeProvider = new ProgrammaticDateTimeProvider

  "Authentication" should "allow everyone to public API" in await {
    for {
      response <- wsUrl(s"/$fakeApiPath/public").get()
    } yield {
      response.status.mustBe(OK)
    }
  }

  it should "block request without jwt token" in await {
    for {
      response <- wsUrl(s"/$fakeApiPath/authenticationRequired").get()
    } yield {
      response.status.mustBe(UNAUTHORIZED)
      response.json.as[HttpExceptionResponse].code.mustBe(MissingOrInvalidCredentialsCode)
    }
  }

  it should "block request with invalid jwt token" in await {
    for {
      response <- wsUrl(s"/$fakeApiPath/authenticationRequired")
        .addHttpHeaders(HeaderNames.AUTHORIZATION -> "TokenS invalidJwtToken")
        .get()
    } yield {
      response.status.mustBe(UNAUTHORIZED)
      response.json.as[HttpExceptionResponse].code.mustBe(MissingOrInvalidCredentialsCode)
    }
  }

  it should "allow authenticated user to secured API" in await {
    for {
      userDetailsWithToken <- userTestHelper.register[UserDetailsWithToken](UserRegistrations.petycjaRegistration)

      response <- wsUrl(s"/$fakeApiPath/authenticationRequired")
        .addHttpHeaders(HeaderNames.AUTHORIZATION -> s"Token ${userDetailsWithToken.token}")
        .get()
    } yield {
      response.status.mustBe(OK)
    }
  }

  override def createComponents: RealWorldWithTestConfig =
    new JwtAuthenticationTestComponents(programmaticDateTimeProvider, context)
}

class AuthenticationTestController(authenticatedAction: AuthenticatedActionBuilder,
                                   components: ControllerComponents,
                                   implicit private val ex: ExecutionContext)
  extends AbstractController(components) {

  def public: Action[AnyContent] = Action { _ =>
    Results.Ok
  }

  def authenticated: Action[AnyContent] = authenticatedAction { request =>
    Ok(Json.toJson(request.user.securityUserId.value))
  }

}

class JwtAuthenticationTestComponents(dateTimeProvider: ProgrammaticDateTimeProvider, context: Context)
  extends RealWorldWithTestConfig(context) {

  lazy val authenticationTestController: AuthenticationTestController = wire[AuthenticationTestController]

  override lazy val router: Router = {
    val testControllerRoutes: PartialFunction[RequestHeader, Handler] = {
      case GET(p"/test/public") => authenticationTestController.public
      case GET(p"/test/authenticationRequired") => authenticationTestController.authenticated
    }

    Router.from(routes.orElse(testControllerRoutes))
  }
} 
Example 10
Source File: AppLoader.scala    From OAuth2-mock-play   with MIT License 5 votes vote down vote up
import models.{AuthorizeStoreCache, PendingContentStoreCache}
import play.api.ApplicationLoader.Context
import play.api.cache.EhCacheComponents
import play.api.mvc.EssentialFilter
import play.api.routing.Router
import play.api._
import play.filters.gzip.GzipFilter
import router.Routes

class AppLoader extends ApplicationLoader {
  override def load(context: Context): Application = {
    LoggerConfigurator(context.environment.classLoader)
      .foreach(_.configure(context.environment))
    new AppComponents(context).application
  }
}

class AppComponents(context: Context)
    extends BuiltInComponentsFromContext(context)
    with EhCacheComponents {

  implicit val executionContext =
    play.api.libs.concurrent.Execution.Implicits.defaultContext
  implicit lazy val authorizeStoreCache = AuthorizeStoreCache(
    cacheApi("authorizeStore"))
  implicit lazy val pendingConsentStoreCache = PendingContentStoreCache(
    cacheApi("pendingConsentStore"))
  implicit val config = configuration.underlying

  lazy val applicationController = new controllers.Application
  lazy val assets                = new controllers.Assets(httpErrorHandler)

  // Routes is a generated class
  override def router: Router =
    new Routes(httpErrorHandler, applicationController, assets)

  val gzipFilter = new GzipFilter(shouldGzip = (request, response) => {
    val contentType = response.header.headers.get("Content-Type")
    contentType.exists(_.startsWith("text/html")) ||
    request.path.endsWith("jsroutes.js")
  })

  override lazy val httpFilters: Seq[EssentialFilter] = Seq(gzipFilter)
} 
Example 11
Source File: AppLoader.scala    From lila-search   with GNU Affero General Public License v3.0 5 votes vote down vote up
import play.api._
import play.api.routing.Router

class AppLoader extends ApplicationLoader {
  private var components: AppComponents = _

  def load(context: ApplicationLoader.Context): Application = {
    components = new AppComponents(context)
    components.application
  }
}

class AppComponents(context: ApplicationLoader.Context) extends BuiltInComponentsFromContext(context) {

  def httpFilters = Nil

  lazy val client = ESConnect(
    actorSystem,
    context.lifecycle,
    configuration
  )

  lazy val homeController = new _root_.controllers.WebApi(
    controllerComponents,
    client
  )

  lazy val router: Router = new _root_.router.Routes(httpErrorHandler, homeController)
} 
Example 12
Source File: MyApplicationLoader.scala    From get-you-a-license   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import controllers.{AssetsComponents, Main}
import filters.OnlyHttpsFilter
import org.webjars.play.{RequireJS, WebJarAssets, WebJarsUtil}
import play.api.{Application, ApplicationLoader, BuiltInComponentsFromContext}
import play.api.ApplicationLoader.Context
import play.api.libs.concurrent.{DefaultFutures, Futures}
import play.api.libs.ws.ahc.AhcWSComponents
import play.api.mvc.EssentialFilter
import play.api.routing.Router
import play.filters.HttpFiltersComponents
import play.filters.csrf.CSRFFilter
import router.Routes
import utils.GitHub

class MyApplicationLoader extends ApplicationLoader {
  def load(context: Context): Application = {
    new MyComponents(context).application
  }
}

class MyComponents(context: Context) extends BuiltInComponentsFromContext(context) with AhcWSComponents with AssetsComponents with HttpFiltersComponents {

  override def httpFilters: Seq[EssentialFilter] = {
    super.httpFilters.filterNot(_.isInstanceOf[CSRFFilter]) :+ new OnlyHttpsFilter(environment)
  }

  lazy val futures = new DefaultFutures(actorSystem)

  lazy val webJarsUtil = new WebJarsUtil(context.initialConfiguration, context.environment)

  lazy val indexView = new views.html.index(webJarsUtil)
  lazy val setupView = new views.html.setup(webJarsUtil)
  lazy val orgView = new views.html.org(webJarsUtil)

  lazy val gitHub = new GitHub(context.initialConfiguration, wsClient, futures)
  lazy val main = new Main(gitHub, controllerComponents)(indexView, orgView, setupView)

  lazy val requireJs = new RequireJS(webJarsUtil)
  lazy val webJarAssets = new WebJarAssets(httpErrorHandler, assetsMetadata)
  lazy val webJarsRoutes = new webjars.Routes(httpErrorHandler, requireJs, webJarAssets)

  lazy val router: Router = new Routes(httpErrorHandler, main, assets, webJarsRoutes)
} 
Example 13
Source File: PlayRouter.scala    From play-grpc   with Apache License 2.0 5 votes vote down vote up
package play.grpc.internal

import java.util.Optional
import java.util.concurrent.CompletionStage

import akka.annotation.InternalApi
import akka.dispatch.Dispatchers
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.HttpResponse
import akka.stream.Materializer
import play.api.inject.Injector
import play.api.mvc.Handler
import play.api.mvc.akkahttp.AkkaHttpHandler
import play.api.routing.Router
import play.api.routing.Router.Routes
import play.mvc.Http

import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.compat.java8.FutureConverters._
import scala.compat.java8.OptionConverters._


  final override def withPrefix(prefix: String): Router =
    if (prefix == "/") this
    else
      throw new UnsupportedOperationException(
        "Prefixing gRPC services is not widely supported by clients, " +
          s"strongly discouraged by the specification and therefore not supported. " +
          s"Attempted to prefix with [$prefix], yet already default prefix known to be [${this.prefix}]. " +
          s"When binding gRPC routers the path in `routes` MUST BE `/`.",
      )

} 
Example 14
Source File: ServiceSupport.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.it

import java.util.Collections
import java.util.function.{ Function => JFunction }

import akka.stream.Materializer
import akka.stream.scaladsl.Source
import org.scalatest.Inside
import play.api.Application
import play.api.Configuration
import play.api.Environment
import play.inject.guice.GuiceApplicationBuilder

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.reflect.ClassTag
import akka.japi.function.Procedure
import com.google.inject.Binder
import com.google.inject.Module
import com.google.inject.TypeLiteral
import com.lightbend.lagom.javadsl.testkit.ServiceTest
import com.lightbend.lagom.javadsl.testkit.ServiceTest.TestServer
import play.api.routing.Router
import java.util

import com.lightbend.lagom.internal.testkit.EmptyAdditionalRoutersModule
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike

sealed trait HttpBackend {
  final val provider: String = s"play.core.server.${codeName}ServerProvider"
  val codeName: String
}

case object AkkaHttp extends HttpBackend {
  val codeName = "AkkaHttp"
}

case object Netty extends HttpBackend {
  val codeName = "Netty"
}

trait ServiceSupport extends AnyWordSpecLike with Matchers with Inside {
  def withServer(
      configureBuilder: GuiceApplicationBuilder => GuiceApplicationBuilder
  )(block: Application => Unit)(implicit httpBackend: HttpBackend): Unit = {
    val jConfigureBuilder = new JFunction[GuiceApplicationBuilder, GuiceApplicationBuilder] {
      override def apply(b: GuiceApplicationBuilder): GuiceApplicationBuilder = {
        configureBuilder(b)
          .overrides(EmptyAdditionalRoutersModule)
          .configure("play.server.provider", httpBackend.provider)
      }
    }
    val jBlock = new Procedure[TestServer] {
      override def apply(server: TestServer): Unit = {
        block(server.app.asScala())
      }
    }
    val setup = ServiceTest.defaultSetup.configureBuilder(jConfigureBuilder).withCluster(false)
    ServiceTest.withServer(setup, jBlock)
  }

  def withClient[T: ClassTag](
      configureBuilder: GuiceApplicationBuilder => GuiceApplicationBuilder
  )(block: Application => T => Unit)(implicit httpBackend: HttpBackend): Unit = {
    withServer(configureBuilder) { application =>
      val client = application.injector.instanceOf[T]
      block(application)(client)
    }
  }

  implicit def materializer(implicit app: Application): Materializer = app.materializer

  def consume[T](source: Source[T, _])(implicit mat: Materializer): List[T] = {
    Await.result(source.runFold(List.empty[T])((list, t) => t :: list), 10.seconds).reverse
  }
} 
Example 15
Source File: PlayScalaTestSpec.scala    From play-grpc   with Apache License 2.0 5 votes vote down vote up
package play.grpc.scalatest

import io.grpc.Status

import org.scalatest.concurrent.IntegrationPatience
import org.scalatest.concurrent.ScalaFutures
import org.scalatestplus.play.PlaySpec
import org.scalatestplus.play.guice.GuiceOneServerPerTest

import play.api.Application
import play.api.inject.bind
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.libs.ws.WSClient
import play.api.routing.Router

import akka.grpc.internal.GrpcProtocolNative

import example.myapp.helloworld.grpc.helloworld._


class PlayScalaTestSpec
    extends PlaySpec
    with GuiceOneServerPerTest
    with ServerGrpcClient
    with ScalaFutures
    with IntegrationPatience {

  override def fakeApplication(): Application = {
    GuiceApplicationBuilder()
      .overrides(bind[Router].to[GreeterServiceImpl])
      .build()
  }

  implicit def ws: WSClient = app.injector.instanceOf(classOf[WSClient])

  "A Play server bound to a gRPC router" must {
    "give a 404 when routing a non-gRPC request" in {
      val result = wsUrl("/").get.futureValue
      result.status must be(404) // Maybe should be a 426, see #396
    }
    "give a 415 error when not using a gRPC content-type" in {
      val result = wsUrl(s"/${GreeterService.name}/FooBar").get.futureValue
      result.status must be(415)
    }
    "give a grpc 'unimplemented' error when routing a non-existent gRPC method" in {
      val result = wsUrl(s"/${GreeterService.name}/FooBar")
        .addHttpHeaders("Content-Type" -> GrpcProtocolNative.contentType.toString)
        .get
        .futureValue
      result.status must be(200) // Maybe should be a 426, see #396
      result.header("grpc-status") mustEqual Some(Status.Code.UNIMPLEMENTED.value().toString)
    }
    "give a grpc 'invalid argument' error when routing an empty request to a gRPC method" in {
      val result = wsUrl(s"/${GreeterService.name}/SayHello")
        .addHttpHeaders("Content-Type" -> GrpcProtocolNative.contentType.toString)
        .get
        .futureValue
      result.status must be(200)
      result.header("grpc-status") mustEqual Some(Status.Code.INVALID_ARGUMENT.value().toString)
    }
    "work with a gRPC client" in withGrpcClient[GreeterServiceClient] { client: GreeterServiceClient =>
      val reply = client.sayHello(HelloRequest("Alice")).futureValue
      reply.message must be("Hello, Alice!")
    }
  }
} 
Example 16
Source File: PlayApiScanner.scala    From swagger-play24   with Apache License 2.0 5 votes vote down vote up
package pl.matisoft.swagger

import com.wordnik.swagger.annotations.Api
import com.wordnik.swagger.core.SwaggerContext
import com.wordnik.swagger.config._

import play.api.Logger
import play.api.routing.Router


class PlayApiScanner(routes: Option[Router]) extends Scanner {

  def classes(): List[Class[_]] = {
    Logger("swagger").warn("ControllerScanner - looking for controllers with API annotation")

    // get controller names from application routes
    val controllers = (routes match {
      case Some(r) => {
        for (doc <- r.documentation) yield {
          Logger("swagger").debug("route: " + doc.toString())
          val m1 = doc._3.lastIndexOf("(") match {
            case i: Int if (i > 0) => doc._3.substring(0, i)
            case _ => doc._3
          }
          Some(m1.substring(0, m1.lastIndexOf(".")).replace("@", ""))
        }
      }
      case None => Seq(None)
    }).flatten.distinct.toList

    controllers.collect {
      case className: String if {
        try {
          SwaggerContext.loadClass(className).getAnnotation(classOf[Api]) != null
        } catch {
          case ex: Exception => {
            Logger("swagger").error("Problem loading class:  %s. %s: %s".format(className, ex.getClass.getName, ex.getMessage))
            false}
        }
      } =>
        Logger("swagger").info("Found API controller:  %s".format(className))
        SwaggerContext.loadClass(className)
    }

  }
} 
Example 17
Source File: SwaggerPluginProvider.scala    From swagger-play24   with Apache License 2.0 5 votes vote down vote up
package pl.matisoft.swagger

import java.net.URL
import javax.inject.{Inject, Provider}

import com.wordnik.swagger.config.{FilterFactory, ScannerFactory, ConfigFactory}
import com.wordnik.swagger.core.SwaggerContext
import com.wordnik.swagger.core.filter.SwaggerSpecFilter
import com.wordnik.swagger.reader.ClassReaders
import play.api.inject.ApplicationLifecycle
import play.api.{Logger, Application}
import play.api.routing.Router
import play.modules.swagger.ApiListingCache
import scala.concurrent.ExecutionContext.Implicits.global

import scala.concurrent.Future

class SwaggerPluginProvider extends Provider[SwaggerPlugin] {

  val logger = Logger("swagger")

  @Inject
  private var router: Router = _

  @Inject
  private var app: Application = _

  @Inject
  private var lifecycle: ApplicationLifecycle = _

  override def get(): SwaggerPlugin = {
    lifecycle.addStopHook(() => Future {
      onStop()
    })

    onStart()
  }

  def onStart(): SwaggerPlugin = {
    val config = app.configuration
    logger.info("Swagger - starting initialisation...")

    val apiVersion = config.getString("api.version") match {
      case None => "beta"
      case Some(value) => value
    }

    val basePath = config.getString("swagger.api.basepath")
        .filter(path => !path.isEmpty)
        .map(getPathUrl(_))
        .getOrElse("http://localhost:9000")

    SwaggerContext.registerClassLoader(app.classloader)
    ConfigFactory.config.setApiVersion(apiVersion)
    ConfigFactory.config.setBasePath(basePath)
    ScannerFactory.setScanner(new PlayApiScanner(Option(router)))
    ClassReaders.reader = Some(new PlayApiReader(Option(router)))

    app.configuration.getString("swagger.filter")
      .filter(p => !p.isEmpty)
      .foreach(loadFilter(_))

    val docRoot = ""
    ApiListingCache.listing(docRoot)

    logger.info("Swagger - initialization done.")
    new SwaggerPlugin()
  }

  def onStop() {
    ApiListingCache.cache = None
    logger.info("Swagger - stopped.")
  }

  def loadFilter(filterClass: String): Unit = {
    try {
      FilterFactory.filter = SwaggerContext.loadClass(filterClass).newInstance.asInstanceOf[SwaggerSpecFilter]
      logger.info(s"Setting swagger.filter to $filterClass")
    } catch {
      case ex: Exception =>logger.error(s"Failed to load filter:$filterClass", ex)
    }
  }

  def getPathUrl(path: String): String = {
    try {
      val basePathUrl = new URL(path)
      logger.info(s"Basepath configured as:$path")
      path
    } catch {
      case ex: Exception =>
        logger.error(s"Misconfiguration - basepath not a valid URL:$path. Swagger abandoning initialisation!")
        throw ex
    }
  }

} 
Example 18
Source File: ApiModule.scala    From metronome   with Apache License 2.0 5 votes vote down vote up
package dcos.metronome
package api

import com.softwaremill.macwire._
import controllers.Assets
import dcos.metronome.api.v0.controllers.ScheduledJobSpecController
import dcos.metronome.api.v1.controllers._
import dcos.metronome.jobinfo.JobInfoService
import dcos.metronome.jobrun.JobRunService
import dcos.metronome.jobspec.JobSpecService
import dcos.metronome.queue.LaunchQueueService
import mesosphere.marathon.MetricsModule
import mesosphere.marathon.core.auth.AuthModule
import mesosphere.marathon.core.base.ActorsModule
import mesosphere.marathon.core.election.ElectionService
import mesosphere.marathon.core.plugin.PluginManager
import mesosphere.marathon.metrics.Metrics
import mesosphere.marathon.plugin.auth.{Authenticator, Authorizer}
import play.api.http.HttpErrorHandler
import play.api.mvc.ControllerComponents
import play.api.routing.Router
import router.Routes

import scala.concurrent.ExecutionContext

class ApiModule(
    controllerComponents: ControllerComponents,
    assets: Assets,
    httpErrorHandler: HttpErrorHandler,
    config: ApiConfig,
    jobSpecService: JobSpecService,
    jobRunService: JobRunService,
    jobInfoService: JobInfoService,
    pluginManager: PluginManager,
    launchQueueService: LaunchQueueService,
    actorsModule: ActorsModule,
    metricsModule: MetricsModule,
    electionService: ElectionService
)(implicit ec: ExecutionContext) {

  lazy val authModule: AuthModule = new AuthModule(pluginManager)

  lazy val authorizer: Authorizer = authModule.authorizer
  lazy val authenticator: Authenticator = authModule.authenticator
  lazy val metrics: Metrics = metricsModule.metrics

  lazy val applicationController: ApplicationController = wire[ApplicationController]
  lazy val jobsSpecController: JobSpecController = wire[JobSpecController]
  lazy val jobRunsController: JobRunController = wire[JobRunController]
  lazy val jobSchedulerController: JobScheduleController = wire[JobScheduleController]
  lazy val scheduledJobSchedulerController: ScheduledJobSpecController = wire[ScheduledJobSpecController]
  lazy val launchQueueController: LaunchQueueController = wire[LaunchQueueController]

  lazy val router: Router = {
    // add the prefix string in local scope for the Routes constructor
    val prefix: String = "/" // scalafix:ok
    wire[Routes]
  }
} 
Example 19
Source File: RouteLatencyFilterSpec.scala    From play-prometheus-filters   with MIT License 5 votes vote down vote up
package com.github.stijndehaes.playprometheusfilters.filters

import com.github.stijndehaes.playprometheusfilters.metrics.DefaultPlayUnmatchedDefaults
import com.github.stijndehaes.playprometheusfilters.mocks.MockController
import io.prometheus.client.CollectorRegistry
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.verify
import org.scalatest.mockito.MockitoSugar
import org.scalatest.{MustMatchers, WordSpec}
import org.scalatestplus.play.guice.GuiceOneAppPerSuite
import play.api.Configuration
import play.api.libs.typedmap.TypedMap
import play.api.mvc._
import play.api.routing.{HandlerDef, Router}
import play.api.test.Helpers.stubControllerComponents
import play.api.test.{DefaultAwaitTimeout, FakeRequest, FutureAwaits}

import scala.concurrent.ExecutionContext.Implicits.global

class RouteLatencyFilterSpec extends WordSpec with MustMatchers with MockitoSugar with Results with DefaultAwaitTimeout with FutureAwaits with GuiceOneAppPerSuite  {

  private implicit val mat = app.materializer
  private val configuration = mock[Configuration]

  "Filter constructor" should {
    "Add a histogram to the prometheus registry" in {
      val collectorRegistry = mock[CollectorRegistry]
      new RouteLatencyFilter(collectorRegistry, configuration)
      verify(collectorRegistry).register(any())
    }
  }

  "Apply method" should {
    "Measure the latency" in {
      val filter = new RouteLatencyFilter(mock[CollectorRegistry], configuration)
      val rh = FakeRequest().withAttrs( TypedMap(
        Router.Attrs.HandlerDef -> HandlerDef(null, null, null, "test", null, null ,null ,null ,null)
      ))
      val action = new MockController(stubControllerComponents()).ok

      await(filter(action)(rh).run())

      val metrics = filter.metrics(0).metric.collect()
      metrics must have size 1
      val samples = metrics.get(0).samples
      //this is the count sample
      val countSample = samples.get(samples.size() - 2)
      countSample.value mustBe 1.0
      countSample.labelValues must have size 1
      countSample.labelValues.get(0) mustBe "test"
    }

    "Measure the latency for an unmatched route" in {
      val filter = new RouteLatencyFilter(mock[CollectorRegistry], configuration)
      val rh = FakeRequest()
      val action = new MockController(stubControllerComponents()).error

      await(filter(action)(rh).run())

      val metrics = filter.metrics(0).metric.collect()
      metrics must have size 1
      val samples = metrics.get(0).samples
      //this is the count sample
      val countSample = samples.get(samples.size() - 2)
      countSample.value mustBe 1.0
      countSample.labelValues must have size 1
      countSample.labelValues.get(0) mustBe DefaultPlayUnmatchedDefaults.UnmatchedRouteString
    }
  }

} 
Example 20
Source File: StatusAndRouteLatencyFilterSpec.scala    From play-prometheus-filters   with MIT License 5 votes vote down vote up
package com.github.stijndehaes.playprometheusfilters.filters

import com.github.stijndehaes.playprometheusfilters.metrics.DefaultPlayUnmatchedDefaults
import com.github.stijndehaes.playprometheusfilters.mocks.MockController
import io.prometheus.client.CollectorRegistry
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.verify
import org.scalatest.mockito.MockitoSugar
import org.scalatest.{MustMatchers, WordSpec}
import org.scalatestplus.play.guice.GuiceOneAppPerSuite
import play.api.Configuration
import play.api.libs.typedmap.TypedMap
import play.api.mvc.Results
import play.api.routing.{HandlerDef, Router}
import play.api.test.Helpers.stubControllerComponents
import play.api.test.{DefaultAwaitTimeout, FakeRequest, FutureAwaits}

import scala.concurrent.ExecutionContext.Implicits.global

class StatusAndRouteLatencyFilterSpec extends WordSpec with MustMatchers with MockitoSugar with Results with DefaultAwaitTimeout with FutureAwaits with GuiceOneAppPerSuite  {

  private implicit val mat = app.materializer
  private val configuration = mock[Configuration]

  "Filter constructor" should {
    "Add a histogram to the prometheus registry" in {
      val collectorRegistry = mock[CollectorRegistry]
      new StatusAndRouteLatencyFilter(collectorRegistry, configuration)
      verify(collectorRegistry).register(any())
    }
  }

  "Apply method" should {
    "Measure the latency" in {
      val filter = new StatusAndRouteLatencyFilter(mock[CollectorRegistry], configuration)
      val rh = FakeRequest().withAttrs( TypedMap(
        Router.Attrs.HandlerDef -> HandlerDef(null, null, "testController", "test", null, "GET", "/path", null ,null)
      ))
      val action = new MockController(stubControllerComponents()).ok

      await(filter(action)(rh).run())

      val metrics = filter.metrics(0).metric.collect()
      metrics must have size 1
      val samples = metrics.get(0).samples
      //this is the count sample
      val countSample = samples.get(samples.size() - 2)
      countSample.value mustBe 1.0
      countSample.labelValues must have size 5
      countSample.labelValues.get(0) mustBe "test"
      countSample.labelValues.get(1) mustBe "200"
      countSample.labelValues.get(2) mustBe "testController"
      countSample.labelValues.get(3) mustBe "/path"
      countSample.labelValues.get(4) mustBe "GET"
    }

    "Measure the latency for an unmatched route" in {
      val filter = new StatusAndRouteLatencyFilter(mock[CollectorRegistry], configuration)
      val rh = FakeRequest()
      val action = new MockController(stubControllerComponents()).error

      await(filter(action)(rh).run())

      val metrics = filter.metrics(0).metric.collect()
      metrics must have size 1
      val samples = metrics.get(0).samples
      //this is the count sample
      val countSample = samples.get(samples.size() - 2)
      countSample.value mustBe 1.0
      countSample.labelValues must have size 5
      countSample.labelValues.get(0) mustBe DefaultPlayUnmatchedDefaults.UnmatchedRouteString
      countSample.labelValues.get(1) mustBe "404"
      countSample.labelValues.get(2) mustBe DefaultPlayUnmatchedDefaults.UnmatchedControllerString
      countSample.labelValues.get(3) mustBe DefaultPlayUnmatchedDefaults.UnmatchedPathString
      countSample.labelValues.get(4) mustBe DefaultPlayUnmatchedDefaults.UnmatchedVerbString
    }
  }
} 
Example 21
Source File: StatusAndRouteCounterFilterSpec.scala    From play-prometheus-filters   with MIT License 5 votes vote down vote up
package com.github.stijndehaes.playprometheusfilters.filters

import com.github.stijndehaes.playprometheusfilters.metrics.DefaultPlayUnmatchedDefaults
import com.github.stijndehaes.playprometheusfilters.mocks.MockController
import io.prometheus.client.CollectorRegistry
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.verify
import org.scalatest.mockito.MockitoSugar
import org.scalatest.{MustMatchers, WordSpec}
import org.scalatestplus.play.guice.GuiceOneAppPerSuite
import play.api.Configuration
import play.api.libs.typedmap.TypedMap
import play.api.mvc.Results
import play.api.routing.{HandlerDef, Router}
import play.api.test.Helpers.stubControllerComponents
import play.api.test.{DefaultAwaitTimeout, FakeRequest, FutureAwaits}

import scala.concurrent.ExecutionContext.Implicits.global

class StatusAndRouteCounterFilterSpec extends WordSpec with MustMatchers with MockitoSugar with Results with DefaultAwaitTimeout with FutureAwaits with GuiceOneAppPerSuite  {

  private implicit val mat = app.materializer
  private val configuration = mock[Configuration]

  "Filter constructor" should {
    "Add a histogram to the prometheus registry" in {
      val collectorRegistry = mock[CollectorRegistry]
      new StatusAndRouteLatencyFilter(collectorRegistry, configuration)
      verify(collectorRegistry).register(any())
    }
  }

  "Apply method" should {
    "Measure the count" in {
      val filter = new StatusAndRouteCounterFilter(mock[CollectorRegistry], configuration)
      val rh = FakeRequest().withAttrs( TypedMap(
        Router.Attrs.HandlerDef -> HandlerDef(null, null, "testController", "test", null, "GET", "/path", null ,null)
      ))
      val action = new MockController(stubControllerComponents()).ok

      await(filter(action)(rh).run())

      val metrics = filter.metrics(0).metric.collect()
      metrics must have size 1
      val samples = metrics.get(0).samples
      //this is the count sample
      val countSample = samples.get(0)
      countSample.value mustBe 1.0
      countSample.labelValues must have size 5
      countSample.labelValues.get(0) mustBe "test"
      countSample.labelValues.get(1) mustBe "200"
      countSample.labelValues.get(2) mustBe "testController"
      countSample.labelValues.get(3) mustBe "/path"
      countSample.labelValues.get(4) mustBe "GET"
    }

    "Measure the count for an unmatched route" in {
      val filter = new StatusAndRouteCounterFilter(mock[CollectorRegistry], configuration)
      val rh = FakeRequest()
      val action = new MockController(stubControllerComponents()).error

      await(filter(action)(rh).run())

      val metrics = filter.metrics(0).metric.collect()
      metrics must have size 1
      val samples = metrics.get(0).samples
      //this is the count sample
      val countSample = samples.get(0)
      countSample.value mustBe 1.0
      countSample.labelValues must have size 5
      countSample.labelValues.get(0) mustBe DefaultPlayUnmatchedDefaults.UnmatchedRouteString
      countSample.labelValues.get(1) mustBe "404"
      countSample.labelValues.get(2) mustBe DefaultPlayUnmatchedDefaults.UnmatchedControllerString
      countSample.labelValues.get(3) mustBe DefaultPlayUnmatchedDefaults.UnmatchedPathString
      countSample.labelValues.get(4) mustBe DefaultPlayUnmatchedDefaults.UnmatchedVerbString
    }
  }

} 
Example 22
Source File: ZipkinTraceFilter.scala    From play-zipkin-tracing   with Apache License 2.0 5 votes vote down vote up
package brave.play.filter

import javax.inject.Inject

import akka.stream.Materializer
import brave.play.ZipkinTraceServiceLike
import play.api.mvc.{Filter, Headers, RequestHeader, Result}
import play.api.routing.Router

import scala.concurrent.Future
import scala.util.Failure


class ZipkinTraceFilter @Inject() (tracer: ZipkinTraceServiceLike)(implicit val mat: Materializer) extends Filter {

  import tracer.executionContext
  private val reqHeaderToSpanName: RequestHeader => String = ZipkinTraceFilter.ParamAwareRequestNamer

  def apply(nextFilter: RequestHeader => Future[Result])(req: RequestHeader): Future[Result] = {
    val serverSpan = tracer.serverReceived(
      spanName = reqHeaderToSpanName(req),
      span = tracer.newSpan(req.headers)((headers, key) => headers.get(key))
    )
    val result = nextFilter(req.withHeaders(new Headers(
      (req.headers.toMap.mapValues(_.headOption getOrElse "") ++ tracer.toMap(serverSpan)).toSeq
    )))
    result.onComplete {
      case Failure(t) => tracer.serverSend(serverSpan, "failed" -> s"Finished with exception: ${t.getMessage}")
      case _ => tracer.serverSend(serverSpan)
    }
    result
  }
}

object ZipkinTraceFilter {
  val ParamAwareRequestNamer: RequestHeader => String = { reqHeader =>
    import org.apache.commons.lang3.StringUtils
    val pathPattern = StringUtils.replace(
      reqHeader.attrs.get(Router.Attrs.HandlerDef).map(_.path).getOrElse(reqHeader.path),
      "<[^/]+>", ""
    )
    s"${reqHeader.method} - $pathPattern"
  }
} 
Example 23
Source File: ErrorHandler.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
import javax.inject.{ Inject, Provider }
import play.api.{ Configuration, Environment, Logger, OptionalSourceMapper, UsefulException }
import play.api.http.DefaultHttpErrorHandler
import play.api.mvc.RequestHeader
import play.api.mvc.Results._
import play.api.routing.Router
import scala.concurrent.Future

class ErrorHandler @Inject() (
    env: Environment,
    config: Configuration,
    sourceMapper: OptionalSourceMapper,
    router: Provider[Router]
  ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  override def onProdServerError(request: RequestHeader, exception: UsefulException) =
    Future.successful(InternalServerError(s"An error occurred: ${exception.getMessage}"))

  override def onClientError(request: RequestHeader, statusCode: Int, message: String) = {
    if (statusCode == 413) // Request entity too large
      Future.successful(EntityTooLarge("Could not upload the file - too large"))
    else if (statusCode == 404) // Not Found
      Future.successful(NotFound(views.html.error404()))
    else
      super.onClientError(request, statusCode, message)
  }

} 
Example 24
Source File: ErrorHandler.scala    From scalafiddle-editor   with Apache License 2.0 5 votes vote down vote up
import javax.inject._

import play.api._
import play.api.http.DefaultHttpErrorHandler
import play.api.mvc.Results._
import play.api.mvc._
import play.api.routing.Router

import scala.concurrent._

@Singleton
class ErrorHandler @Inject() (
    env: Environment,
    config: Configuration,
    sourceMapper: OptionalSourceMapper,
    router: Provider[Router]
) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  override def onProdServerError(request: RequestHeader, exception: UsefulException) =
    Future.successful(InternalServerError("A server error occurred: " + exception.getMessage))

  override def onForbidden(request: RequestHeader, message: String) =
    Future.successful(Forbidden("You're not allowed to access this resource."))

  override protected def onNotFound(request: RequestHeader, message: String) =
    Future.successful(NotFound("Resource not found"))

  override protected def onBadRequest(request: RequestHeader, message: String) =
    Future.successful(BadRequest("Bad request"))

} 
Example 25
Source File: PlayServerTests.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.server.play

import akka.actor.ActorSystem
import cats.data.NonEmptyList
import cats.effect.{IO, Resource}
import play.api.Mode
import play.api.mvc.{Handler, RequestHeader}
import play.api.routing.Router
import play.api.routing.Router.Routes
import play.core.server.{DefaultAkkaHttpServerComponents, ServerConfig}
import sttp.tapir.Endpoint
import sttp.tapir.server.tests.ServerTests
import sttp.tapir.server.{DecodeFailureHandler, ServerDefaults, ServerEndpoint}
import sttp.tapir.tests.{Port, PortCounter}

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scala.reflect.ClassTag

class PlayServerTests extends ServerTests[Future, Nothing, Router.Routes] {
  override def multipleValueHeaderSupport: Boolean = false
  override def multipartInlineHeaderSupport: Boolean = false
  override def streamingSupport: Boolean = false

  private implicit val actorSystem: ActorSystem = ActorSystem()

  override protected def afterAll(): Unit = {
    Await.result(actorSystem.terminate(), 5.seconds)
    super.afterAll()
  }

  override def pureResult[T](t: T): Future[T] = Future.successful(t)

  override def suspendResult[T](t: => T): Future[T] = Future(t)

  override def route[I, E, O](
      e: ServerEndpoint[I, E, O, Nothing, Future],
      decodeFailureHandler: Option[DecodeFailureHandler]
  ): Routes = {
    implicit val serverOptions: PlayServerOptions =
      PlayServerOptions.default.copy(decodeFailureHandler = decodeFailureHandler.getOrElse(ServerDefaults.decodeFailureHandler))
    e.toRoute
  }

  override def routeRecoverErrors[I, E <: Throwable, O](e: Endpoint[I, E, O, Nothing], fn: I => Future[O])(implicit
      eClassTag: ClassTag[E]
  ): Routes = {
    e.toRouteRecoverErrors(fn)
  }

  override def server(routes: NonEmptyList[Routes], port: Port): Resource[IO, Unit] = {
    val components = new DefaultAkkaHttpServerComponents {
      override lazy val serverConfig: ServerConfig = ServerConfig(port = Some(port), address = "127.0.0.1", mode = Mode.Test)
      override def router: Router =
        Router.from(
          routes.reduce((a: Routes, b: Routes) => {
            val handler: PartialFunction[RequestHeader, Handler] = {
              case request => a.applyOrElse(request, b)
            }

            handler
          })
        )
    }
    val bind = IO {
      components.server
    }
    Resource.make(bind)(s => IO(s.stop())).map(_ => ())
  }

  override val portCounter: PortCounter = new PortCounter(38000)
} 
Example 26
Source File: ErrorHandler.scala    From izanami   with Apache License 2.0 5 votes vote down vote up
package handlers

import libs.logs.IzanamiLogger
import play.api._
import play.api.http.DefaultHttpErrorHandler
import play.api.mvc.Results._
import play.api.mvc._
import play.api.routing.Router
import play.core.SourceMapper

import scala.concurrent._

class ErrorHandler(
    env: Environment,
    config: Configuration,
    sourceMapper: Option[SourceMapper],
    router: => Option[Router]
) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    IzanamiLogger.error(s"Error serving request ${request.method} ${request.uri}", exception)
    Future.successful(
      InternalServerError
    )
  }

} 
Example 27
Source File: ErrorHandler.scala    From play-table-of-contents   with MIT License 5 votes vote down vote up
import javax.inject.{Inject, Provider, Singleton}

import play.api._
import play.api.http.DefaultHttpErrorHandler
import play.api.mvc.Results._
import play.api.mvc._
import play.api.routing.Router

import scala.concurrent._


@Singleton
class ErrorHandler @Inject() (
   env: Environment,
   config: Configuration,
   sourceMapper: OptionalSourceMapper,
   router: Provider[Router]
  ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    Future.successful(
      InternalServerError("A server error occurred: " + exception.getMessage)
    )
  }

  override def onForbidden(request: RequestHeader, message: String) = {
    Future.successful(
      Forbidden("You're not allowed to access this resource.")
    )
  }
} 
Example 28
Source File: ErrorHandler.scala    From daf-semantics   with Apache License 2.0 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing


class ErrorHandler @Inject() (
    env: Environment,
    config: Configuration,
    sourceMapper: OptionalSourceMapper,
    router: Provider[Router]
) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }

  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 29
Source File: ErrorHandler.scala    From daf-semantics   with Apache License 2.0 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing

/**
 * The purpose of this ErrorHandler is to override default play's error reporting with application/json content type.
 */
class ErrorHandler @Inject() (
    env: Environment,
    config: Configuration,
    sourceMapper: OptionalSourceMapper,
    router: Provider[Router]
) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }

  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 30
Source File: ErrorHandler.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing


@SuppressWarnings(Array("org.wartremover.warts.Equals", "org.wartremover.warts.ExplicitImplicitTypes"))
class ErrorHandler @Inject() (
    env: Environment,
    config: Configuration,
    sourceMapper: OptionalSourceMapper,
    router: Provider[Router]
) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }

  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 31
Source File: ErrorHandler.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing



@SuppressWarnings(Array("org.wartremover.warts.Equals", "org.wartremover.warts.ExplicitImplicitTypes"))
class ErrorHandler @Inject() (
                               env: Environment,
                               config: Configuration,
                               sourceMapper: OptionalSourceMapper,
                               router: Provider[Router]
                             ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }


  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 32
Source File: ErrorHandler.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing


@SuppressWarnings(Array("org.wartremover.warts.Equals", "org.wartremover.warts.ExplicitImplicitTypes"))
class ErrorHandler @Inject() (
    env: Environment,
    config: Configuration,
    sourceMapper: OptionalSourceMapper,
    router: Provider[Router]
) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }

  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 33
Source File: ErrorHandler.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing



@SuppressWarnings(Array("org.wartremover.warts.Equals", "org.wartremover.warts.ExplicitImplicitTypes"))
class ErrorHandler @Inject() (
                               env: Environment,
                               config: Configuration,
                               sourceMapper: OptionalSourceMapper,
                               router: Provider[Router]
                             ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }


  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 34
Source File: ErrorHandler.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing



//@SuppressWarnings(Array("org.wartremover.warts.Equals", "org.wartremover.warts.ExplicitImplicitTypes"))
class ErrorHandler @Inject() (
                               env: Environment,
                               config: Configuration,
                               sourceMapper: OptionalSourceMapper,
                               router: Provider[Router]
                             ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }


  override def onDevServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }


  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 35
Source File: ErrorHandler.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing



@SuppressWarnings(Array("org.wartremover.warts.Equals", "org.wartremover.warts.ExplicitImplicitTypes"))
class ErrorHandler @Inject() (
                               env: Environment,
                               config: Configuration,
                               sourceMapper: OptionalSourceMapper,
                               router: Provider[Router]
                             ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }


  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 36
Source File: ErrorHandler.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import javax.inject._

import play.api.http.DefaultHttpErrorHandler
import play.api._
import play.api.mvc._
import play.api.mvc.Results._
import play.api.routing.Router

import scala.concurrent.Future

import de.zalando.play.controllers.PlayBodyParsing


class ErrorHandler @Inject() (
    env: Environment,
    config: Configuration,
    sourceMapper: OptionalSourceMapper,
    router: Provider[Router]
) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  private def contentType(request: RequestHeader): String =
    request.acceptedTypes.map(_.toString).filterNot(_ == "text/html").headOption.getOrElse("application/json")

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    implicit val writer = PlayBodyParsing.anyToWritable[Throwable](contentType(request))
    Future.successful(InternalServerError(exception))
  }

  // called when a route is found, but it was not possible to bind the request parameters
  override def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(BadRequest("Bad Request: " + error))
  }

  // 404 - page not found error
  override def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    implicit val writer = PlayBodyParsing.anyToWritable[String](contentType(request))
    Future.successful(NotFound(request.path))
  }
} 
Example 37
Source File: CatalogControllersSpec.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import java.io.IOException
import java.net.ServerSocket

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import catalog_manager.yaml.MetaCatalog
import org.specs2.mutable.Specification
import play.api.Application
import play.api.http.Status
import play.api.routing.Router
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.libs.json.{JsArray, JsValue, Json}
import play.api.libs.ws.WSResponse
import play.api.libs.ws.ahc.AhcWSClient
import play.api.test._
import it.gov.daf.catalogmanager
import it.gov.daf.catalogmanager.client.Catalog_managerClient

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}


class CatalogControllersSpec extends Specification  {

  def application: Application = GuiceApplicationBuilder().build()

  import catalog_manager.yaml.BodyReads.MetaCatalogReads

  "The catalog-manager" should {
    "Call catalog-manager/v1/dataset-catalogs return ok status" in
      new WithServer(app = application, port = 9000) {
        WsTestClient.withClient { implicit client =>
          val response: WSResponse = Await.result[WSResponse](client.
            url(s"http://localhost:9001/catalog-manager/v1/dataset-catalogs").
            execute, Duration.Inf)
          println(response.status)
          response.status must be equalTo Status.OK
        }
      }

    "Call catalog-manager/v1/dataset-catalogs return a non empty list if" +
      "you have error maybe is necessaty to add data to db" in
      new WithServer(app = application, port = 9000) {
        WsTestClient.withClient { implicit client =>
          val response: WSResponse = Await.result[WSResponse](client.
            url(s"http://localhost:9001/catalog-manager/v1/dataset-catalogs").
            execute, Duration.Inf)
          println(response.status)
          println("ALE")
          println(response.body)
          val json: JsValue = Json.parse(response.body)
          json.as[JsArray].value.size must be greaterThan (0)
        }
      }


    "The catalog-manager" should {
      "Call catalog-manager/v1/dataset-catalogs/{logical_uri} return ok status" in
        new WithServer(app = application, port = 9000) {
          val logicalUri = "daf://dataset/std/standard/standard/uri_cultura/standard"
          val url = s"http://localhost:9001/catalog-manager/v1/dataset-catalogs/$logicalUri"
          println(url)
          WsTestClient.withClient { implicit client =>
            val response: WSResponse = Await.result[WSResponse](client.
              url(url).
              execute, Duration.Inf)
            println(response.status)
            response.status must be equalTo Status.OK
          }
        }
    }

    "The catalog-manager" should {
      "Call catalog-manager/v1/dataset-catalogs/{anything} return 401" in
        new WithServer(app = application, port = 9000) {
          val logicalUri = "anything"
          val url = s"http://localhost:9001/catalog-manager/v1/dataset-catalogs/$logicalUri"
          println(url)
          WsTestClient.withClient { implicit client =>
            val response: WSResponse = Await.result[WSResponse](client.
              url(url).
              execute, Duration.Inf)
            println(response.status)
            response.status must be equalTo 401
          }
        }
    }
  }
} 
Example 38
Source File: FeyUIService.scala    From incubator-retired-iota   with Apache License 2.0 5 votes vote down vote up
package org.apache.iota.fey

import org.apache.iota.fey.FeyCore.JSON_TREE
import play.api.BuiltInComponents
import play.api.http.DefaultHttpErrorHandler
import play.api.libs.json.Json
import play.api.mvc._
import play.api.routing.Router
import play.api.routing.sird._
import play.core.server._
import CONFIG._

import scala.concurrent.Future

object FeyUIService {


  val components = new FeyUIService(URL_PATH, PORT)
  val server = components.server
}

class FeyUIService(urlPath: String, port: Int) extends NettyServerComponents with BuiltInComponents {

  val THREAD_SLEEP_TIME = 2000
  lazy val router = Router.from {
    case GET(p"/fey/activeactors") => Action {
      FEY_CORE_ACTOR.actorRef ! JSON_TREE
      Thread.sleep(THREAD_SLEEP_TIME)
      val json = IdentifyFeyActors.generateTreeJson()
      val jsonTree: String = IdentifyFeyActors.getHTMLTree(json)
      Results.Ok(jsonTree).as("text/html")
    }
    case GET(p"/fey/actorslifecycle") => Action {
      val jsonTree = Json.stringify(Monitor.events.printWithEvents)
      Results.Ok(jsonTree).as("application/json")
    }
    case GET(p"/fey/monitoringevents") => Action {
      val returnValue: String = try {
        if (CONFIG.MONITORING_TYPE == "COMPLETE") {
          Monitor.getHTMLevents
        } else {
          Monitor.getSimpleHTMLEvents
        }
      } catch {
        case e: Exception => ""
      }
      Results.Ok(returnValue).as("text/html")
    }
  }

  override lazy val serverConfig = ServerConfig(
    port = Some(port),
    address = urlPath
  )
  override lazy val httpErrorHandler = new DefaultHttpErrorHandler(environment,
    configuration, sourceMapper, Some(router)) {

    override protected def onNotFound(request: RequestHeader, message: String) = {
      Future.successful(Results.NotFound("NO_DATA_FOUND"))
    }
  }
} 
Example 39
Source File: KafkaManagerLoader.scala    From CMAK   with Apache License 2.0 5 votes vote down vote up
package loader

import controllers.{AssetsComponents, BasicAuthenticationFilter, KafkaManagerContext}
import features.ApplicationFeatures
import models.navigation.Menus
import play.api.{Application, ApplicationLoader, BuiltInComponentsFromContext, LoggerConfigurator}
import play.api.ApplicationLoader.Context
import play.api.i18n.I18nComponents
import play.api.mvc.Filter
import play.api.routing.Router
import router.Routes

import scala.concurrent.ExecutionContext



class KafkaManagerLoader extends ApplicationLoader {
  def load(context: Context): Application = {
    LoggerConfigurator(context.environment.classLoader).foreach {
      _.configure(context.environment, context.initialConfiguration, Map.empty)
    }
    new ApplicationComponents(context).application
  }
}

class ApplicationComponents(context: Context) extends BuiltInComponentsFromContext(context) with I18nComponents with AssetsComponents {
  implicit val applicationFeatures: ApplicationFeatures = ApplicationFeatures.getApplicationFeatures(context.initialConfiguration.underlying)
  implicit val menus: Menus = new Menus
  implicit val ec: ExecutionContext = controllerComponents.executionContext
  val kafkaManagerContext = new KafkaManagerContext(applicationLifecycle, context.initialConfiguration)
  private[this] val applicationC = new controllers.Application(controllerComponents, kafkaManagerContext)
  private[this] lazy val clusterC = new controllers.Cluster(controllerComponents, kafkaManagerContext)
  private[this] lazy val topicC = new controllers.Topic(controllerComponents, kafkaManagerContext)
  private[this] lazy val logKafkaC = new controllers.Logkafka(controllerComponents, kafkaManagerContext)
  private[this] lazy val consumerC = new controllers.Consumer(controllerComponents, kafkaManagerContext)
  private[this] lazy val preferredReplicaElectionC= new controllers.PreferredReplicaElection(controllerComponents, kafkaManagerContext)
  private[this] lazy val reassignPartitionsC = new controllers.ReassignPartitions(controllerComponents, kafkaManagerContext)
  lazy val kafkaStateCheckC = new controllers.api.KafkaStateCheck(controllerComponents, kafkaManagerContext)
  lazy val apiHealthC = new controllers.ApiHealth(controllerComponents)

  override lazy val httpFilters: Seq[Filter] = Seq(BasicAuthenticationFilter(context.initialConfiguration))


  override val router: Router = new Routes(
    httpErrorHandler, 
    applicationC, 
    clusterC, 
    topicC, 
    logKafkaC, 
    consumerC, 
    preferredReplicaElectionC,
    reassignPartitionsC, 
    kafkaStateCheckC, 
    assets,
    apiHealthC
  ).withPrefix(context.initialConfiguration.getOptional[String]("play.http.context").orNull)
} 
Example 40
Source File: TOCApplicationLoader.scala    From play-table-of-contents   with MIT License 5 votes vote down vote up
import akka.actor.ActorSystem
import com.typesafe.config.ConfigFactory
import context.MyExecutionContext
import play.api.routing.Router
import play.api.{Application, ApplicationLoader, BuiltInComponentsFromContext}
import com.softwaremill.macwire._
import router.Routes

class TOCApplicationLoader extends ApplicationLoader{

  def load(context: ApplicationLoader.Context): Application = {
    val exeContext = new MyExecutionContext(ActorSystem("tocActor", ConfigFactory.load()))
    new TOCComponents(exeContext,context).application
  }
}

class TOCComponents(ec: MyExecutionContext, context: ApplicationLoader.Context)
  extends BuiltInComponentsFromContext(context)
  with play.filters.HttpFiltersComponents
  with _root_.controllers.AssetsComponents{

  lazy val tableOfContentController = wire[controllers.TableOfContentController]
  // add the prefix string in local scope for the Routes constructor
  val prefix: String = "/"
  lazy val router: Router = wire[Routes]
} 
Example 41
Source File: VersionRoutingMap.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package routing

import com.google.inject.ImplementedBy
import config.{AppConfig, FeatureSwitch}
import definition.Versions.VERSION_1
import javax.inject.Inject
import play.api.Logger
import play.api.routing.Router

// So that we can have API-independent implementations of
// VersionRoutingRequestHandler and VersionRoutingRequestHandlerSpec
// implement this for the specific API...
@ImplementedBy(classOf[VersionRoutingMapImpl])
trait VersionRoutingMap {
  val defaultRouter: Router

  val map: Map[String, Router]

  final def versionRouter(version: String): Option[Router] = map.get(version)
}

// Add routes corresponding to available versions...
case class VersionRoutingMapImpl @Inject()(appConfig: AppConfig,
                                           defaultRouter: Router,
                                           liveRouter: live.Routes,
                                           v1Router: v1.Routes,
                                           v1RouterProd: v1Prod.Routes) extends VersionRoutingMap {

  val featureSwitch = FeatureSwitch(appConfig.featureSwitch)

  val map: Map[String, Router] = Map(
    VERSION_1 ->  {
      if (featureSwitch.refactorEnabled) {
        if (featureSwitch.refactorProdEnabled) {
          Logger.info("[VersionRoutingMap][map] using v1Router - pointing to new packages for Obligations")
          v1RouterProd
        }
        else {
          Logger.info("[VersionRoutingMap][map] using v1Router - pointing to new packages")
          v1Router
        }
      } else {
        Logger.info("[VersionRoutingMap][map] using legacy liveRouter")
        liveRouter
      }
    }
  )
} 
Example 42
Source File: VersionRoutingRequestHandler.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package routing

import config.{AppConfig, FeatureSwitch}
import definition.Versions
import javax.inject.{Inject, Singleton}
import play.api.http.{DefaultHttpRequestHandler, HttpConfiguration, HttpErrorHandler, HttpFilters}
import play.api.libs.json.Json
import play.api.mvc.{DefaultActionBuilder, Handler, RequestHeader, Results}
import play.api.routing.Router
import v1.controllers.requestParsers.validators.validations.VrnValidation
import v1.models.errors.{InvalidAcceptHeaderError, UnsupportedVersionError, VrnFormatError}

@Singleton
class VersionRoutingRequestHandler @Inject()(versionRoutingMap: VersionRoutingMap,
                                             errorHandler: HttpErrorHandler,
                                             httpConfiguration: HttpConfiguration,
                                             config: AppConfig,
                                             filters: HttpFilters,
                                             action: DefaultActionBuilder)
  extends DefaultHttpRequestHandler(versionRoutingMap.defaultRouter, errorHandler, httpConfiguration, filters) {

  private val featureSwitch = FeatureSwitch(config.featureSwitch)

  private val unsupportedVersionAction = action(Results.NotFound(Json.toJson(UnsupportedVersionError)))

  private val invalidAcceptHeaderError = action(Results.NotAcceptable(Json.toJson(InvalidAcceptHeaderError)))

  override def routeRequest(request: RequestHeader): Option[Handler] = {

    def documentHandler = routeWith(versionRoutingMap.defaultRouter)(request)

    def apiHandler = Versions.getFromRequest(request) match {
      case Some(version) =>
        versionRoutingMap.versionRouter(version) match {
          case Some(versionRouter) if featureSwitch.isVersionEnabled(version) =>
            routeWith(versionRouter)(request)
          case Some(_) => Some(unsupportedVersionAction)
          case None => Some(unsupportedVersionAction)
        }
      case None => Some(invalidAcceptHeaderError)
    }

    documentHandler orElse apiHandler
  }

  private def routeWith(router: Router)(request: RequestHeader) =
    router
      .handlerFor(request)
      .orElse {
        if (validatePath(request.path)) {
          if (request.path.endsWith("/")) {
            val pathWithoutSlash = request.path.dropRight(1)
            val requestWithModifiedPath = request.withTarget(request.target.withPath(pathWithoutSlash))
            router.handlerFor(requestWithModifiedPath)
          }
          else None
        }
        else {
          Some(action(Results.BadRequest(Json.toJson(VrnFormatError))))
        }
      }

  private def validatePath(path: String) = {
    val vrn = path.split("/")(1)
    if(VrnValidation.validate(vrn) == Nil)
      true
    else false
  }
} 
Example 43
Source File: ErrorHandler.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.vatapi.utils

import javax.inject._
import play.api._
import play.api.http.DefaultHttpErrorHandler
import play.api.libs.json.Json
import play.api.mvc.Results._
import play.api.mvc._
import play.api.routing.Router
import uk.gov.hmrc.http._
import uk.gov.hmrc.vatapi.models.{ErrorBadRequest, ErrorCode, ErrorNotImplemented}

import scala.concurrent._

@Singleton
class ErrorHandler @Inject()(
                              env: Environment,
                              config: Configuration,
                              sourceMapper: OptionalSourceMapper,
                              router: Provider[Router]
                            )(implicit ec: ExecutionContext) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  override def onServerError(request: RequestHeader, ex: Throwable): Future[Result] = {
    super.onServerError(request, ex).map { result =>
      ex match {
        case _ =>
          ex.getCause match {
            case _: NotImplementedException =>
              NotImplemented(Json.toJson(ErrorNotImplemented))
            case _ =>
              Logger.info(s"[ErrorHandler][onServerError] uncaught 5xx Exception")
              result
          }
      }
    }
  }

  override protected def onBadRequest(request: RequestHeader, error: String): Future[Result] = {
    super.onBadRequest(request, error).map { _ =>
      error match {
        case "ERROR_VRN_INVALID" => BadRequest(Json.toJson(ErrorBadRequest(ErrorCode.VRN_INVALID, "The provided Vrn is invalid")))
        case "ERROR_INVALID_DATE" => BadRequest(Json.toJson(ErrorBadRequest(ErrorCode.INVALID_DATE, "The provided date is invalid")))
        case "ERROR_INVALID_FROM_DATE" => BadRequest(Json.toJson(ErrorBadRequest(ErrorCode.INVALID_FROM_DATE, "The provided from date is invalid")))
        case "ERROR_INVALID_TO_DATE" => BadRequest(Json.toJson(ErrorBadRequest(ErrorCode.INVALID_TO_DATE, "The provided to date is invalid")))
        case "INVALID_STATUS" | "INVALID_DATE_RANGE" => BadRequest(Json.toJson(Json.obj("statusCode" -> 400, "message" -> error)))
        case unmatchedError => {
          Logger.warn(s"[ErrorHandler][onBadRequest] - Received unmatched error: '$unmatchedError'")
          BadRequest(Json.toJson(Json.obj("statusCode" -> 400, "message" -> JsonErrorSanitiser.sanitise(unmatchedError))))
        }
      }
    }
  }

  override protected def onDevServerError(request: RequestHeader, ex: UsefulException): Future[Result] = {
    super.onServerError(request, ex).map { result =>
      ex match {
        case _ =>
          ex.getCause match {
            case _: NotImplementedException =>
              NotImplemented(Json.toJson(ErrorNotImplemented))
            case _ => result
          }
      }
    }
  }
} 
Example 44
Source File: AppLoader.scala    From play-quill-jdbc   with MIT License 5 votes vote down vote up
import java.io.Closeable
import javax.sql.DataSource

import controllers.UsersController
import io.getquill._
import play.api.ApplicationLoader.Context
import play.api._
import play.api.db.evolutions.Evolutions
import play.api.db.{DBComponents, HikariCPComponents}
import play.api.inject.{Injector, NewInstanceInjector, SimpleInjector}
import play.api.routing.Router
import play.api.routing.sird._
import models.{Users}

class AppLoader extends ApplicationLoader {
  override def load(context: Context): Application = new BuiltInComponentsFromContext(context) with DBComponents with HikariCPComponents {

    lazy val db = new H2JdbcContext[SnakeCase](dbApi.database("default").dataSource.asInstanceOf[DataSource with Closeable])


    lazy val users = new Users(db)
    lazy val usersController = new UsersController(users)

    val router = Router.from {
      case GET(p"/users/${long(id)}")    => usersController.get(id)
      case POST(p"/users")               => usersController.create
      case DELETE(p"/users/${long(id)}") => usersController.delete(id)
      case PUT(p"/users/${long(id)}")    => usersController.update(id)
    }

    override lazy val injector: Injector =
      new SimpleInjector(NewInstanceInjector) + users + router + cookieSigner + csrfTokenSigner + httpConfiguration + tempFileCreator + global

    Evolutions.applyEvolutions(dbApi.database("default"))

  }.application
} 
Example 45
Source File: ErrorHandler.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
import javax.inject._

import play.api._
import play.api.http.DefaultHttpErrorHandler
import play.api.libs.json.Json
import play.api.mvc.Results._
import play.api.mvc.{ RequestHeader, Result }
import play.api.routing.Router

import scala.concurrent.Future

@Singleton
class ErrorHandler @Inject() (env: Environment, config: Configuration, sourceMapper: OptionalSourceMapper, router: Provider[Router]) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {
  override protected def onNotFound(request: RequestHeader, message: String): Future[Result] = {
    Future.successful(NotFound(Json.obj("path" -> request.path, "messages" -> List("not found", message))))
  }

  override protected def onDevServerError(request: RequestHeader, exception: UsefulException): Future[Result] = {
    Future.successful(InternalServerError(Json.obj("path" -> request.path, "messages" -> List(exception.description))))
  }

  override protected def onProdServerError(request: RequestHeader, exception: UsefulException): Future[Result] = {
    Future.successful(InternalServerError(Json.obj("path" -> request.path, "messages" -> List(exception.description))))
  }

  override protected def onForbidden(request: RequestHeader, message: String): Future[Result] = {
    Future.successful(Forbidden(Json.obj("path" -> request.path, "messages" -> List("forbidden", message))))
  }
} 
Example 46
Source File: SecurityFilterSpec.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import javax.inject.{Inject, Provider}
import play.api.inject._
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.mvc.Results._
import play.api.mvc._
import play.api.routing.Router
import play.api.test.{FakeRequest, PlaySpecification}
import play.api.{Application, Mode}

class SecurityFilterSpec extends PlaySpecification with BodyParsers {

  val testTokenInfo = TokenInfo("", Scope.Empty, "token type", "user uid", realm = "/employees")

  def appWithRoutes: Application = new GuiceApplicationBuilder()
    .in(Mode.Test)
    .bindings(bind[AuthProvider] to new AlwaysPassAuthProvider(testTokenInfo))
    .overrides(
      bind[Router].toProvider[SecurityFilterTestRouterProvider])
    .configure(
      "play.http.filters" -> "org.zalando.zhewbacca.TestingFilters",
      "authorisation.rules.file" -> "security_filter.conf")
    .build

  "SecurityFilter" should {

    "allow protected inner action to access token info" in {
      val response = route(appWithRoutes, FakeRequest(GET, "/")).get
      status(response) must beEqualTo(OK)
      contentAsString(response) must beEqualTo(testTokenInfo.tokenType)
    }

    "deny an access when there is no security rule for the reguest is given" in {
      val response = route(appWithRoutes, FakeRequest(GET, "/unprotected-by-mistake")).get
      status(response) must beEqualTo(FORBIDDEN)
    }

  }

}

class SecurityFilterTestRouterProvider @Inject() (components: ControllerComponents) extends Provider[Router] {

  import components.{actionBuilder => Action}
  import play.api.routing.sird._

  override def get(): Router = Router.from {
    // test action returning action type. Shows the usage and makes it possible to test basic behaviour
    // security rules described in 'security_filter.conf' file
    case GET(p"/") => Action { request =>
      import TokenInfoConverter._
      Ok(request.tokenInfo.tokenType)
    }

    case GET(p"/unprotected") => Action {
      Ok
    }
  }
} 
Example 47
Source File: Commands.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package cqrs.commands

//#server
import endpoints4s.play.server.{Endpoints, JsonEntitiesFromCodecs, PlayComponents}
import play.api.routing.Router

class Commands(val playComponents: PlayComponents)
    extends CommandsEndpoints
    with Endpoints
    with JsonEntitiesFromCodecs {

  val routes: Router.Routes = routesFromEndpoints(
    command.implementedBy(CommandsService.apply),
    events.implementedBy(CommandsService.events)
  )

}
//#server 
Example 48
Source File: Queries.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package cqrs.queries

import endpoints4s.play.server.{BuiltInErrors, JsonEntitiesFromCodecs, MuxEndpoints, PlayComponents}
import play.api.routing.Router

import scala.concurrent.Future


class Queries(service: QueriesService, val playComponents: PlayComponents)
    extends QueriesEndpoints
    with MuxEndpoints
    with BuiltInErrors
    with JsonEntitiesFromCodecs {

  import playComponents.executionContext

  //#multiplexed-impl
  import endpoints4s.play.server.MuxHandlerAsync

  val routes: Router.Routes = routesFromEndpoints(
    query.implementedByAsync(new MuxHandlerAsync[QueryReq, QueryResp] {
      def apply[R <: QueryResp](
          query: QueryReq { type Response = R }
      ): Future[R] =
        //#multiplexed-impl-essence
        query match {
          case FindById(id, t) => service.findById(id, t).map(MaybeResource)
          case FindAll         => service.findAll().map(ResourceList)
        }
      //#multiplexed-impl-essence
    })
  )
  //#multiplexed-impl

  // These aliases are probably due to a limitation of circe
  implicit private def circeDecoderReq: io.circe.Decoder[QueryReq] =
    QueryReq.queryDecoder
  implicit private def circeEncoderResp: io.circe.Encoder[QueryResp] =
    QueryResp.queryEncoder

} 
Example 49
Source File: Main.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package cqrs.infra

import cqrs.commands.Commands
import cqrs.publicserver.{BootstrapEndpoints, PublicServer}
import cqrs.queries.{Queries, QueriesService}
import endpoints4s.play.server.PlayComponents
import play.api.Mode
import play.api.libs.ws.ahc.{AhcWSClient, AhcWSClientConfig}
import play.api.routing.Router
import play.core.server.{DefaultNettyServerComponents, ServerConfig}


object Main extends App {

  object commandsService extends PlayService(port = 9001, Mode.Prod) {
    lazy val commands = new Commands(playComponents)
    lazy val router = Router.from(commands.routes)
  }

  object queriesService extends PlayService(port = 9002, Mode.Prod) {
    lazy val wsClient = AhcWSClient(AhcWSClientConfig())
    lazy val service = new QueriesService(
      baseUrl(commandsService.port),
      wsClient,
      actorSystem.scheduler
    )
    lazy val queries = new Queries(service, playComponents)
    lazy val router = Router.from(queries.routes)
  }

  object publicService extends PlayService(port = 9000, Mode.Prod) {
    lazy val routes =
      new cqrs.publicserver.Router(
        new PublicServer(
          baseUrl(commandsService.port),
          baseUrl(queriesService.port),
          queriesService.wsClient,
          playComponents
        ),
        new BootstrapEndpoints(playComponents)
      ).routes
    lazy val router = Router.from(routes)
  }

  def baseUrl(port: Int): String = s"http://localhost:$port"

  // Start the commands service
  commandsService.server
  // Start the queries service
  queriesService.server
  // Start the public server
  publicService.server

  // …

  Runtime.getRuntime.addShutdownHook(new Thread {
    override def run(): Unit = {
      queriesService.wsClient.close()
      commandsService.server.stop()
      queriesService.server.stop()
      publicService.server.stop()
    }
  })

}

abstract class PlayService(val port: Int, mode: Mode) extends DefaultNettyServerComponents {
  override lazy val serverConfig = ServerConfig(port = Some(port), mode = mode)
  lazy val playComponents = PlayComponents.fromBuiltInComponents(this)
} 
Example 50
Source File: ServerInterpreterTest.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.play.server

import java.net.ServerSocket

import akka.stream.scaladsl.Source
import endpoints4s.{Invalid, Valid}
import endpoints4s.algebra.server.{
  BasicAuthenticationTestSuite,
  DecodedUrl,
  EndpointsTestSuite,
  ChunkedJsonEntitiesTestSuite,
  SumTypedEntitiesTestSuite,
  TextEntitiesTestSuite
}
import play.api.Mode
import play.api.routing.Router
import play.api.test.FakeRequest
import play.core.server.{DefaultNettyServerComponents, NettyServer, ServerConfig}

import scala.concurrent.Future

class ServerInterpreterTest
    extends EndpointsTestSuite[EndpointsTestApi]
    with BasicAuthenticationTestSuite[EndpointsTestApi]
    with ChunkedJsonEntitiesTestSuite[EndpointsTestApi]
    with SumTypedEntitiesTestSuite[EndpointsTestApi]
    with TextEntitiesTestSuite[EndpointsTestApi] {

  val serverApi: EndpointsTestApi = {
    object NettyServerComponents extends DefaultNettyServerComponents {
      override lazy val serverConfig = ServerConfig(mode = Mode.Test)
      lazy val router = Router.empty
    }
    new EndpointsTestApi(
      PlayComponents.fromBuiltInComponents(NettyServerComponents),
      Map.empty
    )
  }

  def serveEndpoint[Resp](
      endpoint: serverApi.Endpoint[_, Resp],
      response: => Resp
  )(runTests: Int => Unit): Unit =
    serveRoutes(
      serverApi.routesFromEndpoints(endpoint.implementedBy(_ => response))
    )(runTests)

  def serveIdentityEndpoint[Resp](
      endpoint: serverApi.Endpoint[Resp, Resp]
  )(runTests: Int => Unit): Unit =
    serveRoutes(
      serverApi.routesFromEndpoints(endpoint.implementedBy(request => request))
    )(runTests)

  def serveStreamedEndpoint[Resp](
      endpoint: serverApi.Endpoint[_, serverApi.Chunks[Resp]],
      response: Source[Resp, _]
  )(runTests: Int => Unit): Unit =
    serveRoutes(
      serverApi.routesFromEndpoints(endpoint.implementedBy(_ => response))
    )(runTests)

  def serveStreamedEndpoint[Req, Resp](
      endpoint: serverApi.Endpoint[serverApi.Chunks[Req], Resp],
      logic: Source[Req, _] => Future[Resp]
  )(
      runTests: Int => Unit
  ): Unit =
    serveRoutes(
      serverApi.routesFromEndpoints(endpoint.implementedByAsync(logic))
    )(runTests)

  def serveRoutes(routes: Router.Routes)(runTests: Int => Unit): Unit = {
    val port = {
      val socket = new ServerSocket(0)
      try socket.getLocalPort
      finally if (socket != null) socket.close()
    }
    val config = ServerConfig(mode = Mode.Test, port = Some(port))
    val server = NettyServer.fromRouterWithComponents(config)(_ => routes)
    try {
      runTests(port)
    } finally {
      server.stop()
    }
  }

  def decodeUrl[A](url: serverApi.Url[A])(rawValue: String): DecodedUrl[A] = {
    val request = FakeRequest("GET", rawValue)
    url.decodeUrl(request) match {
      case None                  => DecodedUrl.NotMatched
      case Some(Invalid(errors)) => DecodedUrl.Malformed(errors)
      case Some(Valid(a))        => DecodedUrl.Matched(a)
    }
  }

}