akka.http.scaladsl.model.HttpRequest Scala Examples

The following examples show how to use akka.http.scaladsl.model.HttpRequest. 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: HTTPRequestAuth.scala    From skuber   with Apache License 2.0 6 votes vote down vote up
package skuber.api.security

import akka.http.scaladsl.model.{HttpHeader, HttpRequest}
import akka.http.scaladsl.model.headers.{Authorization, BasicHttpCredentials, OAuth2BearerToken}
import skuber.api.client._


object HTTPRequestAuth {
  
  def addAuth(request: HttpRequest, auth: AuthInfo) : HttpRequest = {
    getAuthHeader(auth).map(request.addHeader).getOrElse(request)
  }

  def getAuthHeader(auth: AuthInfo) : Option[HttpHeader] = {
    auth match {
      case NoAuth | _: CertAuth => None
      case BasicAuth(user, password) => Some(Authorization(BasicHttpCredentials(user,password)))
      case auth: AccessTokenAuth => Some(Authorization(OAuth2BearerToken(auth.accessToken)))
    }
  }   
} 
Example 2
Source File: PropertiesApi.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.iep.archaius

import java.io.StringWriter
import java.util.Properties

import akka.actor.ActorRefFactory
import akka.http.scaladsl.model.HttpCharsets
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.model.MediaTypes
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Route
import com.netflix.atlas.akka.CustomDirectives._
import com.netflix.atlas.akka.WebApi
import com.netflix.atlas.json.Json
import com.netflix.frigga.Names

class PropertiesApi(
  val propContext: PropertiesContext,
  implicit val actorRefFactory: ActorRefFactory
) extends WebApi {

  def routes: Route = {
    endpointPath("api" / "v1" / "property") {
      get {
        parameter("asg") { asg =>
          extractRequest { request =>
            val cluster = Names.parseName(asg).getCluster
            if (propContext.initialized) {
              val props = propContext.getClusterProps(cluster)
              complete(encode(request, props))
            } else {
              complete(HttpResponse(StatusCodes.ServiceUnavailable))
            }
          }
        }
      }
    }
  }

  private def encode(request: HttpRequest, props: List[PropertiesApi.Property]): HttpResponse = {
    val useJson = request.headers.exists(h => h.is("accept") && h.value == "application/json")
    if (useJson) {
      HttpResponse(
        StatusCodes.OK,
        entity = HttpEntity(MediaTypes.`application/json`, Json.encode(props))
      )
    } else {
      val ps = new Properties
      props.foreach { p =>
        ps.setProperty(p.key, p.value)
      }
      val writer = new StringWriter()
      ps.store(writer, s"count: ${ps.size}")
      writer.close()
      val entity =
        HttpEntity(MediaTypes.`text/plain`.toContentType(HttpCharsets.`UTF-8`), writer.toString)
      HttpResponse(StatusCodes.OK, entity = entity)
    }
  }
}

object PropertiesApi {
  case class Property(id: String, cluster: String, key: String, value: String, timestamp: Long)
} 
Example 3
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpjackson

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn

object ExampleApp {

  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    // provide an implicit ObjectMapper if you want serialization/deserialization to use it
    // instead of a default ObjectMapper configured only with DefaultScalaModule provided
    // by JacksonSupport
    //
    // for example:
    //
    // implicit val objectMapper = new ObjectMapper()
    //   .registerModule(DefaultScalaModule)
    //   .registerModule(new GuavaModule())

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit sys: ActorSystem) = {
    import Directives._
    import JacksonSupport._

    pathSingleSlash {
      post {

        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 4
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpcirce

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{ HttpRequest, RequestEntity }
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source

import scala.io.StdIn
import scala.concurrent.duration._

object ExampleApp {

  private final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    system.terminate()
  }

  private def route(implicit sys: ActorSystem) = {
    import Directives._
    import FailFastCirceSupport._
    import io.circe.generic.auto._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          import sys._

          Marshal(Source.single(Foo("a"))).to[RequestEntity]

          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 5
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpavro4s

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{ HttpRequest, RequestEntity }
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source
import com.sksamuel.avro4s.{ FromRecord, SchemaFor, ToRecord }

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn

object ExampleApp {

  final object Foo {
    implicit val schemaFor  = SchemaFor[Foo]
    implicit val toRecord   = ToRecord[Foo]
    implicit val fromRecord = FromRecord[Foo]
  }
  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit sys: ActorSystem) = {
    import AvroSupport._
    import Directives._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          import sys._

          Marshal(Source.single(Foo("a"))).to[RequestEntity]

          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 6
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpjson4s

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source
import org.json4s.{ DefaultFormats, jackson }

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn

object ExampleApp {

  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit sys: ActorSystem) = {
    import Directives._
    import Json4sSupport._

    implicit val serialization = jackson.Serialization // or native.Serialization
    implicit val formats       = DefaultFormats

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 7
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpplayjson

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source
import play.api.libs.json.{ Format, JsValue, Json }

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn

object ExampleApp {

  final object Foo {
    implicit val fooFormat: Format[Foo] = Json.format[Foo]
  }
  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit sys: ActorSystem) = {
    import Directives._
    import PlayJsonSupport._

    implicit val prettyPrint: JsValue => String = Json.prettyPrint

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 8
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpjsoniterscala

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.{ Directives, Route }
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn

object ExampleApp {

  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system: ActorSystem = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit sys: ActorSystem): Route = {
    import Directives._
    import JsoniterScalaSupport._
    import com.github.plokhotnyuk.jsoniter_scala.core._
    import com.github.plokhotnyuk.jsoniter_scala.macros._

    // here you should provide implicit codecs for in/out messages of all routes

    implicit val codec: JsonValueCodec[Foo] = JsonCodecMaker.make[Foo](CodecMakerConfig)

    // also, you can provide an implicit reader/writer configs to override defaults:
    //
    // implicit val readerConfig = ReaderConfig.withThrowReaderExceptionWithStackTrace(true)
    // implicit val writerConfig = WriterConfig.withIndentionStep(2)

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 9
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpargonaut

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{ HttpRequest, RequestEntity }
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source
import argonaut.Argonaut.casecodec1
import argonaut.CodecJson

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn

object ExampleApp {

  final object Foo {
    implicit val fooCodec: CodecJson[Foo] =
      casecodec1(Foo.apply, Foo.unapply)("bar")
  }
  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit sys: ActorSystem) = {
    import ArgonautSupport._
    import Directives._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          import sys._

          Marshal(Source.single(Foo("a"))).to[RequestEntity]

          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 10
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpupickle

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn
import upickle.default.{ ReadWriter, macroRW }

object ExampleApp {

  final object Foo {
    implicit val rw: ReadWriter[Foo] = macroRW
  }

  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit system: ActorSystem) = {
    import Directives._
    import UpickleSupport._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 11
Source File: CirceSupport.scala    From typed-schema   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.tschema.utils.json

import akka.http.scaladsl.marshalling.{Marshaller, _}
import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.model.{HttpEntity, HttpRequest}
import akka.http.scaladsl.unmarshalling.{Unmarshaller, _}
import io.circe._
import io.circe.parser._
import io.circe.syntax._
import cats.syntax.either._

import scala.concurrent.Future

object CirceSupport {
  val printer = Printer.noSpaces.copy(dropNullValues = true)

  def marshallResponse[T: Encoder]: ToResponseMarshaller[T] = Marshaller.fromToEntityMarshaller[T]()(marshallEntity)

  def unmarshallRequest[T: Decoder]: FromRequestUnmarshaller[T] =
    Unmarshaller
      .identityUnmarshaller[HttpRequest]
      .map(_.entity)
      .flatMap[T](unmarshallEntity[T]: Unmarshaller[HttpEntity, T])
      .asScala

  def marshallEntity[T: Encoder]: ToEntityMarshaller[T] =
    Marshaller.stringMarshaller(`application/json`).compose((_: T).asJson.printWith(printer))

  def unmarshallEntity[T: Decoder]: FromEntityUnmarshaller[T] =
    Unmarshaller.stringUnmarshaller
      .forContentTypes(`application/json`)
      .flatMap(implicit ec => _ => s => Future.fromTry(parse(s).toTry.flatMap(_.as[T].toTry)))

  object implicits {
    implicit def marshallResponseCirce[T: Encoder]: ToResponseMarshaller[T] = marshallResponse[T]

    implicit def unmarshallRequestCirce[T: Decoder]: FromRequestUnmarshaller[T] = unmarshallRequest[T]

    implicit def marshallEntityCirce[T: Encoder]: ToEntityMarshaller[T] = marshallEntity[T]

    implicit def unmarshallEntityCirce[T: Decoder]: FromEntityUnmarshaller[T] = unmarshallEntity[T]
  }

} 
Example 12
Source File: CompositeHttpService.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.RouteResult.Complete
import akka.http.scaladsl.server._
import akka.http.scaladsl.server.directives.{DebuggingDirectives, LoggingMagnet}
import com.wavesplatform.settings.RestAPISettings
import com.wavesplatform.utils.ScorexLogging

case class CompositeHttpService(routes: Seq[ApiRoute], settings: RestAPISettings)(system: ActorSystem) extends ScorexLogging {

  private val redirectToSwagger = redirect("/api-docs/index.html", StatusCodes.PermanentRedirect)
  private val swaggerRoute: Route =
    (pathEndOrSingleSlash | path("swagger"))(redirectToSwagger) ~
      pathPrefix("api-docs") {
        pathEndOrSingleSlash(redirectToSwagger) ~
          path("swagger.json")(complete(patchedSwaggerJson)) ~
          getFromResourceDirectory("swagger-ui")
      }

  val compositeRoute: Route        = extendRoute(routes.map(_.route).reduce(_ ~ _)) ~ swaggerRoute ~ complete(StatusCodes.NotFound)
  val loggingCompositeRoute: Route = Route.seal(DebuggingDirectives.logRequestResult(LoggingMagnet(_ => logRequestResponse))(compositeRoute))

  private def logRequestResponse(req: HttpRequest)(res: RouteResult): Unit = res match {
    case Complete(resp) =>
      val msg = s"HTTP ${resp.status.value} from ${req.method.value} ${req.uri}"
      if (resp.status == StatusCodes.OK) log.info(msg) else log.warn(msg)
    case _ =>
  }

  private val corsAllowedHeaders = (if (settings.apiKeyDifferentHost) List("api_key", "X-API-Key") else List.empty[String]) ++
    Seq("Authorization", "Content-Type", "X-Requested-With", "Timestamp", "Signature")

  private def corsAllowAll = if (settings.cors) respondWithHeader(`Access-Control-Allow-Origin`.*) else pass

  private def extendRoute(base: Route): Route = handleAllExceptions {
    if (settings.cors) { ctx =>
      val extendedRoute = corsAllowAll(base) ~ options {
        respondWithDefaultHeaders(
          `Access-Control-Allow-Credentials`(true),
          `Access-Control-Allow-Headers`(corsAllowedHeaders),
          `Access-Control-Allow-Methods`(OPTIONS, POST, PUT, GET, DELETE)
        )(corsAllowAll(complete(StatusCodes.OK)))
      }

      extendedRoute(ctx)
    } else base
  }

  private[this] lazy val patchedSwaggerJson = {
    import com.wavesplatform.Version
    import com.wavesplatform.account.AddressScheme
    import play.api.libs.json.{JsObject, Json}

    def chainIdString: String =
      if (Character.isAlphabetic(AddressScheme.current.chainId)) AddressScheme.current.chainId.toChar.toString
      else s"#${AddressScheme.current.chainId}"

    val json = Json.parse(getClass.getClassLoader.getResourceAsStream("swagger-ui/swagger.json")).as[JsObject]
    val patchedInfo = (json \ "info").as[JsObject] ++ Json.obj(
      "version" -> Version.VersionString,
      "title"   -> s"Waves Full Node ($chainIdString)"
    )
    json ++ Json.obj("info" -> patchedInfo)
  }
} 
Example 13
Source File: JsonUnmarshallers.scala    From scala-openrtb   with Apache License 2.0 5 votes vote down vote up
package com.powerspace.openrtb.akka.marshallers

import akka.http.scaladsl.model.{ContentTypeRange, ContentTypes, HttpRequest}
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, FromRequestUnmarshaller, Unmarshaller}
import akka.stream.Materializer
import com.google.openrtb.{BidRequest, BidResponse}
import io.circe.Decoder

import scala.concurrent.{ExecutionContext, Future}
import io.circe.parser.decode

object JsonUnmarshallers {

  import akka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallers._

  def bidRequestJsonUnmarshaller(implicit decoder: Decoder[BidRequest]): FromEntityUnmarshaller[BidRequest] =
    stringUnmarshaller
      .forContentTypes(ContentTypeRange(ContentTypes.`application/json`))
      .map(implicit json => decode[BidRequest](json).handlingFailure)

  def bidResponseJsonUnmarshaller(implicit decoder: Decoder[BidResponse]): FromEntityUnmarshaller[BidResponse] =
    stringUnmarshaller
      .forContentTypes(ContentTypeRange(ContentTypes.`application/json`))
      .map(implicit json => decode[BidResponse](json).handlingFailure)

  def bidRequestHttpJsonUnmarshaller(implicit decoder: Decoder[BidRequest]): FromRequestUnmarshaller[BidRequest] =
    new FromRequestUnmarshaller[BidRequest]() {
      override def apply(
        value: HttpRequest)(implicit ec: ExecutionContext, materializer: Materializer): Future[BidRequest] =
        Unmarshaller
          .stringUnmarshaller(value.entity)
          .map(implicit json => decode[BidRequest](json).handlingFailure)
    }

  def bidResponseHttpJsonUnmarshaller(implicit decoder: Decoder[BidResponse]): FromRequestUnmarshaller[BidResponse] =
    new FromRequestUnmarshaller[BidResponse]() {
      override def apply(
        value: HttpRequest)(implicit ec: ExecutionContext, materializer: Materializer): Future[BidResponse] =
        Unmarshaller
          .stringUnmarshaller(value.entity)
          .map(implicit json => decode[BidResponse](json).handlingFailure)
    }

  implicit class DecodingResultEnhancement[T](decodingResult: Either[_ <: Exception, T]) {

    def handlingFailure(implicit json: String): T = decodingResult match {
      case Right(decoded) => decoded
      case Left(error) => throw new UnsupportedOperationException(error)
    }
  }

} 
Example 14
Source File: AuthenticationClient.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.http.clients.authentication

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpRequest
import akka.stream.{ActorMaterializer, Materializer}
import com.danielasfregola.twitter4s.entities.ConsumerToken
import com.danielasfregola.twitter4s.http.clients.Client
import com.danielasfregola.twitter4s.http.oauth.OAuth1Provider
import com.danielasfregola.twitter4s.http.serializers.{FormSupport, FromMap}

import scala.concurrent.Future

private[twitter4s] class AuthenticationClient(val consumerToken: ConsumerToken)(implicit val system: ActorSystem)
    extends Client {

  lazy val oauthProvider = new OAuth1Provider(consumerToken, None)

  private[twitter4s] implicit class RichRestHttpRequest(val request: HttpRequest) {
    implicit val materializer = ActorMaterializer()
    implicit val ec = materializer.executionContext

    def respondAs[T: Manifest](implicit fromMap: FromMap[T]): Future[T] = respondAs[T](None)

    def respondAs[T: Manifest](callback: Option[String])(implicit fromMap: FromMap[T]): Future[T] =
      for {
        requestWithAuth <- withOAuthHeader(callback)(materializer)(request)
        t <- sendReceiveAs[T](requestWithAuth)
      } yield t
  }

  def sendReceiveAs[T: Manifest](httpRequest: HttpRequest)(implicit system: ActorSystem,
                                                           materializer: Materializer,
                                                           fromMap: FromMap[T]): Future[T] = {
    sendAndReceive(httpRequest, response => FormSupport.unmarshallText(response))
  }

} 
Example 15
Source File: RestClient.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.http.clients.rest

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.{ActorMaterializer, Materializer}
import com.danielasfregola.twitter4s.entities.{AccessToken, ConsumerToken, RateLimit, RatedData}
import com.danielasfregola.twitter4s.http.clients.Client
import com.danielasfregola.twitter4s.http.oauth.OAuth1Provider

import scala.concurrent.Future

private[twitter4s] class RestClient(val consumerToken: ConsumerToken, val accessToken: AccessToken)(
    implicit val system: ActorSystem)
    extends Client {

  lazy val oauthProvider = new OAuth1Provider(consumerToken, Some(accessToken))

  private[twitter4s] implicit class RichRestHttpRequest(val request: HttpRequest) {

    implicit val materializer = ActorMaterializer()
    implicit val ec = materializer.executionContext

    def respondAs[T: Manifest]: Future[T] =
      for {
        requestWithAuth <- withOAuthHeader(None)(materializer)(request)
        t <- sendReceiveAs[T](requestWithAuth)
      } yield t

    def respondAsRated[T: Manifest]: Future[RatedData[T]] =
      for {
        requestWithAuth <- withOAuthHeader(None)(materializer)(request)
        t <- sendReceiveAsRated[T](requestWithAuth)
      } yield t

    def sendAsFormData: Future[Unit] =
      for {
        requestWithAuth <- withSimpleOAuthHeader(None)(materializer)(request)
        _ <- sendIgnoreResponse(requestWithAuth)
      } yield ()
  }

  def sendIgnoreResponse(httpRequest: HttpRequest)(implicit system: ActorSystem,
                                                   materializer: Materializer): Future[Unit] = {
    sendAndReceive(httpRequest, _ => Future.successful((): Unit))
  }

  def sendReceiveAs[T: Manifest](httpRequest: HttpRequest)(implicit system: ActorSystem,
                                                           materializer: Materializer): Future[T] = {
    implicit val ec = materializer.executionContext
    implicit val jsonSerialization = serialization
    sendAndReceive(httpRequest, response => Unmarshal(response.entity).to[T])
  }

  def sendReceiveAsRated[T: Manifest](httpRequest: HttpRequest)(implicit system: ActorSystem,
                                                                materializer: Materializer): Future[RatedData[T]] = {
    implicit val ec = materializer.executionContext
    implicit val jsonSerialization = serialization
    val unmarshallRated: HttpResponse => Future[RatedData[T]] = { response =>
      val rate = RateLimit(response.headers)
      val data = Unmarshal(response.entity).to[T]
      data.map(d => RatedData(rate, d))
    }
    sendAndReceive(httpRequest, unmarshallRated)
  }
} 
Example 16
Source File: CommonClient.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.http.clients

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, HttpResponse}
import akka.stream.Materializer
import com.danielasfregola.twitter4s.exceptions.{Errors, TwitterException}
import com.danielasfregola.twitter4s.http.serializers.JsonSupport
import com.typesafe.scalalogging.LazyLogging
import org.json4s.native.Serialization

import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.Try

private[twitter4s] trait CommonClient extends JsonSupport with LazyLogging {

  def withLogRequest: Boolean
  def withLogRequestResponse: Boolean

  protected def connection(implicit request: HttpRequest, system: ActorSystem) = {
    val scheme = request.uri.scheme
    val host = request.uri.authority.host.toString
    val port = request.uri.effectivePort
    if (scheme == "https") Http().outgoingConnectionHttps(host, port)
    else Http().outgoingConnection(host, port)
  }

  protected def unmarshal[T](requestStartTime: Long, f: HttpResponse => Future[T])(implicit request: HttpRequest,
                                                                                   response: HttpResponse,
                                                                                   materializer: Materializer) = {
    implicit val ec = materializer.executionContext
    if (withLogRequestResponse) logRequestResponse(requestStartTime)

    if (response.status.isSuccess) f(response)
    else parseFailedResponse(response).flatMap(Future.failed)
  }

  protected def parseFailedResponse(response: HttpResponse)(implicit materializer: Materializer) = {
    implicit val ec = materializer.executionContext
    response.entity.toStrict(50 seconds).map { sink =>
      val body = sink.data.utf8String
      val errors = Try {
        Serialization.read[Errors](body)
      } getOrElse Errors(body)
      TwitterException(response.status, errors)
    }
  }

  // TODO - logRequest, logRequestResponse customisable?
  def logRequest(implicit request: HttpRequest, materializer: Materializer): HttpRequest = {
    implicit val ec = materializer.executionContext
    logger.info(s"${request.method.value} ${request.uri}")
    if (logger.underlying.isDebugEnabled) {
      for {
        requestBody <- toBody(request.entity)
      } yield logger.debug(s"${request.method.value} ${request.uri} | $requestBody")
    }
    request
  }

  def logRequestResponse(requestStartTime: Long)(implicit request: HttpRequest,
                                                 materializer: Materializer): HttpResponse => HttpResponse = {
    response =>
      implicit val ec = materializer.executionContext
      val elapsed = System.currentTimeMillis - requestStartTime
      logger.info(s"${request.method.value} ${request.uri} (${response.status}) | ${elapsed}ms")
      if (logger.underlying.isDebugEnabled) {
        for {
          responseBody <- toBody(response.entity)
        } yield
          logger.debug(
            s"${request.method.value} ${request.uri} (${response.status}) | ${response.headers.mkString(", ")} | $responseBody")
      }
      response
  }

  private def toBody(entity: HttpEntity)(implicit materializer: Materializer): Future[String] = {
    implicit val ec = materializer.executionContext
    entity.toStrict(5 seconds).map(_.data.decodeString("UTF-8"))
  }
} 
Example 17
Source File: Client.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.http.clients

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.stream.Materializer
import akka.stream.scaladsl.{Sink, Source}
import com.danielasfregola.twitter4s.http.oauth.OAuth1Provider

import scala.concurrent.Future

trait Client extends OAuthClient {

  val withLogRequest = false
  val withLogRequestResponse = true

  def oauthProvider: OAuth1Provider

  protected def sendAndReceive[T](request: HttpRequest, f: HttpResponse => Future[T])(
      implicit system: ActorSystem,
      materializer: Materializer): Future[T] = {
    implicit val r: HttpRequest = request
    val requestStartTime = System.currentTimeMillis

    if (withLogRequest) logRequest

    Source
      .single(request)
      .via(connection)
      .mapAsync(1)(implicit response => unmarshal(requestStartTime, f))
      .runWith(Sink.head)
  }

} 
Example 18
Source File: BasicAuthentication.scala    From sumobot   with Apache License 2.0 5 votes vote down vote up
package com.sumologic.sumobot.http_frontend.authentication
import java.security.MessageDigest

import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import com.typesafe.config.Config

class BasicAuthentication(config: Config) extends HttpAuthentication {
  private val username = config.getString("username")
  private val password = config.getString("password")

  override def authentication(request: HttpRequest): AuthenticationResult = {
    request.header[`Authorization`] match {
      case Some(header) =>
        val receivedCredentials = BasicHttpCredentials(header.credentials.token())

        val authenticated = MessageDigest.isEqual(receivedCredentials.username.getBytes, username.getBytes) &&
          MessageDigest.isEqual(receivedCredentials.password.getBytes, password.getBytes)
        if (authenticated) AuthenticationSucceeded(AuthenticationInfo(Some(s"Logged in as: $username"), None, Seq.empty))
        else AuthenticationForbidden(HttpResponse(403))
      case None =>
        val header = `WWW-Authenticate`(List(HttpChallenge("basic", Some("SumoBot"))))
        AuthenticationForbidden(HttpResponse(401, headers = List(header)))
    }
  }
} 
Example 19
Source File: RoutingHelper.scala    From sumobot   with Apache License 2.0 5 votes vote down vote up
package com.sumologic.sumobot.http_frontend

import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, HttpResponse, ResponseEntity}
import akka.http.scaladsl.model.HttpMethods.{GET, HEAD}
import akka.stream.Materializer

case class RoutingHelper(origin: String)(implicit materializer: Materializer) {
  def withAllowOriginHeader(routing: PartialFunction[HttpRequest, HttpResponse]): PartialFunction[HttpRequest, HttpResponse] = {
    routing.andThen {
      response: HttpResponse =>
        val oldHeaders = response.headers.filter(header => header.isNot(`Access-Control-Allow-Origin`.lowercaseName)).toList
        val accessOrigin = if (origin == "*") {
          `Access-Control-Allow-Origin`.*
        } else `Access-Control-Allow-Origin`(origin)
        val newHeaders = oldHeaders :+ accessOrigin

        response.withHeaders(newHeaders)
    }
  }

  def withHeadRequests(routing: PartialFunction[HttpRequest, HttpResponse]): PartialFunction[HttpRequest, HttpResponse] = {
    routing.orElse {
      case request@HttpRequest(HEAD, _, _, _, _)
        if routing.isDefinedAt(request.withMethod(GET)) =>
        val response = routing(request.withMethod(GET))

        val oldEntity = response.entity
        val newEntity = HttpEntity(oldEntity.contentType, Array.empty[Byte])

        response.withEntity(newEntity)
    }
  }

  def withForbiddenFallback(routing: PartialFunction[HttpRequest, HttpResponse]): PartialFunction[HttpRequest, HttpResponse] = {
    routing.orElse {
      case invalid: HttpRequest =>
        invalid.discardEntityBytes()
        HttpResponse(403)
    }
  }
} 
Example 20
Source File: BasicAuthenticationTest.scala    From sumobot   with Apache License 2.0 5 votes vote down vote up
package com.sumologic.sumobot.http_frontend.authentication

import akka.http.scaladsl.model.HttpMethods.{GET, POST}
import akka.http.scaladsl.model.{HttpRequest, StatusCodes, Uri}
import com.sumologic.sumobot.test.annotated.SumoBotSpec
import akka.http.scaladsl.model.headers._
import com.typesafe.config.ConfigFactory
import scala.collection.JavaConverters._

class BasicAuthenticationTest extends SumoBotSpec {
  private val authConfig = ConfigFactory.parseMap(
    Map("username" -> "admin", "password" -> "hunter2").asJava)
  val basicAuthentication = new BasicAuthentication(authConfig)
  val base64Credentials = "YWRtaW46aHVudGVyMg=="
  val base64InvalidCredentials = "YWRtaW46aHVpdGVyMg=="

  val rootRequest = HttpRequest(GET, Uri("/"))
  val authorizedRootRequest = rootRequest.withHeaders(List(`Authorization`(GenericHttpCredentials("basic", base64Credentials))))
  val invalidRootRequest = rootRequest.withHeaders(List(`Authorization`(GenericHttpCredentials("basic", base64InvalidCredentials))))

  "BasicAuthentication" should {
      "return 401 Unauthorized" when {
        "unauthenticated" in {
          val result = basicAuthentication.authentication(rootRequest)
          result match {
            case AuthenticationForbidden(response) =>
              response.status should be(StatusCodes.Unauthorized)
              response.header[`WWW-Authenticate`].nonEmpty should be(true)
            case _ =>
              fail("expected AuthenticationForbidden")
          }
        }
      }

    "successfuly authenticate" when {
      "provided correct Authorization header" in {
        val result = basicAuthentication.authentication(authorizedRootRequest)
        result match {
          case AuthenticationSucceeded(info) =>
            info.authMessage match {
              case Some(message) =>
                message should include("admin")
              case _ => fail("expected authMessage")
            }
          case _ =>
            fail("expected AuthenticationSucceeded")
        }
      }
    }

    "return 403 Forbidden" when {
      "provided incorrect Authorization header" in {
        val result = basicAuthentication.authentication(invalidRootRequest)
        result match {
          case AuthenticationForbidden(response) =>
            response.status should be(StatusCodes.Forbidden)
          case _ =>
            fail("expected AuthenticationForbidden")
        }
      }
    }
  }
} 
Example 21
Source File: NoAuthenticationTest.scala    From sumobot   with Apache License 2.0 5 votes vote down vote up
package com.sumologic.sumobot.http_frontend.authentication

import akka.http.scaladsl.model.HttpMethods.{GET, POST}
import akka.http.scaladsl.model.{HttpRequest, Uri}
import com.sumologic.sumobot.test.annotated.SumoBotSpec
import com.typesafe.config.ConfigFactory

class NoAuthenticationTest extends SumoBotSpec {
  val emptyRequest = HttpRequest()
  val rootRequest = HttpRequest(GET, Uri("/"))
  val postRequest = HttpRequest(POST, Uri("/endpoint"))

  val noAuthentication = new NoAuthentication(ConfigFactory.empty())

  "NoAuthentication" should {
    "allow all requests" in {
      noAuthentication.authentication(emptyRequest) shouldBe a[AuthenticationSucceeded]
      noAuthentication.authentication(rootRequest) shouldBe a[AuthenticationSucceeded]
      noAuthentication.authentication(postRequest) shouldBe a[AuthenticationSucceeded]
    }
  }
} 
Example 22
Source File: BasicAuthenticationExtension.scala    From scruid   with Apache License 2.0 5 votes vote down vote up
package ing.wbaa.druid.auth.basic

import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.headers.{ Authorization, BasicHttpCredentials }
import com.typesafe.config.{ Config, ConfigFactory, ConfigValueFactory }
import com.typesafe.scalalogging.LazyLogging
import ing.wbaa.druid.client.{
  NoopRequestInterceptor,
  RequestInterceptor,
  RequestInterceptorBuilder
}


class BasicAuthenticationExtension(username: String, password: String)
    extends NoopRequestInterceptor {
  override def interceptRequest(request: HttpRequest): HttpRequest =
    request.withHeaders(Authorization(BasicHttpCredentials(username, password)))

  override def exportConfig: Config =
    ConfigFactory
      .empty()
      .withValue("username", ConfigValueFactory.fromAnyRef(username))
      .withValue("password", ConfigValueFactory.fromAnyRef(password))
}

object BasicAuthenticationExtension extends RequestInterceptorBuilder with LazyLogging {

  override def apply(config: Config): RequestInterceptor = {

    val username =
      Option(config.getString("username")).getOrElse {
        throw new IllegalStateException(
          "BasicAuthenticationExtension requires 'username' configuration parameter to be specified"
        )
      }

    val password =
      Option(config.getString("password")).getOrElse {
        throw new IllegalStateException(
          "BasicAuthenticationExtension requires 'password' configuration parameter to be specified"
        )
      }

    logger.info(s"BasicAuthenticationExtension[username=$username] created")
    new BasicAuthenticationExtension(username, password)
  }
} 
Example 23
Source File: ClusterSoakSpec.scala    From akka-kubernetes-tests   with Apache License 2.0 5 votes vote down vote up
package akka.cluster.soak
import akka.actor.ActorSystem
import akka.discovery.ServiceDiscovery.Resolved
import akka.event.Logging
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.kubernetes.soak.Tests.{ResponseTimeNanos, Target}
import akka.kubernetes.soak.{StatsJsonSupport, TestResults}
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.time.{Seconds, Span}
import org.scalatest.{Matchers, WordSpec}
import akka.util.PrettyDuration._

import scala.collection.immutable
import scala.concurrent.Future
import scala.concurrent.duration._

class ClusterSoakSpec(endpoints: Resolved)(implicit system: ActorSystem)
    extends WordSpec
    with StatsJsonSupport
    with ScalaFutures
    with Matchers {

  import system.dispatcher
  implicit val mat = ActorMaterializer()
  implicit override val patienceConfig = PatienceConfig(timeout = Span(30, Seconds), interval = Span(2, Seconds))
  val log = Logging(system, getClass)

  "The Clustered service" should {

    "not have had any failures" in {

      val responses: immutable.Seq[TestResults] = Source(endpoints.addresses)
        .mapAsyncUnordered(10) { rt =>
          log.info("Hitting {}", rt.host)
          val request = HttpRequest(uri = s"http://${rt.host}:${rt.port.getOrElse(8080)}/stats")
          for {
            response <- Http().singleRequest(request)
            entity <- response.entity.toStrict(1.second)
            results <- response.status match {
              case StatusCodes.OK =>
                Unmarshal(entity).to[TestResults]
              case unexpected =>
                Future.failed(
                  new RuntimeException(s"Unexpected response code: $unexpected body: ${entity.data.utf8String}")
                )
            }
          } yield results
        }
        .runWith(Sink.seq)
        .futureValue

      log.info("{} nodes tested", responses.size)

      val maxJoinTimes =
        responses.map(_.joiningTime).sorted.reverse.take(5).map(_.nanos.pretty)

      log.info("Max join times: {}", maxJoinTimes)

      val maxResponseTimePerNode: immutable.Seq[(Target, ResponseTimeNanos)] =
        responses.map(_.lastResult.responses.maxBy(_._2))

      val averageResponseTimesPerNode = responses
        .map((eachNode: TestResults) => {
          val total = eachNode.lastResult.responses.map(_._2).sum.nanos
          val count = eachNode.lastResult.responses.size
          total / count
        })
        .sorted
        .reverse

      log.info("All response times: {}", responses)
      log.info("Slowest response times across all node pings: {}",
               maxResponseTimePerNode.sortBy(_._2).reverse.take(5).map(_._2.nanos.pretty))
      log.info("Slowest average response times across all node pings: {}",
               averageResponseTimesPerNode.take(5).map(_.pretty))

      responses.filter(_.testsFailed != 0) shouldEqual Nil

      withClue("Response took longer than 2 seconds. Do some investigation") {
        responses.filter(_.lastResult.responses.exists(_._2.nanos > 2.seconds)) shouldEqual Nil
      }

      withClue("Found unreachable events") {
        responses.filter(_.memberUnreachableEvents != 0) shouldEqual Nil
      }

      withClue("Found downed events") {
        responses.filter(_.memberDownedEvents != 0) shouldEqual Nil
      }
    }
  }

} 
Example 24
Source File: RequestContextSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.pipeline

import akka.actor.ActorSystem
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.testkit.TestKit
import org.scalatest.OptionValues._
import org.scalatest.{BeforeAndAfterAll, FlatSpecLike, Matchers}
import scala.util.Try

class RequestContextSpec
  extends TestKit(ActorSystem("RequestContextSpecSys"))
    with FlatSpecLike
    with Matchers
    with BeforeAndAfterAll {

  override def afterAll(): Unit = {
    system.terminate()
  }

  it should "handle attributes correctly (withAttributes/removeAttributes/expanded variable args)" in {
    val attributeAdditions =
      List(
        "key1" -> "val1",
        "key2" -> 1,
        "key3" -> new Exception("Bad Val")
      )

    val rc1 = RequestContext(HttpRequest(), 0)
    val rc2 = rc1.withAttributes(attributeAdditions:_*)
    rc1.attributes should have size 0
    rc2.attributes should equal(attributeAdditions.toMap)

    val addedKeys = attributeAdditions.map(_._1).toSet
    val removeKeys = Set(addedKeys.head, addedKeys.last)
    val rc3 = rc2.removeAttributes("ibetternotexist" +: removeKeys.toList:_*)
    rc3.attributes.keys.toSet should equal(addedKeys -- removeKeys)
  }

  it should "handle attributes correctly (withAttributes/variable args)" in {
    val rc = RequestContext(HttpRequest(), 0)

    rc.withAttributes(
      "key1" -> "val1",
      "key2" -> 1
    ).attributes should equal(Map("key1" -> "val1", "key2" -> 1))

    rc.attributes should have size 0
  }

  it should "handle attributes correctly (withAttribute/removeAttribute)" in {
    val rc1 = RequestContext(HttpRequest(), 0)

    rc1.attributes should have size 0

    val rc2 = rc1.withAttribute("key1", "val1")
    rc1.attributes should have size 0 // Immutability
    rc2.attribute("key1") should be(Some("val1"))

    val rc3 = rc2.withAttribute("key2", 1).withAttribute("key3", new Exception("Bad Val"))
    rc3.attribute("key2") should be(Some(1))
    rc3.attribute[Exception]("key3").value.getMessage should be("Bad Val")
    rc3.attribute("key1") should be(Some("val1"))

    rc3.attributes should have size 3

    val rc4 = rc3.removeAttribute("key1")
    rc3.attributes should have size 3 // Immutability
    rc4.attributes should have size 2

    val rc5 = rc4.removeAttribute("notexists")
    rc5.attributes should have size 2
    rc5.attribute("key2") should be(Some(1))
    rc5.attribute[Exception]("key3").value.getMessage should be("Bad Val")
  }

  it should "handle headers correctly" in {
    val rc1 = RequestContext(HttpRequest(), 0)
    val rc2 = rc1.withRequestHeader(RawHeader("key1", "val1"))
    val rc3 = rc2.withRequestHeaders(RawHeader("key2", "val2"), RawHeader("key3", "val3"))

    rc3.request.headers should have size 3
    rc3.response should be(None)
    rc3.request.headers should contain(RawHeader("key1", "val1"))

    val rc4 = rc3.withResponse(Try(HttpResponse()))
    rc4.response.value.get.headers should have size 0
    val rc5 = rc4.withResponseHeader(RawHeader("key4", "val4"))
    val rc6 = rc5.withResponseHeaders(RawHeader("key5", "val5"), RawHeader("key6", "val6"))
    val rc7 = rc6.withResponseHeader(RawHeader("key7", "val7"))
    rc7.request.headers should have size 3
    rc7.response.value.get.headers should have size 4
    rc7.response.value.get.headers should contain(RawHeader("key4", "val4"))
  }

} 
Example 25
Source File: PerpetualStreamMergeHubJSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.stream

import akka.actor.{ActorRef, ActorSystem}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.pattern.ask
import akka.stream.ActorMaterializer
import akka.testkit.TestKit
import com.typesafe.config.ConfigFactory
import org.scalatest.{FlatSpecLike, Matchers}
import org.squbs.unicomplex.Timeouts.{awaitMax, _}
import org.squbs.unicomplex._

import scala.collection.mutable
import scala.concurrent.Await

object PerpetualStreamMergeHubJSpec {
  val dummyJarsDir = getClass.getClassLoader.getResource("classpaths").getPath
  val classPaths = Array("JavaPerpetualStreamMergeHubSpec") map (dummyJarsDir + "/" + _)

  val config = ConfigFactory.parseString(
    s"""
       |squbs {
       |  actorsystem-name = JavaPerpetualStreamMergeHubSpec
       |  ${JMX.prefixConfig} = true
       |}
       |default-listener.bind-port = 0
      """.stripMargin
  )

  val boot = UnicomplexBoot(config)
    .createUsing {
      (name, config) => ActorSystem(name, config)
    }
    .scanComponents(classPaths)
    .start()
}

class PerpetualStreamMergeHubJSpec extends TestKit(PerpetualStreamMergeHubJSpec.boot.actorSystem)
  with FlatSpecLike with Matchers  {

  val portBindings = Await.result((Unicomplex(system).uniActor ? PortBindings).mapTo[Map[String, Int]], awaitMax)
  val psActorName = "/user/JavaPerpetualStreamMergeHubSpec/perpetualStreamWithMergeHub"
  val actorRef = Await.result((system.actorSelection(psActorName) ? RetrieveMyMessageStorageActorRef).mapTo[ActorRef],
    awaitMax)
  val port = portBindings("default-listener")


  it should "connect streams with mergehub" in {

    implicit val ac = ActorMaterializer()
    Http().singleRequest(HttpRequest(uri = Uri(s"http://127.0.0.1:$port/mergehub"), entity = "10"))
    Http().singleRequest(HttpRequest(uri = Uri(s"http://127.0.0.1:$port/mergehub"), entity = "11"))

    awaitAssert {
      val messages = Await.result((actorRef ? RetrieveMyMessages).mapTo[mutable.Set[MyMessage]], awaitMax)
      messages should have size 2
      messages should contain(MyMessage(10))
      messages should contain(MyMessage(11))
    }
  }
} 
Example 26
Source File: CubeActorErrorStatesSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.unicomplex

import javax.management.ObjectName
import javax.management.openmbean.CompositeData

import akka.actor.{Actor, ActorSystem}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.pattern._
import akka.stream.ActorMaterializer
import akka.testkit.{ImplicitSender, TestKit}
import com.typesafe.config.ConfigFactory
import org.scalatest.OptionValues._
import org.scalatest.{BeforeAndAfterAll, FlatSpecLike, Matchers}
import org.squbs.lifecycle.GracefulStop
import org.squbs.unicomplex.Timeouts._

import scala.concurrent.Await

object CubeActorErrorStatesSpec{

  val classPaths = Array(getClass.getClassLoader.getResource("classpaths/CubeActorErrorStates").getPath)

  val config = ConfigFactory.parseString(
    s"""
       |default-listener.bind-port = 0
       |squbs {
       |  actorsystem-name = cubeActorErrorStatesSpec
       |  ${JMX.prefixConfig} = true
       |}
    """.stripMargin
  )

  val boot = UnicomplexBoot(config)
    .createUsing {(name, config) => ActorSystem(name, config)}
    .scanComponents(classPaths)
    .initExtensions.start()
}

class CubeActorErrorStatesSpec extends TestKit(CubeActorErrorStatesSpec.boot.actorSystem)
  with FlatSpecLike with Matchers with ImplicitSender with BeforeAndAfterAll {

  val portBindings = Await.result((Unicomplex(system).uniActor ? PortBindings).mapTo[Map[String, Int]], awaitMax)
  val port = portBindings("default-listener")


  implicit val am = ActorMaterializer()

  override def afterAll(): Unit = {
    Unicomplex(system).uniActor ! GracefulStop
  }

  "Route" should "handle request with empty web-context" in {
    Http().singleRequest(HttpRequest(uri = Uri(s"http://127.0.0.1:$port/test2?msg=1")))
    Thread.sleep(100)
    Http().singleRequest(HttpRequest(uri = Uri(s"http://127.0.0.1:$port/test1?msg=1")))
    Thread.sleep(100)
    Http().singleRequest(HttpRequest(uri = Uri(s"http://127.0.0.1:$port/test1?msg=2")))
    Thread.sleep(1000) // wait the agent get refreshed
    import org.squbs.unicomplex.JMX._
    val errorStates = get(new ObjectName(prefix(system) + cubeStateName + "CubeActorErrorStates"), "ActorErrorStates")
      .asInstanceOf[Array[CompositeData]]
    errorStates should have length 2
    val state1 = errorStates.find(_.get("actorPath") == "/user/CubeActorErrorStates/test1-CubeActorTest-handler").value
    state1.get("errorCount") shouldBe 2
    state1.get("latestException").asInstanceOf[String] should include ("test1:2")
    val state2 = errorStates.find(_.get("actorPath") == "/user/CubeActorErrorStates/test2-CubeActorTest-handler").value
    state2.get("errorCount") shouldBe 1
    state2.get("latestException").asInstanceOf[String] should include ("test2:1")
  }
}

class CubeActorTest extends Actor {
  override def receive: Receive = {
    case r: HttpRequest =>
      val msg = r.uri.query().get("msg").getOrElse("")
      throw new RuntimeException(s"${r.uri.path}:$msg")
  }
} 
Example 27
Source File: ConfigurableInitTimeActor.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.unicomplex.timeout

import akka.NotUsed
import akka.http.scaladsl.model.{HttpRequest, HttpResponse, StatusCodes}
import akka.stream.scaladsl.Flow
import org.slf4j.LoggerFactory
import org.squbs.unicomplex.FlowDefinition

object ConfigurableInitTimeActor {
  def log = LoggerFactory.getLogger(classOf[ConfigurableInitTimeActor])
}

class ConfigurableInitTimeActor extends FlowDefinition {
  import ConfigurableInitTimeActor.log

  override def flow: Flow[HttpRequest, HttpResponse, NotUsed] = {
    val system = this.context.system

    val initTime = Option(system.settings.config.getDuration("squbs.test.actor-init-time"))
      .get

    log.info(s"I'll be ready to go in $initTime")
    Thread.sleep(initTime.toMillis)
    log.info("Ready to work!")

    Flow[HttpRequest].map { r => HttpResponse(StatusCodes.OK, entity = "Hello") }
  }
} 
Example 28
Source File: JavaConverters.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package akka.http.org.squbs.util

import java.util.Optional

import akka.NotUsed
import akka.http.impl.util.JavaMapping
import akka.http.javadsl.{model => jm}
import akka.http.scaladsl.Http.HostConnectionPool
import akka.http.scaladsl.HttpsConnectionContext
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.settings.ConnectionPoolSettings
import akka.http.{javadsl => jd}
import akka.japi.Pair
import akka.stream.scaladsl.{BidiFlow, Flow}
import akka.stream.{javadsl => js}

import scala.util.Try


object JavaConverters {
  def fromJava(connectionContext: Optional[jd.HttpsConnectionContext],
                                 settings: Optional[jd.settings.ConnectionPoolSettings]):
  (Option[HttpsConnectionContext], Option[ConnectionPoolSettings]) = {
    import scala.compat.java8.OptionConverters._
    val cCtx = connectionContext.asScala.asInstanceOf[Option[HttpsConnectionContext]]
    val sSettings = settings.asScala.asInstanceOf[Option[ConnectionPoolSettings]]
    (cCtx, sSettings)
  }

  def toJava[In1, Out1, In2, Out2, Context](bidiFlow: BidiFlow[(In1, Context), (Out1, Context), (In2, Context), (Out2, Context), NotUsed]):
  js.BidiFlow[Pair[In1, Context], Pair[Out1, Context], Pair[In2, Context], Pair[Out2, Context], NotUsed] = {
    implicit val sIn1Mapping = JavaMapping.identity[In1]
    implicit val sOut1Mapping = JavaMapping.identity[Out1]
    implicit val sIn2Mapping = JavaMapping.identity[In2]
    implicit val sOut2Mapping = JavaMapping.identity[Out2]
    implicit val contextMapping = JavaMapping.identity[Context]
    val javaToScalaAdapter = JavaMapping.adapterBidiFlow[Pair[In1, Context], (In1, Context), (Out2, Context), Pair[Out2, Context]]
    val scalaToJavaAdapter = JavaMapping.adapterBidiFlow[Pair[In2, Context], (In2, Context), (Out1, Context), Pair[Out1, Context]].reversed
    javaToScalaAdapter.atop(bidiFlow).atop(scalaToJavaAdapter).asJava
  }

  private def adaptTupleFlow[T](scalaFlow: Flow[(HttpRequest, T), (Try[HttpResponse], T), HostConnectionPool]):
  js.Flow[Pair[jm.HttpRequest, T], Pair[Try[jm.HttpResponse], T], jd.HostConnectionPool] = {
    implicit val _ = JavaMapping.identity[T]
    implicit object HostConnectionPoolMapping extends JavaMapping[jd.HostConnectionPool, HostConnectionPool] {
      def toScala(javaObject: jd.HostConnectionPool): HostConnectionPool =
        throw new UnsupportedOperationException("jd.HostConnectionPool cannot be converted to Scala")
      def toJava(scalaObject: HostConnectionPool): jd.HostConnectionPool = scalaObject.toJava
    }
    JavaMapping.toJava(scalaFlow)(JavaMapping.flowMapping[Pair[jm.HttpRequest, T], (HttpRequest, T),
      Pair[Try[jm.HttpResponse], T], (Try[HttpResponse], T), jd.HostConnectionPool, HostConnectionPool])
  }

  def toJava[T](flow: Flow[(HttpRequest, T), (Try[HttpResponse], T), HostConnectionPool]):
  js.Flow[Pair[jm.HttpRequest, T], Pair[Try[jm.HttpResponse], T], jd.HostConnectionPool] = {
    adaptTupleFlow[T](flow)
  }

  def toScala(uri: akka.http.javadsl.model.Uri) = JavaMapping.toScala(uri)
} 
Example 29
Source File: MetronomeFacade.scala    From metronome   with Apache License 2.0 5 votes vote down vote up
package dcos.metronome.integrationtest.utils

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.client.RequestBuilding.{Get, Post}
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpRequest, HttpResponse}
import akka.stream.Materializer
import com.mesosphere.utils.http.RestResult

import scala.concurrent.Await.result
import scala.concurrent.Future
import scala.concurrent.duration.{FiniteDuration, _}

class MetronomeFacade(val url: String, implicit val waitTime: FiniteDuration = 30.seconds)(implicit
    val system: ActorSystem,
    mat: Materializer
) {

  import scala.concurrent.ExecutionContext.Implicits.global

  //info --------------------------------------------------
  def info(): RestResult[HttpResponse] = {
    result(request(Get(s"$url/info")), waitTime)
  }

  def createJob(jobDef: String): RestResult[HttpResponse] = {
    val e = HttpEntity(ContentTypes.`application/json`, jobDef)
    result(request(Post(s"$url/v1/jobs", e)), waitTime)
  }

  def startRun(jobId: String): RestResult[HttpResponse] = {
    val e = HttpEntity(ContentTypes.`application/json`, "")
    result(request(Post(s"$url/v1/jobs/${jobId}/runs", e)), waitTime)
  }

  def getJob(jobId: String): RestResult[HttpResponse] = {
    result(request(Get(s"$url/v1/jobs/${jobId}")), waitTime)
  }

  def getJobs(): RestResult[HttpResponse] = {
    result(request(Get(s"$url/v1/jobs")), waitTime)
  }

  def getRuns(jobId: String): RestResult[HttpResponse] = {
    result(request(Get(s"$url/v1/jobs/${jobId}/runs")), waitTime)
  }

  private[this] def request(request: HttpRequest): Future[RestResult[HttpResponse]] = {
    Http(system).singleRequest(request).flatMap { response =>
      response.entity.toStrict(waitTime).map(_.data.decodeString("utf-8")).map(RestResult(response, _))
    }
  }

} 
Example 30
Source File: AkkaHttpClient.scala    From sttp   with Apache License 2.0 5 votes vote down vote up
package sttp.client.akkahttp

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

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

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

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

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

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

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

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

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

  def stubFromRoute(route: Route)(implicit
      routingSettings: RoutingSettings,
      parserSettings: ParserSettings,
      materializer: Materializer,
      routingLog: RoutingLog,
      executionContext: ExecutionContextExecutor = null,
      rejectionHandler: RejectionHandler = RejectionHandler.default,
      exceptionHandler: ExceptionHandler = null
  ): AkkaHttpClient = stubFromAsyncHandler(Route.asyncHandler(route))
} 
Example 31
Source File: CorsBenchmark.scala    From akka-http-cors   with Apache License 2.0 5 votes vote down vote up
package ch.megard.akka.http.cors

import java.util.concurrent.TimeUnit

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.Http.ServerBinding
import akka.http.scaladsl.model.headers.{Origin, `Access-Control-Request-Method`}
import akka.http.scaladsl.model.{HttpMethods, HttpRequest}
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import ch.megard.akka.http.cors.scaladsl.CorsDirectives
import ch.megard.akka.http.cors.scaladsl.settings.CorsSettings
import com.typesafe.config.ConfigFactory
import org.openjdk.jmh.annotations._

import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext}

@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.SECONDS)
@BenchmarkMode(Array(Mode.Throughput))
class CorsBenchmark extends Directives with CorsDirectives {
  private val config = ConfigFactory.parseString("akka.loglevel = ERROR").withFallback(ConfigFactory.load())

  implicit private val system: ActorSystem  = ActorSystem("CorsBenchmark", config)
  implicit private val ec: ExecutionContext = scala.concurrent.ExecutionContext.global

  private val http         = Http()
  private val corsSettings = CorsSettings.default

  private var binding: ServerBinding        = _
  private var request: HttpRequest          = _
  private var requestCors: HttpRequest      = _
  private var requestPreflight: HttpRequest = _

  @Setup
  def setup(): Unit = {
    val route = {
      path("baseline") {
        get {
          complete("ok")
        }
      } ~ path("cors") {
        cors(corsSettings) {
          get {
            complete("ok")
          }
        }
      }
    }
    val origin = Origin("http://example.com")

    binding = Await.result(http.bindAndHandle(route, "127.0.0.1", 0), 1.second)
    val base = s"http://${binding.localAddress.getHostString}:${binding.localAddress.getPort}"

    request = HttpRequest(uri = base + "/baseline")
    requestCors = HttpRequest(
      method = HttpMethods.GET,
      uri = base + "/cors",
      headers = List(origin)
    )
    requestPreflight = HttpRequest(
      method = HttpMethods.OPTIONS,
      uri = base + "/cors",
      headers = List(origin, `Access-Control-Request-Method`(HttpMethods.GET))
    )
  }

  @TearDown
  def shutdown(): Unit = {
    val f = for {
      _ <- http.shutdownAllConnectionPools()
      _ <- binding.terminate(1.second)
      _ <- system.terminate()
    } yield ()
    Await.ready(f, 5.seconds)
  }

  @Benchmark
  def baseline(): Unit = {
    val f = http.singleRequest(request).flatMap(r => Unmarshal(r.entity).to[String])
    assert(Await.result(f, 1.second) == "ok")
  }

  @Benchmark
  def default_cors(): Unit = {
    val f = http.singleRequest(requestCors).flatMap(r => Unmarshal(r.entity).to[String])
    assert(Await.result(f, 1.second) == "ok")
  }

  @Benchmark
  def default_preflight(): Unit = {
    val f = http.singleRequest(requestPreflight).flatMap(r => Unmarshal(r.entity).to[String])
    assert(Await.result(f, 1.second) == "")
  }
} 
Example 32
Source File: AkkaKubernetesSpec.scala    From akka-kubernetes-tests   with Apache License 2.0 5 votes vote down vote up
package akka.kubernetes.sample

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.management.cluster.{ClusterHttpManagementJsonProtocol, ClusterMembers}
import akka.stream.ActorMaterializer
import org.scalatest.concurrent.{Eventually, ScalaFutures}
import org.scalatest.time.{Seconds, Span}
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec}

class AkkaKubernetesSpec extends WordSpec with BeforeAndAfterAll with ScalaFutures with Matchers with ClusterHttpManagementJsonProtocol with Eventually {
  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()

  implicit override val patienceConfig = PatienceConfig(timeout = Span(60, Seconds), interval = Span(2, Seconds))

  val target = system.settings.config.getString("akka.k8s.target")
  val clusterSize = system.settings.config.getInt("akka.k8s.cluster-size")
  val deployedVersion = system.settings.config.getString("akka.k8s.deployment-version")

  val log = system.log

  log.info("Running with target {} clusterSize {} version {}", target, clusterSize, deployedVersion)

  "Version deployed" should {
    "should have been updated" in {
      eventually {
        val response = Http().singleRequest(HttpRequest(uri = s"$target/version")).futureValue
        val reportedVersion = Unmarshal(response.entity).to[String].futureValue
        log.info("Reported version is: {}", reportedVersion)
        reportedVersion shouldEqual deployedVersion
      }
    }
  }

  "Cluster formation" should {

    "work" in {
      eventually {
        val response = Http().singleRequest(HttpRequest(uri = s"$target/cluster/members")).futureValue
        response.status shouldEqual StatusCodes.OK

        val clusterMembers: ClusterMembers = Unmarshal(response).to[ClusterMembers].futureValue
        withClue("Latest response: " + clusterMembers) {
          clusterMembers.members.size shouldEqual clusterSize
          clusterMembers.unreachable shouldEqual Seq.empty
        }
        log.info("Current cluster members: {}", clusterMembers)
      }
    }
  }

  "Akka Boss (singleton)" should {

    "say hello" in {
      val response = Http().singleRequest(HttpRequest(uri = s"$target/boss")).futureValue
      response.status shouldEqual StatusCodes.OK
    }
  }

  "Akka members (sharding)" should {
    "do some work" in {
      val response = Http().singleRequest(HttpRequest(uri = s"$target/team-member/johan")).futureValue
      response.status shouldEqual StatusCodes.OK
    }
  }

  override protected def afterAll(): Unit = {
    system.terminate()
  }
} 
Example 33
Source File: package.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse, Uri}
import akka.stream.ActorMaterializer
import akka.util.ByteString

import scala.concurrent.Future

package object testkit {
  case object TestPing
  case object TestPong

  def entityAsString(uri: String)(implicit am: ActorMaterializer, system: ActorSystem): Future[String] = {
    import system.dispatcher
    get(uri) flatMap extractEntityAsString
  }

  def get(uri: String)(implicit am: ActorMaterializer, system: ActorSystem): Future[HttpResponse] = {
    Http().singleRequest(HttpRequest(uri = Uri(uri)))
  }

  def extractEntityAsString(response: HttpResponse)
                           (implicit am: ActorMaterializer, system: ActorSystem): Future[String] = {
    import system.dispatcher
    response.entity.dataBytes.runFold(ByteString(""))(_ ++ _) map(_.utf8String)
  }
} 
Example 34
Source File: RouteLogging.scala    From akka-ddd-cqrs-es-example   with MIT License 5 votes vote down vote up
package com.github.j5ik2o.bank.adaptor.controller

import akka.event.Logging
import akka.http.scaladsl.model.headers.{ Authorization, BasicHttpCredentials }
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.http.scaladsl.server.{ Directive0, RouteResult }
import akka.http.scaladsl.server.directives.{ DebuggingDirectives, LogEntry }

trait RequestFormatter {
  def formatRequest(request: HttpRequest): LogEntry
}

trait RequestResultFormatter {
  def formatRequestResponse(request: HttpRequest): RouteResult => Option[LogEntry]
}

object DefaultRequestLoggingFormatter {

  implicit object requestFormatter extends RequestFormatter {
    override def formatRequest(request: HttpRequest): LogEntry = {
      LogEntry(s"${formatRequestToString(request)}/", Logging.InfoLevel)
    }
  }

  implicit object requestResultFormatter extends RequestResultFormatter {
    override def formatRequestResponse(request: HttpRequest): (RouteResult) => Option[LogEntry] = {
      case RouteResult.Complete(response) =>
        val req = formatRequestToString(request)
        val res = formatResponseToString(response)
        Some(LogEntry(s"$req/$res", Logging.InfoLevel))
      case _ =>
        val req = formatRequestToString(request)
        Some(LogEntry(req, Logging.InfoLevel))
    }
  }

  private def formatRequestToString(request: HttpRequest): String = {
    val protocol = request.protocol.value
    val method   = request.method.name()
    val path     = request.uri.toString()
    val headers = request.headers
      .collect {
        case Authorization(_: BasicHttpCredentials) => "authorization:Basic ***"
        case Authorization(_)                       => "authorization:***"
        case h                                      => s"'${h.lowercaseName()}':'${h.value()}'"
      }
      .mkString(", ")
    s"$protocol $method $path [$headers]"
  }

  private def formatResponseToString(request: HttpResponse): String = {
    val status  = request.status.value
    val headers = request.headers.map(h => s"'${h.lowercaseName()}':'${h.value()}'").mkString(", ")
    s"$status [$headers]"
  }
}

class RouteLogging()(implicit requestFormatter: RequestFormatter, requestResultFormatter: RequestResultFormatter) {

  val httpLogRequest: Directive0 = DebuggingDirectives.logRequest(requestFormatter.formatRequest _)

  val httpLogRequestResult: Directive0 =
    DebuggingDirectives.logRequestResult(requestResultFormatter.formatRequestResponse _)

}

object RouteLogging {
  def apply()(implicit requestFormatter: RequestFormatter,
              requestResultFormatter: RequestResultFormatter): RouteLogging = new RouteLogging()

  val default: RouteLogging = new RouteLogging()(DefaultRequestLoggingFormatter.requestFormatter,
                                                 DefaultRequestLoggingFormatter.requestResultFormatter)
} 
Example 35
Source File: Hello.scala    From sbt-guardrail   with MIT License 5 votes vote down vote up
package helloworld

import scala.concurrent.Future
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.stream.Materializer
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import cats.implicits._
import com.example.clients.petstore.user.UserClient

object Hello {

  def buildUserClient(): UserClient = {
    import scala.concurrent.ExecutionContext.Implicits.global

    val server = buildServer()

    implicit val actorSys = ActorSystem()
    implicit val materializer = ActorMaterializer()

    UserClient.httpClient(server)
  }

  private def buildServer(): HttpRequest => Future[HttpResponse] = {
    import com.example.servers.petstore.user._
    import akka.http.scaladsl.server.Route
    import akka.http.scaladsl.settings.RoutingSettings

    implicit val actorSys = ActorSystem()
    implicit val materializer = ActorMaterializer()
    implicit val routingSettings = RoutingSettings(actorSys)

    Route.asyncHandler(
      UserResource.routes(new DummyUserHandler())
    )
  }
}

class DummyUserHandler
  extends com.example.servers.petstore.user.UserHandler {

  import com.example.servers.petstore.user._
  import com.example.servers.petstore.definitions._
  import scala.collection._

  def createUser(respond: UserResource.CreateUserResponse.type)(body: User): scala.concurrent.Future[UserResource.CreateUserResponse] = ???
  def createUsersWithArrayInput(respond: UserResource.CreateUsersWithArrayInputResponse.type)(body: Vector[User]): scala.concurrent.Future[UserResource.CreateUsersWithArrayInputResponse] = ???
  def createUsersWithListInput(respond: UserResource.CreateUsersWithListInputResponse.type)(body: Vector[User]): scala.concurrent.Future[UserResource.CreateUsersWithListInputResponse] = ???
  def loginUser(respond: UserResource.LoginUserResponse.type)(username: String, password: String): scala.concurrent.Future[UserResource.LoginUserResponse] = ???
  def logoutUser(respond: UserResource.LogoutUserResponse.type)(): scala.concurrent.Future[UserResource.LogoutUserResponse] = ???
  def getUserByName(respond: UserResource.GetUserByNameResponse.type)(username: String): scala.concurrent.Future[UserResource.GetUserByNameResponse] = {
    val user = new User(
      id = Some(1234),
      username = Some(username),
      firstName = Some("First"),
      lastName = Some("Last"),
      email = Some(username + "@example.com"))
    Future.successful(respond.OK(user))
  }
  def updateUser(respond: UserResource.UpdateUserResponse.type)(username: String, body: User): scala.concurrent.Future[UserResource.UpdateUserResponse] = ???
  def deleteUser(respond: UserResource.DeleteUserResponse.type)(username: String): scala.concurrent.Future[UserResource.DeleteUserResponse] = ???
} 
Example 36
Source File: ContainerServiceSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.service

import akka.actor.{ActorSystem, Terminated}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import com.github.vonnagy.service.container.{AkkaTestkitSpecs2Support, TestUtils}
import com.typesafe.config.ConfigFactory
import org.specs2.concurrent.ExecutionEnv
import org.specs2.matcher.FutureMatchers
import org.specs2.mutable.SpecificationLike

class ContainerServiceSpec extends AkkaTestkitSpecs2Support(ActorSystem("test", {
  val http = TestUtils.temporaryServerHostnameAndPort()

  ConfigFactory.parseString(
  s"""
      container.http.interface="${http._2}"
      container.http.port=${http._3}
    """)})) with SpecificationLike with FutureMatchers {

  sequential
  val cont = new ContainerService(Nil, Nil, name = "test")

  "The ContainerService" should {

    "create the appropriate parts during construction" in {
      cont.registeredHealthChecks must be equalTo Nil
      cont.registeredRoutes must be equalTo Nil
      cont.started must beFalse
    }

    "start properly and respond to a `/ping` request" in {
      cont.start()
      cont.started must beTrue

      val host = system.settings.config.getString("container.http.interface")
      val port = system.settings.config.getInt("container.http.port")

      val resp = Http().singleRequest(HttpRequest(uri = s"http://$host:$port/ping"))
      resp.value.get.get.status must eventually(be_==(StatusCodes.OK))

    }

    "shut down properly when asked" in {
      cont.shutdown
      implicit val ec = ExecutionEnv.fromExecutionContext(system.dispatcher)
      cont.system.whenTerminated must beAnInstanceOf[Terminated].await
    }
  }
} 
Example 37
Source File: WSSecurityProperties.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci
package communicator
package ws.akka

import java.security.cert.Certificate

import akka.http.scaladsl.model.{HttpMessage, HttpRequest, HttpResponse, Uri}
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.ws.WebSocketRequest

private case class WSSecurityProperties(
  isAuthenticated: Boolean, isProtected: Boolean, isEncrypted: Boolean,
  certificates: Seq[Certificate])

private object WSSecurityProperties {
  final val HTTPS = "https"
  final val WSS = "wss"
  final val NoProtocol = "NONE" // TLSv1, etc.
  final val NoCipher = "SSL_NULL_WITH_NULL_NULL" // see RFC2246, RFC3268, etc.
  final val NoEncryptionFragment = "WITH_NULL"

  def apply(request: WebSocketRequest, response: HttpResponse,
      authenticated: Boolean): WSSecurityProperties =
    create(request.uri, response, authenticated)

  def apply(request: HttpRequest, authenticated: Boolean): WSSecurityProperties =
    create(request.uri, request, authenticated)

  private def create(uri: Uri, message: HttpMessage, authenticated: Boolean)
    : WSSecurityProperties = {

    val tls = uri.scheme == HTTPS || uri.scheme == WSS

    val properties = message.header[`Tls-Session-Info`] map { info =>
      val protocol = info.session.getProtocol
      val cipher = info.session.getCipherSuite

      val tls = protocol != NoProtocol && cipher != NoCipher

      val certificates = info.peerCertificates
      val isAuthenticated = tls && certificates.nonEmpty
      val isProtected = tls
      val isEncrypted = tls && !(cipher contains NoEncryptionFragment)

      WSSecurityProperties(authenticated || isAuthenticated, isProtected, isEncrypted, certificates)
    }

    properties getOrElse { WSSecurityProperties(authenticated, tls, tls, Seq.empty) }
  }
} 
Example 38
Source File: WebSocketRoute.scala    From vamp   with Apache License 2.0 5 votes vote down vote up
package io.vamp.http_api.ws

import java.util.UUID

import akka.actor.PoisonPill
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.ws.{ Message, TextMessage }
import akka.http.scaladsl.server.Route
import akka.stream._
import akka.stream.scaladsl.{ Flow, Sink, Source }
import akka.util.Timeout
import io.vamp.common.akka.IoC._
import io.vamp.common.http.{ HttpApiDirectives, HttpApiHandlers, TerminateFlowStage }
import io.vamp.common.{ Config, Namespace }
import io.vamp.http_api.ws.WebSocketActor.{ SessionClosed, SessionEvent, SessionOpened, SessionRequest }
import io.vamp.http_api.{ AbstractRoute, LogDirective }

import scala.concurrent.Future

trait WebSocketRoute extends AbstractRoute with WebSocketMarshaller with HttpApiHandlers {
  this: HttpApiDirectives with LogDirective ⇒

  implicit def materializer: Materializer

  private lazy val limit = Config.int("vamp.http-api.websocket.stream-limit")

  protected def websocketApiHandler(implicit namespace: Namespace, timeout: Timeout): Route

  def websocketRoutes(implicit namespace: Namespace, timeout: Timeout) = {
    pathEndOrSingleSlash {
      get {
        extractRequest { request ⇒
          handleWebSocketMessages {
            websocket(request)
          }
        }
      }
    }
  }

  protected def filterWebSocketOutput(message: AnyRef)(implicit namespace: Namespace, timeout: Timeout): Future[Boolean] = Future.successful(true)

  private def apiHandler(implicit namespace: Namespace, timeout: Timeout) = Route.asyncHandler(log {
    websocketApiHandler
  })

  private def websocket(origin: HttpRequest)(implicit namespace: Namespace, timeout: Timeout): Flow[AnyRef, Message, Any] = {
    val id = UUID.randomUUID()

    val in = Flow[AnyRef].collect {
      case TextMessage.Strict(message)  ⇒ Future.successful(message)
      case TextMessage.Streamed(stream) ⇒ stream.limit(limit()).completionTimeout(timeout.duration).runFold("")(_ + _)
    }.mapAsync(parallelism = 3)(identity)
      .mapConcat(unmarshall)
      .map(SessionRequest(apiHandler, id, origin, _))
      .to(Sink.actorRef[SessionEvent](actorFor[WebSocketActor], SessionClosed(id)))

    val out = Source.actorRef[AnyRef](16, OverflowStrategy.dropHead)
      .mapMaterializedValue(actorFor[WebSocketActor] ! SessionOpened(id, _))
      .via(new TerminateFlowStage[AnyRef](_ == PoisonPill))
      .mapAsync(parallelism = 3)(message ⇒ filterWebSocketOutput(message).map(f ⇒ f → message))
      .collect { case (true, m) ⇒ m }
      .map(message ⇒ TextMessage.Strict(marshall(message)))

    Flow.fromSinkAndSource(in, out)
  }
} 
Example 39
Source File: SseConnector.scala    From vamp   with Apache License 2.0 5 votes vote down vote up
package io.vamp.common.http

import akka.Done
import akka.actor.ActorSystem
import akka.event.LoggingAdapter
import akka.http.scaladsl.model.HttpHeader.ParsingResult.Ok
import akka.http.scaladsl.model.sse.ServerSentEvent
import akka.http.scaladsl.model.{ HttpHeader, HttpRequest, HttpResponse, Uri }
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{ Sink, Source }
import io.vamp.common.http.EventSource.EventSource

import scala.collection.mutable
import scala.concurrent.Future
import scala.concurrent.duration.{ FiniteDuration, _ }
import scala.language.postfixOps
import scala.util.{ Failure, Success }

private case class SseConnectionConfig(url: String, headers: List[(String, String)], tlsCheck: Boolean)

private case class SseConnectionEntryValue(source: EventSource)

trait SseListener {
  def onEvent(event: ServerSentEvent): Unit
}

object SseConnector {

  private val retryDelay: FiniteDuration = 5 second
  private val listeners: mutable.Map[SseConnectionConfig, Set[SseListener]] = mutable.Map()
  private val connections: mutable.Map[SseConnectionConfig, Future[Done]] = mutable.Map()

  def open(url: String, headers: List[(String, String)] = Nil, tlsCheck: Boolean)(listener: SseListener)(implicit system: ActorSystem, logger: LoggingAdapter): Unit = synchronized {
    val config = SseConnectionConfig(url, headers, tlsCheck)
    implicit val materializer: ActorMaterializer = ActorMaterializer()

    listeners.update(config, listeners.getOrElse(config, Set()) + listener)

    connections.getOrElseUpdate(config, {
      logger.info(s"Opening SSE connection: $url")
      EventSource(Uri(url), send(config), None, retryDelay).takeWhile { event ⇒
        event.eventType.foreach(t ⇒ logger.info(s"SSE: $t"))
        val receivers = listeners.getOrElse(config, Set())
        receivers.foreach(_.onEvent(event))
        val continue = receivers.nonEmpty
        if (!continue) logger.info(s"Closing SSE connection: $url")
        continue
      }.runWith(Sink.ignore)
    })
  }

  def close(listener: SseListener): Unit = synchronized {
    listeners.transform((_, v) ⇒ v - listener)
  }

  private def send(config: SseConnectionConfig)(request: HttpRequest)(implicit system: ActorSystem, materializer: ActorMaterializer): Future[HttpResponse] = {
    val httpHeaders = config.headers.map { case (k, v) ⇒ HttpHeader.parse(k, v) } collect { case Ok(h, _) ⇒ h } filterNot request.headers.contains
    Source.single(request.withHeaders(request.headers ++ httpHeaders) → 1).via(HttpClient.pool[Any](config.url, config.tlsCheck)).map {
      case (Success(response: HttpResponse), _) ⇒ response
      case (Failure(f), _)                      ⇒ throw new RuntimeException(f.getMessage)
    }.runWith(Sink.head)
  }
} 
Example 40
Source File: AkkaHTTPClient.scala    From learn-akka   with Apache License 2.0 5 votes vote down vote up
package com.allaboutscala.learn.akka.client

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{MediaTypes, HttpEntity, HttpMethods, HttpRequest}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import akka.util.ByteString
import com.allaboutscala.learn.akka.http.jsonsupport.{Donuts, JsonSupport}

import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success}
import scala.concurrent.duration._


