akka.http.scaladsl.server.StandardRoute Scala Examples

The following examples show how to use akka.http.scaladsl.server.StandardRoute. 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: HealthService.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.api

import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{ Route, StandardRoute }
import com.ing.wbaa.rokku.proxy.data.HealthCheck.{ RGWListBuckets, S3ListBucket }
import com.ing.wbaa.rokku.proxy.handler.radosgw.RadosGatewayHandler
import com.ing.wbaa.rokku.proxy.provider.aws.S3Client
import com.typesafe.scalalogging.LazyLogging
import java.util.concurrent.ConcurrentHashMap

import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.concurrent.{ ExecutionContext, Future }
import scala.util.{ Failure, Success, Try }

object HealthService {
  private def timestamp: Long = System.currentTimeMillis()

  private val statusMap = new ConcurrentHashMap[Long, StandardRoute]()

  private def clearStatus(): Unit = statusMap.clear()

  private def addStatus(probeResult: StandardRoute): StandardRoute = statusMap.put(timestamp, probeResult)

  private def getCurrentStatusMap: Future[mutable.Map[Long, StandardRoute]] = Future.successful(statusMap.asScala)

  private def getRouteStatus(implicit ec: ExecutionContext): Future[Option[StandardRoute]] = getCurrentStatusMap.map(_.headOption.map { case (_, r) => r })

}

trait HealthService extends RadosGatewayHandler with S3Client with LazyLogging {

  protected[this] implicit def executionContext: ExecutionContext

  import HealthService.{ addStatus, getCurrentStatusMap, clearStatus, getRouteStatus, timestamp }

  private lazy val interval = storageS3Settings.hcInterval

  private def updateStatus: Future[StandardRoute] = Future {
    clearStatus()
    storageS3Settings.hcMethod match {
      case RGWListBuckets => addStatus(execProbe(listAllBuckets _))
      case S3ListBucket   => addStatus(execProbe(listBucket _))
    }
  }
  private def updateStatusAndGet: Future[Option[StandardRoute]] =
    for {
      _ <- updateStatus
      s <- getRouteStatus
    } yield s

  def getStatus(currentTime: Long): Future[Option[StandardRoute]] =
    getCurrentStatusMap.flatMap(_ match {
      case m if m.isEmpty =>
        logger.debug("Status cache empty, running probe")
        updateStatusAndGet
      case m => m.keys.map {
        case entryTime if (entryTime + interval) < currentTime =>
          logger.debug("Status entry expired, renewing")
          updateStatusAndGet
        case _ =>
          logger.debug("Serving status from cache")
          Future.successful(m.map { case (_, r) => r }.headOption)
      }.head
    })

  private def execProbe[A](p: () => A): StandardRoute =
    Try {
      p()
    } match {
      case Success(_)  => complete("pong")
      case Failure(ex) => complete(StatusCodes.InternalServerError -> s"storage not available - $ex")
    }

  final val healthRoute: Route =
    path("ping") {
      get {
        onComplete(getStatus(timestamp)) {
          case Success(opt) => opt.getOrElse(complete(StatusCodes.InternalServerError -> "Failed to read status cache"))
          case Failure(e)   => complete(StatusCodes.InternalServerError -> "Failed to read status cache " + e.getMessage)
        }
      }
    }
} 
Example 2
Source File: HttpMetricsDirectives.scala    From akka-http-metrics   with Apache License 2.0 5 votes vote down vote up
package fr.davit.akka.http.metrics.core.scaladsl.server

import akka.http.scaladsl.marshalling.ToEntityMarshaller
import akka.http.scaladsl.model.HttpHeader
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.PathMatcher.{Matched, Unmatched}
import akka.http.scaladsl.server.directives.BasicDirectives.{mapRequestContext, tprovide}
import akka.http.scaladsl.server.directives.RouteDirectives.reject
import akka.http.scaladsl.server.util.Tuple
import akka.http.scaladsl.server.{Directive, PathMatcher, StandardRoute}
import fr.davit.akka.http.metrics.core.HttpMetricsRegistry
import fr.davit.akka.http.metrics.core.scaladsl.model.PathLabelHeader