object AkkaHttpClient extends App with JsonSupport {

  implicit val system = ActorSystem("akka-http-donuts-client")
  implicit val materializer = ActorMaterializer()
  implicit val ec = system.dispatcher

  // HTTP GET request
  val donutsUri = "http://localhost:8080/donuts"
  val donutsHttpRequest = HttpRequest(
    uri = donutsUri,
    method = HttpMethods.GET
  )

  val donutsResponse = Http().singleRequest(donutsHttpRequest)
  donutsResponse
    .onComplete {
      case Success(donutsResponse) =>
        println(s"Raw HttpResponse = $donutsResponse")

        // You obviously should not block using Await.result(...) and use flatMap or other similar future sequencing mechanics
        val donutsF: Future[Donuts] = Unmarshal(donutsResponse).to[Donuts]
        val donuts: Donuts = Await.result(donutsF, 5.second)
        println(s"Unmarshalled HttpResponse to Case Class = $donuts")


      case Failure(e) => println(s"Failed to HTTP GET $donutsUri, error = ${e.getMessage}")
    }

  Thread.sleep(3000)



  // HTTP POST request
  val jsonDonutInput = ByteString("""{"name":"plain donut", "price":1.50}""")
  val httpPostCreateDonut = HttpRequest(
    uri = "http://localhost:8080/create-donut",
    method = HttpMethods.POST,
    entity = HttpEntity(MediaTypes.`application/json`, jsonDonutInput))

  val createDonutF = for {
    response <- Http().singleRequest(httpPostCreateDonut)
    _        = println(s"Akka HTTP request status = ${response.status}")
    if response.status.isSuccess()
    output   <- Unmarshal(response).to[String]
  } yield println(s"HTTP POST request output = $output")

  Await.result(createDonutF, 5.second)


  system.terminate()
} 
Example 41
Source File: CreateDonutTest.scala    From learn-akka   with Apache License 2.0 5 votes vote down vote up
package com.allaboutscala.learn.akka.http

import akka.http.scaladsl.model.{HttpEntity, HttpMethods, HttpRequest, MediaTypes}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import akka.util.ByteString
import com.allaboutscala.learn.akka.http.routes.DonutRoutes
import org.scalatest.{Matchers, WordSpec}


class CreateDonutTest
  extends WordSpec
    with Matchers
    with ScalatestRouteTest {

  val donutRoutes = new DonutRoutes().route()

  "Donut API" should {
    "Create a valid Donut when posting JSON to /create-donut path" in {
      val jsonDonutInput = ByteString("""{"name":"plain donut", "price":1.50}""")
      val httpPostCreateDonut = HttpRequest(
        uri = "http://localhost:8080/create-donut",
        method = HttpMethods.POST,
        entity = HttpEntity(MediaTypes.`application/json`, jsonDonutInput))

      httpPostCreateDonut ~> donutRoutes ~> check {
        status.isSuccess() shouldEqual true
        status.intValue() shouldEqual 201
        status.reason shouldEqual "Created"
      }
    }
  }

} 
Example 42
Source File: EventSource.scala    From nexus-kg   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.kg.client

import java.util.UUID

import akka.NotUsed
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.headers.OAuth2BearerToken
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.persistence.query.{NoOffset, Offset, Sequence, TimeBasedUUID}
import akka.stream.Materializer
import akka.stream.alpakka.sse.scaladsl.{EventSource => SSESource}
import akka.stream.scaladsl.Source
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.iam.client.types.AuthToken
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri
import com.typesafe.scalalogging.Logger
import io.circe.Decoder
import io.circe.parser.decode

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try

trait EventSource[A] {

  
  def apply[A: Decoder](
      config: KgClientConfig
  )(implicit as: ActorSystem, mt: Materializer, ec: ExecutionContext): EventSource[A] =
    new EventSource[A] {
      private val logger = Logger[this.type]
      private val http   = Http()

      private def addCredentials(request: HttpRequest)(implicit cred: Option[AuthToken]): HttpRequest =
        cred.map(token => request.addCredentials(OAuth2BearerToken(token.value))).getOrElse(request)

      private def send(request: HttpRequest)(implicit cred: Option[AuthToken]): Future[HttpResponse] =
        http.singleRequest(addCredentials(request)).map { resp =>
          if (!resp.status.isSuccess())
            logger.warn(s"HTTP response when performing SSE request: status = '${resp.status}'")
          resp
        }

      private def toOffset(id: String): Offset =
        Try(TimeBasedUUID(UUID.fromString(id))).orElse(Try(Sequence(id.toLong))).getOrElse(NoOffset)

      override def apply(iri: AbsoluteIri, offset: Option[String])(
          implicit cred: Option[AuthToken]
      ): Source[(Offset, A), NotUsed] =
        SSESource(iri.asAkka, send, offset, config.sseRetryDelay).flatMapConcat { sse =>
          val offset = sse.id.map(toOffset).getOrElse(NoOffset)
          decode[A](sse.data) match {
            case Right(ev) => Source.single(offset -> ev)
            case Left(err) =>
              logger.error(s"Failed to decode admin event '$sse'", err)
              Source.empty
          }
        }
    }
} 
Example 43
Source File: TestResponseFromUnsupportedApis.scala    From ohara   with Apache License 2.0 5 votes vote down vote up
package oharastream.ohara.configurator

import java.util.concurrent.TimeUnit

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import akka.http.scaladsl.model.{HttpMethod, HttpMethods, HttpRequest}
import akka.http.scaladsl.unmarshalling.Unmarshal
import oharastream.ohara.client.configurator.ErrorApi
import oharastream.ohara.common.rule.OharaTest
import oharastream.ohara.common.util.{CommonUtils, Releasable}
import org.junit.{After, Test}
import org.scalatest.matchers.should.Matchers._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}

class TestResponseFromUnsupportedApis extends OharaTest {
  private[this] val configurator = Configurator.builder.fake().build()

  private[this] implicit val actorSystem: ActorSystem = ActorSystem("Executor-TestResponseFromUnsupportedApis")