import scala.collection.immutable

trait HttpMetricsDirectives {

  def metrics[T <: HttpMetricsRegistry: ToEntityMarshaller](registry: T): StandardRoute = complete(registry)

  def pathLabeled[L](pm: PathMatcher[L]): Directive[L] =
    pathPrefixLabeled(pm ~ PathEnd)

  def pathLabeled[L](pm: PathMatcher[L], label: String): Directive[L] =
    pathPrefixLabeled(pm ~ PathEnd, label)

  def pathPrefixLabeled[L](pm: PathMatcher[L]): Directive[L] =
    rawPathPrefixLabeled(Slash ~ pm)

  def pathPrefixLabeled[L](pm: PathMatcher[L], label: String): Directive[L] =
    rawPathPrefixLabeled(Slash ~ pm, label)

  def rawPathPrefixLabeled[L](pm: PathMatcher[L]): Directive[L] =
    rawPathPrefixLabeled(pm, None)

  def rawPathPrefixLabeled[L](pm: PathMatcher[L], label: String): Directive[L] =
    rawPathPrefixLabeled(pm, Some(label))

  private def rawPathPrefixLabeled[L](pm: PathMatcher[L], label: Option[String]): Directive[L] = {
    implicit val LIsTuple: Tuple[L] = pm.ev
    extractRequestContext.flatMap { ctx =>
      val pathCandidate = ctx.unmatchedPath.toString
      pm(ctx.unmatchedPath) match {
        case Matched(rest, values) =>
          tprovide(values) & mapRequestContext(_ withUnmatchedPath rest) & mapResponseHeaders { headers =>
            var pathHeader = label match {
              case Some(l) => PathLabelHeader("/" + l) // pm matches additional slash prefix
              case None    => PathLabelHeader(pathCandidate.substring(0, pathCandidate.length - rest.charCount))
            }
            val builder = immutable.Seq.newBuilder[HttpHeader]
            headers.foreach {
              case PathLabelHeader(suffix) =>
                pathHeader = PathLabelHeader(pathHeader.value + suffix)
              case h: HttpHeader =>
                builder += h
            }
            builder += pathHeader
            builder.result()
          }
        case Unmatched =>
          reject
      }
    }
  }
}

object HttpMetricsDirectives extends HttpMetricsDirectives 
Example 3
Source File: AkkaHttpHelpers.scala    From akka-viz   with MIT License 5 votes vote down vote up
package akkaviz.server

import akka.http.scaladsl.marshalling.{Marshal, Marshaller}
import akka.http.scaladsl.model.HttpEntity.ChunkStreamPart
import akka.http.scaladsl.model.{HttpEntity, HttpResponse, MediaTypes}
import akka.http.scaladsl.server.{Directives, StandardRoute}
import akka.stream.scaladsl.{Flow, Source}

import scala.concurrent.ExecutionContext

trait AkkaHttpHelpers {

  def asJsonArray[T](implicit m: Marshaller[T, String], ec: ExecutionContext): Flow[T, HttpEntity.ChunkStreamPart, _] = {
    Flow.apply[T]
      .mapAsync[String](4)(t => Marshal(t).to[String])
      .scan[Option[ChunkStreamPart]](None) {
        case (None, s: String) => Some(ChunkStreamPart(s))
        case (_, s: String)    => Some(ChunkStreamPart(s",${s}"))
      }.mapConcat(_.toList)
      .prepend(Source.single(ChunkStreamPart("[")))
      .concat(Source.single(ChunkStreamPart("]")))
  }

  def completeAsJson[T](source: Source[T, _])(implicit m: Marshaller[T, String], ec: ExecutionContext): StandardRoute = {
    Directives.complete(HttpResponse(
      entity = HttpEntity.Chunked(MediaTypes.`application/json`, source.via(asJsonArray))
    ))
  }
}

object AkkaHttpHelpers extends AkkaHttpHelpers