  private[this] val expectedMessage = oharastream.ohara.configurator.route.apiUrl

  private[this] def result[T](f: Future[T]): T = Await.result(f, Duration(20, TimeUnit.SECONDS))

  @Test
  def testGet(): Unit = sendRequest(HttpMethods.GET, CommonUtils.randomString()).apiUrl.get shouldBe expectedMessage

  @Test
  def testPut(): Unit = sendRequest(HttpMethods.PUT, CommonUtils.randomString()).apiUrl.get shouldBe expectedMessage

  @Test
  def testDelete(): Unit =
    sendRequest(HttpMethods.DELETE, CommonUtils.randomString()).apiUrl.get shouldBe expectedMessage

  @Test
  def testPost(): Unit = sendRequest(HttpMethods.POST, CommonUtils.randomString()).apiUrl.get shouldBe expectedMessage

  private[this] def sendRequest(method: HttpMethod, postfix: String): ErrorApi.Error =
    result(
      Http()
        .singleRequest(HttpRequest(method, s"http://${configurator.hostname}:${configurator.port}/$postfix"))
        .flatMap { response =>
          if (response.status.isSuccess()) Future.failed(new AssertionError())
          else Unmarshal(response.entity).to[ErrorApi.Error]
        }
    )

  @After
  def tearDown(): Unit = {
    Releasable.close(configurator)
    result(actorSystem.terminate())
  }
} 
Example 44
Source File: HttpServiceIntegrationTest.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.http

import java.io.File
import java.nio.file.Files

import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpMethods, HttpRequest, StatusCodes, Uri}
import com.daml.http.Statement.discard
import com.daml.http.util.TestUtil.writeToFile
import org.scalacheck.Gen
import org.scalatest.{Assertion, BeforeAndAfterAll}

import scala.concurrent.Future

class HttpServiceIntegrationTest extends AbstractHttpServiceIntegrationTest with BeforeAndAfterAll {

  private val staticContent: String = "static"

  private val staticContentDir: File =
    Files.createTempDirectory("integration-test-static-content").toFile

  override def staticContentConfig: Option[StaticContentConfig] =
    Some(StaticContentConfig(prefix = staticContent, directory = staticContentDir))

  override def jdbcConfig: Option[JdbcConfig] = None

  private val expectedDummyContent: String = Gen
    .listOfN(100, Gen.identifier)
    .map(_.mkString(" "))
    .sample
    .getOrElse(throw new IllegalStateException(s"Cannot create dummy text content"))

  private val dummyFile: File =
    writeToFile(new File(staticContentDir, "dummy.txt"), expectedDummyContent).get
  require(dummyFile.exists)

  override protected def afterAll(): Unit = {
    // clean up temp directory
    discard { dummyFile.delete() }
    discard { staticContentDir.delete() }
    super.afterAll()
  }

  "should serve static content from configured directory" in withHttpService { (uri: Uri, _, _) =>
    Http()
      .singleRequest(
        HttpRequest(
          method = HttpMethods.GET,
          uri = uri.withPath(Uri.Path(s"/$staticContent/${dummyFile.getName}"))))
      .flatMap { resp =>
        discard { resp.status shouldBe StatusCodes.OK }
        val bodyF: Future[String] = getResponseDataBytes(resp, debug = false)
        bodyF.flatMap { body =>
          body shouldBe expectedDummyContent
        }
      }: Future[Assertion]
  }

  "Forwarded" - {
    import Endpoints.Forwarded
    "can 'parse' sample" in {
      Forwarded("for=192.168.0.1;proto=http;by=192.168.0.42").proto should ===(Some("http"))
    }

    "can 'parse' quoted sample" in {
      Forwarded("for=192.168.0.1;proto = \"https\" ;by=192.168.0.42").proto should ===(
        Some("https"))
    }
  }
} 
Example 45
Source File: Registry.scala    From kanadi   with MIT License 5 votes vote down vote up
package org.zalando.kanadi.api

import java.net.URI

import defaults._
import akka.http.scaladsl.HttpExt
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.{ContentTypes, HttpMethods, HttpRequest, Uri}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.Materializer
import com.typesafe.scalalogging.{Logger, LoggerTakingImplicit}
import de.heikoseeberger.akkahttpcirce.ErrorAccumulatingCirceSupport._
import org.mdedetrich.webmodels.{FlowId, OAuth2TokenProvider}
import org.mdedetrich.webmodels.RequestHeaders.`X-Flow-ID`
import org.zalando.kanadi.models._

import scala.concurrent.{ExecutionContext, Future}

case class Registry(baseUri: URI, oAuth2TokenProvider: Option[OAuth2TokenProvider] = None)(implicit
                                                                                           kanadiHttpConfig: HttpConfig,
                                                                                           http: HttpExt,
                                                                                           materializer: Materializer)
    extends RegistryInterface {
  protected val logger: LoggerTakingImplicit[FlowId] = Logger.takingImplicit[FlowId](classOf[Registry])
  private val baseUri_                               = Uri(baseUri.toString)

  
  def partitionStrategies(implicit flowId: FlowId = randomFlowId(),
                          executionContext: ExecutionContext): Future[List[PartitionStrategy]] = {
    val uri =
      baseUri_.withPath(baseUri_.path / "registry" / "partition-strategies")

    val baseHeaders = List(RawHeader(`X-Flow-ID`, flowId.value))

    for {
      headers <- oAuth2TokenProvider match {
                  case None => Future.successful(baseHeaders)
                  case Some(futureProvider) =>
                    futureProvider.value().map { oAuth2Token =>
                      toHeader(oAuth2Token) +: baseHeaders
                    }
                }
      request  = HttpRequest(HttpMethods.GET, uri, headers)
      _        = logger.debug(request.toString)
      response <- http.singleRequest(request)
      result <- {
        if (response.status.isSuccess()) {
          Unmarshal(response.entity.httpEntity.withContentType(ContentTypes.`application/json`))
            .to[List[PartitionStrategy]]
        } else
          processNotSuccessful(request, response)
      }
    } yield result
  }

} 
Example 46
Source File: GeneralError.scala    From kanadi   with MIT License 5 votes vote down vote up
package org.zalando.kanadi.models

import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import org.mdedetrich.webmodels.Problem

class GeneralError(val problem: Problem, override val httpRequest: HttpRequest, override val httpResponse: HttpResponse)
    extends HttpServiceError(httpRequest, httpResponse, Right(problem)) {
  override def getMessage: String = s"Error from server, response is $problem"
}

final case class OtherError(error: BasicServerError) extends Exception {
  override def getMessage: String = s"Error from server, response is $error"
}

class ExpectedHeader(val headerName: String,
                     override val httpRequest: HttpRequest,
                     override val httpResponse: HttpResponse)
    extends HttpServiceError(httpRequest, httpResponse, Left("")) {
  override def getMessage: String =
    s"Expected header with name: $headerName, request is $httpRequest, response is $httpResponse"
} 
Example 47
Source File: Client.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.examples.akka.http

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.stream.scaladsl.{Sink, Source}
import io.opencensus.scala.akka.http.TracingClient
import org.slf4j.bridge.SLF4JBridgeHandler

import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success}

object Client extends App {
  // Forward java.util.Logging to slf4j
  SLF4JBridgeHandler.removeHandlersForRootLogger()
  SLF4JBridgeHandler.install()

  implicit val system: ActorSystem = ActorSystem()
  import system.dispatcher

  def await[T](f: Future[T]) = Await.result(f, 3.seconds)

  // Request level client
  val pipeling = Http().singleRequest(_: HttpRequest)
  val r1 = await {
    TracingClient
      .traceRequest(pipeling)(HttpRequest(uri = "http://localhost:8080"))
      .flatMap(_.entity.toStrict(1.second))
      .map(_.data.utf8String)
  }
  println(r1)

  // Host level client
  val pool     = Http().cachedHostConnectionPool[Unit]("localhost", 8080)
  val hostFlow = TracingClient.traceRequestForPool(pool)

  val r2 = await {
    Source
      .single(HttpRequest(uri = "/"))
      .map((_, ()))
      .via(hostFlow)
      .map(_._1)
      .flatMapConcat {
        case Success(response) => response.entity.dataBytes
        case Failure(e)        => throw e
      }
      .map(_.utf8String)
      .runWith(Sink.head)
  }
  println(r2)

  // Connection level client
  val connection     = Http().outgoingConnection("localhost", 8080)
  val connectionFlow = TracingClient.traceRequestForConnection(connection)

  val r3 = await {
    Source
      .single(HttpRequest(uri = "/"))
      .via(connectionFlow)
      .flatMapConcat(_.entity.dataBytes)
      .map(_.utf8String)
      .runWith(Sink.head)
  }
  println(r3)
} 
Example 48
Source File: TracingDirective.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.akka.http

import akka.http.scaladsl.model.{HttpHeader, HttpRequest}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{Directive0, Directive1, ExceptionHandler}
import com.typesafe.scalalogging.LazyLogging
import io.opencensus.scala.Tracing
import io.opencensus.scala.akka.http.propagation.AkkaB3FormatPropagation
import io.opencensus.scala.akka.http.trace.EndSpanResponse
import io.opencensus.scala.akka.http.trace.HttpExtractors._
import io.opencensus.scala.http.{HttpAttributes, ServiceAttributes, ServiceData}
import io.opencensus.scala.http.propagation.Propagation
import io.opencensus.trace.{Span, Status}

import scala.util.control.NonFatal

trait TracingDirective extends LazyLogging {

  protected def tracing: Tracing
  protected def propagation: Propagation[HttpHeader, HttpRequest]

  
  def traceRequestForServiceNoSpan(serviceData: ServiceData): Directive0 =
    traceRequest(serviceData).map(_ => ())

  private def traceRequest(serviceData: ServiceData): Directive1[Span] =
    extractRequest.flatMap { req =>
      val span = buildSpan(req, serviceData)
      recordSuccess(span) & recordException(span) & provide(span)
    }

  private def buildSpan(req: HttpRequest, serviceData: ServiceData): Span = {
    val name = req.uri.path.toString()

    val span = propagation
      .extractContext(req)
      .fold(
        { error =>
          logger.debug("Extracting of parent context failed", error)
          tracing.startSpan(name)
        },
        tracing.startSpanWithRemoteParent(name, _)
      )

    ServiceAttributes.setAttributesForService(span, serviceData)
    HttpAttributes.setAttributesForRequest(span, req)
    span
  }

  private def recordSuccess(span: Span) =
    mapResponse(EndSpanResponse.forServer(tracing, _, span))

  private def recordException(span: Span) =
    handleExceptions(ExceptionHandler {
      case NonFatal(ex) =>
        tracing.endSpan(span, Status.INTERNAL)
        throw ex
    })
}

object TracingDirective extends TracingDirective {
  override protected def tracing: Tracing = Tracing
  override protected def propagation: Propagation[HttpHeader, HttpRequest] =
    AkkaB3FormatPropagation
} 
Example 49
Source File: StatsClient.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.akka.http

import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import com.typesafe.scalalogging.LazyLogging
import io.opencensus.scala.Stats
import io.opencensus.scala.akka.http.stats.HttpStats
import io.opencensus.scala.akka.http.utils.ExecuteAfterResponse

import scala.concurrent.{ExecutionContext, Future}

trait StatsClient extends HttpStats with LazyLogging {

  
  def recorded(
      doRequest: HttpRequest => Future[HttpResponse],
      routeName: String
  )(
      implicit ec: ExecutionContext
  ): HttpRequest => Future[HttpResponse] = req => {
    val start = System.currentTimeMillis()

    doRequest(req).map(response =>
      ExecuteAfterResponse.onComplete(
        response,
        onFinish = () =>
          measureClientRoundtripLatency(
            routeName,
            req.method,
            response.status,
            (System.currentTimeMillis() - start).toDouble
          ).fold(
            error => logger.warn("Failed to measure server latency", error),
            identity
          ),
        onFailure = _ => ()
      )
    )
  }
}

object StatsClient extends StatsClient {
  override private[http] val stats = Stats
} 
Example 50
Source File: HttpExtractors.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.akka.http.trace

import akka.http.scaladsl.model.headers.{Host, `User-Agent`}
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import io.opencensus.scala.http.{RequestExtractor, ResponseExtractor}

object HttpExtractors {

  implicit val requestExtractor: RequestExtractor[HttpRequest] =
    new RequestExtractor[HttpRequest] {
      override def host(req: HttpRequest): String = {
        if (req.uri.isAbsolute)
          req.uri.authority.host.address()
        else
          req
            .header[Host]
            .map(_.value())
            // Having no Host header with a relative URL is invalid according to rfc2616,
            // but Akka-HTTP still allows to create such HttpRequests.
            .getOrElse("")
      }

      override def method(req: HttpRequest): String = req.method.value

      override def path(req: HttpRequest): String = req.uri.path.toString()

      override def userAgent(req: HttpRequest): Option[String] =
        req
          .header[`User-Agent`]
          .map(_.value())
    }

  implicit val responseExtractor: ResponseExtractor[HttpResponse] =
    (res: HttpResponse) => res.status.intValue().toLong
} 
Example 51
Source File: StatsDirective.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.akka.http

import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directive0
import akka.http.scaladsl.server.Directives._
import com.typesafe.scalalogging.LazyLogging
import io.opencensus.scala.Stats
import io.opencensus.scala.akka.http.stats.HttpStats
import io.opencensus.scala.akka.http.utils.ExecuteAfterResponse

trait StatsDirective extends HttpStats with LazyLogging {

  
  def recordRequest(routeName: String): Directive0 =
    extractRequest.flatMap { req =>
      val startTime = System.currentTimeMillis()

      record(req, routeName, startTime)
    }

  private def record(req: HttpRequest, routeName: String, startTime: Long) =
    mapResponse(res =>
      ExecuteAfterResponse
        .onComplete(
          res,
          onFinish = () =>
            measureServerLatency(
              routeName,
              req.method,
              res.status,
              (System.currentTimeMillis() - startTime).toDouble
            ).fold(
              error => logger.warn("Failed to measure server latency", error),
              identity
            ),
          onFailure = _ => ()
        )
    )
}

object StatsDirective extends StatsDirective {
  override private[http] val stats = Stats
} 
Example 52
Source File: StatsClientSpec.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.akka.http

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import io.opencensus.scala.http.testSuite.MockStats
import io.opencensus.scala.stats.{Distribution, MeasurementDouble}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers

import scala.concurrent.Future

class StatsClientSpec
    extends AsyncFlatSpec
    with BeforeAndAfterAll
    with Matchers {
  implicit val system: ActorSystem = ActorSystem()

  def statsClientWithMock: (StatsClient, MockStats) = {
    val mockStats = new MockStats
    val client = new StatsClient {
      override private[http] val stats = mockStats
    }

    (client, mockStats)
  }

  it should "register the correct view" in {
    val (client, mock) = statsClientWithMock

    val doRequest =
      client.recorded(_ => Future.successful(HttpResponse()), "routeName")

    doRequest(HttpRequest()).flatMap(_.discardEntityBytes().future()).map { _ =>
      mock.registeredViews should have length 1

      val roundtripLatency = mock.registeredViews.head

      roundtripLatency.name shouldBe "opencensus.io/http/client/roundtrip_latency"
      roundtripLatency.measure.name shouldBe "opencensus.io/http/client/roundtrip_latency"
      roundtripLatency.aggregation shouldBe a[Distribution]
    }
  }
  it should "record the correct measure value" in {
    val (client, mock) = statsClientWithMock

    val doRequest =
      client.recorded(_ => Future.successful(HttpResponse()), "routeName")

    doRequest(HttpRequest()).flatMap(_.discardEntityBytes().future()).map { _ =>
      val (measurement, _) = mock.recordedMeasurements.head

      measurement match {
        case MeasurementDouble(measure, value) =>
          measure.name shouldBe "opencensus.io/http/client/roundtrip_latency"
          value.toInt shouldBe >(0)
        case other => fail(s"Expected MeasurementDouble got $other")
      }
    }
  }

  it should "record the correct measure tags" in {
    val (client, mock) = statsClientWithMock

    val doRequest =
      client.recorded(_ => Future.successful(HttpResponse()), "routeName")

    doRequest(HttpRequest()).flatMap(_.discardEntityBytes().future()).map { _ =>
      mock.recordedMeasurements should have length 1
      val (_, tags) = mock.recordedMeasurements.head

      val tagsKeyValues =
        tags.map(tag => (tag.key.getName, tag.value.asString()))

      val expectedTags = List(
        "http_client_method" -> "GET",
        "http_client_route"  -> "routeName",
        "http_client_status" -> "200"
      )

      tagsKeyValues should contain theSameElementsAs expectedTags
    }
  }

  override def afterAll(): Unit = {
    system.terminate()
    super.afterAll()
  }
} 
Example 53
Source File: HttpAkkaAttributesSpec.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.akka.http.trace

import akka.http.scaladsl.model.headers.{Host, `User-Agent`}
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import io.opencensus.scala.http.HttpAttributesSpec

class HttpAkkaAttributesSpec extends HttpAttributesSpec {
  import HttpExtractors._

  "Akka http attributes extraction" should behave like httpAttributes(
    request,
    response
  )

  def request: BuildRequest => HttpRequest =
    (request: BuildRequest) =>
      HttpRequest(
        uri = request.host ++ request.path,
        headers = List(`User-Agent`(request.userAgent)) ++ request.hostHeader
          .map(Host(_))
      )

  def response: Int => HttpResponse = HttpResponse(_)
} 
Example 54
Source File: CompositeHttpService.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http

import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.RouteResult.Complete
import akka.http.scaladsl.server.directives.{DebuggingDirectives, LoggingMagnet}
import akka.http.scaladsl.server.{Directive0, Route, RouteResult}
import com.wavesplatform.dex.Application
import com.wavesplatform.dex.api.routes.ApiRoute
import com.wavesplatform.dex.domain.utils.ScorexLogging
import com.wavesplatform.dex.settings.RestAPISettings

class CompositeHttpService(apiTypes: Set[Class[_]], routes: Seq[ApiRoute], settings: RestAPISettings) extends ScorexLogging {

  private val swaggerService    = new SwaggerDocService(apiTypes, s"${settings.address}:${settings.port}")
  private val redirectToSwagger = redirect("/api-docs/index.html", StatusCodes.PermanentRedirect)
  private val swaggerRoute: Route = swaggerService.routes ~
    (pathEndOrSingleSlash | path("swagger"))(redirectToSwagger) ~
    pathPrefix("api-docs") {
      pathEndOrSingleSlash(redirectToSwagger) ~
        getFromResourceDirectory(s"META-INF/resources/webjars/swagger-ui/${SwaggerUiVersion.VersionString}", Application.getClass.getClassLoader)
    }

  val compositeRoute: Route        = extendRoute(routes.map(_.route).reduce(_ ~ _)) ~ swaggerRoute ~ complete(StatusCodes.NotFound)
  val loggingCompositeRoute: Route = DebuggingDirectives.logRequestResult(LoggingMagnet(_ => logRequestResponse))(compositeRoute)

  private def logRequestResponse(req: HttpRequest)(res: RouteResult): Unit = res match {
    case Complete(resp) =>
      val msg = s"HTTP ${resp.status.value} from ${req.method.value} ${req.uri}"
      if (resp.status == StatusCodes.OK) log.info(msg) else log.warn(msg)
    case _ =>
  }

  private val corsAllowedHeaders = (if (settings.apiKeyDifferentHost) List("api_key", "X-API-Key") else List.empty[String]) ++
    Seq("Authorization", "Content-Type", "X-Requested-With", "Timestamp", "Signature")

  private def corsAllowAll: Directive0 = if (settings.cors) respondWithHeader(`Access-Control-Allow-Origin`.*) else pass

  private def extendRoute(base: Route): Route =
    if (settings.cors) { ctx =>
      val extendedRoute = corsAllowAll(base) ~ options {
        respondWithDefaultHeaders(
          `Access-Control-Allow-Credentials`(true),
          `Access-Control-Allow-Headers`(corsAllowedHeaders),
          `Access-Control-Allow-Methods`(OPTIONS, POST, PUT, GET, DELETE)
        )(corsAllowAll(complete(StatusCodes.OK)))
      }

      extendedRoute(ctx)
    } else base
} 
Example 55
Source File: akkaHttp.scala    From sup   with Apache License 2.0 5 votes vote down vote up
package sup.modules

import akka.http.scaladsl.marshalling.ToEntityMarshaller
import akka.http.scaladsl.model.StatusCode
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives.{path => akkaPath, _}
import akka.http.scaladsl.server.Route
import cats.effect.Effect
import cats.syntax.functor._
import cats.syntax.reducible._
import cats.~>
import cats.Functor
import cats.Reducible
import sup.HealthCheck
import sup.HealthResult

import scala.concurrent.Future
import scala.util.Failure
import scala.util.Success
import akka.http.scaladsl.model.HttpRequest

object akkahttp {

  
  def healthCheckRoutes[F[_]: Effect, H[_]: Reducible](
    healthCheck: HealthCheck[F, H],
    path: String = "health-check"
  )(
    implicit marshaller: ToEntityMarshaller[HealthResult[H]]
  ): Route =
    akkaPath(path) {
      get {
        onComplete(Effect[F].toIO(healthCheckResponse(healthCheck)).unsafeToFuture()) {
          case Success(response) => complete(response)
          case Failure(error)    => failWith(error)
        }
      }
    }

  def healthCheckResponse[F[_]: Functor, H[_]: Reducible](
    healthCheck: HealthCheck[F, H]
  ): F[(StatusCode, HealthResult[H])] =
    healthCheck.check.map { check =>
      if (check.value.reduce.isHealthy) StatusCodes.OK -> check
      else StatusCodes.ServiceUnavailable -> check
    }

  def healthCheckRoutesWithContext[F[_]: Functor, H[_]: Reducible, R](
    healthCheck: HealthCheck[F, H],
    path: String = "health-check"
  )(
    run: HttpRequest => F ~> Future
  )(
    implicit marshaller: ToEntityMarshaller[HealthResult[H]]
  ): Route =
    akkaPath(path) {
      get {
        extractRequest { request =>
          onComplete(run(request)(healthCheckResponse(healthCheck))) {
            case Success(response) => complete(response)
            case Failure(error)    => failWith(error)
          }
        }
      }
    }
} 
Example 56
Source File: ScoresApiSupport.scala    From avoin-voitto   with MIT License 5 votes vote down vote up
package liigavoitto.scores

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.stream.ActorMaterializer
import liigavoitto.util.Logging
import org.joda.time.format.DateTimeFormat

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.util.{ Failure, Properties, Success, Try }

trait ScoresApiSupport extends Logging {
  implicit val system: ActorSystem
  implicit val ec = system.dispatcher
  implicit val fm = ActorMaterializer()

  val oneHundredMegabytes = 100000000

  val apiUrl = Properties.envOrElse("SCORES_API_URL", "http://scores.api.yle.fi/v0/")
  val scoresAuth = Map[String, String](
    "app_id" -> Properties.envOrElse("SCORES_API_APP_ID", ""),
    "app_key" -> Properties.envOrElse("SCORES_API_APP_KEY", "")
  )
  val dateFormat = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss")
  val timeout = 15.seconds

  protected def get(url: String) = {
    Try {
      val request = HttpRequest(GET, url)
      log.info("REQUEST: " + request)
      Http().singleRequest(request).map(r => getStr(r))
    } match {
      case Success(s) => s
      case Failure(e) =>
        log.warn(s"Failed to get $url: " + e.getMessage)
        e.printStackTrace()
        throw new RuntimeException("Failure: " + e)
    }
  }

  protected def getStr(r: HttpResponse) = {
    Try {
      val entity = Await.result(r.entity.withSizeLimit(oneHundredMegabytes).toStrict(timeout), timeout)
      entity.data.decodeString("UTF-8")
    } match {
      case Success(s) => s
      case Failure(e) => throw new RuntimeException(s"Scores api failure: " + e.getMessage)
    }
  }
} 
Example 57
Source File: ReliableHttpProxyFactory.scala    From reliable-http-client   with Apache License 2.0 5 votes vote down vote up
package rhttpc.akkahttp.proxy

import akka.NotUsed
import akka.actor._
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, HttpResponse}
import akka.stream.Materializer
import akka.stream.scaladsl.{Flow, Sink, Source}
import org.slf4j.LoggerFactory
import rhttpc.client.protocol.{Correlated, Request}
import rhttpc.client.proxy._

import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal
import scala.util.{Failure, Success}

object ReliableHttpProxyFactory {

  private lazy val logger = LoggerFactory.getLogger(getClass)

  def send(successRecognizer: SuccessHttpResponseRecognizer, batchSize: Int, parallelConsumers: Int)
          (request: Request[HttpRequest])
          (implicit actorSystem: ActorSystem, materialize: Materializer): Future[HttpResponse] = {
    import actorSystem.dispatcher
    send(prepareHttpFlow(batchSize * parallelConsumers), successRecognizer)(request.correlated)
  }

  private def prepareHttpFlow(parallelism: Int)
                             (implicit actorSystem: ActorSystem, materialize: Materializer):
    Flow[(HttpRequest, String), HttpResponse, NotUsed] = {

    import actorSystem.dispatcher
    Http().superPool[String]().mapAsync(parallelism) {
      case (tryResponse, id) =>
        tryResponse match {
          case Success(response) =>
            response.toStrict(1 minute)
          case Failure(ex) =>
            Future.failed(ex)
        }
    }
  }

  private def send(httpFlow: Flow[(HttpRequest, String), HttpResponse, Any], successRecognizer: SuccessHttpResponseRecognizer)
                  (corr: Correlated[HttpRequest])
                  (implicit ec: ExecutionContext, materialize: Materializer): Future[HttpResponse] = {
    import collection.JavaConverters._
    logger.debug(
      s"""Sending request for ${corr.correlationId} to ${corr.msg.getUri()}. Headers:
         |${corr.msg.getHeaders().asScala.toSeq.map(h => "  " + h.name() + ": " + h.value()).mkString("\n")}
         |Body:
         |${corr.msg.entity.asInstanceOf[HttpEntity.Strict].data.utf8String}""".stripMargin
    )
    val logResp = logResponse(corr) _
    val responseFuture = Source.single((corr.msg, corr.correlationId)).via(httpFlow).runWith(Sink.head)
    responseFuture.onComplete {
      case Failure(ex) =>
        logger.error(s"Got failure for ${corr.correlationId} to ${corr.msg.getUri()}", ex)
      case Success(_) =>
    }
    for {
      response <- responseFuture
      transformedToFailureIfNeed <- {
        if (successRecognizer.isSuccess(response)) {
          logResp(response, "success response")
          Future.successful(response)
        } else {
          logResp(response, "response recognized as non-success")
          Future.failed(NonSuccessResponse)
        }
      }
    } yield transformedToFailureIfNeed
  }

  private def logResponse(corr: Correlated[HttpRequest])
                         (response: HttpResponse, additionalInfo: String): Unit = {
    import collection.JavaConverters._
    logger.debug(
      s"""Got $additionalInfo for ${corr.correlationId} to ${corr.msg.getUri()}. Status: ${response.status.value}. Headers:
         |${response.getHeaders().asScala.toSeq.map(h => "  " + h.name() + ": " + h.value()).mkString("\n")}
         |Body:
         |${response.entity.asInstanceOf[HttpEntity.Strict].data.utf8String}""".stripMargin
    )
  }

} 
Example 58
Source File: package.scala    From reliable-http-client   with Apache License 2.0 5 votes vote down vote up
package rhttpc

import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import org.json4s.Formats
import rhttpc.akkahttp.json4s._
import rhttpc.client.proxy.ReliableProxy
import rhttpc.client.{InOnlyReliableClient, InOutReliableClient}
import rhttpc.transport.json4s.CommonFormats

package object akkahttp {
  type InOutReliableHttpClient = InOutReliableClient[HttpRequest]
  type InOnlyReliableHttpClient = InOnlyReliableClient[HttpRequest]
  type ReliableHttpProxy = ReliableProxy[HttpRequest, HttpResponse]

  implicit val formats: Formats =
    CommonFormats.formats +
      ContentTypeSerializer +
      ByteStringSerializer +
      UriSerializer

} 
Example 59
Source File: AmqpSubscriberPerfSpec.scala    From reliable-http-client   with Apache License 2.0 5 votes vote down vote up
package rhttpc.transport.amqp

import akka.Done
import akka.actor.{Actor, ActorSystem, Props}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.pattern._
import akka.stream.ActorMaterializer
import akka.testkit.{TestKit, TestProbe}
import dispatch.url
import org.scalatest.{BeforeAndAfterAll, FlatSpecLike, Ignore}
import rhttpc.transport.{Deserializer, InboundQueueData, OutboundQueueData, Serializer}

import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
import scala.util.{Random, Try}

@Ignore
class AmqpSubscriberPerfSpec extends TestKit(ActorSystem("AmqpSubscriberPerfSpec")) with FlatSpecLike with BeforeAndAfterAll {
  import system.dispatcher

  implicit val materializer = ActorMaterializer()

  implicit def serializer[Msg] = new Serializer[Msg] {
    override def serialize(obj: Msg): String = obj.toString
  }

  implicit def deserializer[Msg] = new Deserializer[Msg] {
    override def deserialize(value: String): Try[Msg] = Try(value.asInstanceOf[Msg])
  }

  val queueName = "request"
  val outboundQueueData = OutboundQueueData(queueName, autoDelete = true, durability = false)
  val inboundQueueData = InboundQueueData(queueName, batchSize = 10, parallelConsumers = 10, autoDelete = true, durability = false)
  val count = 100

  private val interface = "localhost"
  private val port = 8081

  def handle(request: HttpRequest) = {
    val delay = 5 + Random.nextInt(10)
    after(delay.seconds, system.scheduler)(Future.successful(HttpResponse()))
  }

  it should "have a good throughput" in {
    val bound = Await.result(
      Http().bindAndHandleAsync(
        handle, interface, port
      ),
      5.seconds
    )
    val http = dispatch.Http()
//      .configure(_.setMaxConnections(count)
//        .setExecutorService(Executors.newFixedThreadPool(count)))

    val connection = Await.result(AmqpConnectionFactory.connect(system), 5 seconds)
    val transport = AmqpTransport(
      connection = connection
    )
    val publisher = transport.publisher[String](outboundQueueData)
    val probe = TestProbe()
    val actor = system.actorOf(Props(new Actor {
      override def receive: Receive = {
        case str: String =>
          http(url(s"http://$interface:$port") OK identity).map(_ => Done).pipeTo(self)(sender())
        case Done =>
          probe.ref ! Done
          sender() ! Done
      }
    }))
    val subscriber = transport.subscriber[String](inboundQueueData, actor)
    subscriber.start()

    try {
      measureMeanThroughput(count) {
        (1 to count).foreach { _ => publisher.publish("x") }

        probe.receiveWhile(10 minutes, messages = count) { case a => a }
      }
    } finally {
      Await.result(subscriber.stop(), 5.seconds)
      connection.close(5 * 1000)
      Await.result(bound.unbind(), 5.seconds)
    }
  }

  def measureMeanThroughput(count: Int)(consume: => Unit) = {
    val before = System.currentTimeMillis()
    consume
    val msgsPerSecond = count / ((System.currentTimeMillis() - before).toDouble / 1000)
    println(s"Throughput was: $msgsPerSecond msgs/sec")
  }

  override protected def afterAll(): Unit = {
    shutdown()
  }
} 
Example 60
Source File: JacksonSupport.scala    From Sidechains-SDK   with MIT License 5 votes vote down vote up
package com.horizen.api.http

import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.unmarshalling._
import akka.stream.Materializer
import com.fasterxml.jackson.databind._
import com.fasterxml.jackson.module.scala.DefaultScalaModule

import scala.concurrent.{ExecutionContext, Future}
import scala.reflect.ClassTag
import scala.language.postfixOps

object JacksonSupport {

  private val mapper = new ObjectMapper().registerModule(DefaultScalaModule)

  implicit def JacksonRequestUnmarshaller[T <: AnyRef](implicit c: ClassTag[T]): FromRequestUnmarshaller[T] = {
    new FromRequestUnmarshaller[T] {
      override def apply(request: HttpRequest)(implicit ec: ExecutionContext, materializer: Materializer): Future[T] = {
        Unmarshal(request.entity).to[String].map(str => {
          if (str.isEmpty) mapper.readValue("{}", c.runtimeClass).asInstanceOf[T]
          else mapper.readValue(str, c.runtimeClass).asInstanceOf[T]
        })
      }
    }
  }
} 
Example 61
Source File: HttpRequestFactory.scala    From hydra   with Apache License 2.0 5 votes vote down vote up
package hydra.ingest.http

import akka.http.scaladsl.model.{HttpMethods, HttpRequest}
import akka.http.scaladsl.server.directives.CodingDirectives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.Materializer
import hydra.core.ingest.RequestParams._
import hydra.core.ingest._
import hydra.core.transport.{AckStrategy, ValidationStrategy}

import scala.concurrent.Future
import scala.util.Success


class HttpRequestFactory
    extends RequestFactory[HttpRequest]
    with CodingDirectives {

  override def createRequest(correlationId: String, request: HttpRequest)(
      implicit mat: Materializer
  ): Future[HydraRequest] = {
    implicit val ec = mat.executionContext

    lazy val vs = request.headers
      .find(_.lowercaseName() == HYDRA_VALIDATION_STRATEGY)
      .map(h => ValidationStrategy(h.value()))
      .getOrElse(ValidationStrategy.Strict)

    lazy val as = request.headers
      .find(_.lowercaseName() == HYDRA_ACK_STRATEGY)
      .map(h => AckStrategy(h.value()))
      .getOrElse(Success(AckStrategy.NoAck))

    lazy val clientId = request.headers
      .find(_.lowercaseName() == HydraClientId)
      .map(_.value().toLowerCase)

    Unmarshal(request.entity).to[String].flatMap { payload =>
      val dPayload = if (request.method == HttpMethods.DELETE) null else payload
      val metadata: Map[String, String] =
        request.headers.map(h => h.name.toLowerCase -> h.value).toMap
      Future
        .fromTry(as)
        .map(ack =>
          HydraRequest(correlationId, dPayload, clientId, metadata, vs, ack)
        )
    }
  }
} 
Example 62
Source File: RequestFactories.scala    From hydra   with Apache License 2.0 5 votes vote down vote up
package hydra.ingest.bootstrap

import akka.http.scaladsl.model.HttpRequest
import akka.stream.Materializer
import hydra.core.ingest.{HydraRequest, RequestFactory}
import hydra.ingest.http.HttpRequestFactory

import scala.concurrent.Future


object RequestFactories {

  implicit object RequestFactoryLikeHttp extends RequestFactory[HttpRequest] {

    override def createRequest(correlationId: String, source: HttpRequest)(
        implicit mat: Materializer
    ): Future[HydraRequest] = {
      implicit val ec = mat.executionContext
      new HttpRequestFactory().createRequest(correlationId, source)
    }
  }

  def createRequest[D](
      correlationId: String,
      source: D
  )(implicit ev: RequestFactory[D], mat: Materializer): Future[HydraRequest] = {
    ev.createRequest(correlationId, source)
  }
} 
Example 63
Source File: RequestFactoriesSpec.scala    From hydra   with Apache License 2.0 5 votes vote down vote up
package hydra.ingest.bootstrap

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpRequest
import akka.stream.ActorMaterializer
import akka.testkit.TestKit
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.matchers.should.Matchers
import org.scalatest.funspec.AnyFunSpecLike
import org.scalatest.BeforeAndAfterAll

import scala.concurrent.duration._

class RequestFactoriesSpec
    extends TestKit(ActorSystem("RequestFactoriesSpec"))
    with Matchers
    with AnyFunSpecLike
    with BeforeAndAfterAll
    with ScalaFutures {

  override def afterAll =
    TestKit.shutdownActorSystem(
      system,
      verifySystemShutdown = true,
      duration = 10.seconds
    )

  import RequestFactories._

  describe("The RequestFactories") {
    it("build a Hydra request from an HTTP request") {
      val hr = HttpRequest(entity = "test")
      val hydraReq = createRequest("1", hr)
      whenReady(hydraReq) { r => r.payload shouldBe "test" }
    }
  }
} 
Example 64
Source File: GitHub.scala    From akka-api-gateway-example   with MIT License 5 votes vote down vote up
package jp.co.dzl.example.akka.api.service

import akka.NotUsed
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.stream.scaladsl.Flow

trait GitHub {
  def from(original: HttpRequest): Flow[HttpRequest, HttpRequest, NotUsed]
  def send: Flow[HttpRequest, HttpResponse, NotUsed]
}

class GitHubImpl(
    host:       String,
    port:       Int,
    timeout:    Int,
    httpClient: HttpClient
) extends GitHub {
  def from(original: HttpRequest): Flow[HttpRequest, HttpRequest, NotUsed] = Flow[HttpRequest].map { req =>
    val xForwardedHost = original.headers.find(_.is("host")).map(_.value()).getOrElse(s"$host:$port")
    val modifiedHeader = original.addHeader(RawHeader("X-Forwarded-Host", xForwardedHost))
      .headers
      .filterNot(_.lowercaseName() == "host")
      .filterNot(_.lowercaseName() == "timeout-access")

    req.withHeaders(modifiedHeader)
  }

  def send: Flow[HttpRequest, HttpResponse, NotUsed] =
    Flow[HttpRequest].via(httpClient.connectionHttps(host, port, timeout))
} 
Example 65
Source File: GitHubSpec.scala    From akka-api-gateway-example   with MIT License 5 votes vote down vote up
package jp.co.dzl.example.akka.api.service

import akka.actor.ActorSystem
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.{ HttpMethods, HttpRequest, HttpResponse }
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{ Flow, Source }
import akka.stream.testkit.scaladsl.TestSink
import org.scalamock.scalatest.MockFactory
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{ BeforeAndAfterAll, FlatSpec, Matchers }

import scala.concurrent.Await
import scala.concurrent.duration.Duration

class GitHubSpec extends FlatSpec with Matchers with ScalaFutures with BeforeAndAfterAll with MockFactory {
  implicit val system = ActorSystem("github-spec")
  implicit val executor = system.dispatcher
  implicit val materializer = ActorMaterializer()

  override protected def afterAll: Unit = {
    Await.result(system.terminate(), Duration.Inf)
  }

  "#from" should "merge original headers to github request" in {
    val github = new GitHubImpl("127.0.0.1", 8000, 5, mock[HttpClient])
    val request = HttpRequest(HttpMethods.GET, "/")
      .addHeader(RawHeader("host", "dummy"))
      .addHeader(RawHeader("timeout-access", "dummy"))

    val result = Source.single(HttpRequest(HttpMethods.GET, "/v1/github/users/xxxxxx"))
      .via(github.from(request))
      .runWith(TestSink.probe[HttpRequest])
      .request(1)
      .expectNext()

    result.headers.filter(_.lowercaseName() == "host") shouldBe empty
    result.headers.filter(_.lowercaseName() == "timeout-access") shouldBe empty
    result.headers.filter(_.lowercaseName() == "x-forwarded-host") shouldNot be(empty)
  }

  "#send" should "connect using http client" in {
    val httpResponse = HttpResponse()
    val httpClient = mock[HttpClient]
    (httpClient.connectionHttps _).expects(*, *, *).returning(Flow[HttpRequest].map(_ => httpResponse))

    val github = new GitHubImpl("127.0.0.1", 8000, 5, httpClient)
    val result = Source.single(HttpRequest(HttpMethods.GET, "/"))
      .via(github.send)
      .runWith(TestSink.probe[HttpResponse])
      .request(1)
      .expectNext()

    result shouldBe httpResponse
  }
} 
Example 66
Source File: ClickhouseQueryBuilder.scala    From clickhouse-scala-client   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package com.crobox.clickhouse.internal

import akka.http.scaladsl.model.Uri.Query
import akka.http.scaladsl.model.headers.{HttpEncodingRange, RawHeader}
import akka.http.scaladsl.model.{HttpMethods, HttpRequest, RequestEntity, Uri}
import com.crobox.clickhouse.internal.QuerySettings.ReadQueries
import com.crobox.clickhouse.internal.progress.ProgressHeadersAsEventsStage
import com.typesafe.config.Config
import com.typesafe.scalalogging.LazyLogging

import scala.collection.immutable

private[clickhouse] trait ClickhouseQueryBuilder extends LazyLogging {

  private val Headers = {
    import HttpEncodingRange.apply
    import akka.http.scaladsl.model.headers.HttpEncodings.{deflate, gzip}
    import akka.http.scaladsl.model.headers.`Accept-Encoding`
    immutable.Seq(`Accept-Encoding`(gzip, deflate))
  }
  private val MaxUriSize = 16 * 1024

  protected def toRequest(uri: Uri,
                          query: String,
                          queryIdentifier: Option[String],
                          settings: QuerySettings,
                          entity: Option[RequestEntity])(config: Config): HttpRequest = {
    val urlQuery = uri.withQuery(Query(Query("query" -> query) ++ settings.withFallback(config).asQueryParams: _*))
    entity match {
      case Some(e) =>
        logger.debug(s"Executing clickhouse query [$query] on host [${uri
          .toString()}] with entity payload of length ${e.contentLengthOption}")
        HttpRequest(
          method = HttpMethods.POST,
          uri = urlQuery,
          entity = e,
          headers = Headers ++ queryIdentifier.map(RawHeader(ProgressHeadersAsEventsStage.InternalQueryIdentifier, _))
        )
      case None
          if settings.idempotent.contains(true) && settings.readOnly == ReadQueries && urlQuery
            .toString()
            .getBytes
            .length < MaxUriSize => //max url size
        logger.debug(s"Executing clickhouse idempotent query [$query] on host [${uri.toString()}]")
        HttpRequest(
          method = HttpMethods.GET,
          uri = urlQuery.withQuery(
            urlQuery
              .query()
              .filterNot(
                _._1 == "readonly"
              ) //get requests are readonly by default, if we send the readonly flag clickhouse will fail the request
          ),
          headers = Headers ++ queryIdentifier.map(RawHeader(ProgressHeadersAsEventsStage.InternalQueryIdentifier, _))
        )
      case None =>
        logger.debug(s"Executing clickhouse query [$query] on host [${uri.toString()}]")
        HttpRequest(
          method = HttpMethods.POST,
          uri = uri.withQuery(settings.withFallback(config).asQueryParams),
          entity = query,
          headers = Headers ++ queryIdentifier.map(RawHeader(ProgressHeadersAsEventsStage.InternalQueryIdentifier, _))
        )
    }
  }

} 
Example 67
Source File: ProxyServiceWithListAllBuckets.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.marshallers.xml.ScalaXmlSupport
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import com.ing.wbaa.rokku.proxy.data.{ Read, RequestId, S3Request, User }

import scala.xml.NodeSeq


trait ProxyServiceWithListAllBuckets extends ProxyService with ScalaXmlSupport {

  protected[this] def listAllBuckets: Seq[String]

  override protected[this] def processAuthorizedRequest(httpRequest: HttpRequest, s3Request: S3Request, userSTS: User)(implicit id: RequestId): Route = {
    s3Request match {
      //only when list buckets is requested we show all buckets
      case S3Request(_, None, None, accessType, _, _, _) if accessType.isInstanceOf[Read] =>
        complete(getListAllMyBucketsXml())
      case _ => super.processAuthorizedRequest(httpRequest, s3Request, userSTS)
    }
  }

  private def getListAllMyBucketsXml(user: String = "npa", createDate: String = "2018-01-01T00:00:00.000Z"): NodeSeq = {
    <ListAllMyBucketsResult>
      <Owner>
        <ID>{ user }</ID>
        <DisplayName>{ user }</DisplayName>
      </Owner>
      <Buckets>
        { for (bucketName <- listAllBuckets) yield <Bucket><Name>{ bucketName }</Name><CreationDate>{ createDate }</CreationDate></Bucket> }
      </Buckets>
    </ListAllMyBucketsResult>
  }
} 
Example 68
Source File: HttpRequestRecorder.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.persistence

import akka.http.scaladsl.model.{ HttpRequest, RemoteAddress }
import akka.persistence.{ PersistentActor, RecoveryCompleted, SaveSnapshotFailure, SaveSnapshotSuccess, SnapshotOffer }
import com.ing.wbaa.rokku.proxy.data.User
import com.ing.wbaa.rokku.proxy.persistence.HttpRequestRecorder.{ ExecutedRequestCmd, LatestRequests, LatestRequestsResult, Shutdown }
import com.typesafe.config.ConfigFactory
import com.typesafe.scalalogging.LazyLogging

sealed trait Evt
case class ExecutedRequestEvt(httpRequest: HttpRequest, userSTS: User, clientIPAddress: RemoteAddress) extends Evt

object HttpRequestRecorder {
  case class ExecutedRequestCmd(httpRequest: HttpRequest, userSTS: User, clientIPAddress: RemoteAddress)
  case class LatestRequests(amount: Int)
  case class LatestRequestsResult(requests: List[ExecutedRequestEvt])
  case object Shutdown
}

case class CurrentRequestsState(requests: List[ExecutedRequestEvt] = Nil) {
  def add(e: ExecutedRequestEvt): CurrentRequestsState = {
    if (size > 200) { copy(requests.reverse.drop(100)) }
    copy(e :: requests)
  }
  def getRequests(n: Int = 100): List[ExecutedRequestEvt] = this.requests.reverse.take(n)
  def size: Int = requests.size
}

class HttpRequestRecorder extends PersistentActor with LazyLogging {
  var state: CurrentRequestsState = CurrentRequestsState()
  val snapShotInterval = ConfigFactory.load().getInt("rokku.requestPersistence.snapshotInterval")

  private def updateState(e: ExecutedRequestEvt) = state = state.add(e)

  override def persistenceId: String = ConfigFactory.load().getString("rokku.requestPersistence.persistenceId")

  override def receiveRecover: Receive = {
    case e: ExecutedRequestEvt => {
      logger.debug("No snapshot, replying event sequence {}", lastSequenceNr)
      updateState(e)
    }
    case SnapshotOffer(metadata, snapshot: CurrentRequestsState) => {
      logger.debug("Received snapshot offer, timestamp: {} for persistenceId: {} ", metadata.timestamp, metadata.persistenceId)
      state = snapshot
    }
    case RecoveryCompleted => logger.debug("Actor State recovery completed!")
  }

  override def receiveCommand: Receive = {
    case SaveSnapshotSuccess(metadata)  => logger.debug("Snapshot saved successfully, seq: {}", metadata.sequenceNr)

    case SaveSnapshotFailure(_, reason) => logger.error("Failed to save snapshot, reason: {}", reason.getMessage)

    case rc: ExecutedRequestCmd =>
      persist(ExecutedRequestEvt(rc.httpRequest, rc.userSTS, rc.clientIPAddress)) { e =>
        logger.debug("Received event for event sourcing {} from user: {}", e.httpRequest.uri, e.userSTS.userName)
        updateState(e)
        if (lastSequenceNr % snapShotInterval == 0 && lastSequenceNr != 0)
          saveSnapshot(state)
      }

    case get: LatestRequests => sender() ! LatestRequestsResult(state.getRequests(get.amount))

    case Shutdown            => context.stop(self)

    case _                   => logger.debug(s"{} Got unsupported message type", HttpRequestRecorder.getClass.getName)
  }

} 
Example 69
Source File: HttpRequestSerializer.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.persistence.serializers

import java.nio.charset.Charset

import akka.http.scaladsl.model.{ HttpEntity, HttpRequest, RemoteAddress }
import akka.serialization.SerializerWithStringManifest
import com.ing.wbaa.rokku.proxy.data.{ User, UserRawJson }
import com.ing.wbaa.rokku.proxy.persistence.{ CurrentRequestsState, ExecutedRequestEvt }
import spray.json._

class HttpRequestSerializer extends SerializerWithStringManifest with HttpRequestConversionSupport {
  override def identifier: Int = 197642

  val Utf8 = Charset.forName("UTF-8")
  val HttpRequestManifest = classOf[ExecutedRequestEvt].getName
  val HttpRequestsManifest = classOf[CurrentRequestsState].getName

  def simplifiedHttpRequestString(e: HttpRequest) =
    SimplifiedHttpRequest(
      e.method.value,
      e.uri.toString(),
      convertAkkaHeadersToStrings(e.headers),
      HttpEntity.Empty.withContentType(e.entity.contentType).toString(),
      e.protocol.value
    ).toJson.toString

  def userSTSString(u: User) =
    UserRawJson(
      u.userName.value,
      Option(u.userGroups.map(g => g.value)),
      u.accessKey.value,
      u.secretKey.value,
      Option(u.userRole.value)).toJson.toString

  def remoteIPString(a: RemoteAddress) = SimplifiedRemoteAddress(a.value).toJson.toString()

  def toExecutedRequestEvt(r: String) = {
    val Array(hr, u, ip) = r.split("[|]")
    val httpRequest = toAkkaHttpRequest(hr.parseJson.convertTo[SimplifiedHttpRequest])
    val userSTS = User(u.parseJson.convertTo[UserRawJson])
    val simplifiedRemoteAddress = ip.parseJson.convertTo[SimplifiedRemoteAddress]

    ExecutedRequestEvt(httpRequest, userSTS, simplifiedRemoteAddress.toRemoteAddr)
  }

  override def manifest(o: AnyRef): String = o.getClass.getName

  override def toBinary(o: AnyRef): Array[Byte] =
    o match {
      case r: ExecutedRequestEvt =>
        s"${simplifiedHttpRequestString(r.httpRequest)}|${userSTSString(r.userSTS)}|${remoteIPString(r.clientIPAddress)}".getBytes(Utf8)

      case c: CurrentRequestsState =>
        c.requests.map { re =>
          s"${simplifiedHttpRequestString(re.httpRequest)}|${userSTSString(re.userSTS)}|${remoteIPString(re.clientIPAddress)}"
        }.mkString("|-").getBytes(Utf8)

      case e: IllegalArgumentException =>
        throw new IllegalArgumentException(s"Unable to serialize to bytes, class: ${o.getClass} ${e.getMessage}")
    }

  override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = {
    manifest match {
      case s: String if s == HttpRequestManifest =>
        val storedRequest = new String(bytes, Utf8)
        toExecutedRequestEvt(storedRequest)

      case s: String if s == HttpRequestsManifest =>
        val storedRequests = new String(bytes, Utf8)
        val requestsList: List[String] = storedRequests.split("[|-]{2}").toList
        CurrentRequestsState(requestsList.map(toExecutedRequestEvt))

      case _ => throw new IllegalArgumentException(s"Unable to de-serialize from bytes for manifest: $manifest")
    }
  }
} 
Example 70
Source File: HttpRequestConversionSupport.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.persistence.serializers

import java.net.InetAddress

import akka.http.scaladsl.model.HttpHeader.ParsingResult
import akka.http.scaladsl.model.{ HttpEntity, HttpHeader, HttpMethod, HttpMethods, HttpProtocol, HttpRequest, RemoteAddress, Uri }
import com.ing.wbaa.rokku.proxy.data.{ UserAssumeRole, UserRawJson }
import spray.json.DefaultJsonProtocol

import scala.collection.immutable

trait HttpRequestConversionSupport extends DefaultJsonProtocol {

  case class SimplifiedRemoteAddress(host: String) {
    def toRemoteAddr: RemoteAddress = {
      val a = host.split(":")
      RemoteAddress(InetAddress.getByName(a(0)), Some(a(1).toInt))
    }
  }

  case class SimplifiedHttpRequest(method: String, uri: String, headers: List[String], entity: String, httpProtocol: String)

  implicit val httpRequestF = jsonFormat5(SimplifiedHttpRequest)
  implicit val userRoleF = jsonFormat1(UserAssumeRole)
  implicit val userSTSF = jsonFormat5(UserRawJson)
  implicit val remoteAddressF = jsonFormat1(SimplifiedRemoteAddress)

  private[persistence] def convertAkkaHeadersToStrings(headers: Seq[HttpHeader]): List[String] = headers.map(h => s"${h.name()}=${h.value()}").toList

  private def convertStringsToAkkaHeaders(headers: List[String]): immutable.Seq[HttpHeader] = headers.map { p =>
    val kv = p.split("=")
    HttpHeader.parse(kv(0), kv(1)) match {
      case ParsingResult.Ok(header, _) => header
      case ParsingResult.Error(error)  => throw new Exception(s"Unable to convert to HttpHeader: ${error.summary}")
    }
  }

  private def httpMethodFrom(m: String): HttpMethod = m match {
    case "GET"    => HttpMethods.GET
    case "HEAD"   => HttpMethods.HEAD
    case "PUT"    => HttpMethods.PUT
    case "POST"   => HttpMethods.POST
    case "DELETE" => HttpMethods.DELETE
  }

  private[persistence] def toAkkaHttpRequest(s: SimplifiedHttpRequest): HttpRequest =
    HttpRequest(
      httpMethodFrom(s.method),
      Uri(s.uri),
      convertStringsToAkkaHeaders(s.headers),
      HttpEntity(s.entity),
      HttpProtocol(s.httpProtocol)
    )
} 
Example 71
Source File: FilterRecursiveListBucketHandler.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.handler

import java.net.URLDecoder

import akka.NotUsed
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.stream.alpakka.xml.scaladsl.{ XmlParsing, XmlWriting }
import akka.stream.alpakka.xml.{ EndElement, ParseEvent, StartElement, TextEvent }
import akka.stream.scaladsl.Flow
import akka.util.ByteString
import com.ing.wbaa.rokku.proxy.data.{ Read, RequestId, S3Request, User }

import scala.collection.immutable
import scala.collection.mutable.ListBuffer


  protected[this] def filterRecursiveListObjects(user: User, requestS3: S3Request)(implicit id: RequestId): Flow[ByteString, ByteString, NotUsed] = {
    def elementResult(allContentsElements: ListBuffer[ParseEvent], isContentsTag: Boolean, element: ParseEvent): immutable.Seq[ParseEvent] = {
      if (isContentsTag) {
        allContentsElements += element
        immutable.Seq.empty
      } else {
        immutable.Seq(element)
      }
    }

    def isPathOkInRangerPolicy(path: String)(implicit id: RequestId): Boolean = {
      val pathToCheck = normalizePath(path)
      val isUserAuthorized = isUserAuthorizedForRequest(requestS3.copy(s3BucketPath = Some(pathToCheck)), user)
      isUserAuthorized
    }

    def normalizePath(path: String): String = {
      val delimiter = "/"
      val decodedPath = URLDecoder.decode(path, "UTF-8")
      val delimiterIndex = decodedPath.lastIndexOf(delimiter)
      val pathToCheckWithoutLastSlash = if (delimiterIndex > 0) delimiter + decodedPath.substring(0, delimiterIndex) else ""
      val s3BucketName = requestS3.s3BucketPath.getOrElse(delimiter)
      val s3pathWithoutLastDelimiter = if (s3BucketName.length > 1 && s3BucketName.endsWith(delimiter)) s3BucketName.substring(0, s3BucketName.length - 1) else s3BucketName
      s3pathWithoutLastDelimiter + pathToCheckWithoutLastSlash
    }

    Flow[ByteString].via(XmlParsing.parser)
      .statefulMapConcat(() => {
        // state
        val keyTagValue = StringBuilder.newBuilder
        val allContentsElements = new ListBuffer[ParseEvent]
        var isContentsTag = false
        var isKeyTag = false

        // aggregation function
        parseEvent =>
          parseEvent match {
            //catch <Contents> to start collecting elements
            case element: StartElement if element.localName == "Contents" =>
              isContentsTag = true
              allContentsElements.clear()
              allContentsElements += element
              immutable.Seq.empty
            //catch end </Contents> to validate the path in ranger
            case element: EndElement if element.localName == "Contents" =>
              isContentsTag = false
              allContentsElements += element
              if (isPathOkInRangerPolicy(keyTagValue.stripMargin)) {
                allContentsElements.toList
              } else {
                immutable.Seq.empty
              }
            // catch <Key> where is the patch name to match in ranger
            case element: StartElement if element.localName == "Key" =>
              keyTagValue.clear()
              isKeyTag = true
              elementResult(allContentsElements, isContentsTag, element)
            //catch end </Key>
            case element: EndElement if element.localName == "Key" =>
              isKeyTag = false
              elementResult(allContentsElements, isContentsTag, element)
            //catch all element text <..>text<\..> but only set the text from <Key>
            case element: TextEvent =>
              if (isKeyTag) keyTagValue.append(element.text)
              elementResult(allContentsElements, isContentsTag, element)
            //just past through the rest of elements
            case element =>
              elementResult(allContentsElements, isContentsTag, element)
          }
      })
      .via(XmlWriting.writer)
  }

} 
Example 72
Source File: HazelcastCache.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.cache

import akka.http.scaladsl.model.HttpRequest
import akka.util.ByteString
import com.hazelcast.core.{ Hazelcast, HazelcastInstance }
import com.hazelcast.map.IMap
import com.hazelcast.query.Predicates
import com.ing.wbaa.rokku.proxy.data.RequestId
import com.ing.wbaa.rokku.proxy.handler.LoggerHandlerWithId
import com.typesafe.config.ConfigFactory
import com.ing.wbaa.rokku.proxy.handler.parsers.CacheHelpers.isHead

import scala.util.{ Failure, Success, Try }

object HazelcastCache {
  // implementation specific settings
  private val conf = ConfigFactory.load()
  private val cacheEnabled = conf.getBoolean("rokku.storage.s3.enabledCache")
  private val mapName = conf.getString("rokku.storage.s3.cacheDStructName")
}

trait HazelcastCache extends StorageCache {
  import HazelcastCache.{ mapName, cacheEnabled }

  private val logger = new LoggerHandlerWithId

  private val keyDelimiter = "-#r-end-path#-"

  private val hInstance: Option[HazelcastInstance] =
    if (cacheEnabled)
      Some(Hazelcast.newHazelcastInstance())
    else
      None

  private def getIMap(map: String): Option[IMap[String, ByteString]] = hInstance.map(h => h.getMap(map))

  override def getKey(request: HttpRequest)(implicit id: RequestId): String = {
    val headMethod = if (isHead(request)) "-head" else ""
    val rangeHeader = request.getHeader("Range").map[String](r => s"-r-${r.value()}").orElse("")
    request.uri.path.toString + keyDelimiter + rangeHeader + headMethod
  }

  override def getObject(key: String, map: String = mapName)(implicit id: RequestId): Option[ByteString] =
    Try {
      getIMap(map) match {
        case Some(m) => m.getOrDefault(key, ByteString.empty)
        case None    => ByteString.empty
      }
    } match {
      case Success(bs) if bs.nonEmpty =>
        logger.debug("Object already in cache - key {}", key)
        Some(bs)
      case Success(_) =>
        logger.debug("Object not found in cache")
        None
      case Failure(ex) =>
        logger.debug("Failed to get object from cache, e: {}", ex.getMessage)
        None
    }

  override def putObject(key: String, value: ByteString, map: String = mapName)(implicit id: RequestId): Unit =
    Try {
      getIMap(map).map(m => m.put(key, value))
    } match {
      case Success(_)  => logger.debug("Object added to cache, {}", key)
      case Failure(ex) => logger.debug("Failed to add object to cache, e: {}", ex.getMessage)
    }

  override def removeObject(key: String, map: String = mapName)(implicit id: RequestId): Unit =
    Try {
      getIMap(map).map(m => m.removeAll(Predicates.sql(s"__key like $key%")))
    } match {
      case Success(_)  => logger.debug("Object removed from cache, {}", key)
      case Failure(ex) => logger.debug("Failed to remove object from cache: {}", ex.getMessage)
    }
} 
Example 73
Source File: SignatureHelpersV4.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.provider.aws

import java.util

import akka.http.scaladsl.model.HttpRequest
import com.amazonaws.DefaultRequest
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.util.DateUtils
import com.ing.wbaa.rokku.proxy.provider.aws.SignatureHelpersCommon.extractHeaderOption
import com.ing.wbaa.rokku.proxy.data
import com.ing.wbaa.rokku.proxy.data.{ AWSHeaderValues, RequestId }
import com.ing.wbaa.rokku.proxy.handler.LoggerHandlerWithId

import scala.collection.JavaConverters._

class SignatureHelpersV4 extends SignatureHelpersCommon {
  private val logger = new LoggerHandlerWithId

  private def fixHeaderCapitals(header: String): String = {
    header.split("-").map { h =>
      h(0).toUpper + h.substring(1).toLowerCase
    }.mkString("-")
  }

  // java Map[String, util.List[String]] is need by AWS4Signer
  def extractRequestParameters(httpRequest: HttpRequest): util.Map[String, util.List[String]] = {
    val rawQueryString = httpRequest.uri.rawQueryString.getOrElse("")

    if (rawQueryString.length > 1) {
      rawQueryString match {
        // for aws subresource ?acl etc.
        case queryString if queryString.length > 1 && !queryString.contains("=") =>
          // aws uses subresource= during signature generation, so we add empty string to list - /demobucket/?acl="
          Map(queryString -> List[String]("").asJava).asJava

        // single param=value
        case queryString if queryString.contains("=") && !queryString.contains("&") => splitQueryToJavaMap(queryString)

        // multiple param=value
        case queryString if queryString.contains("&") => splitQueryToJavaMap(queryString)

        case _ => Map[String, java.util.List[String]]().empty.asJava
      }
    } else {
      Map[String, java.util.List[String]]().empty.asJava
    }
  }

  def getSignedHeaders(authorization: String): String =
    """\S+ SignedHeaders=(\S+), """.r
      .findFirstMatchIn(authorization)
      .map(_ group 1).getOrElse("")

  def getAWSHeaders(httpRequest: HttpRequest): AWSHeaderValues = {
    implicit val hr = httpRequest
    val authorization: Option[String] = extractHeaderOption("authorization")
    val signature = authorization.map(auth => getSignatureFromAuthorization(auth))
    val accessKey = authorization.map(auth => getCredentialFromAuthorization(auth))

    val signedHeadersMap = authorization.map(auth => getSignedHeaders(auth)).getOrElse("")
      .split(";")
      .toList
      .map { header =>
        if (header == "content-type") {
          (fixHeaderCapitals(header), httpRequest.entity.contentType.mediaType.value)
        } else if (header == "content-length") {
          val contentLength = httpRequest.entity.getContentLengthOption().orElse(0L)
          (fixHeaderCapitals(header), contentLength.toString)
        } else if (header == "amz-sdk-invocation-id" || header == "amz-sdk-retry") {
          (header, extractHeaderOption(header).getOrElse(""))
        } else if (header == "x-amz-content-sha256") {
          ("X-Amz-Content-SHA256", extractHeaderOption(header).getOrElse(""))
        } else {
          (fixHeaderCapitals(header), extractHeaderOption(header).getOrElse(""))
        }
      }.toMap

    data.AWSHeaderValues(accessKey, signedHeadersMap, signature, None, None, None)
  }

  // for now we do not have any regions, we use default one
  def signS3Request(request: DefaultRequest[_], credentials: BasicAWSCredentials, date: String, region: String = "us-east-1")(implicit id: RequestId): Unit = {
    logger.debug("Using version 4 signer")

    val signer = new CustomV4Signer()
    signer.setRegionName(region)
    signer.setServiceName(request.getServiceName)
    signer.setOverrideDate(DateUtils.parseCompressedISO8601Date(date))
    signer.sign(request, credentials)
  }

  // add headers from original request before sign
  def addHeadersToRequest(request: DefaultRequest[_], awsHeaders: AWSHeaderValues, mediaType: String): Unit =
    awsHeaders.signedHeadersMap.foreach(p => request.addHeader(p._1, p._2))

} 
Example 74
Source File: AuthenticationProviderSTS.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.provider

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.{ HttpRequest, StatusCodes, Uri }
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.Materializer
import com.ing.wbaa.rokku.proxy.config.StsSettings
import com.ing.wbaa.rokku.proxy.data.{ AwsRequestCredential, JsonProtocols, RequestId, User, UserRawJson }
import com.ing.wbaa.rokku.proxy.handler.LoggerHandlerWithId
import com.ing.wbaa.rokku.proxy.util.JwtToken

import scala.concurrent.{ ExecutionContext, Future }

trait AuthenticationProviderSTS extends JsonProtocols with JwtToken {

  private val logger = new LoggerHandlerWithId

  import AuthenticationProviderSTS.STSException
  import spray.json._

  protected[this] implicit def system: ActorSystem
  protected[this] implicit def executionContext: ExecutionContext
  protected[this] implicit def materializer: Materializer

  protected[this] def stsSettings: StsSettings

  protected[this] def areCredentialsActive(awsRequestCredential: AwsRequestCredential)(implicit id: RequestId): Future[Option[User]] = {
    val QueryParameters =
      Map("accessKey" -> awsRequestCredential.accessKey.value) ++
        awsRequestCredential.sessionToken.map(s => "sessionToken" -> s.value)

    val uri = stsSettings.stsBaseUri
      .withPath(Uri.Path("/isCredentialActive"))
      .withQuery(Uri.Query(QueryParameters))

    Http()
      .singleRequest(
        HttpRequest(uri = uri)
          .addHeader(RawHeader("Authorization", createInternalToken))
          .addHeader(RawHeader("x-rokku-request-id", id.value))
      )
      .flatMap { response =>
        response.status match {

          case StatusCodes.OK =>
            Unmarshal(response.entity).to[String].map { jsonString =>
              Some(User(jsonString.parseJson.convertTo[UserRawJson]))
            }

          case StatusCodes.Forbidden =>
            logger.error(s"User not authenticated " +
              s"with accessKey (${awsRequestCredential.accessKey.value}) " +
              s"and sessionToken (${awsRequestCredential.sessionToken})")
            Future.successful(None)

          case c =>
            val msg = s"Received unexpected StatusCode ($c) for " +
              s"accessKey (${awsRequestCredential.accessKey.value}) " +
              s"and sessionToken (${awsRequestCredential.sessionToken})"
            logger.error(msg)
            Future.failed(STSException(msg))
        }
      }
  }
}

object AuthenticationProviderSTS {
  final case class STSException(private val message: String, private val cause: Throwable = None.orNull)
    extends Exception(message, cause)
} 
Example 75
Source File: SignatureProviderAws.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.provider

import akka.http.scaladsl.model.HttpRequest
import com.amazonaws.auth._
import com.ing.wbaa.rokku.proxy.provider.aws.SignatureHelpersCommon.awsVersion
import com.ing.wbaa.rokku.proxy.config.StorageS3Settings
import com.ing.wbaa.rokku.proxy.data.{ AwsSecretKey, RequestId }
import com.ing.wbaa.rokku.proxy.handler.LoggerHandlerWithId

trait SignatureProviderAws {

  private val logger = new LoggerHandlerWithId
  protected[this] def storageS3Settings: StorageS3Settings

  def isUserAuthenticated(httpRequest: HttpRequest, awsSecretKey: AwsSecretKey)(implicit id: RequestId): Boolean = {
    val awsSignature = awsVersion(httpRequest)
    val awsHeaders = awsSignature.getAWSHeaders(httpRequest)

    val credentials = new BasicAWSCredentials(awsHeaders.accessKey.getOrElse(""), awsSecretKey.value)
    val incomingRequest = awsSignature.getSignableRequest(httpRequest)

    if (!credentials.getAWSAccessKeyId.isEmpty) {
      awsSignature.addHeadersToRequest(incomingRequest, awsHeaders, httpRequest.entity.contentType.mediaType.value)
      awsSignature.signS3Request(incomingRequest, credentials, awsHeaders.signedHeadersMap.getOrElse("X-Amz-Date", ""), storageS3Settings.awsRegion)
      logger.debug("Signed Request:" + incomingRequest.getHeaders.toString)
    }

    if (incomingRequest.getHeaders.containsKey("Authorization")) {
      val proxySignature = awsSignature.getSignatureFromAuthorization(incomingRequest.getHeaders.get("Authorization"))
      logger.debug(s"New Signature: $proxySignature Original Signature: ${awsHeaders.signature.getOrElse("")}")
      awsHeaders.signature.getOrElse("") == proxySignature
    } else false
  }

} 
Example 76
Source File: AuditLogProvider.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.provider

import akka.Done
import akka.http.scaladsl.model.{ HttpRequest, StatusCode }
import com.ing.wbaa.rokku.proxy.data.{ AWSMessageEventJsonSupport, RequestId, S3Request }
import com.ing.wbaa.rokku.proxy.handler.parsers.RequestParser.AWSRequestType
import com.ing.wbaa.rokku.proxy.provider.aws.s3ObjectAudit
import com.ing.wbaa.rokku.proxy.provider.kafka.EventProducer
import com.typesafe.config.ConfigFactory

import scala.concurrent.Future

trait AuditLogProvider extends EventProducer with AWSMessageEventJsonSupport {

  protected[this] def auditEnabled: Boolean = ConfigFactory.load().getBoolean("rokku.auditEnable")

  def auditLog(s3Request: S3Request, httpRequest: HttpRequest, user: String, awsRequest: AWSRequestType, responseStatus: StatusCode)(implicit id: RequestId): Future[Done] = {

    if (auditEnabled) {
      prepareAWSMessage(s3Request, httpRequest.method, user, s3Request.userIps, s3ObjectAudit(httpRequest.method.value), id, responseStatus, awsRequest)
        .map(jse =>
          sendSingleMessage(jse.toString(), kafkaSettings.auditEventsTopic))
        .getOrElse(Future(Done))
    } else {
      Future(Done)
    }
  }
} 
Example 77
Source File: HttpRequestRecorderItTest.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.persistence

import akka.Done
import akka.actor.{ActorSystem, Props}
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.Uri.{Authority, Host}
import akka.persistence.cassandra.query.scaladsl.CassandraReadJournal
import akka.persistence.query.PersistenceQuery
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import com.amazonaws.services.s3.AmazonS3
import com.ing.wbaa.rokku.proxy.RokkuS3Proxy
import com.ing.wbaa.rokku.proxy.config.{HttpSettings, KafkaSettings, StorageS3Settings}
import com.ing.wbaa.rokku.proxy.data._
import com.ing.wbaa.rokku.proxy.handler.parsers.RequestParser
import com.ing.wbaa.rokku.proxy.handler.{FilterRecursiveListBucketHandler, RequestHandlerS3Cache}
import com.ing.wbaa.rokku.proxy.provider.{AuditLogProvider, MessageProviderKafka, SignatureProviderAws}
import com.ing.wbaa.rokku.proxy.queue.MemoryUserRequestQueue
import com.ing.wbaa.testkit.RokkuFixtures
import org.scalatest.Assertion
import org.scalatest.diagrams.Diagrams
import org.scalatest.wordspec.AsyncWordSpec

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

class HttpRequestRecorderItTest extends AsyncWordSpec with Diagrams with RokkuFixtures {
  implicit val testSystem: ActorSystem = ActorSystem.create("test-system")
  implicit val mat: ActorMaterializer = ActorMaterializer()

  val rokkuHttpSettings: HttpSettings = new HttpSettings(testSystem.settings.config) {
    override val httpPort: Int = 0
    override val httpBind: String = "127.0.0.1"
  }

  def withS3SdkToMockProxy(testCode: AmazonS3 => Assertion): Future[Assertion] = {
    val proxy: RokkuS3Proxy = new RokkuS3Proxy with RequestHandlerS3Cache with SignatureProviderAws
      with FilterRecursiveListBucketHandler with MessageProviderKafka with AuditLogProvider with MemoryUserRequestQueue with RequestParser {
      override implicit lazy val system: ActorSystem = testSystem
      override val httpSettings: HttpSettings = rokkuHttpSettings

      override def isUserAuthorizedForRequest(request: S3Request, user: User)(implicit id: RequestId): Boolean = true

      override def isUserAuthenticated(httpRequest: HttpRequest, awsSecretKey: AwsSecretKey)(implicit id: RequestId): Boolean = true

      override val storageS3Settings: StorageS3Settings = StorageS3Settings(testSystem)
      override val kafkaSettings: KafkaSettings = KafkaSettings(testSystem)

      override def areCredentialsActive(awsRequestCredential: AwsRequestCredential)(implicit id: RequestId): Future[Option[User]] =
        Future(Some(User(UserRawJson("userId", Some(Set("group")), "accesskey", "secretkey", None))))

      def createLineageFromRequest(httpRequest: HttpRequest, userSTS: User, userIPs: UserIps)(implicit id: RequestId): Future[Done] = Future.successful(Done)

      override protected def auditEnabled: Boolean = false

      override val requestPersistenceEnabled: Boolean = true
      override val configuredPersistenceId: String = "localhost-1"
    }
    proxy.startup.map { binding =>
      try testCode(getAmazonS3(
        authority = Authority(Host(binding.localAddress.getAddress), binding.localAddress.getPort)
      ))
      finally proxy.shutdown()
    }
  }

  private val CHECKER_PERSISTENCE_ID = "localhost-1"
  val requestRecorder = testSystem.actorOf(Props(classOf[HttpRequestRecorder]), CHECKER_PERSISTENCE_ID)

  val queries = PersistenceQuery(testSystem)
    .readJournalFor[CassandraReadJournal](CassandraReadJournal.Identifier)


  "S3 Proxy" should {
    s"with Request Recorder" that {
      "persists requests in Cassandra" in withS3SdkToMockProxy { sdk =>
        withBucket(sdk) { bucketName =>
          Thread.sleep(6000)
          val storedInCassandraF = queries.currentEventsByPersistenceId(CHECKER_PERSISTENCE_ID, 1L, Long.MaxValue)
            .map(_.event)
            .runWith(Sink.seq)
            .mapTo[Seq[ExecutedRequestEvt]]
          val r = Await.result(storedInCassandraF, 5.seconds).filter(_.httpRequest.getUri().toString.contains(bucketName))
          assert(r.size == 1)
          assert(r.head.userSTS.userName.value == "userId")
        }
      }
    }
  }
} 
Example 78
Source File: AuditLogProviderItTest.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.provider

import java.net.InetAddress

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{HttpMethods, HttpRequest, RemoteAddress, StatusCodes}
import com.ing.wbaa.rokku.proxy.config.KafkaSettings
import com.ing.wbaa.rokku.proxy.data._
import com.ing.wbaa.rokku.proxy.handler.parsers.RequestParser.RequestTypeUnknown
import net.manub.embeddedkafka.{EmbeddedKafka, EmbeddedKafkaConfig}
import org.scalatest.diagrams.Diagrams
import org.scalatest.wordspec.AnyWordSpecLike

import scala.concurrent.ExecutionContext

class AuditLogProviderItTest extends AnyWordSpecLike with Diagrams with EmbeddedKafka with AuditLogProvider {

  implicit val testSystem: ActorSystem = ActorSystem("kafkaTest")

  private val testKafkaPort = 9093

  override def auditEnabled = true

  override implicit val kafkaSettings: KafkaSettings = new KafkaSettings(testSystem.settings.config) {
    override val bootstrapServers: String = s"localhost:$testKafkaPort"
  }

  override implicit val executionContext: ExecutionContext = testSystem.dispatcher

  implicit val requestId: RequestId = RequestId("test")

  val s3Request = S3Request(AwsRequestCredential(AwsAccessKey("a"), None), Some("demobucket"), Some("s3object"), Read())
    .copy(headerIPs = HeaderIPs(Some(RemoteAddress(InetAddress.getByName("127.0.0.1"))),
      Some(Seq(RemoteAddress(InetAddress.getByName("1.1.1.1")))),
      Some(RemoteAddress(InetAddress.getByName("2.2.2.2")))))

  "AuditLogProvider" should {
    "send audit" in {
      implicit val config = EmbeddedKafkaConfig(kafkaPort = testKafkaPort)

      withRunningKafka {
        Thread.sleep(3000)
        val createEventsTopic = "audit_events"
        createCustomTopic(createEventsTopic)
        auditLog(s3Request, HttpRequest(HttpMethods.PUT, "http://localhost", Nil), "testUser", RequestTypeUnknown(), StatusCodes.Processing)
        val result = consumeFirstStringMessageFrom(createEventsTopic)
        assert(result.contains("\"eventName\":\"PUT\""))
        assert(result.contains("\"sourceIPAddress\":\"ClientIp=unknown|X-Real-IP=127.0.0.1|X-Forwarded-For=1.1.1.1|Remote-Address=2.2.2.2\""))
        assert(result.contains("\"x-amz-request-id\":\"test\""))
        assert(result.contains("\"principalId\":\"testUser\""))
      }
    }
  }

} 
Example 79
Source File: CacheRulesV1Spec.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.cache

import akka.actor.ActorSystem
import akka.http.scaladsl.model.Uri.Path
import akka.http.scaladsl.model.{ HttpMethod, HttpMethods, HttpRequest, Uri }
import com.ing.wbaa.rokku.proxy.config.StorageS3Settings
import com.ing.wbaa.rokku.proxy.data.RequestId
import com.ing.wbaa.rokku.proxy.handler.parsers.RequestParser
import org.scalatest.diagrams.Diagrams
import org.scalatest.wordspec.AnyWordSpec

class CacheRulesV1Spec extends AnyWordSpec with Diagrams with CacheRulesV1 with RequestParser {

  private implicit val id = RequestId("testRequestId")

  val system: ActorSystem = ActorSystem.create("test-system")
  override val storageS3Settings: StorageS3Settings = new StorageS3Settings(system.settings.config) {
    override val storageS3Authority: Uri.Authority = Uri.Authority(Uri.Host("1.2.3.4"), 1234)
  }

  override def getMaxEligibleCacheObjectSizeInBytes(implicit id: RequestId): Long = 5242880L

  override def getEligibleCachePaths(implicit id: RequestId): Array[String] = "/home/,/test/".trim.split(",")

  override def getHeadEnabled(implicit id: RequestId): Boolean = true

  private val uri = Uri("http", Uri.Authority(Uri.Host("1.2.3.4")), Path(""), None, None)

  private val methods = Seq(HttpMethods.GET, HttpMethods.PUT, HttpMethods.POST, HttpMethods.DELETE, HttpMethods.HEAD)

  "Cache rules v1 set isEligibleToBeCached " should {

    methods.foreach { method =>
      testIsEligibleToBeCached(method, "/home/test", HttpRequest.apply(method = method, uri = uri.copy(path = Path("/home/test"))))
      testIsEligibleToBeCached(method, "/home2/test", HttpRequest.apply(method = method, uri = uri.copy(path = Path("/home2/test"))))
      testIsEligibleToBeCached(method, "/test/abc", HttpRequest.apply(method = method, uri = uri.copy(path = Path("/test/abc"))))
      testIsEligibleToBeCached(method, "/testtest/test", HttpRequest.apply(method = method, uri = uri.copy(path = Path("/testtest/test"))))
    }
  }

  private def testIsEligibleToBeCached(method: HttpMethod, path: String, request: HttpRequest): Unit = {
    method match {
      case HttpMethods.GET | HttpMethods.HEAD if storageS3Settings.eligibleCachePaths.exists(path.startsWith) =>
        s"for method=$method and path=$path to true" in {
          assert(isEligibleToBeCached(request))
        }
      case _ =>
        s"for method=$method and path=$path to false" in {
          assert(!isEligibleToBeCached(request))
        }
    }
  }

  "Cache rules v1 set isEligibleToBeInvalidated" should {

    methods.foreach { method =>
      val request = HttpRequest.apply(method = method, uri)
      method match {
        case HttpMethods.POST | HttpMethods.PUT | HttpMethods.DELETE =>
          s"for method=$method to true" in {
            assert(isEligibleToBeInvalidated(request))
          }
        case _ =>
          s"for method=$method to false" in {
            assert(!isEligibleToBeInvalidated(request))
          }
      }
    }
  }
} 
Example 80
Source File: LineageHelperSpec.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.provider

import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.headers.RawHeader
import com.ing.wbaa.rokku.proxy.config.KafkaSettings
import com.ing.wbaa.rokku.proxy.data.{ BucketClassification, DirClassification, ObjectClassification, RequestId }
import com.ing.wbaa.rokku.proxy.provider.atlas.LineageHelpers
import org.scalatest.PrivateMethodTester
import org.scalatest.diagrams.Diagrams
import org.scalatest.wordspec.AnyWordSpec

import scala.concurrent.ExecutionContext

class LineageHelperSpec extends AnyWordSpec with Diagrams with PrivateMethodTester {

  object LineageHelpersTest extends LineageHelpers {
    override protected[this] implicit val kafkaSettings: KafkaSettings = null
    override protected[this] implicit val executionContext: ExecutionContext = null
  }

  implicit val id = RequestId("1")

  "extractMetadataFromHeader" that {
    "return None for empty header" in {
      val result = LineageHelpersTest.extractMetadataHeader(None)
      assert(result.isEmpty)
    }

    "return None for wrong header" in {
      val result = LineageHelpersTest.extractMetadataHeader(Some("k,v"))
      assert(result.isEmpty)
      val result2 = LineageHelpersTest.extractMetadataHeader(Some("k=v,k2"))
      assert(result2.isEmpty)
      val result3 = LineageHelpersTest.extractMetadataHeader(Some("kv,=k2,v2"))
      assert(result3.isEmpty)
    }

    "return key and value for metadata header" in {
      val result = LineageHelpersTest.extractMetadataHeader(Some("k=v"))
      assert(result.contains(Map("k" -> "v")))
    }

    "return keys and values for metadata header" in {
      val result = LineageHelpersTest.extractMetadataHeader(Some("k1=v1,k2=v2"))
      assert(result.contains(Map("k1" -> "v1", "k2" -> "v2")))
    }
  }

  "extractClassifications" that {
    "returns bucket classifications" in {
      val request = HttpRequest().withUri("bucket").withHeaders(RawHeader(LineageHelpersTest.CLASSIFICATIONS_HEADER, "classification1"))
      val result = LineageHelpersTest.extractClassifications(request)
      assert(result.size == 1)
      assert(result contains BucketClassification())
      assert(result(BucketClassification()) == List("classification1"))
    }

    "returns dir classifications" in {
      val request = HttpRequest().withUri("bucket/dir1/").withHeaders(RawHeader(LineageHelpersTest.CLASSIFICATIONS_HEADER, "classification1,classification2"))
      val result = LineageHelpersTest.extractClassifications(request)
      assert(result.size == 1)
      assert(result contains DirClassification())
      assert(result(DirClassification()) == List("classification1", "classification2"))
    }

    "returns object classifications" in {
      val request = HttpRequest().withUri("bucket/obj").withHeaders(RawHeader(LineageHelpersTest.CLASSIFICATIONS_HEADER, "classification1,classification2,classification3"))
      val result = LineageHelpersTest.extractClassifications(request)
      assert(result.size == 1)
      assert(result contains ObjectClassification())
      assert(result(ObjectClassification()) == List("classification1", "classification2", "classification3"))
      val request2 = HttpRequest().withUri("bucket/dir1/obj").withHeaders(RawHeader(LineageHelpersTest.CLASSIFICATIONS_HEADER, "classification1"))
      val result2 = LineageHelpersTest.extractClassifications(request2)
      assert(result2.size == 1)
      assert(result2 contains ObjectClassification())
      assert(result2(ObjectClassification()) == List("classification1"))
    }
  }

} 
Example 81
Source File: RefreshTokenStrategy.scala    From akka-http-oauth2-client   with Apache License 2.0 5 votes vote down vote up
package com.github.dakatsuka.akka.http.oauth2.client.strategy

import akka.NotUsed
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.{ FormData, HttpCharsets, HttpRequest, Uri }
import akka.stream.scaladsl.Source
import com.github.dakatsuka.akka.http.oauth2.client.{ ConfigLike, GrantType }

class RefreshTokenStrategy extends Strategy(GrantType.RefreshToken) {
  override def getAuthorizeUrl(config: ConfigLike, params: Map[String, String] = Map.empty): Option[Uri] = None

  override def getAccessTokenSource(config: ConfigLike, params: Map[String, String] = Map.empty): Source[HttpRequest, NotUsed] = {
    require(params.contains("refresh_token"))

    val uri = Uri
      .apply(config.site.toASCIIString)
      .withPath(Uri.Path(config.tokenUrl))

    val request = HttpRequest(
      method = config.tokenMethod,
      uri = uri,
      headers = List(
        RawHeader("Accept", "*/*")
      ),
      FormData(
        params ++ Map(
          "grant_type"    -> grant.value,
          "client_id"     -> config.clientId,
          "client_secret" -> config.clientSecret
        )
      ).toEntity(HttpCharsets.`UTF-8`)
    )

    Source.single(request)
  }
} 
Example 82
Source File: ImplicitStrategy.scala    From akka-http-oauth2-client   with Apache License 2.0 5 votes vote down vote up
package com.github.dakatsuka.akka.http.oauth2.client.strategy

import akka.NotUsed
import akka.http.scaladsl.model.{ HttpRequest, Uri }
import akka.stream.scaladsl.Source
import com.github.dakatsuka.akka.http.oauth2.client.{ ConfigLike, GrantType }

class ImplicitStrategy extends Strategy(GrantType.Implicit) {
  override def getAuthorizeUrl(config: ConfigLike, params: Map[String, String] = Map.empty): Option[Uri] = {
    val uri = Uri
      .apply(config.site.toASCIIString)
      .withPath(Uri.Path(config.authorizeUrl))
      .withQuery(Uri.Query(params ++ Map("response_type" -> "token", "client_id" -> config.clientId)))

    Option(uri)
  }

  override def getAccessTokenSource(config: ConfigLike, params: Map[String, String] = Map.empty): Source[HttpRequest, NotUsed] =
    Source.empty
} 
Example 83
Source File: Client.scala    From akka-http-oauth2-client   with Apache License 2.0 5 votes vote down vote up
package com.github.dakatsuka.akka.http.oauth2.client

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.headers.OAuth2BearerToken
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse, Uri }
import akka.stream.Materializer
import akka.stream.scaladsl.{ Flow, Sink }
import com.github.dakatsuka.akka.http.oauth2.client.Error.UnauthorizedException
import com.github.dakatsuka.akka.http.oauth2.client.strategy.Strategy

import scala.concurrent.{ ExecutionContext, Future }

class Client(config: ConfigLike, connection: Option[Flow[HttpRequest, HttpResponse, _]] = None)(implicit system: ActorSystem)
    extends ClientLike {
  def getAuthorizeUrl[A <: GrantType](grant: A, params: Map[String, String] = Map.empty)(implicit s: Strategy[A]): Option[Uri] =
    s.getAuthorizeUrl(config, params)

  def getAccessToken[A <: GrantType](
      grant: A,
      params: Map[String, String] = Map.empty
  )(implicit s: Strategy[A], ec: ExecutionContext, mat: Materializer): Future[Either[Throwable, AccessToken]] = {
    val source = s.getAccessTokenSource(config, params)

    source
      .via(connection.getOrElse(defaultConnection))
      .mapAsync(1)(handleError)
      .mapAsync(1)(AccessToken.apply)
      .runWith(Sink.head)
      .map(Right.apply)
      .recover {
        case ex => Left(ex)
      }
  }

  def getConnectionWithAccessToken(accessToken: AccessToken): Flow[HttpRequest, HttpResponse, _] =
    Flow[HttpRequest]
      .map(_.addCredentials(OAuth2BearerToken(accessToken.accessToken)))
      .via(connection.getOrElse(defaultConnection))

  private def defaultConnection: Flow[HttpRequest, HttpResponse, _] =
    config.site.getScheme match {
      case "http"  => Http().outgoingConnection(config.getHost, config.getPort)
      case "https" => Http().outgoingConnectionHttps(config.getHost, config.getPort)
    }

  private def handleError(response: HttpResponse)(implicit ec: ExecutionContext, mat: Materializer): Future[HttpResponse] = {
    if (response.status.isFailure()) UnauthorizedException.fromHttpResponse(response).flatMap(Future.failed(_))
    else Future.successful(response)
  }
}

object Client {
  def apply(config: ConfigLike)(implicit system: ActorSystem): Client =
    new Client(config)

  def apply(config: ConfigLike, connection: Flow[HttpRequest, HttpResponse, _])(implicit system: ActorSystem): Client =
    new Client(config, Some(connection))
} 
Example 84
Source File: HttpMetricsRoute.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.NotUsed
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.server._
import akka.http.scaladsl.settings.{ParserSettings, RoutingSettings}
import akka.stream.Materializer
import akka.stream.scaladsl.Flow
import fr.davit.akka.http.metrics.core.HttpMetricsHandler
import fr.davit.akka.http.metrics.core.scaladsl.model.PathLabelHeader

import scala.concurrent.{ExecutionContextExecutor, Future}

object HttpMetricsRoute {

  implicit def apply(route: Route): HttpMetricsRoute = new HttpMetricsRoute(route)

}


final class HttpMetricsRoute private (route: Route) extends HttpMetricsDirectives {

  private def markUnhandled(inner: Route): Route = {
    Directives.mapResponse(markUnhandled).tapply(_ => inner)
  }

  private def markUnhandled(response: HttpResponse): HttpResponse = {
    response.addHeader(PathLabelHeader.Unhandled)
  }

  def recordMetrics(metricsHandler: HttpMetricsHandler)(
      implicit
      routingSettings: RoutingSettings,
      parserSettings: ParserSettings,
      materializer: Materializer,
      routingLog: RoutingLog,
      executionContext: ExecutionContextExecutor = null,
      rejectionHandler: RejectionHandler = RejectionHandler.default,
      exceptionHandler: ExceptionHandler = null
  ): Flow[HttpRequest, HttpResponse, NotUsed] = {
    val effectiveEC = if (executionContext ne null) executionContext else materializer.executionContext

    {
      // override the execution context passed as parameter
      implicit val executionContext: ExecutionContextExecutor = effectiveEC
      Flow[HttpRequest]
        .mapAsync(1)(recordMetricsAsync(metricsHandler))
        .watchTermination() {
          case (mat, completion) =>
            // every connection materializes a stream.
            metricsHandler.onConnection(completion)
            mat
        }
    }
  }

  def recordMetricsAsync(metricsHandler: HttpMetricsHandler)(
      implicit
      routingSettings: RoutingSettings,
      parserSettings: ParserSettings,
      materializer: Materializer,
      routingLog: RoutingLog,
      executionContext: ExecutionContextExecutor = null,
      rejectionHandler: RejectionHandler = RejectionHandler.default,
      exceptionHandler: ExceptionHandler = null
  ): HttpRequest => Future[HttpResponse] = {
    val effectiveEC               = if (executionContext ne null) executionContext else materializer.executionContext
    val effectiveRejectionHandler = rejectionHandler.mapRejectionResponse(markUnhandled)
    val effectiveExceptionHandler = ExceptionHandler.seal(exceptionHandler).andThen(markUnhandled(_))

    {
      // override the execution context passed as parameter, rejection and error handler
      implicit val executionContext: ExecutionContextExecutor = effectiveEC
      implicit val rejectionHandler: RejectionHandler         = effectiveRejectionHandler
      implicit val exceptionHandler: ExceptionHandler         = effectiveExceptionHandler

      request =>
        val response = Route.asyncHandler(route).apply(request)
        metricsHandler.onRequest(request, response)
        response
    }
  }
} 
Example 85
Source File: SwaggerValidator.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package common.rest

import scala.collection.JavaConverters._

import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.HttpResponse
import com.atlassian.oai.validator.SwaggerRequestResponseValidator
import com.atlassian.oai.validator.model.SimpleRequest
import com.atlassian.oai.validator.model.SimpleResponse
import com.atlassian.oai.validator.report.ValidationReport
import com.atlassian.oai.validator.whitelist.ValidationErrorsWhitelist
import com.atlassian.oai.validator.whitelist.rule.WhitelistRules

trait SwaggerValidator {
  private val specWhitelist = ValidationErrorsWhitelist
    .create()
    .withRule(
      "Ignore action and trigger payloads",
      WhitelistRules.allOf(
        WhitelistRules.messageContains("Object instance has properties which are not allowed by the schema"),
        WhitelistRules.anyOf(
          WhitelistRules.pathContains("/web/"),
          WhitelistRules.pathContains("/actions/"),
          WhitelistRules.pathContains("/triggers/")),
        WhitelistRules.methodIs(io.swagger.models.HttpMethod.POST)))
    .withRule(
      "Ignore invalid action kinds",
      WhitelistRules.allOf(
        WhitelistRules.messageContains("kind"),
        WhitelistRules.messageContains("Instance value"),
        WhitelistRules.messageContains("not found"),
        WhitelistRules.pathContains("/actions/"),
        WhitelistRules.methodIs(io.swagger.models.HttpMethod.PUT)))
    .withRule(
      "Ignore tests that check for invalid DELETEs and PUTs on actions",
      WhitelistRules.anyOf(
        WhitelistRules.messageContains("DELETE operation not allowed on path '/api/v1/namespaces/_/actions/'"),
        WhitelistRules.messageContains("PUT operation not allowed on path '/api/v1/namespaces/_/actions/'")))

  private val specValidator = SwaggerRequestResponseValidator
    .createFor("apiv1swagger.json")
    .withWhitelist(specWhitelist)
    .build()

  
  def validateRequestAndResponse(request: HttpRequest, response: HttpResponse): Seq[String] = {
    val specRequest = {
      val builder = new SimpleRequest.Builder(request.method.value, request.uri.path.toString())
      val body = strictEntityBodyAsString(request.entity)
      val withBody =
        if (body.isEmpty) builder
        else
          builder
            .withBody(body)
            .withHeader("content-type", request.entity.contentType.value)
      val withHeaders = request.headers.foldLeft(builder)((b, header) => b.withHeader(header.name, header.value))
      val andQuery =
        request.uri.query().foldLeft(withHeaders) { case (b, (key, value)) => b.withQueryParam(key, value) }
      andQuery.build()
    }

    val specResponse = {
      val builder = SimpleResponse.Builder
        .status(response.status.intValue)
      val body = strictEntityBodyAsString(response.entity)
      val withBody =
        if (body.isEmpty) builder
        else
          builder
            .withBody(body)
            .withHeader("content-type", response.entity.contentType.value)
      val withHeaders = response.headers.foldLeft(builder)((b, header) => b.withHeader(header.name, header.value))
      withHeaders.build()
    }

    specValidator
      .validate(specRequest, specResponse)
      .getMessages
      .asScala
      .filter(m => m.getLevel == ValidationReport.Level.ERROR)
      .map(_.toString)
      .toSeq
  }

  def strictEntityBodyAsString(entity: HttpEntity): String = entity match {
    case s: HttpEntity.Strict => s.data.utf8String
    case _                    => ""
  }
} 
Example 86
Source File: OpenWhiskEventsTests.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package org.apache.openwhisk.core.monitoring.metrics

import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import akka.http.scaladsl.unmarshalling.Unmarshal
import com.typesafe.config.ConfigFactory
import io.prometheus.client.CollectorRegistry
import kamon.Kamon
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

import scala.concurrent.duration._
import scala.util.Try

@RunWith(classOf[JUnitRunner])
class OpenWhiskEventsTests extends KafkaSpecBase {
  behavior of "Server"

  it should "start working http server" in {
    val httpPort = freePort()
    val globalConfig = system.settings.config
    val config = ConfigFactory.parseString(s"""
           | akka.kafka.consumer.kafka-clients {
           |  bootstrap.servers = "localhost:$kafkaPort"
           | }
           | kamon {
           |  metric {
           |    tick-interval = 50 ms
           |    optimistic-tick-alignment = no
           |  }
           | }
           | whisk {
           |  user-events {
           |    port = $httpPort
           |    rename-tags {
           |      namespace = "ow_namespace"
           |    }
           |  }
           | }
         """.stripMargin).withFallback(globalConfig)
    CollectorRegistry.defaultRegistry.clear()
    val binding = OpenWhiskEvents.start(config).futureValue
    val res = get("localhost", httpPort, "/ping")
    res shouldBe Some(StatusCodes.OK, "pong")

    //Check if metrics using Kamon API gets included in consolidated Prometheus
    Kamon.counter("fooTest").withoutTags().increment(42)
    sleep(1.second)
    val metricRes = get("localhost", httpPort, "/metrics")
    metricRes.get._2 should include("fooTest")

    binding.unbind().futureValue
  }

  def get(host: String, port: Int, path: String = "/") = {
    val response = Try {
      Http()
        .singleRequest(HttpRequest(uri = s"http://$host:$port$path"))
        .futureValue
    }.toOption

    response.map { res =>
      (res.status, Unmarshal(res).to[String].futureValue)
    }
  }
} 
Example 87
Source File: ServiceApp.scala    From BusFloatingData   with Apache License 2.0 5 votes vote down vote up
package de.nierbeck.floating.data.server

import akka.actor.{ActorRef, ActorSystem, Props}
import akka.event.Logging
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.ws.UpgradeToWebSocket
import akka.http.scaladsl.model.{HttpRequest, HttpResponse, Uri}
import akka.stream.ActorMaterializer
import de.nierbeck.floating.data.server.actors.websocket.{FLINK, RouterActor, SPARK, TiledVehiclesFromKafkaActor}

import scala.concurrent.Await
import scala.concurrent.duration.Duration
import scala.util.{Failure, Success}

object ServiceApp extends RestService {

  import ServiceConfig._
  import system.dispatcher

  implicit val system = ActorSystem("service-api-http")
  implicit val mat = ActorMaterializer()

  override val logger = Logging(system, getClass.getName)
  override val session = CassandraConnector.connect()

  def main(args: Array[String]): Unit = {

    val router: ActorRef = system.actorOf(Props[RouterActor], "router")
    val sparkKafkaConsumer: ActorRef = system.actorOf(TiledVehiclesFromKafkaActor.props(router, "tiledVehicles", SPARK), "Kafka-Consumer-Spark")
    val flinkKafkaConsumer: ActorRef = system.actorOf(TiledVehiclesFromKafkaActor.props(router, "flinkTiledVehicles", FLINK), "Kafka-Consumer-Flink")


    val requestHandler: HttpRequest => HttpResponse = {
      case req@HttpRequest(GET, Uri.Path("/ws/vehicles"), _, _, _) =>
        req.header[UpgradeToWebSocket] match {
          case Some(upgrade) => upgrade.handleMessages(Flows.graphFlowWithStats(router))
          case None => HttpResponse(400, entity = "Not a valid websocket request!")
        }
      case _: HttpRequest => HttpResponse(404, entity = "Unknown resource!")
    }

    Http()
      .bindAndHandle(route(), serviceInterface, servicePort)
      .onComplete {
        case Success(_) => logger.info(s"Successfully bound to $serviceInterface:$servicePort")
        case Failure(e) => logger.error(s"Failed !!!! ${e.getMessage}")
      }

    Http()
      .bindAndHandleSync(requestHandler, serviceInterface, 8001)
      .onComplete {
        case Success(_) => logger.info(s"Successfully started Server to $serviceInterface:8001")
        case Failure(e) => logger.error(s"Failed !!!! ${e.getMessage}")
      }

    Await.ready(system.whenTerminated, Duration.Inf)
    CassandraConnector.close(session)
  }

} 
Example 88
Source File: CustomJsonController.scala    From playsonify   with MIT License 5 votes vote down vote up
package com.alexitc.playsonify.akka.common

import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.headers.Authorization
import com.alexitc.playsonify.akka._
import com.alexitc.playsonify.core.FutureApplicationResult
import com.alexitc.playsonify.models.{ErrorId, ServerError}
import org.scalactic.{One, Or}

import scala.concurrent.Future

class CustomJsonController extends AbstractJsonController(new CustomJsonController.CustomJsonComponents) {

  override protected def onServerError(error: ServerError, id: ErrorId): Unit = {
    error
        .cause
        .orElse {
          println(s"Server error: $error, id = ${error.id}")
          None
        }
        .foreach { cause =>
          println(s"Server error: $error, id = $id")
          cause.printStackTrace()
        }
  }
}

object CustomJsonController {

  class CustomJsonComponents extends JsonControllerComponents[CustomUser] {

    override def i18nService: SingleLangService = SingleLangService.Default

    override def publicErrorRenderer: PublicErrorRenderer = new PublicErrorRenderer

    override def authenticatorService: AbstractAuthenticatorService[CustomUser] = new CustomAuthenticator
  }

  class CustomAuthenticator extends AbstractAuthenticatorService[CustomUser] {

    override def authenticate(request: HttpRequest): FutureApplicationResult[CustomUser] = {

      val header = request
          .header[Authorization]
          .map(_.value())
          .map(CustomUser.apply)

      val result = Or.from(header, One(CustomError.FailedAuthError))
      Future.successful(result)
    }
  }
} 
Example 89
Source File: AkkaHttpBackend.scala    From drunk   with Apache License 2.0 5 votes vote down vote up
package com.github.jarlakxen.drunk.backend

import scala.collection.immutable
import scala.concurrent.{ExecutionContext, Future}
import akka.actor.ActorSystem
import akka.http.scaladsl.{Http, HttpExt}
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpHeader, HttpMethods, HttpRequest, Uri}
import akka.stream.ActorMaterializer

class AkkaHttpBackend private[AkkaHttpBackend] (
  uri: Uri,
  headers: immutable.Seq[HttpHeader],
  httpExt: HttpExt
)(override implicit val as: ActorSystem, override implicit val mat: ActorMaterializer)
    extends AkkaBackend {

  def send(body: String): Future[(Int, String)] = {
    implicit val ec: ExecutionContext = as.dispatcher

    val req = HttpRequest(HttpMethods.POST, uri, headers, HttpEntity(ContentTypes.`application/json`, body))

    val res = httpExt.singleRequest(req)

    res.flatMap { hr =>
      val code = hr.status.intValue()

      val charsetFromHeaders = encodingFromContentType(hr.entity.contentType.toString).getOrElse("utf-8")
      val decodedResponse = decodeResponse(hr)
      val stringBody = bodyToString(decodedResponse, charsetFromHeaders)

      if (code >= 200 && code < 300) {
        stringBody.map { body =>
          hr.discardEntityBytes()
          (code, body)
        }
      } else {
        stringBody.flatMap { body =>
          hr.discardEntityBytes()
          Future.failed(new RuntimeException(s"${uri.toString} return $code with body: $body"))
        }
      }
    }
  }

}

object AkkaHttpBackend {
  val ContentTypeHeader = "Content-Type"

  def apply(
    uri: Uri,
    headers: immutable.Seq[HttpHeader] = Nil,
    httpExt: Option[HttpExt] = None
  )(implicit as: ActorSystem, mat: ActorMaterializer): AkkaHttpBackend = {

    val http = httpExt.getOrElse { Http(as) }
    new AkkaHttpBackend(uri, headers, http)
  }
} 
Example 90
Source File: PostcodeClient.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend.component.webservices.postcode

import akka.NotUsed
import akka.actor.ActorSystem
import akka.event.LoggingAdapter
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.stream.Materializer
import akka.stream.scaladsl.Flow
import com.github.dnvriend.component.webservices.generic.HttpClient
import spray.json.DefaultJsonProtocol

import scala.concurrent.{ ExecutionContext, Future }
import scala.util.Try
import scala.util.matching.Regex

case class Address(
  street: String,
  houseNumber: Int,
  houseNumberAddition: String,
  postcode: String,
  city: String,
  municipality: String,
  province: String,
  rdX: Option[Int],
  rdY: Option[Int],
  latitude: Double,
  longitude: Double,
  bagNumberDesignationId: String,
  bagAddressableObjectId: String,
  addressType: String,
  purposes: Option[List[String]],
  surfaceArea: Int,
  houseNumberAdditions: List[String]
)

trait Marshallers extends DefaultJsonProtocol {
  implicit val addressJsonFormat = jsonFormat17(Address)
}

case class GetAddressRequest(zip: String, houseNumber: String)

trait PostcodeClient {
  def address(postcode: String, houseNumber: Int): Future[Option[Address]]

  def address[T](implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext): Flow[(GetAddressRequest, T), (Option[Address], T), NotUsed]
}

object PostcodeClient {
  import spray.json._
  val ZipcodeWithoutSpacePattern: Regex = """([1-9][0-9]{3})([A-Za-z]{2})""".r
  val ZipcodeWithSpacePattern: Regex = """([1-9][0-9]{3})[\s]([A-Za-z]{2})""".r

  def mapToAddress(json: String)(implicit reader: JsonReader[Address]): Option[Address] =
    Try(json.parseJson.convertTo[Address]).toOption

  def responseToString(resp: HttpResponse)(implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext): Future[String] =
    HttpClient.responseToString(resp)

  def getAddressRequestFlow[T]: Flow[(GetAddressRequest, T), (HttpRequest, T), NotUsed] =
    Flow[(GetAddressRequest, T)].map { case (request, id) => (HttpClient.mkGetRequest(s"/rest/addresses/${request.zip}/${request.houseNumber}/"), id) }

  def mapResponseToAddressFlow[T](implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext, reader: JsonReader[Address]): Flow[(Try[HttpResponse], T), (Option[Address], T), NotUsed] =
    HttpClient.responseToString[T].map { case (json, id) => (mapToAddress(json), id) }
  
  def normalizeZipcode(zipcode: String): Option[String] = zipcode.toUpperCase match {
    case ZipcodeWithoutSpacePattern(numbers, letters) => Option(s"$numbers$letters")
    case ZipcodeWithSpacePattern(numbers, letters)    => Option(s"$numbers$letters")
    case _                                            => None
  }

  def apply()(implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext, log: LoggingAdapter) = new PostcodeClientImpl
}

class PostcodeClientImpl()(implicit val system: ActorSystem, val mat: Materializer, val ec: ExecutionContext, val log: LoggingAdapter) extends PostcodeClient with Marshallers {
  import PostcodeClient._
  private val client = HttpClient("postcode")

  override def address(postcode: String, houseNumber: Int): Future[Option[Address]] =
    normalizeZipcode(postcode) match {
      case Some(zip) => client.get(s"/rest/addresses/$zip/$houseNumber/")
        .flatMap(responseToString).map(mapToAddress)
      case None => Future.successful(None)
    }

  override def address[T](implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext): Flow[(GetAddressRequest, T), (Option[Address], T), NotUsed] =
    getAddressRequestFlow[T]
      .via(client.cachedHostConnectionFlow[T])
      .via(mapResponseToAddressFlow[T])
} 
Example 91
Source File: WeatherClient.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend.component.webservices.weather

import akka.NotUsed
import akka.actor.ActorSystem
import akka.event.LoggingAdapter
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.stream.Materializer
import akka.stream.scaladsl.Flow
import com.github.dnvriend.component.webservices.generic.HttpClient
import spray.json.DefaultJsonProtocol

import scala.concurrent.{ ExecutionContext, Future }
import scala.util.Try

case class Wind(speed: Double, deg: Double)
case class Main(temp: Double, temp_min: Double, temp_max: Double, pressure: Double, sea_level: Option[Double], grnd_level: Option[Double], humidity: Int)
case class Cloud(all: Int)
case class Weather(id: Int, main: String, description: String, icon: String)
case class Sys(message: Double, country: String, sunrise: Long, sunset: Long)
case class Coord(lon: Double, lat: Double)
case class WeatherResult(coord: Coord, sys: Sys, weather: List[Weather], base: String, main: Main, wind: Wind, clouds: Cloud, dt: Long, id: Int, name: String, cod: Int)

trait Marshallers extends DefaultJsonProtocol {
  implicit val windJsonFormat = jsonFormat2(Wind)
  implicit val mainJsonFormat = jsonFormat7(Main)
  implicit val cloudJsonFormat = jsonFormat1(Cloud)
  implicit val weatherJsonFormat = jsonFormat4(Weather)
  implicit val sysJsonFormat = jsonFormat4(Sys)
  implicit val coordJsonFormat = jsonFormat2(Coord)
  implicit val weatherResultJsonFormat = jsonFormat11(WeatherResult)
}

case class GetWeatherRequest(zip: String, country: String)

trait OpenWeatherApi {
  def getWeather(zip: String, country: String): Future[Option[WeatherResult]]

  def getWeather[T](implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext): Flow[(GetWeatherRequest, T), (Option[WeatherResult], T), NotUsed]
}

object OpenWeatherApi {
  import spray.json._
  def apply()(implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext, log: LoggingAdapter) = new OpenWeatherApiImpl

  def mapResponseToWeatherResult(json: String)(implicit reader: JsonReader[WeatherResult]): Option[WeatherResult] =
    Try(json.parseJson.convertTo[WeatherResult]).toOption

  def responseToString(resp: HttpResponse)(implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext): Future[String] =
    HttpClient.responseToString(resp)

  def getWeatherRequestFlow[T]: Flow[(GetWeatherRequest, T), (HttpRequest, T), NotUsed] =
    Flow[(GetWeatherRequest, T)].map { case (request, id) => (HttpClient.mkGetRequest(s"/data/2.5/weather?zip=${request.zip},${request.country}"), id) }

  def mapResponseToWeatherResultFlow[T](implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext, reader: JsonReader[WeatherResult]): Flow[(Try[HttpResponse], T), (Option[WeatherResult], T), NotUsed] =
    HttpClient.responseToString[T].map { case (json, id) => (mapResponseToWeatherResult(json), id) }
}

class OpenWeatherApiImpl()(implicit val system: ActorSystem, val ec: ExecutionContext, val mat: Materializer, val log: LoggingAdapter) extends OpenWeatherApi with Marshallers {
  import OpenWeatherApi._

  private val client = HttpClient("weather")

  override def getWeather(zip: String, country: String): Future[Option[WeatherResult]] =
    client.get(s"/data/2.5/weather?zip=$zip,$country").
      flatMap(responseToString)
      .map(mapResponseToWeatherResult)

  override def getWeather[T](implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext): Flow[(GetWeatherRequest, T), (Option[WeatherResult], T), NotUsed] =
    getWeatherRequestFlow[T]
      .via(client.cachedHostConnectionFlow[T])
      .via(mapResponseToWeatherResultFlow[T])
} 
Example 92
Source File: ServerTestBase.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.algebra.server

import java.nio.charset.StandardCharsets

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.headers.`Content-Type`
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.util.ByteString
import endpoints4s.algebra
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{BeforeAndAfter, BeforeAndAfterAll}

import scala.concurrent.duration._
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

import scala.concurrent.{ExecutionContext, Future}

trait ServerTestBase[T <: algebra.Endpoints]
    extends AnyWordSpec
    with Matchers
    with ScalaFutures
    with BeforeAndAfterAll
    with BeforeAndAfter {

  override implicit def patienceConfig: PatienceConfig =
    PatienceConfig(10.seconds, 10.millisecond)

  val serverApi: T

  
  case class Malformed(errors: Seq[String]) extends DecodedUrl[Nothing]
} 
Example 93
Source File: BasicAuthenticationTestSuite.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.algebra.server

import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import akka.http.scaladsl.model.headers.{BasicHttpCredentials, `WWW-Authenticate`}
import endpoints4s.algebra.BasicAuthenticationTestApi

trait BasicAuthenticationTestSuite[T <: BasicAuthenticationTestApi] extends EndpointsTestSuite[T] {

  "BasicAuthentication" should {

    "reject unauthenticated requests" in {
      serveEndpoint(serverApi.protectedEndpoint, Some("Hello!")) { port =>
        val request = HttpRequest(uri = s"http://localhost:$port/users")
        whenReady(sendAndDecodeEntityAsText(request)) {
          case (response, entity) =>
            response.status shouldBe StatusCodes.Unauthorized
            response
              .header[`WWW-Authenticate`]
              .exists(_.challenges.exists(_.scheme == "Basic")) shouldBe true
            entity shouldBe ""
            ()
        }
      }
    }

    "accept authenticated requests" in {
      serveEndpoint(serverApi.protectedEndpoint, Some("Hello!")) { port =>
        val request =
          HttpRequest(uri = s"http://localhost:$port/users")
            .addCredentials(BasicHttpCredentials("admin", "foo"))
        whenReady(sendAndDecodeEntityAsText(request)) {
          case (response, entity) =>
            response.status shouldBe StatusCodes.OK
            entity shouldBe "Hello!"
            ()
        }
      }
    }

    "reject unauthenticated requests with invalid parameters before handling authorization" in {
      serveEndpoint(serverApi.protectedEndpointWithParameter, Some("Hello!")) { port =>
        val request = HttpRequest(uri = s"http://localhost:$port/users/foo")
        whenReady(sendAndDecodeEntityAsText(request)) {
          case (response, entity) =>
            response.status shouldBe StatusCodes.BadRequest
            entity shouldBe "[\"Invalid integer value 'foo' for segment 'id'\"]"
            ()
        }
      }
    }

  }

} 
Example 94
Source File: SumTypedEntitiesTestSuite.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.algebra.server

import akka.http.scaladsl.model.{ContentTypes, HttpMethods, HttpRequest}
import endpoints4s.algebra

trait SumTypedEntitiesTestSuite[
    T <: algebra.SumTypedEntitiesTestApi
] extends ServerTestBase[T] {

  "Sum typed route" should {

    "handle `text/plain` content-type requests" in {
      serveIdentityEndpoint(serverApi.sumTypedEndpoint) { port =>
        val request =
          HttpRequest(HttpMethods.POST, s"http://localhost:$port/user-or-name")
            .withEntity(ContentTypes.`text/plain(UTF-8)`, "Alice")
        whenReady(sendAndDecodeEntityAsText(request)) {
          case (response, entity) =>
            assert(response.status.intValue() == 200)
            assert(
              response.entity.contentType == ContentTypes.`text/plain(UTF-8)`
            )
            entity shouldEqual "Alice"
        }
        ()
      }
    }

    "handle `application/json` content-type requests" in {
      serveIdentityEndpoint(serverApi.sumTypedEndpoint) { port =>
        val request =
          HttpRequest(HttpMethods.POST, s"http://localhost:$port/user-or-name")
            .withEntity(
              ContentTypes.`application/json`,
              "{\"name\":\"Alice\",\"age\":42}"
            )
        whenReady(sendAndDecodeEntityAsText(request)) {
          case (response, entity) =>
            assert(response.status.intValue() == 200)
            assert(
              response.entity.contentType == ContentTypes.`application/json`
            )
            ujson.read(entity) shouldEqual ujson.Obj(
              "name" -> ujson.Str("Alice"),
              "age" -> ujson.Num(42)
            )
        }
        ()
      }
    }

    "handle `application/json` content-type requests with malformed bodies" in {
      serveIdentityEndpoint(serverApi.sumTypedEndpoint) { port =>
        val request =
          HttpRequest(HttpMethods.POST, s"http://localhost:$port/user-or-name")
            .withEntity(
              ContentTypes.`application/json`,
              "{\"name\":\"Alice\"}"
            )
        whenReady(sendAndDecodeEntityAsText(request)) {
          case (response, entity) =>
            assert(response.status.intValue() == 400)
        }
        ()
      }

    }

    "not handle `application/x-www-form-urlencoded` content-type requests" in {
      serveIdentityEndpoint(serverApi.sumTypedEndpoint) { port =>
        val request =
          HttpRequest(HttpMethods.POST, s"http://localhost:$port/user-or-name")
            .withEntity(
              ContentTypes.`application/x-www-form-urlencoded`,
              "name=Alice&age=42"
            )
        whenReady(sendAndDecodeEntityAsText(request)) {
          case (response, _) =>
            assert(response.status.intValue() == 415)
        }
        ()
      }
    }
  }
} 
Example 95
Source File: CounterTest.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package quickstart

import java.net.ServerSocket

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpMethods, HttpRequest, StatusCodes}
import akka.http.scaladsl.server.Directives._
import org.scalatest.BeforeAndAfterAll

import scala.concurrent.Await
import scala.concurrent.duration.DurationInt
import org.scalatest.freespec.AsyncFreeSpec

class CounterTest extends AsyncFreeSpec with BeforeAndAfterAll {

  implicit val actorSystem: ActorSystem = ActorSystem()
  val routes = CounterServer.routes ~ DocumentationServer.routes
  val interface = "0.0.0.0"
  val port = findOpenPort()
  val server = Http().bindAndHandle(routes, interface, port)

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

  "CounterServer" - {
    "Query counter value" in {
      for {
        response <- Http().singleRequest(
          HttpRequest(uri = uri("/current-value"))
        )
        entity <- response.entity.toStrict(1.second)
      } yield {
        assert(response.status == StatusCodes.OK)
        assert(entity.contentType == ContentTypes.`application/json`)
        assert(entity.data.utf8String == "{\"value\":0}")
      }
    }
    "Increment counter value" in {
      val request =
        HttpRequest(
          method = HttpMethods.POST,
          uri = uri("/increment"),
          entity = HttpEntity(ContentTypes.`application/json`, "{\"step\":1}")
        )
      for {
        response <- Http().singleRequest(request)
      } yield {
        assert(response.status == StatusCodes.OK)
      }
    }
    "Query API documentation" in {
      for {
        response <- Http().singleRequest(
          HttpRequest(uri = uri("/documentation.json"))
        )
        entity <- response.entity.toStrict(1.second)
      } yield {
        assert(response.status == StatusCodes.OK)
        assert(entity.contentType == ContentTypes.`application/json`)
      }
    }
  }

  def findOpenPort(): Int = {
    val socket = new ServerSocket(0)
    try socket.getLocalPort
    finally if (socket != null) socket.close()
  }

  def uri(suffix: String) = s"http://$interface:$port$suffix"

} 
Example 96
Source File: EndpointsSettings.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.akkahttp.client

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, HttpResponse, Uri}
import akka.stream.Materializer
import akka.stream.scaladsl.{Flow, Sink, Source}

import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.Try

final case class EndpointsSettings(
    requestExecutor: AkkaHttpRequestExecutor,
    baseUri: Uri = Uri("/"),
    toStrictTimeout: FiniteDuration = 2.seconds,
    stringContentExtractor: HttpEntity.Strict => String = _.data.utf8String
)

trait AkkaHttpRequestExecutor {
  def apply(request: HttpRequest): Future[HttpResponse]
}

object AkkaHttpRequestExecutor {
  def cachedHostConnectionPool(host: String, port: Int)(implicit
      system: ActorSystem,
      materializer: Materializer
  ): AkkaHttpRequestExecutor =
    default(Http().cachedHostConnectionPool[Int](host, port))

  def default(
      poolClientFlow: Flow[
        (HttpRequest, Int),
        (Try[HttpResponse], Int),
        Http.HostConnectionPool
      ]
  )(implicit materializer: Materializer): AkkaHttpRequestExecutor =
    new AkkaHttpRequestExecutor {
      override def apply(request: HttpRequest): Future[HttpResponse] =
        Source
          .single(request -> 1)
          .via(poolClientFlow)
          .map(_._1.get)
          .runWith(Sink.head)
    }
} 
Example 97
Source File: ChunkedEntities.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.akkahttp.server

import akka.http.scaladsl.marshalling.Marshaller
import akka.http.scaladsl.model.{ContentType, ContentTypes, HttpEntity, HttpRequest, MessageEntity}
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.stream.scaladsl.Source
import akka.util.ByteString
import endpoints4s.algebra

import scala.concurrent.Future


trait ChunkedJsonEntities
    extends algebra.ChunkedJsonEntities
    with ChunkedEntities
    with JsonEntitiesFromCodecs {

  def jsonChunksRequest[A](implicit
      codec: JsonCodec[A]
  ): RequestEntity[Chunks[A]] = {
    val decoder = stringCodec(codec)
    chunkedRequestEntity { byteString =>
      val string = byteString.utf8String
      decoder
        .decode(string)
        .toEither
        .left
        .map(errors => new Throwable(errors.mkString(". ")))
    }
  }

  def jsonChunksResponse[A](implicit
      codec: JsonCodec[A]
  ): ResponseEntity[Chunks[A]] = {
    val encoder = stringCodec(codec)
    chunkedResponseEntity(
      ContentTypes.`application/json`,
      a => ByteString(encoder.encode(a))
    )
  }

} 
Example 98
Source File: MarshallerTestSupport.scala    From wix-http-testkit   with MIT License 5 votes vote down vote up
package com.wix.e2e.http.drivers

import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import com.wix.e2e.http.drivers.MarshallingTestObjects.SomeCaseClass
import com.wix.e2e.http.exceptions.MissingMarshallerException
import com.wix.test.random.{randomInt, randomStr}
import org.specs2.execute.AsResult
import org.specs2.matcher.Matcher
import org.specs2.matcher.ResultMatchers.beError

trait MarshallerTestSupport {
  val someObject = SomeCaseClass(randomStr, randomInt)
  val content = randomStr

  def aResponseWith(body: String) = HttpResponse(entity = body)
  def aRequestWith(body: String) = HttpRequest(entity = body)
  val request = HttpRequest()
}


object MarshallingTestObjects {
  case class SomeCaseClass(s: String, i: Int)
}

object MarshallerMatchers {
  def beMissingMarshallerMatcherError[T : AsResult]: Matcher[T] = beError[T](new MissingMarshallerException().getMessage)
} 
Example 99
Source File: MarshallerTestSupport.scala    From wix-http-testkit   with MIT License 5 votes vote down vote up
package com.wix.e2e.http.drivers

import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import com.wix.e2e.http.api.Marshaller
import com.wix.e2e.http.drivers.MarshallingTestObjects.SomeCaseClass
import com.wix.test.random.{randomInt, randomStr}

import scala.collection.concurrent.TrieMap

trait MarshallerTestSupport {
  val someObject = SomeCaseClass(randomStr, randomInt)
  val content = randomStr

  def givenMarshallerThatUnmarshalWith(unmarshal: SomeCaseClass, forContent: String): Unit =
    MarshallingTestObjects.unmarshallResult.put(forContent, unmarshal)

  def givenMarshallerThatMarshal(content: String, to: SomeCaseClass): Unit =
    MarshallingTestObjects.marshallResult.put(to, content)

  def aResponseWith(body: String) = HttpResponse(entity = body)
  def aRequestWith(body: String) = HttpRequest(entity = body)
  val request = HttpRequest()
}

object MarshallingTestObjects {
  case class SomeCaseClass(s: String, i: Int)

  val marshallResult = TrieMap.empty[SomeCaseClass, String]
  val unmarshallResult = TrieMap.empty[String, SomeCaseClass]

  class MarshallerForTest extends Marshaller {

    def unmarshall[T: Manifest](jsonStr: String) =
      MarshallingTestObjects.unmarshallResult
                            .getOrElse(jsonStr, throw new UnsupportedOperationException)
                            .asInstanceOf[T]

    def marshall[T](t: T) =
      MarshallingTestObjects.marshallResult
                            .getOrElse(t.asInstanceOf[SomeCaseClass], throw new UnsupportedOperationException)
  }
} 
Example 100
Source File: HttpClientTransformersTestSupport.scala    From wix-http-testkit   with MIT License 5 votes vote down vote up
package com.wix.e2e.http.drivers

import java.nio.file.{Files, Path}

import akka.http.scaladsl.model.HttpRequest
import com.wix.e2e.http.HttpRequest
import com.wix.e2e.http.client.extractors._
import com.wix.e2e.http.client.transformers._
import com.wix.e2e.http.matchers.RequestMatcher
import com.wix.test.random._
import org.specs2.matcher.Matchers.contain

trait HttpClientTransformersTestSupport {
  val request = HttpRequest()

  val keyValue1 = randomStrPair
  val keyValue2 = randomStrPair
  val keyValue3 = randomStrPair
  val escapedCharacters = "!'();:@&=+$,/?%#[]\"'/\\"
  val userAgent = randomStr
  val someBody = randomStr
  val someBytes = randomBytes(100)
  val payload = SomePayload(randomStr, randomStr)
  val strBody = randomStr

  val partName = randomStr
  val fileNameOpt = randomStrOpt

  val plainRequestPart = randomStr -> PlainRequestPart(randomStr)
  val plainRequestXmlPart = randomStr -> PlainRequestPart(randomStr, HttpClientContentTypes.XmlContent)
  val binaryRequestPart = randomStr -> BinaryRequestPart(randomBytes(20))
  val binaryRequestXmlPart = randomStr -> BinaryRequestPart(randomBytes(20), HttpClientContentTypes.XmlContent)
  val binaryRequestXmlPartAndFilename = randomStr -> BinaryRequestPart(randomBytes(20), HttpClientContentTypes.XmlContent, fileNameOpt)


  def givenFileWith(content: Array[Byte]): Path = {
    val f = Files.createTempFile("multipart", ".tmp")
    Files.write(f, content)
    f
  }
}

case class SomePayload(key: String, value: String)

object HttpClientTransformersMatchers extends HttpClientTransformers {

  def haveBodyPartWith(part: (String, PlainRequestPart)): RequestMatcher =
    ( contain(s"""Content-Disposition: form-data; name="${part._1}"""") and
      contain(s"""Content-Type: ${part._2.contentType.value}""") and
      contain(part._2.body) ) ^^ { (_: HttpRequest).entity.extractAsString }

  // todo: matcher binary data on multipart request
  def haveBinaryBodyPartWith(part: (String, BinaryRequestPart)): RequestMatcher =
    ( contain(s"""Content-Disposition: form-data;""") and
      contain(s"""; name="${part._1}"""") and
      (if (part._2.filename.isEmpty) contain(";") else contain(s"""; filename="${part._2.filename.get}""")) and
      contain(s"""Content-Type: ${part._2.contentType.value}""") and
      contain(s"""Content-Type: ${part._2.contentType.value}""")  ) ^^ { (_: HttpRequest).entity.extractAsString } // todo: match body

} 
Example 101
Source File: AkkaHttpMockWebServer.scala    From wix-http-testkit   with MIT License 5 votes vote down vote up
package com.wix.e2e.http.server.internals

import akka.http.scaladsl.Http
import akka.http.scaladsl.Http.ServerBinding
import akka.http.scaladsl.model.headers.{ProductVersion, Server}
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.settings.ServerSettings
import com.wix.e2e.http.api.BaseWebServer
import com.wix.e2e.http.info.HttpTestkitVersion
import com.wix.e2e.http.utils._
import com.wix.e2e.http.{BaseUri, RequestHandler, WixHttpTestkitResources}

import scala.concurrent.Future
import scala.concurrent.duration._

abstract class AkkaHttpMockWebServer(specificPort: Option[Int], val initialHandlers: Seq[RequestHandler])
  extends BaseWebServer
  with AdjustableServerBehaviorSupport {

  import WixHttpTestkitResources.{executionContext, materializer, system}

  protected def serverBehavior: RequestHandler

  def start() = this.synchronized {
    val s = waitFor( Http().bindAndHandleAsync(handler = TransformToStrictAndHandle,
                                               interface = "localhost",
                                               settings = customSettings,
                                               port = specificPort.getOrElse( AllocateDynamicPort )) )
    serverBinding = Option(s)
    println(s"Web server started on port: ${baseUri.port}.")
    this
  }

  def stop() = this.synchronized {
    serverBinding.foreach{ s =>
      waitFor( s.unbind() )
    }
    serverBinding = None
    this
  }

  def baseUri =
    specificPort.map( p => BaseUri("localhost", port = p) )
                .orElse( serverBinding.map( s => BaseUri(port = s.localAddress.getPort) ))
                .getOrElse( throw new IllegalStateException("Server port and baseUri will have value after server is started") )

  private var serverBinding: Option[ServerBinding] = None
  private val AllocateDynamicPort = 0
  private val TransformToStrictAndHandle: HttpRequest => Future[HttpResponse] = _.toStrict(1.minutes).map( serverBehavior )
  private def customSettings =
    ServerSettings(system).withTransparentHeadRequests(false)
                          .withServerHeader( Some(Server(ProductVersion("server-http-testkit", HttpTestkitVersion))) )
} 
Example 102
Source File: K8sProbesTest.scala    From healthchecks   with MIT License 5 votes vote down vote up
package com.chatwork.healthcheck.k8s

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import akka.stream.ActorMaterializer
import com.github.everpeace.healthchecks._
import com.github.everpeace.healthchecks.k8s._
import org.scalatest._

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

class K8sProbesTest extends FreeSpec with Matchers {

  private def fixture(probe: K8sProbe, probes: K8sProbe*) = new {}

  "K8sProbes" - {
    "should start successfully and return correct response" in {
      implicit val system = ActorSystem()
      implicit val am     = ActorMaterializer()
      implicit val ec     = system.dispatcher

      val probeBinding = bindAndHandleProbes(
        readinessProbe(healthCheck("readiness_check")(healthy)),
        livenessProbe(asyncHealthCheck("liveness_check")(Future(healthy)))
      )

      def requestToLivenessProbe =
        Http().singleRequest(HttpRequest(uri = "http://localhost:8086/live"))
      def requestToReadinessProbe =
        Http().singleRequest(HttpRequest(uri = "http://localhost:8086/ready"))

      val livenessResponse = Await.result(requestToLivenessProbe, 10 seconds)
      val redinessResponse = Await.result(requestToReadinessProbe, 10 seconds)

      livenessResponse.status shouldEqual StatusCodes.OK
      redinessResponse.status shouldEqual StatusCodes.OK

      system.terminate()
    }
  }
} 
Example 103
Source File: MockOAuth2Server.scala    From incubator-retired-gearpump   with Apache License 2.0 5 votes vote down vote up
package org.apache.gearpump.services.security.oauth2

import scala.concurrent.{Await, Future}

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.Http.ServerBinding
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink

import org.apache.gearpump.util.Util
// NOTE: This cannot be removed!!
import org.apache.gearpump.services.util.UpickleUtil._


class MockOAuth2Server(
    actorSystem: ActorSystem,
    var requestHandler: HttpRequest => HttpResponse) {

  implicit val system: ActorSystem = actorSystem
  implicit val materializer = ActorMaterializer()
  implicit val ec = system.dispatcher

  private var _port: Int = 0
  private var bindingFuture: Future[ServerBinding] = null

  def port: Int = _port

  def start(): Unit = {
    _port = Util.findFreePort().get

    val serverSource = Http().bind(interface = "127.0.0.1", port = _port)
    bindingFuture = {
      serverSource.to(Sink.foreach { connection =>
        connection handleWithSyncHandler requestHandler
      }).run()
    }
  }

  def stop(): Unit = {
    import scala.concurrent.duration._
    Await.result(bindingFuture.map(_.unbind()), 120.seconds)
  }
} 
Example 104
Source File: HttpFeeRateProvider.scala    From bitcoin-s   with MIT License 5 votes vote down vote up
package org.bitcoins.feeprovider

import java.time.{Duration, Instant}

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.util.ByteString
import org.bitcoins.core.api.FeeRateApi
import org.bitcoins.core.util.TimeUtil
import org.bitcoins.core.wallet.fee.FeeUnit

import scala.concurrent.{ExecutionContextExecutor, Future}
import scala.util.Try

object HttpFeeRateProvider {

  def makeApiCall(uri: Uri)(implicit system: ActorSystem): Future[String] = {
    implicit val ec: ExecutionContextExecutor = system.dispatcher
    Http()
      .singleRequest(HttpRequest(uri = uri))
      .flatMap(response =>
        response.entity.dataBytes
          .runFold(ByteString.empty)(_ ++ _)
          .map(payload => payload.decodeString(ByteString.UTF_8)))
  }
}

abstract class HttpFeeRateProvider extends FeeRateApi {
  implicit protected val system: ActorSystem

  protected def uri: Uri

  protected def converter(str: String): Try[FeeUnit]

  def getFeeRate: Future[FeeUnit] = {
    HttpFeeRateProvider
      .makeApiCall(uri)
      .flatMap(ret => Future.fromTry(converter(ret)))(system.dispatcher)
  }
}

abstract class CachedHttpFeeRateProvider extends HttpFeeRateProvider {

  private var cachedFeeRateOpt: Option[(FeeUnit, Instant)] = None

  val cacheDuration: Duration = Duration.ofMinutes(5)

  private def updateFeeRate(): Future[FeeUnit] = {
    implicit val ec: ExecutionContextExecutor = system.dispatcher
    super.getFeeRate.map { feeRate =>
      cachedFeeRateOpt = Some(feeRate, TimeUtil.now)
      feeRate
    }
  }

  override def getFeeRate: Future[FeeUnit] = {
    cachedFeeRateOpt match {
      case None =>
        updateFeeRate()
      case Some((cachedFeeRate, time)) =>
        val now = TimeUtil.now
        if (time.plus(cacheDuration).isAfter(now)) {
          updateFeeRate()
        } else {
          Future.successful(cachedFeeRate)
        }
    }
  }
} 
Example 105
Source File: TestKit.scala    From introduction-to-akkahttp   with Apache License 2.0 5 votes vote down vote up
package com.shashank.akkahttp.basic.routing

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives._
import akka.stream.{ActorMaterializer, Materializer}
import org.scalatest.{ Matchers, WordSpec }
import akka.http.scaladsl.testkit.ScalatestRouteTest



object TestKit extends WordSpec with Matchers with ScalatestRouteTest {

  def main(args: Array[String]) {

    val route =
      path("welcome"){
        get{
          complete {
            "welcome to rest service"
          }
        }
      } ~
        path("demo"){
          get{
            complete {
              "welcome to demonstration"
            }
          }
        }


    val getRequest = HttpRequest(GET, "/welcome")

    getRequest ~> route ~> check {
      status.intValue shouldEqual 200
      entityAs[String] shouldEqual "welcome to rest service"
    }

    system.terminate()
  }

} 
Example 106
Source File: UnMarshalling.scala    From introduction-to-akkahttp   with Apache License 2.0 5 votes vote down vote up
package com.shashank.akkahttp.basic.routing

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{HttpMethods, HttpRequest, HttpResponse, MessageEntity}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.{ActorMaterializer, Materializer}
import akka.util.ByteString

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import spray.json._


object UnMarshalling {

  def main(args: Array[String]) {

    implicit val sys = ActorSystem("IntroductionToAkkaHttp")
    implicit val mat:Materializer = ActorMaterializer()

    //type FromStringUnmarshaller[T] = Unmarshaller[String, T]
    val intFuture = Unmarshal("42").to[Int]
    val int = Await.result(intFuture, 1.second)
    println("int unmarshalling "+int)

    //type FromStringUnmarshaller[T] = Unmarshaller[String, T]
    val boolFuture = Unmarshal("off").to[Boolean]
    val bool = Await.result(boolFuture, 1.second)
    println("off unmarshalling "+bool)

    //type ToEntityMarshaller[T] = Marshaller[T, MessageEntity]
    val string = "Yeah"
    val entityFuture = Marshal(string).to[MessageEntity]
    val entity = Await.result(entityFuture, 1.second) // don't block in non-test code!
    println(entity)

    //type ToResponseMarshaller[T] = Marshaller[T, HttpResponse]
    val errorMsg = "Not found, pal!"
    val responseFuture = Marshal(404 -> errorMsg).to[HttpResponse]
    val response = Await.result(responseFuture, 1.second)
    println(response)


    //type FromEntityUnmarshaller[T] = Unmarshaller[HttpEntity, T]
    val jsonByteString = ByteString("""{"name":"Hello"}""")
    val httpRequest = HttpRequest(HttpMethods.POST, entity = jsonByteString)
    val jsonDataUnmarshalledFuture = Unmarshal(httpRequest).to[String]
    val jsonDataUnmarshalled = Await.result(jsonDataUnmarshalledFuture, 1.second)
    println(jsonDataUnmarshalled)

    sys.terminate()

  }

} 
Example 107
Source File: RequestLevelClientAPIApplication.scala    From Akka-Cookbook   with MIT License 5 votes vote down vote up
package com.packt.chapter9

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.stream.ActorMaterializer
import scala.concurrent.duration._
import scala.util.Success

object RequestLevelClientAPIApplication extends App {

  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()
  implicit val executionContext = system.dispatcher

  val akkaToolkitRequest = HttpRequest(uri = "https://api.github.com/repos/akka/akka-http")
  val responseFuture = Http().singleRequest(akkaToolkitRequest)

  responseFuture.andThen {
    case Success(response) =>
      response.entity.toStrict(5 seconds).map(_.data.decodeString("UTF-8")).andThen {
        case Success(json) =>
          val pattern = """.*"open_issues":(.*?),.*""".r
          pattern.findAllIn(json).matchData foreach { m =>
            println(s"There are ${m.group(1)} open issues in Akka Http.")
            materializer.shutdown()
            system.terminate()
          }
        case _ =>
      }
    case _ => println(s"request failed")
  }
} 
Example 108
Source File: HostLevelClientAPIApplication.scala    From Akka-Cookbook   with MIT License 5 votes vote down vote up
package com.packt.chapter9

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}

import scala.concurrent.duration._
import scala.util.{Failure, Success}

object HostLevelClientAPIApplication extends App {
  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()
  implicit val executionContext = system.dispatcher

  val poolClientFlow = Http().cachedHostConnectionPoolHttps[String]("api.github.com")
  val akkaToolkitRequest = HttpRequest(uri = "/repos/akka/akka-http") -> """.*"open_issues":(.*?),.*"""
  val responseFuture = Source.single(akkaToolkitRequest).via(poolClientFlow).runWith(Sink.head)

  responseFuture.andThen {
    case Success(result) =>
      val (tryResponse, regex) = result
      tryResponse match {
        case Success(response) =>
          response.entity.toStrict(5 seconds).map(_.data.decodeString("UTF-8")).andThen {
            case Success(json) =>
              val pattern = regex.r
              pattern.findAllIn(json).matchData foreach { m =>
                println(s"There are ${m.group(1)} open issues in Akka Http.")
                materializer.shutdown()
                system.terminate()
              }
            case _ =>
          }
        case _ => println("request failed")
      }
    case _ => println("request failed")
  }
} 
Example 109
Source File: ConnectionLevelClientAPIApplication.scala    From Akka-Cookbook   with MIT License 5 votes vote down vote up
package com.packt.chapter9

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}

import scala.util.{Failure, Success}
import scala.concurrent.duration._

object ConnectionLevelClientAPIApplication extends App {

  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()
  implicit val executionContext = system.dispatcher

  val connectionFlow = Http().outgoingConnectionHttps("api.github.com")
  val akkaToolkitRequest = HttpRequest(uri = "/repos/akka/akka-http")

  val responseFuture = Source.single(akkaToolkitRequest).via(connectionFlow).runWith(Sink.head)

  responseFuture.andThen {
    case Success(response) =>
      response.entity.toStrict(5 seconds).map(_.data.decodeString("UTF-8")).andThen {
        case Success(json) =>
          val pattern = """.*"open_issues":(.*?),.*""".r
          pattern.findAllIn(json).matchData foreach { m =>
            println(s"There are ${m.group(1)} open issues in Akka Http.")
            materializer.shutdown()
            system.terminate()
          }
        case _ =>
      }
    case _ => println("request failed")
  }
} 
Example 110
Source File: QrCodesBot.scala    From telegram   with Apache License 2.0 5 votes vote down vote up
import java.net.URLEncoder

import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.util.ByteString
import com.bot4s.telegram.api.declarative.Commands
import com.bot4s.telegram.api._
import com.bot4s.telegram.future.Polling
import com.bot4s.telegram.methods._
import com.bot4s.telegram.models.AkkaInputFile

import scala.concurrent.Future


class QrCodesBot(token: String) extends AkkaExampleBot(token)
  with Polling
  with Commands[Future]
  with ChatActions[Future] {

  // Multiple variants
  onCommand('qr | 'qrcode | 'qr_code) { implicit msg =>
    withArgs { args =>
      val url = "https://api.qrserver.com/v1/create-qr-code/?data=" +
        URLEncoder.encode(args mkString " ", "UTF-8")

      for {
        response <- Http().singleRequest(HttpRequest(uri = Uri(url)))
        if response.status.isSuccess()
        bytes <- Unmarshal(response).to[ByteString]
        photo = AkkaInputFile("qrcode.png", bytes)
        _ <- uploadingPhoto // Hint the user
        _ <- request(SendPhoto(msg.source, photo))
      } yield ()
    }
  }
} 
Example 111
Source File: VoiceFileBot.scala    From telegram   with Apache License 2.0 5 votes vote down vote up
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.util.ByteString
import cats.instances.future._
import cats.syntax.functor._
import com.bot4s.telegram.api.declarative.Commands
import com.bot4s.telegram.future.Polling
import com.bot4s.telegram.methods._

import scala.concurrent.Future
import scala.util.{Failure, Success}


class VoiceFileBot(token: String) extends AkkaExampleBot(token)
  with Polling
  with Commands[Future] {

  onMessage { implicit msg =>

    using(_.voice) { voice =>
      request(GetFile(voice.fileId)).andThen({
        case Success(file) =>
          file.filePath match {

            case Some(filePath) =>
              // See https://core.telegram.org/bots/api#getfile
              val url = s"https://api.telegram.org/file/bot${token}/${filePath}"

              for {
                res <- Http().singleRequest(HttpRequest(uri = Uri(url)))
                if res.status.isSuccess()
                bytes <- Unmarshal(res).to[ByteString]
                _ <- reply(s"File with ${bytes.size} bytes received.")
              } yield ()
            case None =>
              reply("No file_path was returned")
          }

        case Failure(e) =>
          logger.error("Exception: " + e) // poor's man logging
      }).void
    }
  }
} 
Example 112
Source File: WebhookBot.scala    From telegram   with Apache License 2.0 5 votes vote down vote up
import java.net.URLEncoder

import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.http.scaladsl.unmarshalling.Unmarshal
import com.bot4s.telegram.api.Webhook
import com.bot4s.telegram.methods._
import com.bot4s.telegram.models.Message

import scala.concurrent.Future


class WebhookBot(token: String) extends AkkaExampleBot(token) with Webhook {

  val port = 8080
  val webhookUrl = "https://88c444ab.ngrok.io"

  val baseUrl = "http://api.mathjs.org/v1/?expr="

  override def receiveMessage(msg: Message): Future[Unit] = {
    msg.text.fold(Future.successful(())) { text =>
      val url = baseUrl + URLEncoder.encode(text, "UTF-8")
      for {
        res <- Http().singleRequest(HttpRequest(uri = Uri(url)))
        if res.status.isSuccess()
        result <- Unmarshal(res).to[String]
        _ <- request(SendMessage(msg.source, result))
      } yield ()
    }
  }
} 
Example 113
Source File: StreamingUpload.scala    From ws_to_kafka   with MIT License 5 votes vote down vote up
package com.pkinsky

import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpResponse, HttpRequest}
import akka.http.scaladsl.model.ws.{TextMessage, Message}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.PathMatchers.PathEnd
import akka.stream._
import akka.stream.scaladsl._
import com.softwaremill.react.kafka.ReactiveKafka
import play.api.libs.json.Json
import scala.concurrent.{Future, ExecutionContext}
import scala.concurrent.duration._
import scala.util.Success
import scala.language.postfixOps

object StreamingUpload extends App with AppContext {
  val kafkaPublisherGraph: RunnableGraph[SourceQueue[Event]] =
    Source.queue[Event](1024, OverflowStrategy.backpressure).to(kafka.publish[Event](eventTopic))

  val sourceQueue: SourceQueue[Event] = kafkaPublisherGraph.run

  val queueWriter: Sink[Event, Unit] =
    Flow[Event].mapAsync(1){ elem =>
      sourceQueue.offer(elem)
        .andThen{
          case Success(false) => println(s"failed to publish $elem to topic $eventTopic")
          case Success(true) => println(s"published $elem to topic $eventTopic")
        }
    }.to(Sink.ignore)

  val parseMessages: Flow[Message, Event, Unit] =
    Flow[Message]
      .collect{
        case TextMessage.Strict(t) =>
          val js = Json.parse(t)
          Json.fromJson[Event](js).get
      }

  val wsHandlerFlow: Flow[Message, Message, Unit] =
    Flow.fromSinkAndSource(
      sink = parseMessages.to(queueWriter),
      source = Source.maybe
    )

  val routes: Flow[HttpRequest, HttpResponse, Unit] =
      get {
        path(PathEnd) {
          getFromResource("test.html")
        } ~
          path("ws") {
            println("ws connection accepted")
            handleWebsocketMessages(wsHandlerFlow)
          }
      }

  Http().bindAndHandle(routes, "localhost", port).andThen{ case util.Failure(t) => println(s"error binding to localhost: $t")}

  println(s"listening on port $port, press ENTER to stop")

  awaitTermination()
}

object KafkaListener extends App with AppContext {
  val graph = kafka.consume[Event](eventTopic, "kafka_listener").toMat(Sink.foreach(println))(Keep.right)

  graph.run.onComplete(println)

  println(s"listening to Kafka topic $eventTopic, press ENTER to stop")

  awaitTermination()
} 
Example 114
Source File: HttpClusterBootstrapRoutes.scala    From akka-management   with Apache License 2.0 5 votes vote down vote up
package akka.management.cluster.bootstrap.contactpoint

import scala.concurrent.duration._

import akka.actor.ActorSystem
import akka.cluster.Cluster
import akka.cluster.Member
import akka.event.Logging
import akka.event.LoggingAdapter
import akka.http.javadsl.server.directives.RouteAdapter
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.Uri
import akka.http.scaladsl.server.Route
import akka.management.cluster.bootstrap.ClusterBootstrapSettings
import akka.management.cluster.bootstrap.contactpoint.HttpBootstrapJsonProtocol.ClusterMember
import akka.management.cluster.bootstrap.contactpoint.HttpBootstrapJsonProtocol.SeedNodes

final class HttpClusterBootstrapRoutes(settings: ClusterBootstrapSettings) extends HttpBootstrapJsonProtocol {

  import akka.http.scaladsl.server.Directives._

  private def routeGetSeedNodes: Route = extractClientIP { clientIp =>
    extractActorSystem { implicit system =>
      import akka.cluster.MemberStatus
      val cluster = Cluster(system)

      def memberToClusterMember(m: Member): ClusterMember =
        ClusterMember(m.uniqueAddress.address, m.uniqueAddress.longUid, m.status.toString, m.roles)

      val state = cluster.state

      // TODO shuffle the members so in a big deployment nodes start joining different ones and not all the same?
      val members = state.members
        .diff(state.unreachable)
        .filter(m =>
          m.status == MemberStatus.up || m.status == MemberStatus.weaklyUp || m.status == MemberStatus.joining)
        .take(settings.contactPoint.httpMaxSeedNodesToExpose)
        .map(memberToClusterMember)

      val info = SeedNodes(cluster.selfMember.uniqueAddress.address, members)
      log.info(
        "Bootstrap request from {}: Contact Point returning {} seed-nodes [{}]",
        clientIp,
        members.size,
        members.map(_.node).mkString(", "))
      complete(info)
    }
  }

  
  def getRoutes: akka.http.javadsl.server.Route = RouteAdapter(routes)

  private def log(implicit sys: ActorSystem): LoggingAdapter =
    Logging(sys, classOf[HttpClusterBootstrapRoutes])

}

object ClusterBootstrapRequests {

  import akka.http.scaladsl.client.RequestBuilding._

  def bootstrapSeedNodes(baseUri: Uri): HttpRequest =
    Get(baseUri + "/bootstrap/seed-nodes")

} 
Example 115
Source File: MultiDcSpec.scala    From akka-management   with Apache License 2.0 5 votes vote down vote up
package akka.management.cluster

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{ HttpRequest, StatusCodes }
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.management.scaladsl.ManagementRouteProviderSettings
import akka.stream.ActorMaterializer
import akka.testkit.SocketUtil
import com.typesafe.config.ConfigFactory
import org.scalatest.{ Matchers, WordSpec }
import org.scalatest.concurrent.{ Eventually, ScalaFutures }
import org.scalatest.time.{ Millis, Seconds, Span }

class MultiDcSpec
    extends WordSpec
    with Matchers
    with ScalaFutures
    with ClusterHttpManagementJsonProtocol
    with Eventually {

  implicit val patience: PatienceConfig = PatienceConfig(timeout = Span(10, Seconds), interval = Span(50, Millis))

  val config = ConfigFactory.parseString(
    """
      |akka.actor.provider = "cluster"
      |akka.remote.log-remote-lifecycle-events = off
      |akka.remote.netty.tcp.hostname = "127.0.0.1"
      |#akka.loglevel = DEBUG
    """.stripMargin
  )

  "Http cluster management" must {
    "allow multiple DCs" in {
      val Vector(httpPortA, portA, portB) = SocketUtil.temporaryServerAddresses(3, "127.0.0.1").map(_.getPort)
      val dcA = ConfigFactory.parseString(
        s"""
           |akka.management.http.hostname = "127.0.0.1"
           |akka.management.http.port = $httpPortA
           |akka.cluster.seed-nodes = ["akka.tcp://[email protected]:$portA"]
           |akka.cluster.multi-data-center.self-data-center = "DC-A"
           |akka.remote.netty.tcp.port = $portA
          """.stripMargin
      )
      val dcB = ConfigFactory.parseString(
        s"""
           |akka.cluster.seed-nodes = ["akka.tcp://[email protected]:$portA"]
           |akka.cluster.multi-data-center.self-data-center = "DC-B"
           |akka.remote.netty.tcp.port = $portB
          """.stripMargin
      )

      implicit val dcASystem = ActorSystem("MultiDcSystem", config.withFallback(dcA))
      val dcBSystem = ActorSystem("MultiDcSystem", config.withFallback(dcB))
      implicit val materializer = ActorMaterializer()

      val routeSettings =
        ManagementRouteProviderSettings(selfBaseUri = s"http://127.0.0.1:$httpPortA", readOnly = false)

      try {
        Http()
          .bindAndHandle(ClusterHttpManagementRouteProvider(dcASystem).routes(routeSettings), "127.0.0.1", httpPortA)
          .futureValue

        eventually {
          val response =
            Http().singleRequest(HttpRequest(uri = s"http://127.0.0.1:$httpPortA/cluster/members")).futureValue
          response.status should equal(StatusCodes.OK)
          val members = Unmarshal(response.entity).to[ClusterMembers].futureValue
          members.members.size should equal(2)
          members.members.map(_.status) should equal(Set("Up"))
        }
      } finally {
        dcASystem.terminate()
        dcBSystem.terminate()
      }
    }
  }
} 
Example 116
Source File: WebService.scala    From heimdallr   with Apache License 2.0 5 votes vote down vote up
package chat

import scala.concurrent.ExecutionContext.Implicits._
import scala.util.{Failure,Success}
import akka.actor.ActorSystem
import akka.stream.Materializer
import akka.http.scaladsl.Http
import akka.http.scaladsl.Http.{ ServerBinding }
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse, Uri }
import akka.stream.scaladsl.{ Flow, Sink, Source }
import org.slf4j.LoggerFactory

trait WebService {
  val log = LoggerFactory.getLogger("total")
  private var binding: scala.concurrent.Future[ServerBinding] = null

  def serviceBind(serviceName: String, bindRoute: Flow[HttpRequest, HttpResponse, Any], bindPort: Int)
                 (implicit actorSystem: ActorSystem, materializer: Materializer): Unit = {
    binding = Http().bindAndHandle(bindRoute,"0.0.0.0", bindPort)

    // the rest of the sample code will go here
    binding.onComplete {
      //binding success check
      case Success(binding) =>
        val localAddress = binding.localAddress
        log.info(s"${serviceName} is listening on ${localAddress.getAddress}:${localAddress.getPort}")

      case Failure(e) =>
        log.error(s"${serviceName} Binding failed with ${e.getMessage}")
    }
  }

  def serviceUnbind(serviceName: String) = {
    if( binding != null )
    {
      binding
        .flatMap(_.unbind())
        .onComplete(_ =>
          log.info(s"${serviceName} listening port unbinding ... ")
        )
    }
    else
      log.info( s"${serviceName} Unbinding Failed !" )
  }
} 
Example 117
Source File: ElasticSearchBaseClient.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.commons.es.client

import akka.http.scaladsl.model.StatusCodes.GatewayTimeout
import akka.http.scaladsl.model.{HttpRequest, StatusCode, StatusCodes}
import cats.effect.{Effect, Timer}
import cats.implicits._
import ch.epfl.bluebrain.nexus.commons.es.client.ElasticSearchBaseClient._
import ch.epfl.bluebrain.nexus.commons.es.client.ElasticSearchFailure.{ElasticServerError, ElasticUnexpectedError}
import ch.epfl.bluebrain.nexus.commons.http.HttpClient.UntypedHttpClient
import ch.epfl.bluebrain.nexus.sourcing.RetryStrategyConfig
import com.typesafe.scalalogging.Logger
import retry.CatsEffect._
import retry.syntax.all._
import retry.{RetryDetails, RetryPolicy}

import scala.util.control.NonFatal


  private[client] def sanitize(index: String, allowWildCard: Boolean): String = {
    val regex = if (allowWildCard) """[\s|"|\\|<|>|\||,|/|?]""" else """[\s|"|*|\\|<|>|\||,|/|?]"""
    index.replaceAll(regex, "_").dropWhile(_ == '_')
  }
}

object ElasticSearchBaseClient {
  private[client] val docType           = "_doc"
  private[client] val source            = "_source"
  private[client] val anyIndexPath      = "_all"
  private[client] val ignoreUnavailable = "ignore_unavailable"
  private[client] val allowNoIndices    = "allow_no_indices"
  private[client] val trackTotalHits    = "track_total_hits"
} 
Example 118
Source File: EventSource.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.kg.client

import java.util.UUID

import akka.NotUsed
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.headers.OAuth2BearerToken
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.persistence.query.{NoOffset, Offset, Sequence, TimeBasedUUID}
import akka.stream.Materializer
import akka.stream.alpakka.sse.scaladsl.{EventSource => SSESource}
import akka.stream.scaladsl.Source
import ch.epfl.bluebrain.nexus.iam.auth.AccessToken
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri
import com.typesafe.scalalogging.Logger
import io.circe.Decoder
import io.circe.parser.decode

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try

trait EventSource[A] {

  
  def apply[A: Decoder](
      config: KgClientConfig
  )(implicit as: ActorSystem, mt: Materializer, ec: ExecutionContext): EventSource[A] =
    new EventSource[A] {
      private val logger = Logger[this.type]
      private val http   = Http()

      private def addCredentials(request: HttpRequest)(implicit cred: Option[AccessToken]): HttpRequest =
        cred.map(token => request.addCredentials(OAuth2BearerToken(token.value))).getOrElse(request)

      private def send(request: HttpRequest)(implicit cred: Option[AccessToken]): Future[HttpResponse] =
        http.singleRequest(addCredentials(request)).map { resp =>
          if (!resp.status.isSuccess())
            logger.warn(s"HTTP response when performing SSE request: status = '${resp.status}'")
          resp
        }

      private def toOffset(id: String): Offset =
        Try(TimeBasedUUID(UUID.fromString(id))).orElse(Try(Sequence(id.toLong))).getOrElse(NoOffset)

      override def apply(iri: AbsoluteIri, offset: Option[String])(implicit
          cred: Option[AccessToken]
      ): Source[(Offset, A), NotUsed] =
        SSESource(iri.asAkka, send, offset, config.sseRetryDelay).flatMapConcat { sse =>
          val offset = sse.id.map(toOffset).getOrElse(NoOffset)
          decode[A](sse.data) match {
            case Right(ev) => Source.single(offset -> ev)
            case Left(err) =>
              logger.error(s"Failed to decode admin event '$sse'", err)
              Source.empty
          }
        }
    }
} 
Example 119
Source File: IamIdentitiesClient.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.storage

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.client.RequestBuilding.Get
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.headers.OAuth2BearerToken
import akka.http.scaladsl.unmarshalling.FromEntityUnmarshaller
import akka.util.ByteString
import cats.effect.{ContextShift, Effect, IO}
import cats.implicits._
import ch.epfl.bluebrain.nexus.rdf.implicits._
import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClient.Identity._
import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClient._
import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClientError.IdentitiesSerializationError
import ch.epfl.bluebrain.nexus.storage.config.IamClientConfig
import de.heikoseeberger.akkahttpcirce.ErrorAccumulatingCirceSupport.{DecodingFailures => AccDecodingFailures}
import io.circe.Decoder.Result
import io.circe.{Decoder, DecodingFailure, HCursor}

import scala.concurrent.ExecutionContext

class IamIdentitiesClient[F[_]](config: IamClientConfig)(implicit F: Effect[F], as: ActorSystem)
    extends JsonLdCirceSupport {

  private val um: FromEntityUnmarshaller[Caller]      = unmarshaller[Caller]
  implicit private val ec: ExecutionContext           = as.dispatcher
  implicit private val contextShift: ContextShift[IO] = IO.contextShift(ec)

  def apply()(implicit credentials: Option[AccessToken]): F[Caller] =
    credentials match {
      case Some(token) => execute(Get(config.identitiesIri.asAkka).addCredentials(OAuth2BearerToken(token.value)))
      case None        => F.pure(Caller.anonymous)
    }

  private def execute(req: HttpRequest): F[Caller] = {
    IO.fromFuture(IO(Http().singleRequest(req))).to[F].flatMap { resp =>
      if (resp.status.isSuccess())
        IO.fromFuture(IO(um(resp.entity))).to[F].recoverWith {
          case err: AccDecodingFailures => F.raiseError(IdentitiesSerializationError(err.getMessage))
          case err: Error               => F.raiseError(IdentitiesSerializationError(err.getMessage))
        }
      else
        IO.fromFuture(IO(resp.entity.dataBytes.runFold(ByteString(""))(_ ++ _).map(_.utf8String)))
          .to[F]
          .flatMap { err => F.raiseError(IamIdentitiesClientError.unsafe(resp.status, err)) }
    }
  }

}

object IamIdentitiesClient {

  
    final case class Authenticated(realm: String) extends Identity

    private def decodeAnonymous(hc: HCursor): Result[Subject] =
      hc.get[String]("@type").flatMap {
        case "Anonymous" => Right(Anonymous)
        case _           => Left(DecodingFailure("Cannot decode Anonymous Identity", hc.history))
      }

    private def decodeUser(hc: HCursor): Result[Subject] =
      (hc.get[String]("subject"), hc.get[String]("realm")).mapN {
        case (subject, realm) => User(subject, realm)
      }

    private def decodeGroup(hc: HCursor): Result[Identity] =
      (hc.get[String]("group"), hc.get[String]("realm")).mapN {
        case (group, realm) => Group(group, realm)
      }

    private def decodeAuthenticated(hc: HCursor): Result[Identity] =
      hc.get[String]("realm").map(Authenticated)

    private val attempts =
      List[HCursor => Result[Identity]](decodeAnonymous, decodeUser, decodeGroup, decodeAuthenticated)

    implicit val identityDecoder: Decoder[Identity] =
      Decoder.instance { hc =>
        attempts.foldLeft(Left(DecodingFailure("Unexpected", hc.history)): Result[Identity]) {
          case (acc @ Right(_), _) => acc
          case (_, f)              => f(hc)
        }
      }
  }

} 
Example 120
Source File: WolframServiceImpl.scala    From lagom-on-kube   with Apache License 2.0 5 votes vote down vote up
package me.alexray.wolfram.impl

import java.net.URLEncoder

import akka.NotUsed
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.Materializer
import akka.util.ByteString
import com.lightbend.lagom.scaladsl.api.ServiceCall
import me.alexray.wolfram.api.WolframService
import play.api.Configuration

import scala.concurrent.{ExecutionContext, Future}


class WolframServiceImpl(config: Configuration)
                        (implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext)
  extends WolframService
{

  val appID = config.underlying.getString("wolfram.appid")
  val apiUrl = s"http://api.wolframalpha.com/v2/"


  override def query(q: String): ServiceCall[NotUsed, String] = ServiceCall { _ =>

    val url = apiUrl + s"query?appid=$appID&input=" + URLEncoder.encode(q, "UTF-8")

    for {
      response <- Http().singleRequest(HttpRequest(uri = Uri(url)))
      if response.status.isSuccess()
      data <- Unmarshal(response).to[String]
    } yield data

  }

  override def simple(q: String): ServiceCall[NotUsed, Array[Byte]] = ServiceCall { _ =>

    println(s"quetions = '$q'")

    val url = apiUrl + s"simple?appid=$appID&input=" +  URLEncoder.encode(q, "UTF-8").replace("+", "%20")

    println(s"url = '$url'")

    for {
      response <- Http().singleRequest(HttpRequest(uri = Uri(url)))
      if response.status.isSuccess()
      bytes <- Unmarshal(response).to[ByteString]
    } yield {
      println(s"received image ${bytes.size} bytes long")
      bytes.toArray
    }

  }
} 
Example 121
Source File: TimeResponseDirective.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.metrics.extensions

import akka.event.Logging.LogLevel
import akka.event.{Logging, LoggingAdapter}
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.RouteResult.{Complete, Rejected}
import akka.http.scaladsl.server.directives.{DebuggingDirectives, LoggingMagnet}
import cool.graph.metrics.{CustomTag, MetricsManager, TimerMetric}

trait TimeResponseDirective {

  
  def captureResponseTimeFunction(
      loggingAdapter: LoggingAdapter,
      requestTimestamp: Long,
      level: LogLevel = Logging.InfoLevel
  )(req: HttpRequest)(res: Any): Unit = {
    res match {
      case Complete(resp) =>
        val responseTimestamp: Long = System.nanoTime
        val elapsedTime: Long       = (responseTimestamp - requestTimestamp) / 1000000
        requestTimer.record(elapsedTime, Seq(resp.status.toString()))

      case Rejected(_) =>
    }
  }

  def captureResponseTime(log: LoggingAdapter) = {
    val requestTimestamp = System.nanoTime
    captureResponseTimeFunction(log, requestTimestamp)(_)
  }

  val timeResponse = DebuggingDirectives.logRequestResult(LoggingMagnet(captureResponseTime(_)))
}

case class TimeResponseDirectiveImpl(metricsManager: MetricsManager) extends TimeResponseDirective {
  val requestTimer: TimerMetric = metricsManager.defineTimer("responseTime", CustomTag("status"))
} 
Example 122
Source File: RequestRunner.scala    From aws-spi-akka-http   with Apache License 2.0 5 votes vote down vote up
package com.github.matsluni.akkahttpspi

import java.util.concurrent.CompletableFuture

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.settings.ConnectionPoolSettings
import akka.stream.Materializer
import akka.stream.scaladsl.{Keep, Sink}
import org.slf4j.LoggerFactory
import software.amazon.awssdk.http.SdkHttpFullResponse
import software.amazon.awssdk.http.async.SdkAsyncHttpResponseHandler

import scala.compat.java8.FutureConverters
import scala.concurrent.ExecutionContext
import scala.collection.JavaConverters._

class RequestRunner(connectionPoolSettings: ConnectionPoolSettings)(implicit sys: ActorSystem,
                                                          ec: ExecutionContext,
                                                          mat: Materializer) {
  val logger = LoggerFactory.getLogger(this.getClass)

  def run(httpRequest: HttpRequest,
          handler: SdkAsyncHttpResponseHandler): CompletableFuture[Void] = {
    val result = Http()
      .singleRequest(httpRequest, settings = connectionPoolSettings)
      .flatMap { response =>
        val sdkResponse = SdkHttpFullResponse.builder()
          .headers(response.headers.groupBy(_.name()).map{ case (k, v) => k -> v.map(_.value()).asJava }.asJava)
          .statusCode(response.status.intValue())
          .statusText(response.status.reason)
          .build

        handler.onHeaders(sdkResponse)

        val (complete, publisher) = response
          .entity
          .dataBytes
          .map(_.asByteBuffer)
          .alsoToMat(Sink.ignore)(Keep.right)
          .toMat(Sink.asPublisher(fanout = false))(Keep.both)
          .run()

        handler.onStream(publisher)

        complete
      }

    result.failed.foreach(handler.onError)
    FutureConverters.toJava(result.map(_ => null: Void)).toCompletableFuture
  }
} 
Example 123
Source File: Gateway.scala    From reactive-microservices   with MIT License 5 votes vote down vote up
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.client.RequestBuilding
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.FlowMaterializer
import akka.stream.scaladsl.{Sink, Source}
import java.io.IOException
import scala.concurrent.{ExecutionContext, Future}

case class InternalLoginRequest(identityId: Long, authMethod: String = "codecard")
case class InternalReloginRequest(tokenValue: String, authMethod: String = "codecard")

class Gateway(implicit actorSystem: ActorSystem, materializer: FlowMaterializer, ec: ExecutionContext)
  extends JsonProtocols with Config {

  private val identityManagerConnectionFlow = Http().outgoingConnection(identityManagerHost, identityManagerPort)
  private val tokenManagerConnectionFlow = Http().outgoingConnection(tokenManagerHost, tokenManagerPort)

  private def requestIdentityManager(request: HttpRequest): Future[HttpResponse] = {
    Source.single(request).via(identityManagerConnectionFlow).runWith(Sink.head)
  }

  private def requestTokenManager(request: HttpRequest): Future[HttpResponse] = {
    Source.single(request).via(tokenManagerConnectionFlow).runWith(Sink.head)
  }

  def requestToken(tokenValue: String): Future[Either[String, Token]] = {
    requestTokenManager(RequestBuilding.Get(s"/tokens/$tokenValue")).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token].map(Right(_))
        case NotFound => Future.successful(Left("Token expired or not found"))
        case _ => Future.failed(new IOException(s"Token request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestNewIdentity(): Future[Identity] = {
    requestIdentityManager(RequestBuilding.Post("/identities")).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Identity]
        case _ => Future.failed(new IOException(s"Identity request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestLogin(identityId: Long): Future[Token] = {
    val loginRequest = InternalLoginRequest(identityId)
    requestTokenManager(RequestBuilding.Post("/tokens", loginRequest)).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token]
        case _ => Future.failed(new IOException(s"Login request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestRelogin(tokenValue: String): Future[Option[Token]] = {
    requestTokenManager(RequestBuilding.Patch("/tokens", InternalReloginRequest(tokenValue))).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token].map(Option(_))
        case NotFound => Future.successful(None)
        case _ => Future.failed(new IOException(s"Relogin request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }
} 
Example 124
Source File: Gateway.scala    From reactive-microservices   with MIT License 5 votes vote down vote up
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.client.RequestBuilding
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.FlowMaterializer
import akka.stream.scaladsl.{Sink, Source}
import java.io.IOException
import scala.concurrent.{ExecutionContext, Future}

case class InternalLoginRequest(identityId: Long, authMethod: String = "password")
case class InternalReloginRequest(tokenValue: String, authMethod: String = "password")

class Gateway(implicit actorSystem: ActorSystem, materializer: FlowMaterializer, ec: ExecutionContext)
  extends JsonProtocols with Config {

  private val identityManagerConnectionFlow = Http().outgoingConnection(identityManagerHost, identityManagerPort)
  private val tokenManagerConnectionFlow = Http().outgoingConnection(tokenManagerHost, tokenManagerPort)

  private def requestIdentityManager(request: HttpRequest): Future[HttpResponse] = {
    Source.single(request).via(identityManagerConnectionFlow).runWith(Sink.head)
  }

  private def requestTokenManager(request: HttpRequest): Future[HttpResponse] = {
    Source.single(request).via(tokenManagerConnectionFlow).runWith(Sink.head)
  }

  def requestToken(tokenValue: String): Future[Either[String, Token]] = {
    requestTokenManager(RequestBuilding.Get(s"/tokens/$tokenValue")).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token].map(Right(_))
        case NotFound => Future.successful(Left("Token expired or not found"))
        case _ => Future.failed(new IOException(s"Token request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestNewIdentity(): Future[Identity] = {
    requestIdentityManager(RequestBuilding.Post("/identities")).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Identity]
        case _ => Future.failed(new IOException(s"Identity request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestLogin(identityId: Long): Future[Token] = {
    val loginRequest = InternalLoginRequest(identityId)
    requestTokenManager(RequestBuilding.Post("/tokens", loginRequest)).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token]
        case _ => Future.failed(new IOException(s"Login request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestRelogin(tokenValue: String): Future[Option[Token]] = {
    requestTokenManager(RequestBuilding.Patch("/tokens", InternalReloginRequest(tokenValue))).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token].map(Option(_))
        case NotFound => Future.successful(None)
        case _ => Future.failed(new IOException(s"Relogin request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }
} 
Example 125
Source File: MetricsDirectives.scala    From reactive-microservices   with MIT License 5 votes vote down vote up
package metrics.common

import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.server.Directive0

case class RequestResponseStats(request: HttpRequest, response: HttpResponse, time: Long)

trait MetricsDirectives {
  import akka.http.scaladsl.server.directives.BasicDirectives._

  def measureRequestResponse(f: (RequestResponseStats => Unit)): Directive0 = {
    extractRequestContext.flatMap { ctx =>
      val start = System.currentTimeMillis()
      mapResponse { response =>
        val stop = System.currentTimeMillis()
        f(RequestResponseStats(ctx.request, response, stop - start))
        response
      }
    }
  }
}

object MetricsDirectives extends MetricsDirectives 
Example 126
Source File: SessionManager.scala    From reactive-microservices   with MIT License 5 votes vote down vote up
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.client.RequestBuilding
import akka.http.scaladsl.model.{HttpResponse, HttpRequest}
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorFlowMaterializer
import akka.stream.scaladsl.{Sink, Source}
import com.typesafe.config.ConfigFactory
import scala.concurrent.Future

object SessionManager extends App {
  val config = ConfigFactory.load()
  val interface = config.getString("http.interface")
  val port = config.getInt("http.port")
  val tokenManagerHost = config.getString("services.token-manager.host")
  val tokenManagerPort = config.getInt("services.token-manager.port")

  implicit val actorSystem = ActorSystem()
  implicit val materializer = ActorFlowMaterializer()
  implicit val dispatcher = actorSystem.dispatcher

  val tokenManagerConnectionFlow = Http().outgoingConnection(tokenManagerHost, tokenManagerPort)

  def requestTokenManager(request: HttpRequest): Future[HttpResponse] = {
    Source.single(request).via(tokenManagerConnectionFlow).runWith(Sink.head)
  }

  Http().bindAndHandle(interface = interface, port = port, handler = {
    logRequestResult("session-manager") {
      path("session") {
        headerValueByName("Auth-Token") { tokenValue =>
          pathEndOrSingleSlash {
            get {
              complete {
                requestTokenManager(RequestBuilding.Get(s"/tokens/$tokenValue"))
              }
            } ~
            delete {
              complete {
                requestTokenManager(RequestBuilding.Delete(s"/tokens/$tokenValue"))
              }
            }
          }
        }
      }
    }
  })
} 
Example 127
Source File: Gateway.scala    From reactive-microservices   with MIT License 5 votes vote down vote up
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.client.RequestBuilding
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.FlowMaterializer
import akka.stream.scaladsl.{Sink, Source}
import com.restfb.DefaultFacebookClient
import com.restfb.types.User
import java.io.IOException
import scala.concurrent.{blocking, ExecutionContext, Future}
import scala.util.Try

case class InternalLoginRequest(identityId: Long, authMethod: String = "fb")
case class InternalReloginRequest(tokenValue: String, authMethod: String = "fb")

class Gateway(implicit actorSystem: ActorSystem, materializer: FlowMaterializer, ec: ExecutionContext)
  extends JsonProtocols with Config {

  private val identityManagerConnectionFlow = Http().outgoingConnection(identityManagerHost, identityManagerPort)
  private val tokenManagerConnectionFlow = Http().outgoingConnection(tokenManagerHost, tokenManagerPort)

  private def requestIdentityManager(request: HttpRequest): Future[HttpResponse] = {
    Source.single(request).via(identityManagerConnectionFlow).runWith(Sink.head)
  }

  private def requestTokenManager(request: HttpRequest): Future[HttpResponse] = {
    Source.single(request).via(tokenManagerConnectionFlow).runWith(Sink.head)
  }

  def requestToken(tokenValue: String): Future[Either[String, Token]] = {
    requestTokenManager(RequestBuilding.Get(s"/tokens/$tokenValue")).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token].map(Right(_))
        case NotFound => Future.successful(Left("Token expired or not found"))
        case _ => Future.failed(new IOException(s"Token request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestNewIdentity(): Future[Identity] = {
    requestIdentityManager(RequestBuilding.Post("/identities")).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Identity]
        case _ => Future.failed(new IOException(s"Identity request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestLogin(identityId: Long): Future[Token] = {
    val loginRequest = InternalLoginRequest(identityId)
    requestTokenManager(RequestBuilding.Post("/tokens", loginRequest)).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token]
        case _ => Future.failed(new IOException(s"Login request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def requestRelogin(tokenValue: String): Future[Option[Token]] = {
    requestTokenManager(RequestBuilding.Patch("/tokens", InternalReloginRequest(tokenValue))).flatMap { response =>
      response.status match {
        case Success(_) => Unmarshal(response.entity).to[Token].map(Option(_))
        case NotFound => Future.successful(None)
        case _ => Future.failed(new IOException(s"Relogin request failed with status ${response.status} and error ${response.entity}"))
      }
    }
  }

  def getFbUserDetails(accessToken: String): Try[User] = {
    Try {
      blocking {
        val client = new DefaultFacebookClient(accessToken)
        client.fetchObject("me", classOf[User])
      }
    }
  }
} 
Example 128
Source File: HttpClientProvider.scala    From reactive-nakadi   with MIT License 5 votes vote down vote up
package org.zalando.react.nakadi.client.providers

import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.{SSLContext, TrustManager, X509TrustManager}

import akka.actor.ActorContext
import akka.http.scaladsl.Http.OutgoingConnection
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.settings.ClientConnectionSettings
import akka.http.scaladsl.{Http, HttpsConnectionContext}
import akka.stream.scaladsl.Flow

import scala.concurrent.Future
import scala.concurrent.duration._


class HttpClientProvider(actorContext: ActorContext,
                         server: String, port: Int,
                         isConnectionSSL: Boolean = false,
                         acceptAnyCertificate: Boolean = false,
                         connectionTimeout: FiniteDuration) {

  val http = Http(actorContext.system)

  private val settings = {
    ClientConnectionSettings
      .apply(actorContext.system)
      .withConnectingTimeout(connectionTimeout)
      .withIdleTimeout(Duration.Inf)
  }

  val connection: Flow[HttpRequest, HttpResponse, Future[OutgoingConnection]] = {

    isConnectionSSL match {
      case true =>
        val sslContext = if (!acceptAnyCertificate) SSLContext.getDefault else {

          val permissiveTrustManager: TrustManager = new X509TrustManager() {
            override def checkClientTrusted(chain: Array[X509Certificate], authType: String): Unit = {}
            override def checkServerTrusted(chain: Array[X509Certificate], authType: String): Unit = {}
            override def getAcceptedIssuers(): Array[X509Certificate] = Array.empty
          }

          val ctx = SSLContext.getInstance("TLS")
          ctx.init(Array.empty, Array(permissiveTrustManager), new SecureRandom())
          ctx
        }
        http.outgoingConnectionHttps(server, port, new HttpsConnectionContext(sslContext), settings = settings)
      case false =>
        http.outgoingConnection(server, port, settings = settings)
    }
  }

} 
Example 129
Source File: HttpUtil.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package cmwell.analytics.util

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.RequestEntityAcceptance.Tolerated
import akka.http.scaladsl.model.{HttpMethod, HttpRequest, HttpResponse}
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import akka.util.ByteString
import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper}
import com.typesafe.config.ConfigFactory

import scala.concurrent.duration.{MILLISECONDS, _}
import scala.concurrent.{Await, ExecutionContextExecutor, Future}

object HttpUtil {

  private val mapper = new ObjectMapper()

  private val config = ConfigFactory.load
  private val ReadTimeout = FiniteDuration(config.getDuration("extract-index-from-es.read-timeout").toMillis, MILLISECONDS)

  // Elasticsearch uses the POST verb in some places where the request is actually idempotent.
  // Requests that use POST, but are known to be idempotent can use this method.
  // The presence of any non-idempotent request in-flight causes Akka to not retry, and that will tend result in
  // entire downloads failing more often.
  val SAFE_POST = HttpMethod(
    value = "POST",
    isSafe = true,
    isIdempotent = true,
    requestEntityAcceptance = Tolerated)

  def resultAsync(request: HttpRequest,
                  action: String)
                 (implicit system: ActorSystem,
                  executionContext: ExecutionContextExecutor,
                  actorMaterializer: ActorMaterializer): Future[ByteString] =
    Http().singleRequest(request).map {

      case HttpResponse(status, _, entity, _) if status.isSuccess =>
        entity.dataBytes
          .fold(ByteString.empty)(_ ++ _)
          .runWith(Sink.head)

      case HttpResponse(status, _, entity, _) =>
        val message = Await.result(entity.toStrict(10.seconds).map(_.data), 10.seconds).utf8String
        throw new RuntimeException(s"HTTP request for $action failed. Status code: $status, message:$message")
    }
      .flatMap(identity)

  def result(request: HttpRequest,
             action: String,
             timeout: FiniteDuration = ReadTimeout)
            (implicit system: ActorSystem,
             executionContext: ExecutionContextExecutor,
             actorMaterializer: ActorMaterializer): ByteString =
    Await.result(resultAsync(request, action), timeout)

  def jsonResult(request: HttpRequest,
                 action: String,
                 timeout: FiniteDuration = ReadTimeout)
                (implicit system: ActorSystem,
                 executionContext: ExecutionContextExecutor,
                 actorMaterializer: ActorMaterializer): JsonNode =
    mapper.readTree(result(request, action, timeout).utf8String)

  def jsonResultAsync(request: HttpRequest,
                      action: String)
                     (implicit system: ActorSystem,
                      executionContext: ExecutionContextExecutor,
                      actorMaterializer: ActorMaterializer): Future[JsonNode] =
    resultAsync(request, action).map((bytes: ByteString) => mapper.readTree(bytes.utf8String))
} 
Example 130
Source File: DiscoverEsTopology.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package cmwell.analytics.util

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpRequest
import akka.stream.ActorMaterializer
import com.fasterxml.jackson.databind.JsonNode

import scala.collection.JavaConverters._
import scala.collection.breakOut
import scala.concurrent.ExecutionContextExecutor

case class Shard(indexName: String, shard: Int) {

  // This field is not in the constructor argument list since it is not part of equality.
  private var _downloadAttempt: Int = 0

  def downloadAttempt: Int = _downloadAttempt

  def nextAttempt: Shard = {
    val copy = this.copy()
    copy._downloadAttempt = this._downloadAttempt + 1
    copy
  }
}


case class EsTopology(nodes: Map[String, String], // nodeId -> address
                      shards: Map[Shard, Seq[String]], // shard -> Seq[nodeId]
                      allIndexNames: Set[String])


object DiscoverEsTopology {

  def apply(esContactPoint: String,
            aliases: Seq[String] = Seq.empty)
           (implicit system: ActorSystem,
            executionContext: ExecutionContextExecutor,
            actorMaterializer: ActorMaterializer): EsTopology = {

    // Get a map from node name -> address

    val nodesJson = HttpUtil.jsonResult(HttpRequest(uri = s"http://$esContactPoint/_nodes"), "find es nodes")
    val extractAddress = "inet\\[/(.+)]".r // "inet[/10.204.146.152:9304]"
    val nodes: Map[String, String] = nodesJson.get("nodes").fields.asScala.map { entry =>

      val nodeId = entry.getKey
      val extractAddress(hostPort) = entry.getValue.get("http_address").asText

      nodeId -> hostPort
    }.toMap

    // Find all the shards for all indexes.

    val searchShardsJson = HttpUtil.jsonResult(HttpRequest(uri = s"http://$esContactPoint/_search_shards"), "search shards")

    val shards: Map[Shard, Seq[String]] = searchShardsJson.get("shards").elements.asScala.map { shardLocations: JsonNode =>

      // Sort the shard locations so that the primary is first - we will always try the primary first
      val locations = shardLocations.elements.asScala.toSeq.sortBy(_.findValue("primary").booleanValue).reverse

      assert(locations.nonEmpty)
      assert(locations.head.findValue("primary").booleanValue) // first one is primary node

      val indexName = locations.head.findValue("index").asText
      val shard = locations.head.findValue("shard").asInt
      val nodeIds: Vector[String] = locations.map(_.findValue("node").asText)(breakOut)

      Shard(indexName, shard) -> nodeIds
    }.toMap

    // Get a list of aliases that we want to read from.
    // This is used to filter the list of all shards down to the ones that we want to read from.

    def resolveAlias(alias: String): Set[String] = {
      val aliasesJson = HttpUtil.jsonResult(HttpRequest(uri = s"http://$esContactPoint/$alias/_alias"), s"shards for $alias")
      aliasesJson.fieldNames.asScala.toSet
    }

    val readIndexNames: Set[String] = if (aliases.isEmpty)
      resolveAlias("cm_well_all") // Default if no alias or index name specified.
    else
      (Set.empty[String] /: aliases) (_ ++ resolveAlias(_)) // resolve and combine all the index names

    // allIndexNames is useful for validation of parameters to ensure they are all valid index names.

    val allIndexNames: Set[String] = {
      val aliasesJson = HttpUtil.jsonResult(HttpRequest(uri = s"http://$esContactPoint/_all/_alias"), "Get all index names")
      aliasesJson.fieldNames.asScala.toSet
    }

    EsTopology(
      nodes = nodes,
      // Only read shards for indexes that are included in the given aliases or index names.
      shards = shards.filter { case (shard, _) => readIndexNames.contains(shard.indexName) },
      allIndexNames = allIndexNames)
  }
} 
Example 131
Source File: FindContactPoints.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package cmwell.analytics.util

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpMethods.GET
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.stream.ActorMaterializer
import com.fasterxml.jackson.databind.JsonNode

import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContextExecutor
import scala.util.Try

// TODO: These s/b `Uri`s?
case class ContactPoints(cassandra: String,
                         es: String)

object FindContactPoints {

  
  def es(url: String)
        (implicit system: ActorSystem,
         executionContext: ExecutionContextExecutor,
         actorMaterializer: ActorMaterializer): String = {

    val uri = Uri(url)

    val request = HttpRequest(
      method = GET,
      uri = s"http://${uri.authority.host}:${uri.authority.port}/proc/health?format=json")

    val json: JsonNode = HttpUtil.jsonResult(request, "fetch /proc/health")

    val masterIpAddresses: Seq[String] = json.get("fields").findValue("masters").elements.asScala.map(_.textValue).toSeq

    if (masterIpAddresses.isEmpty)
      throw new RuntimeException("No master node addresses found.")

    // For Elasticsearch, the port is 9201 for a single node, and 9200 for clustered.
    val esPort = if (masterIpAddresses.lengthCompare(1) > 0) "9200" else "9201"

    // All the masters should be accessible, but verify that.
    // A better implementation would keep all the endpoints in the list, and we could fall back to the others
    // if the one we are using disappears.
    val firstAccessibleESEndpoint = masterIpAddresses.find { ipAddress =>
      val request = HttpRequest(
        method = GET,
        uri = s"http://$ipAddress:$esPort")

      Try(HttpUtil.result(request, "probe for accessible es endpoint")).isSuccess
    }

    if (firstAccessibleESEndpoint.isEmpty)
      throw new RuntimeException("No accessible ES endpoint was found.")

    s"${firstAccessibleESEndpoint.get}:$esPort"
  }
} 
Example 132
Source File: EsUtil.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package cmwell.analytics.util

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpRequest
import akka.stream.ActorMaterializer
import akka.util.ByteString

import scala.concurrent.ExecutionContextExecutor

object EsUtil {

  def countDocumentsInShard(httpAddress: String,
                            shard: Shard,
                            filter: String)
                           (implicit system: ActorSystem,
                            executionContext: ExecutionContextExecutor,
                            actorMaterializer: ActorMaterializer): Long = {

    val request = HttpRequest(
      method = HttpUtil.SAFE_POST,
      uri = s"http://$httpAddress/${shard.indexName}/_count?preference=_shards:${shard.shard}",
      entity = ByteString(s"{$filter}"))

    val json = HttpUtil.jsonResult(request, "count documents in shard")

    json.get("count").asLong
  }
} 
Example 133
Source File: SimpleDowningSpec.scala    From simple-akka-downing   with Apache License 2.0 5 votes vote down vote up
package com.ajjpj.simpleakkadowning.util

import akka.actor.Props
import akka.cluster.{Cluster, MemberStatus}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, Uri}
import akka.remote.testconductor.RoleName
import akka.remote.testkit.MultiNodeSpec
import akka.remote.transport.ThrottlerTransportAdapter.Direction
import akka.stream.ActorMaterializer
import akka.testkit.ImplicitSender

import scala.concurrent.duration._
import scala.util.control.NonFatal

abstract class SimpleDowningSpec(config: SimpleDowningConfig) extends MultiNodeSpec(config) with STMultiNodeSpec with ImplicitSender {

  def initialParticipants = roles.size

  private var portToNode = Map.empty[Int,RoleName]

  def init(): Unit = {
    if (roles.headOption contains myself) {
      enterBarrier("initialized")
    }
    else {
      val cluster = Cluster(system)
      cluster.joinSeedNodes(seedAddresses)
      system.actorOf(Props(new ClusterHttpInspector(httpPort(myself))), "http-server")

      while (cluster.state.members.count(_.status == MemberStatus.Up) < roles.tail.size) Thread.sleep(100)
      enterBarrier("initialized")
    }

    portToNode = roles.map(r => node(r).address.port.get -> r).toMap
  }

  def httpPort (node: RoleName) = {
    val nodeNo = roles.indexOf(node)
    require(nodeNo > 0)
    8080 + nodeNo
  }

  def seedAddresses = roles.tail.map(node(_).root.address)

  private def httpGetNodes(node: RoleName, path: String): Set[RoleName] = {
    try {
      import system.dispatcher
      implicit val mat = ActorMaterializer()

      val uri = Uri (s"http://localhost:${httpPort (node)}$path")
      val response = Http (system).singleRequest (HttpRequest (uri = uri)).await
      val strict = response.entity.toStrict (10.seconds).await
      strict.data.decodeString ("utf-8") match {
        case s if s.isEmpty => Set.empty
        case s => s.split (' ').map (_.toInt).map (portToNode).toSet
      }
    }
    catch {
      case NonFatal(th) =>
        th.printStackTrace()
        Set.empty
    }
  }

  def upNodesFor(node: RoleName) = httpGetNodes(node, "/cluster-members/up")
  def unreachableNodesFor (node: RoleName) = httpGetNodes(node, "/cluster-members/unreachable")

  
  def createPartition(nodes: RoleName*) = {
    val otherNodes = roles.tail.toSet -- nodes
    for (n1 <- nodes; n2 <- otherNodes) testConductor.blackhole(n1, n2, Direction.Both).await
  }

  def healPartition(): Unit = {
    for (n1 <- roles.tail; n2 <- roles.tail) testConductor.passThrough(n1, n2, Direction.Both).await
  }
} 
Example 134
Source File: Endpoints.scala    From akka-http-microservice-templates   with MIT License 5 votes vote down vote up
package io.github.gabfssilva.endpoints

import java.lang.System.currentTimeMillis

import akka.actor.ActorSystem
import akka.event.{Logging, LoggingAdapter}
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.RouteResult.Complete
import akka.http.scaladsl.server.directives.{DebuggingDirectives, LogEntry, LoggingMagnet}
import akka.http.scaladsl.settings.RoutingSettings
import akka.stream.{ActorMaterializer, Materializer}

import scala.concurrent.ExecutionContext

class Endpoints(greetingEndpoint: GreetingEndpoint,
                healthCheckEndpoint: HealthCheckEndpoint) {
  def routes(implicit
             sys: ActorSystem,
             mat: ActorMaterializer,
             ec: ExecutionContext) = loggableRoute {
    Route.seal {
      greetingEndpoint.greetingRoute ~ healthCheckEndpoint.healthCheckRoute
    }
  }

  def logRequestAndResponse(loggingAdapter: LoggingAdapter, before: Long)(req: HttpRequest)(res: Any): Unit = {
    val entry = res match {
      case Complete(resp) =>
        val message = s"{path=${req.uri}, method=${req.method.value}, status=${resp.status.intValue()}, elapsedTime=${currentTimeMillis() - before}"
        LogEntry(message, Logging.InfoLevel)
      case other => LogEntry(other, Logging.InfoLevel)
    }

    entry.logTo(loggingAdapter)
  }

  def loggableRoute(route: Route)(implicit m: Materializer,
                                  ex: ExecutionContext,
                                  routingSettings: RoutingSettings): Route = {
    DebuggingDirectives.logRequestResult(LoggingMagnet(log => {
      val requestTimestamp = currentTimeMillis()
      logRequestAndResponse(log, requestTimestamp)
    }))(route)
  }
} 
Example 135
Source File: Endpoints.scala    From akka-http-microservice-templates   with MIT License 5 votes vote down vote up
package endpoints

import java.lang.System.currentTimeMillis

import akka.actor.ActorSystem
import akka.event.{Logging, LoggingAdapter}
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.RouteResult.Complete
import akka.http.scaladsl.server._
import akka.http.scaladsl.server.directives._
import akka.http.scaladsl.settings.RoutingSettings
import akka.stream.{ActorMaterializer, Materializer}

import scala.concurrent.ExecutionContext

class Endpoints(userEndpoint: UserEndpoint,
                healthCheckEndpoint: HealthCheckEndpoint) {
  def routes(implicit
             sys: ActorSystem,
             mat: ActorMaterializer,
             ec: ExecutionContext) = loggableRoute {
    Route.seal {
      userEndpoint.userRoutes ~ healthCheckEndpoint.healthCheckRoute
    }
  }

  def logRequestAndResponse(loggingAdapter: LoggingAdapter, before: Long)(req: HttpRequest)(res: Any): Unit = {
    val entry = res match {
      case Complete(resp) =>
        val message = s"{path=${req.uri}, method=${req.method.value}, status=${resp.status.intValue()}, elapsedTime=${currentTimeMillis() - before}"
        LogEntry(message, Logging.InfoLevel)
      case other => LogEntry(other, Logging.InfoLevel)
    }

    entry.logTo(loggingAdapter)
  }

  def loggableRoute(route: Route)(implicit m: Materializer,
                                  ex: ExecutionContext,
                                  routingSettings: RoutingSettings): Route = {
    DebuggingDirectives.logRequestResult(LoggingMagnet(log => {
      val requestTimestamp = currentTimeMillis()
      logRequestAndResponse(log, requestTimestamp)
    }))(route)
  }
} 
Example 136
Source File: Endpoints.scala    From akka-http-microservice-templates   with MIT License 5 votes vote down vote up
package endpoints

import java.lang.System.currentTimeMillis

import akka.actor.ActorSystem
import akka.event.{Logging, LoggingAdapter}
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.RouteResult.Complete
import akka.http.scaladsl.server._
import akka.http.scaladsl.server.directives._
import akka.http.scaladsl.settings.RoutingSettings
import akka.stream.{ActorMaterializer, Materializer}

import scala.concurrent.ExecutionContext

class Endpoints(userEndpoint: UserEndpoint,
                healthCheckEndpoint: HealthCheckEndpoint) {
  def routes(implicit
             sys: ActorSystem,
             mat: ActorMaterializer,
             ec: ExecutionContext) = loggableRoute {
    Route.seal {
      userEndpoint.userRoutes ~ healthCheckEndpoint.healthCheckRoute
    }
  }

  def logRequestAndResponse(loggingAdapter: LoggingAdapter, before: Long)(req: HttpRequest)(res: Any): Unit = {
    val entry = res match {
      case Complete(resp) =>
        val message = s"{path=${req.uri}, method=${req.method.value}, status=${resp.status.intValue()}, elapsedTime=${currentTimeMillis() - before}"
        LogEntry(message, Logging.InfoLevel)
      case other => LogEntry(other, Logging.InfoLevel)
    }

    entry.logTo(loggingAdapter)
  }

  def loggableRoute(route: Route)(implicit m: Materializer,
                                  ex: ExecutionContext,
                                  routingSettings: RoutingSettings): Route = {
    DebuggingDirectives.logRequestResult(LoggingMagnet(log => {
      val requestTimestamp = currentTimeMillis()
      logRequestAndResponse(log, requestTimestamp)
    }))(route)
  }
} 
Example 137
Source File: Endpoints.scala    From akka-http-microservice-templates   with MIT License 5 votes vote down vote up
package endpoints

import java.lang.System.currentTimeMillis

import akka.actor.ActorSystem
import akka.event.{Logging, LoggingAdapter}
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.RouteResult.Complete
import akka.http.scaladsl.server._
import akka.http.scaladsl.server.directives._
import akka.http.scaladsl.settings.RoutingSettings
import akka.stream.{ActorMaterializer, Materializer}

import scala.concurrent.ExecutionContext

class Endpoints(userEndpoint: UserEndpoint,
                healthCheckEndpoint: HealthCheckEndpoint) {
  def routes(implicit
             sys: ActorSystem,
             mat: ActorMaterializer,
             ec: ExecutionContext) = loggableRoute {
    Route.seal {
      userEndpoint.userRoutes ~ healthCheckEndpoint.healthCheckRoute
    }
  }

  def logRequestAndResponse(loggingAdapter: LoggingAdapter, before: Long)(req: HttpRequest)(res: Any): Unit = {
    val entry = res match {
      case Complete(resp) =>
        val message = s"{path=${req.uri}, method=${req.method.value}, status=${resp.status.intValue()}, elapsedTime=${currentTimeMillis() - before}"
        LogEntry(message, Logging.InfoLevel)
      case other => LogEntry(other, Logging.InfoLevel)
    }

    entry.logTo(loggingAdapter)
  }

  def loggableRoute(route: Route)(implicit m: Materializer,
                                  ex: ExecutionContext,
                                  routingSettings: RoutingSettings): Route = {
    DebuggingDirectives.logRequestResult(LoggingMagnet(log => {
      val requestTimestamp = currentTimeMillis()
      logRequestAndResponse(log, requestTimestamp)
    }))(route)
  }
} 
Example 138
Source File: PrometheusUtils.scala    From kafka-lag-exporter   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.kafkalagexporter.integration

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse, StatusCodes}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.Materializer
import com.lightbend.kafkalagexporter.MetricsSink.GaugeDefinition
import org.scalatest.Matchers
import org.scalatest.concurrent.ScalaFutures
import org.slf4j.{Logger, LoggerFactory}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.matching.Regex


      val regex = s"""$name\\{$labels.*\\}\\s+(-?.+)""".r
      log.debug(s"Created regex: {}", regex.pattern.toString)
      Rule(regex, assertion)
    }
  }

  case class Rule(regex: Regex, assertion: String => _)

  case class Result(rule: Rule, groupResults: List[String]) {
    def assertDne(): Unit = {
      log.debug(s"Rule: ${rule.regex.toString}")
      groupResults.length shouldBe 0
    }

    def assert(): Unit = {
      log.debug(s"Rule: ${rule.regex.toString}")
      groupResults.length shouldBe 1
      log.debug(s"Actual value is ${groupResults.head}")
      rule.assertion(groupResults.head)
    }
  }
} 
Example 139
Source File: EventSource.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.client

import akka.NotUsed
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.headers.OAuth2BearerToken
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.stream.Materializer
import akka.stream.alpakka.sse.scaladsl.{EventSource => SSESource}
import akka.stream.scaladsl.Source
import ch.epfl.bluebrain.nexus.iam.client.config.IamClientConfig
import ch.epfl.bluebrain.nexus.iam.client.types.AuthToken
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri
import ch.epfl.bluebrain.nexus.rdf.implicits._
import com.typesafe.scalalogging.Logger
import io.circe.Decoder
import io.circe.parser.decode

import scala.concurrent.{ExecutionContext, Future}

trait EventSource[A] {

  
  def apply[A: Decoder](
      config: IamClientConfig
  )(implicit as: ActorSystem, mt: Materializer, ec: ExecutionContext): EventSource[A] =
    new EventSource[A] {
      private val logger = Logger[this.type]
      private val http   = Http()

      private def addCredentials(request: HttpRequest)(implicit cred: Option[AuthToken]): HttpRequest =
        cred.map(token => request.addCredentials(OAuth2BearerToken(token.value))).getOrElse(request)

      private def send(request: HttpRequest)(implicit cred: Option[AuthToken]): Future[HttpResponse] =
        http.singleRequest(addCredentials(request)).map { resp =>
          if (!resp.status.isSuccess())
            logger.warn(s"HTTP response when performing SSE request: status = '${resp.status}'")
          resp
        }

      override def apply(iri: AbsoluteIri, offset: Option[String])(
          implicit cred: Option[AuthToken]
      ): Source[A, NotUsed] =
        SSESource(iri.asAkka, send, offset, config.sseRetryDelay).flatMapConcat { sse =>
          decode[A](sse.data) match {
            case Right(ev) => Source.single(ev)
            case Left(err) =>
              logger.error(s"Failed to decode admin event '$sse'", err)
              Source.empty
          }
        }
    }
} 
Example 140
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 141
Source File: Aws4AuthenticatorSpec.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package vinyldns.api.route

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpRequest}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class Aws4AuthenticatorSpec extends AnyWordSpec with Matchers {

  "getting canonical headers" should {
    "pull the content type" in {
      val entity = HttpEntity(ContentTypes.`application/json`, "")
      val req = HttpRequest(
        entity = entity
      )

      val canonicalHeaders = new Aws4Authenticator().canonicalHeaders(req, Set("content-type"))
      canonicalHeaders.keys should contain("content-type")
      canonicalHeaders("content-type") should contain("application/json")
    }
    "pull the content-length" in {
      val entity = HttpEntity(ContentTypes.`application/json`, "")
      val req = HttpRequest(
        entity = entity
      )

      val canonicalHeaders = new Aws4Authenticator().canonicalHeaders(req, Set("content-length"))
      canonicalHeaders.keys should contain("content-length")
      canonicalHeaders("content-length") should contain("0")
    }
  }
} 
Example 142
Source File: CorsDirective.scala    From mist   with Apache License 2.0 5 votes vote down vote up
package io.hydrosphere.mist.master.interfaces.http

import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpHeader, HttpRequest, StatusCodes}
import akka.http.scaladsl.server.Directives.handleRejections
import akka.http.scaladsl.server._

import scala.collection.immutable._

trait CorsDirective {

  import Directives._
  import StatusCodes._
  import scala.concurrent.ExecutionContext.Implicits.global


  private val defaultHeaders = Seq(
    `Access-Control-Allow-Origin`.*,
    `Access-Control-Allow-Methods`(Seq(GET, POST, PUT, DELETE, HEAD, OPTIONS))
  )


  // old akka-http doesn't have build-in rejection response mapping method
  private val rejectionsHandler = new RejectionHandler {

    val original = RejectionHandler.default

    override def apply(rejections: Seq[Rejection]): Option[Route] = {
      original(rejections).map(route => route.andThen(_.map({
        case c @ RouteResult.Complete(r) =>
          RouteResult.Complete(r.withHeaders(defaultHeaders))
        case x => x
      })))
    }
  }

  def cors(): Directive0 = extractRequest.flatMap(request => {
    val headers = corsHeaders(request)
    if (request.method == OPTIONS) {
      respondWithHeaders(headers) & complete(OK, "Preflight response")
    } else {
      extractSettings.flatMap(routeSettings => {
        handleRejections(rejectionsHandler) &
        respondWithHeaders(headers) &
        handleExceptions(ExceptionHandler.default(routeSettings)) &
        pass
      })
    }
  })

  private def corsHeaders(request: HttpRequest): Seq[HttpHeader] = {
    val accessed = request.header[`Access-Control-Request-Headers`].map(_.headers).getOrElse(Seq.empty)
    val allowHeaders = `Access-Control-Allow-Headers`(accessed)
    allowHeaders +: defaultHeaders
  }

}

object CorsDirective extends CorsDirective 
Example 143
Source File: TestUtils.scala    From mist   with Apache License 2.0 5 votes vote down vote up
package io.hydrosphere.mist.master

import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.stream.scaladsl.Flow
import com.typesafe.config.ConfigFactory

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

trait TestUtils {

  implicit class AwaitSyntax[A](f: => Future[A]) {
    def await: A = Await.result(f, Duration.Inf)
    def await(d: FiniteDuration): A = Await.result(f, d)
  }

}
object TestUtils extends TestUtils {

  val cfgStr =
    """
      |context-defaults {
      | downtime = Inf
      | streaming-duration = 1 seconds
      | max-parallel-jobs = 20
      | precreated = false
      | spark-conf = { }
      | worker-mode = "shared"
      | run-options = "--opt"
      | max-conn-failures = 5
      |}
      |
      |context {
      |
      |  foo {
      |    spark-conf {
      |       spark.master = "local[2]"
      |    }
      |  }
      |}
    """.stripMargin

  val contextSettings = {
    val cfg = ConfigFactory.parseString(cfgStr)
    ContextsSettings(cfg)
  }

  val FooContext = contextSettings.contexts.get("foo").get




  object MockHttpServer {

    import akka.actor.ActorSystem
    import akka.http.scaladsl.Http
    import akka.stream.ActorMaterializer
    import akka.util.Timeout

    import scala.concurrent.duration._

    def onServer[A](
      routes: Flow[HttpRequest, HttpResponse, _],
      f: (Http.ServerBinding) => A): Future[A] = {

      implicit val system = ActorSystem("mock-http-cli")
      implicit val materializer = ActorMaterializer()

      implicit val executionContext = system.dispatcher
      implicit val timeout = Timeout(1.seconds)

      val binding = Http().bindAndHandle(routes, "localhost", 0)

      val close = Promise[Http.ServerBinding]
      close.future
        .flatMap(binding => binding.unbind())
        .onComplete(_ => {
          materializer.shutdown()
          Await.result(system.terminate(), Duration.Inf)
        })

      val result = binding.flatMap(binding => {
        try {
          Future.successful(f(binding))
        } catch {
          case e: Throwable =>
            Future.failed(e)
        } finally {
          close.success(binding)
        }
      })
      result
    }
  }

} 
Example 144
Source File: GreeterServer.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
//#full-server
package example.myapp.helloworld

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.http.scaladsl.{ Http, HttpConnectionContext }
import akka.stream.{ ActorMaterializer, Materializer }
import com.typesafe.config.ConfigFactory
import example.myapp.helloworld.grpc._

import scala.concurrent.{ ExecutionContext, Future }

object GreeterServer {
  def main(args: Array[String]): Unit = {
    // Important: enable HTTP/2 in ActorSystem's config
    // We do it here programmatically, but you can also set it in the application.conf
    val conf = ConfigFactory
      .parseString("akka.http.server.preview.enable-http2 = on")
      .withFallback(ConfigFactory.defaultApplication())
    val system = ActorSystem("HelloWorld", conf)
    new GreeterServer(system).run()
    // ActorSystem threads will keep the app alive until `system.terminate()` is called
  }
}

class GreeterServer(system: ActorSystem) {
  def run(): Future[Http.ServerBinding] = {
    // Akka boot up code
    implicit val sys: ActorSystem = system
    implicit val mat: Materializer = ActorMaterializer()
    implicit val ec: ExecutionContext = sys.dispatcher

    // Create service handlers
    val service: HttpRequest => Future[HttpResponse] =
      GreeterServiceHandler(new GreeterServiceImpl())

    // Bind service handler servers to localhost:8080/8081
    val binding = Http().bindAndHandleAsync(
      service,
      interface = "127.0.0.1",
      port = 8080,
      connectionContext = HttpConnectionContext())

    // report successful binding
    binding.foreach { binding => println(s"gRPC server bound to: ${binding.localAddress}") }

    binding
  }
}

//#full-server 
Example 145
Source File: PowerGreeterServer.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
//#full-server
package example.myapp.helloworld

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.http.scaladsl.{ Http, HttpConnectionContext }
import akka.stream.{ ActorMaterializer, Materializer }
import example.myapp.helloworld.grpc._

import scala.concurrent.{ ExecutionContext, Future }

class PowerGreeterServer(system: ActorSystem) {
  def run(): Future[Http.ServerBinding] = {
    // Akka boot up code
    implicit val sys: ActorSystem = system
    implicit val mat: Materializer = ActorMaterializer()
    implicit val ec: ExecutionContext = sys.dispatcher

    // Create service handlers
    val service: HttpRequest => Future[HttpResponse] =
      GreeterServicePowerApiHandler(new PowerGreeterServiceImpl(mat))

    // Bind service handler servers to localhost:8080/8081
    val binding = Http().bindAndHandleAsync(
      service,
      interface = "127.0.0.1",
      port = 8081,
      connectionContext = HttpConnectionContext())

    // report successful binding
    binding.foreach { binding => println(s"gRPC server bound to: ${binding.localAddress}") }

    binding
  }
}

//#full-server 
Example 146
Source File: CombinedServer.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package example.myapp

import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import akka.actor.ActorSystem
import akka.http.scaladsl.{ Http, HttpConnectionContext }
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.HttpResponse
import akka.grpc.scaladsl.ServerReflection
import akka.stream.ActorMaterializer
import akka.stream.Materializer
import com.typesafe.config.ConfigFactory
import example.myapp.helloworld._
import example.myapp.echo._
import example.myapp.echo.grpc._
import example.myapp.helloworld.grpc.GreeterService

//#concatOrNotFound
import akka.grpc.scaladsl.ServiceHandler

//#concatOrNotFound

//#grpc-web
import akka.grpc.scaladsl.WebHandler

//#grpc-web

object CombinedServer {
  def main(args: Array[String]): Unit = {
    // important to enable HTTP/2 in ActorSystem's config
    val conf = ConfigFactory
      .parseString("akka.http.server.preview.enable-http2 = on")
      .withFallback(ConfigFactory.defaultApplication())
    implicit val sys: ActorSystem = ActorSystem("HelloWorld", conf)
    implicit val mat: Materializer = ActorMaterializer()
    implicit val ec: ExecutionContext = sys.dispatcher

    //#concatOrNotFound
    // explicit types not needed but included in example for clarity
    val greeterService: PartialFunction[HttpRequest, Future[HttpResponse]] =
      example.myapp.helloworld.grpc.GreeterServiceHandler.partial(new GreeterServiceImpl())
    val echoService: PartialFunction[HttpRequest, Future[HttpResponse]] =
      EchoServiceHandler.partial(new EchoServiceImpl)
    val reflectionService = ServerReflection.partial(List(GreeterService, EchoService))
    val serviceHandlers: HttpRequest => Future[HttpResponse] =
      ServiceHandler.concatOrNotFound(greeterService, echoService, reflectionService)

    Http()
      .bindAndHandleAsync(
        serviceHandlers,
        interface = "127.0.0.1",
        port = 8080,
        connectionContext = HttpConnectionContext())
      //#concatOrNotFound
      .foreach { binding => println(s"gRPC server bound to: ${binding.localAddress}") }

    //#grpc-web
    val grpcWebServiceHandlers = WebHandler.grpcWebHandler(greeterService, echoService)

    Http()
      .bindAndHandleAsync(
        grpcWebServiceHandlers,
        interface = "127.0.0.1",
        port = 8081,
        connectionContext = HttpConnectionContext())
      //#grpc-web
      .foreach { binding => println(s"gRPC-Web server bound to: ${binding.localAddress}") }
  }
} 
Example 147
Source File: WebHandler.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.scaladsl

import scala.collection.immutable
import scala.concurrent.Future
import akka.actor.ClassicActorSystemProvider
import akka.annotation.ApiMayChange
import akka.http.javadsl.{ model => jmodel }
import akka.http.scaladsl.model.{ HttpMethods, HttpRequest, HttpResponse }
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.directives.MarshallingDirectives.handleWith
import ch.megard.akka.http.cors.scaladsl.CorsDirectives.cors
import ch.megard.akka.http.cors.scaladsl.model.HttpHeaderRange
import ch.megard.akka.http.cors.scaladsl.settings.CorsSettings

@ApiMayChange
object WebHandler {

  
  def grpcWebHandler(handlers: PartialFunction[HttpRequest, Future[HttpResponse]]*)(
      implicit as: ClassicActorSystemProvider,
      corsSettings: CorsSettings = defaultCorsSettings): HttpRequest => Future[HttpResponse] = {
    implicit val system = as.classicSystem
    val servicesHandler = ServiceHandler.concat(handlers: _*)
    Route.asyncHandler(cors(corsSettings) {
      handleWith(servicesHandler)
    })
  }

} 
Example 148
Source File: ServiceHandler.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.scaladsl

import akka.annotation.ApiMayChange
import akka.grpc.GrpcProtocol
import akka.grpc.internal.{ GrpcProtocolNative, GrpcProtocolWeb, GrpcProtocolWebText }
import akka.http.javadsl.{ model => jmodel }
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse, StatusCodes }

import scala.concurrent.Future

@ApiMayChange
object ServiceHandler {

  private[scaladsl] val notFound: Future[HttpResponse] = Future.successful(HttpResponse(StatusCodes.NotFound))

  private[scaladsl] val unsupportedMediaType: Future[HttpResponse] =
    Future.successful(HttpResponse(StatusCodes.UnsupportedMediaType))

  private def matchesVariant(variants: Set[GrpcProtocol])(request: jmodel.HttpRequest) =
    variants.exists(_.mediaTypes.contains(request.entity.getContentType.mediaType))

  private[grpc] val isGrpcRequest: jmodel.HttpRequest => Boolean = matchesVariant(Set(GrpcProtocolNative))
  private[grpc] val isGrpcWebRequest: jmodel.HttpRequest => Boolean = matchesVariant(
    Set(GrpcProtocolWeb, GrpcProtocolWebText))

  def concatOrNotFound(
      handlers: PartialFunction[HttpRequest, Future[HttpResponse]]*): HttpRequest => Future[HttpResponse] =
    concat(handlers: _*).orElse { case _ => notFound }

  def concat(handlers: PartialFunction[HttpRequest, Future[HttpResponse]]*)
      : PartialFunction[HttpRequest, Future[HttpResponse]] =
    handlers.foldLeft(PartialFunction.empty[HttpRequest, Future[HttpResponse]]) {
      case (acc, pf) => acc.orElse(pf)
    }
} 
Example 149
Source File: ServerReflection.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.scaladsl

import akka.actor.ClassicActorSystemProvider
import akka.annotation.ApiMayChange
import akka.grpc.ServiceDescription
import akka.grpc.internal.ServerReflectionImpl
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }

import grpc.reflection.v1alpha.reflection.ServerReflectionHandler

@ApiMayChange(issue = "https://github.com/akka/akka-grpc/issues/850")
object ServerReflection {
  @ApiMayChange(issue = "https://github.com/akka/akka-grpc/issues/850")
  def apply(objects: List[ServiceDescription])(
      implicit sys: ClassicActorSystemProvider): HttpRequest => scala.concurrent.Future[HttpResponse] =
    ServerReflectionHandler.apply(ServerReflectionImpl(objects.map(_.descriptor), objects.map(_.name)))

  @ApiMayChange(issue = "https://github.com/akka/akka-grpc/issues/850")
  def partial(objects: List[ServiceDescription])(
      implicit sys: ClassicActorSystemProvider): PartialFunction[HttpRequest, scala.concurrent.Future[HttpResponse]] =
    ServerReflectionHandler.partial(ServerReflectionImpl(objects.map(_.descriptor), objects.map(_.name)))
} 
Example 150
Source File: GrpcRequestHelpers.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.internal

import akka.actor.ActorSystem
import akka.actor.ClassicActorSystemProvider
import akka.grpc.{ ProtobufSerializer, Trailers }
import akka.grpc.GrpcProtocol.GrpcProtocolWriter
import akka.http.scaladsl.model.HttpEntity.ChunkStreamPart
import akka.stream.scaladsl.Source
import akka.NotUsed
import akka.annotation.InternalApi
import akka.grpc.scaladsl.{ headers, GrpcExceptionHandler }
import akka.http.scaladsl.model.{ HttpEntity, HttpMethods, HttpRequest, Uri }
import io.grpc.Status

import scala.collection.immutable

@InternalApi
object GrpcRequestHelpers {

  def apply[T](
      uri: Uri,
      e: Source[T, NotUsed],
      eHandler: ActorSystem => PartialFunction[Throwable, Trailers] = GrpcExceptionHandler.defaultMapper)(
      implicit m: ProtobufSerializer[T],
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider): HttpRequest =
    request(uri, GrpcEntityHelpers(e, Source.single(GrpcEntityHelpers.trailer(Status.OK)), eHandler))

  private def request[T](uri: Uri, entity: Source[ChunkStreamPart, NotUsed])(
      implicit writer: GrpcProtocolWriter): HttpRequest = {
    HttpRequest(
      uri = uri,
      method = HttpMethods.POST,
      headers = immutable.Seq(
        headers.`Message-Encoding`(writer.messageEncoding.name),
        headers.`Message-Accept-Encoding`(Codecs.supportedCodecs.map(_.name).mkString(","))),
      entity = HttpEntity.Chunked(writer.contentType, entity))
  }

} 
Example 151
Source File: CodecsSpec.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc
import akka.grpc.internal.{ Codecs, Gzip, Identity }
import akka.grpc.scaladsl.headers
import akka.http.scaladsl.model.HttpRequest
import io.grpc.Status
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.TryValues

import scala.collection.immutable

class CodecsSpec extends AnyWordSpec with Matchers with TryValues {

  private def accept(encodings: String*): HttpRequest =
    HttpRequest(headers = immutable.Seq(headers.`Message-Accept-Encoding`(encodings.mkString(","))))

  private def enc(encodings: String*): HttpRequest =
    HttpRequest(headers = immutable.Seq(headers.`Message-Encoding`(encodings.mkString(","))))

  "Negotiating message encoding with remote client" should {

    "default to Identity if no encoding provided" in {
      Codecs.negotiate(HttpRequest()) should be(Identity)
    }

    "accept explicit Identity" in {
      Codecs.negotiate(accept(Identity.name)) should be(Identity)
    }

    "accept explicit Gzip" in {
      Codecs.negotiate(accept(Gzip.name)) should be(Gzip)
    }

    "use client preference with multiple known encodings" in {
      Codecs.negotiate(accept(Gzip.name, Identity.name)) should be(Gzip)
      Codecs.negotiate(accept(Identity.name, Gzip.name)) should be(Identity)
    }

    "use first known encoding" in {
      Codecs.negotiate(accept("xxxxx", Gzip.name, Identity.name)) should be(Gzip)
    }

    "use default encoding if unknown encodings specified" in {
      Codecs.negotiate(accept("xxxxx")) should be(Identity)
    }

  }

  "Detecting message encoding from remote" should {

    "default to Identity if not specified" in {
      Codecs.detect(HttpRequest()).success.value should be(Identity)
    }

    "accept explicit Identity" in {
      Codecs.detect(enc(Identity.name)).success.value should be(Identity)
    }

    "accept explicit Gzip" in {
      Codecs.detect(enc(Gzip.name)).success.value should be(Gzip)
    }

    "fail with unknown encoding" in {
      val detected = Codecs.detect(enc("xxxxxxx"))
      detected.failure.exception shouldBe a[GrpcServiceException]
      detected.failure.exception.asInstanceOf[GrpcServiceException].status.getCode should be(
        Status.UNIMPLEMENTED.getCode)
    }
  }

} 
Example 152
Source File: AkkaGrpcServerScala.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.interop

import java.io.FileInputStream
import java.nio.file.{ Files, Paths }
import java.security.cert.CertificateFactory
import java.security.spec.PKCS8EncodedKeySpec
import java.security.{ KeyFactory, KeyStore, SecureRandom }

import scala.concurrent.duration._

import akka.actor.ActorSystem
import akka.util.ByteString
import akka.http.scaladsl.Http.ServerBinding
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.http.scaladsl.{ Http2, HttpsConnectionContext }
import akka.stream.SystemMaterializer
import io.grpc.internal.testing.TestUtils
import javax.net.ssl.{ KeyManagerFactory, SSLContext }

import scala.concurrent.{ Await, Future }


case class AkkaGrpcServerScala(serverHandlerFactory: ActorSystem => HttpRequest => Future[HttpResponse])
    extends GrpcServer[(ActorSystem, ServerBinding)] {
  override def start() = {
    implicit val sys = ActorSystem()
    implicit val mat = SystemMaterializer(sys).materializer

    val testService = serverHandlerFactory(sys)

    val bindingFuture = Http2().bindAndHandleAsync(
      testService,
      interface = "127.0.0.1",
      port = 0,
      parallelism = 256, // TODO remove once https://github.com/akka/akka-http/pull/2146 is merged
      connectionContext = serverHttpContext())

    val binding = Await.result(bindingFuture, 10.seconds)
    (sys, binding)
  }

  override def stop(binding: (ActorSystem, ServerBinding)) =
    binding match {
      case (sys, binding) =>
        sys.log.info("Exception thrown, unbinding")
        Await.result(binding.unbind(), 10.seconds)
        Await.result(sys.terminate(), 10.seconds)
    }

  private def serverHttpContext() = {
    val keyEncoded =
      new String(Files.readAllBytes(Paths.get(TestUtils.loadCert("server1.key").getAbsolutePath)), "UTF-8")
        .replace("-----BEGIN PRIVATE KEY-----\n", "")
        .replace("-----END PRIVATE KEY-----\n", "")
        .replace("\n", "")

    val decodedKey = ByteString(keyEncoded).decodeBase64.toArray

    val spec = new PKCS8EncodedKeySpec(decodedKey)

    val kf = KeyFactory.getInstance("RSA")
    val privateKey = kf.generatePrivate(spec)

    val fact = CertificateFactory.getInstance("X.509")
    val is = new FileInputStream(TestUtils.loadCert("server1.pem"))
    val cer = fact.generateCertificate(is)

    val ks = KeyStore.getInstance("PKCS12")
    ks.load(null)
    ks.setKeyEntry("private", privateKey, Array.empty, Array(cer))

    val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
    keyManagerFactory.init(ks, null)

    val context = SSLContext.getInstance("TLS")
    context.init(keyManagerFactory.getKeyManagers, null, new SecureRandom)

    new HttpsConnectionContext(context)
  }

  override def getPort(binding: (ActorSystem, ServerBinding)): Int = binding._2.localAddress.getPort
} 
Example 153
Source File: GrpcMarshallingSpec.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.scaladsl

import akka.actor.ActorSystem
import akka.grpc.internal.{ AbstractGrpcProtocol, GrpcProtocolNative, Gzip }
import akka.grpc.scaladsl.headers.`Message-Encoding`
import akka.http.scaladsl.model.{ HttpEntity, HttpRequest }
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import io.grpc.{ Status, StatusException }
import io.grpc.testing.integration.messages.{ BoolValue, SimpleRequest }
import io.grpc.testing.integration.test.TestService
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

import scala.collection.immutable
import scala.concurrent.{ Await, Future }
import scala.concurrent.duration._

class GrpcMarshallingSpec extends AnyWordSpec with Matchers {
  "The scaladsl GrpcMarshalling" should {
    val message = SimpleRequest(responseCompressed = Some(BoolValue(true)))
    implicit val serializer = TestService.Serializers.SimpleRequestSerializer
    implicit val system = ActorSystem()
    implicit val mat = ActorMaterializer()
    val awaitTimeout = 10.seconds
    val zippedBytes =
      AbstractGrpcProtocol.encodeFrameData(
        AbstractGrpcProtocol.fieldType(Gzip),
        Gzip.compress(serializer.serialize(message)))

    "correctly unmarshal a zipped object" in {
      val request = HttpRequest(
        headers = immutable.Seq(`Message-Encoding`("gzip")),
        entity = HttpEntity.Strict(GrpcProtocolNative.contentType, zippedBytes))

      val marshalled = Await.result(GrpcMarshalling.unmarshal(request), 10.seconds)
      marshalled.responseCompressed should be(Some(BoolValue(true)))
    }

    "correctly unmarshal a zipped stream" in {
      val request = HttpRequest(
        headers = immutable.Seq(`Message-Encoding`("gzip")),
        entity = HttpEntity.Strict(GrpcProtocolNative.contentType, zippedBytes ++ zippedBytes))

      val stream = Await.result(GrpcMarshalling.unmarshalStream(request), 10.seconds)
      val items = Await.result(stream.runWith(Sink.seq), 10.seconds)
      items(0).responseCompressed should be(Some(BoolValue(true)))
      items(1).responseCompressed should be(Some(BoolValue(true)))
    }

    // https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-method-asymmetry-between-peers
    // test case 6
    "fail with INTERNAL when the compressed bit is on but the encoding is identity" in {
      val request = HttpRequest(
        headers = immutable.Seq(`Message-Encoding`("identity")),
        entity = HttpEntity.Strict(GrpcProtocolNative.contentType, zippedBytes))

      assertFailure(GrpcMarshalling.unmarshal(request), Status.Code.INTERNAL, "encoding")
    }

    // https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-method-asymmetry-between-peers
    // test case 6
    "fail with INTERNAL when the compressed bit is on but the encoding is missing" in {
      val request = HttpRequest(entity = HttpEntity.Strict(GrpcProtocolNative.contentType, zippedBytes))

      assertFailure(GrpcMarshalling.unmarshal(request), Status.Code.INTERNAL, "encoding")
    }

    def assertFailure(failure: Future[_], expectedStatusCode: Status.Code, expectedMessageFragment: String): Unit = {
      val e = Await.result(failure.failed, awaitTimeout).asInstanceOf[StatusException]
      e.getStatus.getCode should be(expectedStatusCode)
      e.getStatus.getDescription should include(expectedMessageFragment)
    }
  }
} 
Example 154
Source File: AkkaHttpActionAdapterTest.scala    From akka-http-pac4j   with Mozilla Public License 2.0 5 votes vote down vote up
package com.stackstate.pac4j

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpRequest, HttpResponse}
import org.scalatest.{Matchers, WordSpecLike}
import akka.http.scaladsl.model.StatusCodes._
import akka.util.ByteString
import com.stackstate.pac4j.AkkaHttpActionAdapterTest.ActionInt
import com.stackstate.pac4j.http.AkkaHttpActionAdapter
import com.stackstate.pac4j.store.ForgetfulSessionStorage
import org.pac4j.core.exception.http.{
  BadRequestAction,
  ForbiddenAction,
  FoundAction,
  HttpAction,
  NoContentAction,
  OkAction,
  StatusAction,
  UnauthorizedAction
}
import org.scalatest.concurrent.ScalaFutures

class AkkaHttpActionAdapterTest extends WordSpecLike with Matchers with ScalaFutures {
  "AkkaHttpActionAdapter" should {
    "convert 200 to OK" in withContext { context =>
      AkkaHttpActionAdapter.adapt(new OkAction(""), context).futureValue.response shouldEqual HttpResponse(
        OK,
        Nil,
        HttpEntity(ContentTypes.`application/octet-stream`, ByteString(""))
      )
    }
    "convert 401 to Unauthorized" in withContext { context =>
      AkkaHttpActionAdapter.adapt(UnauthorizedAction.INSTANCE, context).futureValue.response shouldEqual HttpResponse(Unauthorized)
      context.getChanges.cookies.map(_.name) shouldBe List(AkkaHttpWebContext.DEFAULT_COOKIE_NAME)
    }
    "convert 302 to SeeOther (to support login flow)" in withContext { context =>
      val r = AkkaHttpActionAdapter.adapt(new FoundAction("/login"), context).futureValue.response
      r.status shouldEqual SeeOther
      r.headers.head.value() shouldEqual "/login"
      context.getChanges.cookies.map(_.name) shouldBe List(AkkaHttpWebContext.DEFAULT_COOKIE_NAME)
    }
    "convert 400 to BadRequest" in withContext { context =>
      AkkaHttpActionAdapter.adapt(BadRequestAction.INSTANCE, context).futureValue.response shouldEqual HttpResponse(BadRequest)
    }
    "convert 201 to Created" in withContext { context =>
      AkkaHttpActionAdapter.adapt(201.action(), context).futureValue.response shouldEqual HttpResponse(Created)
    }
    "convert 403 to Forbidden" in withContext { context =>
      AkkaHttpActionAdapter.adapt(ForbiddenAction.INSTANCE, context).futureValue.response shouldEqual HttpResponse(Forbidden)
    }
    "convert 204 to NoContent" in withContext { context =>
      AkkaHttpActionAdapter.adapt(NoContentAction.INSTANCE, context).futureValue.response shouldEqual HttpResponse(NoContent)
    }
    "convert 200 to OK with content set from the context" in withContext { context =>
      AkkaHttpActionAdapter.adapt(new OkAction("content"), context).futureValue.response shouldEqual HttpResponse
        .apply(OK, Nil, HttpEntity(ContentTypes.`application/octet-stream`, ByteString("content")))
    }
    "convert 200 to OK with content type set from the context" in withContext { context =>
      context.setResponseContentType("application/json")
      AkkaHttpActionAdapter.adapt(new OkAction(""), context).futureValue.response shouldEqual HttpResponse
        .apply(OK, Nil, HttpEntity(ContentTypes.`application/json`, ByteString("")))
    }
  }

  def withContext(f: AkkaHttpWebContext => Unit): Unit = {
    f(AkkaHttpWebContext(HttpRequest(), Seq.empty, new ForgetfulSessionStorage, AkkaHttpWebContext.DEFAULT_COOKIE_NAME))
  }
}

object AkkaHttpActionAdapterTest {
  implicit class ActionInt(val i: Int) extends AnyVal {
    def action(): HttpAction = new StatusAction(i)
  }
} 
Example 155
Source File: AkkaHttpSessionStoreTest.scala    From akka-http-pac4j   with Mozilla Public License 2.0 5 votes vote down vote up
package com.stackstate.pac4j.http

import java.util.Optional

import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.testkit.ScalatestRouteTest
import com.stackstate.pac4j.AkkaHttpWebContext
import com.stackstate.pac4j.store.{ForgetfulSessionStorage, InMemorySessionStorage}
import org.scalatest.{Matchers, WordSpecLike}

import scala.concurrent.duration._

class AkkaHttpSessionStoreTest extends WordSpecLike with Matchers with ScalatestRouteTest {
  "AkkaHttpSessionStore.get" should {
    "return null when the data is not available" in {
      new AkkaHttpSessionStore().get(
        new AkkaHttpWebContext(HttpRequest(), Seq.empty, new ForgetfulSessionStorage, AkkaHttpWebContext.DEFAULT_COOKIE_NAME),
        "mykey"
      ) shouldBe Optional.empty()
    }

    "return the data when available" in {
      val context = new AkkaHttpWebContext(HttpRequest(), Seq.empty, new InMemorySessionStorage(30.minutes), AkkaHttpWebContext.DEFAULT_COOKIE_NAME)
      new AkkaHttpSessionStore().set(context, "mykey", "yooo")
      new AkkaHttpSessionStore().get(context, "mykey") shouldBe Optional.of("yooo")
    }
  }
} 
Example 156
Source File: AkkaHttpServerWithMinio.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4gate_akka_s3

import java.util.UUID

import akka.http.scaladsl.model.{HttpMethods, HttpRequest}
import akka.stream.scaladsl.StreamConverters
import com.typesafe.scalalogging.LazyLogging
import ee.cone.c4actor_s3.S3FileStorage
import ee.cone.c4di.c4
import ee.cone.c4gate_akka._

import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}

@c4("AkkaMinioGatewayApp") final class AkkaMinioRequestPreHandler(
  s3FileStorage: S3FileStorage,
  akkaMat: AkkaMat,
) extends AkkaRequestPreHandler with LazyLogging {
  def handleAsync(
    income: HttpRequest
  )(
    implicit ec: ExecutionContext
  ): Future[HttpRequest] = if (income.method == HttpMethods.PUT) {
    for { mat <- akkaMat.get } yield {
      val tmpFilename: String = s"tmp/${UUID.randomUUID()}"
      logger debug s"PUT request received; Storing request body to $tmpFilename"
      val is = income.entity.dataBytes.runWith(StreamConverters.asInputStream(5.minutes))(mat) //todo check throw
      logger debug s"Bytes Stream created"
      s3FileStorage.uploadByteStream(tmpFilename, is)
      logger debug s"Uploaded bytestream to $tmpFilename"
      // ? income.headers
      income.withEntity(tmpFilename)
    }
  } else Future.successful(income)
} 
Example 157
Source File: BasicAuth.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api.auth

import java.nio.charset.StandardCharsets
import java.util.Base64

import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.headers.RawHeader
import asura.core.auth.AuthorizeAndValidate
import asura.core.es.model.Authorization

import scala.concurrent.Future

object BasicAuth extends AuthorizeAndValidate {

  override val `type`: String = "Basic Auth"
  override val description: String =
    """## Basic Auth
      |> Add a header with the key `Authorization` and the value a string encoded by base64.
      |
      |### Example
      |
      |If the data is as below:
      |
      |```json
      |{
      |    "username" : "a",
      |    "password": "b"
      |}
      |```
      |
      |A header `Authorization: Basic YTpi` will be added. `YTpi` is generated by call `Base64.encode("a:b")`.
      |
    """.stripMargin


  override val template: String =
    """{
      |    "username" : "",
      |    "password": ""
      |}
    """.stripMargin

  override def authorize(request: HttpRequest, auth: Authorization): Future[HttpRequest] = {
    val username = auth.data.get("username")
    val password = auth.data.get("password")
    val bytes = Base64.getEncoder.encode(s"${username.get}:${password.get}".getBytes(StandardCharsets.UTF_8))
    val value = new String(bytes, StandardCharsets.UTF_8)
    Future.successful(request.withHeaders(request.headers :+ RawHeader("Authorization", s"Basic ${value}")))
  }

  override def validate(auth: Authorization): (Boolean, String) = {
    val username = auth.data.get("username")
    val password = auth.data.get("password")
    if (username.isEmpty || password.isEmpty) {
      (false, "username and password can't be empty")
    } else {
      (true, null)
    }
  }
} 
Example 158
Source File: ExampleAuth.scala    From asura   with MIT License 5 votes vote down vote up
package com.example.asura.auth

import akka.http.scaladsl.model.HttpRequest
import asura.core.auth.AuthorizeAndValidate
import asura.core.es.model.Authorization
import play.api.Configuration

import scala.concurrent.Future

class ExampleAuth(config: Configuration) extends AuthorizeAndValidate {

  override val `type`: String = "ExampleAuth"
  override val description: String =
    """# ExampleAuth do nothing
      |markdown syntax
    """.stripMargin
  override val template: String =
    """{
      |    "appKey" : "",
      |    "appSecret" : ""
      |}
    """.stripMargin

  override def authorize(request: HttpRequest, auth: Authorization): Future[HttpRequest] = {
    Future.successful(request)
  }

  override def validate(auth: Authorization): (Boolean, String) = (true, null)
} 
Example 159
Source File: JacksonSupport.scala    From asura   with MIT License 5 votes vote down vote up
package asura.core.util

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.model.{HttpEntity, HttpRequest}
import akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller
import akka.stream.Materializer
import asura.common.util.JsonUtils
import com.sksamuel.elastic4s.Indexable

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

object JacksonSupport extends JsonUtils {

  val mapper = JsonUtils.mapper

  implicit def JacksonMarshaller: ToEntityMarshaller[AnyRef] = {
    Marshaller.withFixedContentType(`application/json`) { obj =>
      HttpEntity(`application/json`, mapper.writeValueAsString(obj).getBytes("UTF-8"))
    }
  }

  implicit def jacksonUnmarshaller[T <: AnyRef](implicit c: ClassTag[T]): FromRequestUnmarshaller[T] = {
    new FromRequestUnmarshaller[T] {
      override def apply(request: HttpRequest)(implicit ec: ExecutionContext, materializer: Materializer): Future[T] = {
        request.entity.toStrict(5 seconds).map(_.data.decodeString("UTF-8")).map { str =>
          mapper.readValue(str, c.runtimeClass).asInstanceOf[T]
        }
      }
    }
  }

  implicit def jacksonJsonIndexable[T]: Indexable[T] = {
    new Indexable[T] {
      override def json(t: T): String = mapper.writeValueAsString(t)
    }
  }
}