akka.http.scaladsl.model.Uri.Query Scala Examples
The following examples show how to use akka.http.scaladsl.model.Uri.Query.
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: ClickhouseQueryBuilder.scala From clickhouse-scala-client with GNU Lesser General Public License v3.0 | 5 votes |
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 2
Source File: QuerySettings.scala From clickhouse-scala-client with GNU Lesser General Public License v3.0 | 5 votes |
package com.crobox.clickhouse.internal import akka.http.scaladsl.model.Uri.Query import com.crobox.clickhouse.internal.QuerySettings._ import com.typesafe.config.Config import scala.collection.JavaConverters._ import scala.util.Try case class QuerySettings(readOnly: ReadOnlySetting = AllQueries, authentication: Option[(String, String)] = None, progressHeaders: Option[Boolean] = None, queryId: Option[String] = None, profile: Option[String] = None, httpCompression: Option[Boolean] = None, settings: Map[String, String] = Map.empty, idempotent: Option[Boolean] = None) { def asQueryParams: Query = Query( settings ++ (Seq("readonly" -> readOnly.value.toString) ++ queryId.map("query_id" -> _) ++ authentication.map( auth => "user" -> auth._1 ) ++ authentication.map(auth => "password" -> auth._2) ++ profile.map("profile" -> _) ++ progressHeaders.map( progress => "send_progress_in_http_headers" -> (if (progress) "1" else "0") ) ++ httpCompression .map(compression => "enable_http_compression" -> (if (compression) "1" else "0"))).toMap ) def withFallback(config: Config): QuerySettings = { val custom = config.getConfig(path("custom")) this.copy( authentication = authentication.orElse(Try { val authConfig = config.getConfig(path("authentication")) (authConfig.getString("user"), authConfig.getString("password")) }.toOption), profile = profile.orElse(Try { config.getString(path("profile")) }.toOption), httpCompression = httpCompression.orElse(Try { config.getBoolean(path("http-compression")) }.toOption), settings = custom.entrySet().asScala.map(u => (u.getKey, custom.getString(u.getKey))).toMap ++ settings ) } private def path(setting: String) = s"settings.$setting" } object QuerySettings { sealed trait ReadOnlySetting { val value: Int } case object AllQueries extends ReadOnlySetting { override val value: Int = 0 } case object ReadQueries extends ReadOnlySetting { override val value: Int = 1 } case object ReadAndChangeQueries extends ReadOnlySetting { override val value: Int = 2 } }
Example 3
package org.apache.openwhisk.standalone import akka.Done import akka.actor.ActorSystem import akka.http.scaladsl.model.Uri.Query import akka.http.scaladsl.model.headers.{Accept, Authorization, BasicHttpCredentials} import akka.http.scaladsl.model.{HttpHeader, HttpMethods, MediaTypes, Uri} import org.apache.openwhisk.core.database.PutException import org.apache.openwhisk.http.PoolingRestClient import spray.json._ import scala.concurrent.{ExecutionContext, Future} class Wsk(host: String, port: Int, authKey: String)(implicit system: ActorSystem) extends DefaultJsonProtocol { import PoolingRestClient._ private implicit val ec: ExecutionContext = system.dispatcher private val client = new PoolingRestClient("http", host, port, 10) private val baseHeaders: List[HttpHeader] = { val Array(username, password) = authKey.split(':') List(Authorization(BasicHttpCredentials(username, password)), Accept(MediaTypes.`application/json`)) } def updatePgAction(name: String, content: String): Future[Done] = { val js = actionJson(name, content) val params = Map("overwrite" -> "true") val uri = Uri(s"/api/v1/namespaces/_/actions/$name").withQuery(Query(params)) client.requestJson[JsObject](mkJsonRequest(HttpMethods.PUT, uri, js, baseHeaders)).map { case Right(_) => Done case Left(status) => throw PutException(s"Error creating action $name " + status) } } private def actionJson(name: String, code: String) = { s"""{ | "namespace": "_", | "name": "$name", | "exec": { | "kind": "nodejs:default", | "code": ${quote(code)} | }, | "annotations": [{ | "key": "provide-api-key", | "value": true | }, { | "key": "web-export", | "value": true | }, { | "key": "raw-http", | "value": false | }, { | "key": "final", | "value": true | }], | "parameters": [{ | "key": "__ignore_certs", | "value": true | }] |}""".stripMargin.parseJson.asJsObject } private def quote(code: String) = { JsString(code).compactPrint } }
Example 4
Source File: request.scala From wix-http-testkit with MIT License | 5 votes |
package com.wix.e2e.http.client.transformers.internals import java.io.File import akka.http.scaladsl.model.Uri.Query import akka.http.scaladsl.model._ import akka.http.scaladsl.model.headers.{Cookie, RawHeader, `User-Agent`} import akka.util.ByteString import com.wix.e2e.http.api.Marshaller import com.wix.e2e.http.client.transformers._ import com.wix.e2e.http.client.transformers.internals.RequestPartOps._ import com.wix.e2e.http.exceptions.UserAgentModificationNotSupportedException import com.wix.e2e.http.{RequestTransformer, WixHttpTestkitResources} import scala.xml.Node trait HttpClientRequestUrlTransformers { def withParam(param: (String, String)): RequestTransformer = withParams(param) def withParams(params: (String, String)*): RequestTransformer = r => r.copy(uri = r.uri .withQuery( Query(currentParams(r) ++ params: _*)) ) private def currentParams(r: HttpRequest): Seq[(String, String)] = r.uri.rawQueryString .map( Query(_).toSeq ) .getOrElse( Seq.empty ) } trait HttpClientRequestHeadersTransformers { def withHeader(header: (String, String)): RequestTransformer = withHeaders(header) def withHeaders(headers: (String, String)*): RequestTransformer = appendHeaders( headers.map { case (h, _) if h.toLowerCase == "user-agent" => throw new UserAgentModificationNotSupportedException case (h, v) => RawHeader(h, v) } ) def withUserAgent(value: String): RequestTransformer = appendHeaders(Seq(`User-Agent`(value))) def withCookie(cookie: (String, String)): RequestTransformer = withCookies(cookie) def withCookies(cookies: (String, String)*): RequestTransformer = appendHeaders( cookies.map(p => Cookie(p._1, p._2)) ) private def appendHeaders[H <: HttpHeader](headers: Iterable[H]): RequestTransformer = r => r.withHeaders( r.headers ++ headers) } trait HttpClientRequestBodyTransformers extends HttpClientContentTypes { @deprecated("use `withTextPayload`", since = "Dec18, 2017") def withPayload(body: String, contentType: ContentType = TextPlain): RequestTransformer = withPayload(ByteString(body).toByteBuffer.array, contentType) def withTextPayload(body: String, contentType: ContentType = TextPlain): RequestTransformer = withPayload(ByteString(body).toByteBuffer.array, contentType) def withPayload(bytes: Array[Byte], contentType: ContentType): RequestTransformer = setBody(HttpEntity(contentType, bytes)) def withPayload(xml: Node): RequestTransformer = setBody(HttpEntity(XmlContent, WixHttpTestkitResources.xmlPrinter.format(xml))) // todo: enable default marshaller when deprecated `withPayload` is removed def withPayload(entity: AnyRef)(implicit marshaller: Marshaller): RequestTransformer = withTextPayload(marshaller.marshall(entity), JsonContent) def withFormData(formParams: (String, String)*): RequestTransformer = setBody(FormData(formParams.toMap).toEntity) def withMultipartData(parts: (String, RequestPart)*): RequestTransformer = setBody( Multipart.FormData(parts.map { case (n, p) => Multipart.FormData.BodyPart(n, p.asBodyPartEntity, p.withAdditionalParams) }:_*) .toEntity) private def setBody(entity: RequestEntity): RequestTransformer = _.copy(entity = entity) } object RequestPartOps { implicit class `RequestPart --> HttpEntity`(private val r: RequestPart) extends AnyVal { def asBodyPartEntity: BodyPartEntity = r match { case PlainRequestPart(v, c) => HttpEntity(v).withContentType(c) case BinaryRequestPart(b, c, _) => HttpEntity(c, b) case FileRequestPart(f, c, _) => HttpEntity.fromPath(c, f.toPath) case FileNameRequestPart(p, c, fn) => FileRequestPart(new File(p), c, fn).asBodyPartEntity } } implicit class `RequestPart --> AdditionalParams`(private val r: RequestPart) extends AnyVal { def withAdditionalParams: Map[String, String] = r match { case _: PlainRequestPart => NoAdditionalParams case BinaryRequestPart(_, _, fn) => additionalParams(fn) case FileRequestPart(_, _, fn) => additionalParams(fn) case FileNameRequestPart(_, _, fn) => additionalParams(fn) } private def additionalParams(filenameOpt: Option[String]) = filenameOpt.map(fn => Map("filename" -> fn)) .getOrElse( NoAdditionalParams ) private def NoAdditionalParams = Map.empty[String, String] } } trait HttpClientRequestTransformersOps { implicit class TransformerConcatenation(first: RequestTransformer) { def and(second: RequestTransformer): RequestTransformer = first andThen second } }
Example 5
Source File: LmgtfyBot.scala From telegram with Apache License 2.0 | 5 votes |
import akka.http.scaladsl.model.Uri import akka.http.scaladsl.model.Uri.Query import cats.instances.future._ import cats.syntax.functor._ import com.bot4s.telegram.Implicits._ import com.bot4s.telegram.api.declarative.{Commands, InlineQueries} import com.bot4s.telegram.future.Polling import com.bot4s.telegram.methods.ParseMode import com.bot4s.telegram.models._ import scala.concurrent.Future class LmgtfyBot(token: String) extends ExampleBot(token) with Polling with InlineQueries[Future] with Commands[Future] { def lmgtfyBtn(query: String): InlineKeyboardMarkup = InlineKeyboardMarkup.singleButton( InlineKeyboardButton.url("\uD83C\uDDECoogle it now!", lmgtfyUrl(query))) onCommand('start | 'help) { implicit msg => reply( s"""Generates ${"Let me \uD83C\uDDECoogle that for you!".italic} links. | |/start | /help - list commands | |/lmgtfy args - generate link | |/lmgtfy2 | /btn args - clickable button | |@Bot args - Inline mode """.stripMargin, parseMode = ParseMode.Markdown).void } onCommand('lmgtfy) { implicit msg => withArgs { args => val query = args.mkString(" ") replyMd( query.altWithUrl(lmgtfyUrl(query)), disableWebPagePreview = true ).void } } def lmgtfyUrl(query: String): String = Uri("http://lmgtfy.com") .withQuery(Query("q" -> query)) .toString() onCommand('btn | 'lmgtfy2) { implicit msg => withArgs { args => val query = args.mkString(" ") reply(query, replyMarkup = lmgtfyBtn(query)).void } } onInlineQuery { implicit iq => val query = iq.query if (query.isEmpty) answerInlineQuery(Seq()).void else { val textMessage = InputTextMessageContent( query.altWithUrl(lmgtfyUrl(query)), disableWebPagePreview = true, parseMode = ParseMode.Markdown) val results = List( InlineQueryResultArticle( "btn:" + query, inputMessageContent = textMessage, title = iq.query, description = "Clickable button + link", replyMarkup = lmgtfyBtn(query) ), InlineQueryResultArticle( query, inputMessageContent = textMessage, description = "Clickable link", title = iq.query ) ) answerInlineQuery(results, cacheTime = 1).void } } }
Example 6
Source File: GitHubHosted2048Bot.scala From telegram with Apache License 2.0 | 5 votes |
import akka.http.scaladsl.model.Uri import akka.http.scaladsl.model.Uri.{Path, Query} import akka.http.scaladsl.model.headers.{HttpOrigin, HttpOriginRange} import ch.megard.akka.http.cors.scaladsl.model.{HttpHeaderRange, HttpOriginMatcher} import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import cats.instances.future._ import cats.syntax.functor._ import ch.megard.akka.http.cors.scaladsl.CorsDirectives.cors import ch.megard.akka.http.cors.scaladsl.settings.CorsSettings import com.bot4s.telegram.api.declarative.{Callbacks, Commands} import com.bot4s.telegram.api.{GameManager, Payload} import com.bot4s.telegram.future.Polling import com.bot4s.telegram.methods.SendGame import scala.concurrent.Future class GitHubHosted2048Bot(token: String, gameManagerHost: String) extends AkkaExampleBot(token) with Polling with Commands[Future] with Callbacks[Future] with GameManager { override val port: Int = 8080 val Play2048 = "play_2048" val GitHubPages = Uri("https://mukel.github.io") onCommand(Play2048 or "2048" or "start") { implicit msg => request( SendGame(msg.source, Play2048) ).void } onCallbackQuery { implicit cbq => val acked = cbq.gameShortName.collect { case Play2048 => val payload = Payload.forCallbackQuery(gameManagerHost) val url = GitHubPages .withPath(Path(s"/$Play2048/index.html")) .withQuery(Query("payload" -> payload.base64Encode)) ackCallback(url = Some(url.toString())) } acked.getOrElse(ackCallback()).void } // Enable CORS for GitHub Pages. // Allows GitHub Pages to call cross-domain getScores and setScore. private val allowGitHub = CorsSettings.defaultSettings .withAllowedOrigins(HttpOriginMatcher(HttpOrigin(GitHubPages.toString()))) override def routes: Route = super.routes ~ cors(allowGitHub) { gameManagerRoute } }
Example 7
Source File: SelfHosted2048Bot.scala From telegram with Apache License 2.0 | 5 votes |
import akka.http.scaladsl.model.Uri import akka.http.scaladsl.model.Uri.{Path, Query} import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import cats.instances.future._ import cats.syntax.functor._ import com.bot4s.telegram.api.declarative.{Callbacks, Commands} import com.bot4s.telegram.api.{AkkaDefaults, GameManager, Payload} import com.bot4s.telegram.future.Polling import com.bot4s.telegram.methods.SendGame import scala.concurrent.Future class SelfHosted2048Bot(token: String, gameManagerHost: String) extends ExampleBot(token) with Polling with AkkaDefaults with Callbacks[Future] with GameManager with Commands[Future] { override val port: Int = 8080 val Play2048 = "play_2048" onCommand(Play2048 or "2048" or "start") { implicit msg => request( SendGame(msg.source, Play2048) ).void } onCallbackQuery { implicit cbq => val acked = cbq.gameShortName.collect { case Play2048 => val payload = Payload.forCallbackQuery(gameManagerHost) val url = Uri(gameManagerHost) .withPath(Path(s"/$Play2048/index.html")) .withQuery(Query("payload" -> payload.base64Encode)) ackCallback(url = Some(url.toString())) } acked.getOrElse(ackCallback()).void } override def routes: Route = super.routes ~ gameManagerRoute ~ { pathPrefix(Play2048) { getFromResourceDirectory(Play2048) } } }
Example 8
Source File: OAuth2Routes.scala From scastie with Apache License 2.0 | 5 votes |
package com.olegych.scastie package web package routes import oauth2._ import com.softwaremill.session.SessionDirectives._ import com.softwaremill.session.SessionOptions._ import com.softwaremill.session.CsrfDirectives._ import com.softwaremill.session.CsrfOptions._ import akka.http.scaladsl.model._ import akka.http.scaladsl.model.Uri.Query import akka.http.scaladsl.model.StatusCodes.TemporaryRedirect import akka.http.scaladsl.model.headers.Referer import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import scala.concurrent.ExecutionContext class OAuth2Routes(github: Github, session: GithubUserSession)( implicit val executionContext: ExecutionContext ) { import session._ val routes: Route = get( concat( path("login") { parameter("home".?)( home => optionalHeaderValueByType[Referer](()) { referrer => redirect( Uri("https://github.com/login/oauth/authorize").withQuery( Query( "client_id" -> github.clientId, "state" -> { val homeUri = "/" if (home.isDefined) homeUri else referrer.map(_.value).getOrElse(homeUri) } ) ), TemporaryRedirect ) } ) }, path("logout") { headerValueByType[Referer](()) { referrer => requiredSession(refreshable, usingCookies) { _ => invalidateSession(refreshable, usingCookies) { ctx => ctx.complete( HttpResponse( status = TemporaryRedirect, headers = headers.Location(Uri(referrer.value)) :: Nil, entity = HttpEntity.Empty ) ) } } } }, pathPrefix("callback") { pathEnd { parameters(("code", "state".?)) { (code, state) => onSuccess(github.getUserWithOauth2(code)) { user => setSession(refreshable, usingCookies, session.addUser(user)) { setNewCsrfToken(checkHeader) { ctx => ctx.complete( HttpResponse( status = TemporaryRedirect, headers = headers .Location(Uri(state.getOrElse("/"))) :: Nil, entity = HttpEntity.Empty ) ) } } } } } } ) ) }
Example 9
Source File: QueryResultEncoder.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.search import akka.http.scaladsl.model.Uri import akka.http.scaladsl.model.Uri.Query import ch.epfl.bluebrain.nexus.commons.search.QueryResult.{ScoredQueryResult, UnscoredQueryResult} import ch.epfl.bluebrain.nexus.commons.search.QueryResults.{ScoredQueryResults, UnscoredQueryResults} import ch.epfl.bluebrain.nexus.commons.search.{FromPagination, QueryResult, QueryResults} import ch.epfl.bluebrain.nexus.kg.config.Contexts.{resourceCtxUri, searchCtxUri} import ch.epfl.bluebrain.nexus.kg.directives.QueryDirectives.{after, from, size} import ch.epfl.bluebrain.nexus.kg.indexing.SparqlLink import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig import ch.epfl.bluebrain.nexus.service.config.Vocabulary.nxv import io.circe.syntax._ import io.circe.{Encoder, Json} trait LowPriorityQueryResultsEncoder { implicit def qrsEncoderLowPrio[A: Encoder]: Encoder[QueryResults[A]] = Encoder.instance(qrsEncoderJsonLinks[A](None).apply(_)) implicit private val uriEncoder: Encoder[Uri] = Encoder.encodeString.contramap(_.toString) protected def qrsEncoderJsonLinks[A: Encoder](next: Option[Uri]): Encoder[QueryResults[A]] = { implicit def qrEncoderJson: Encoder[QueryResult[A]] = Encoder.instance { case UnscoredQueryResult(v) => v.asJson.removeKeys(nxv.original_source.prefix) case ScoredQueryResult(score, v) => v.asJson.removeKeys(nxv.original_source.prefix) deepMerge Json.obj(nxv.score.prefix -> Json.fromFloatOrNull(score)) } def json(total: Long, list: List[QueryResult[A]]): Json = Json .obj(nxv.total.prefix -> Json.fromLong(total), nxv.results.prefix -> Json.arr(list.map(qrEncoderJson(_)): _*)) .addContext(searchCtxUri) .addContext(resourceCtxUri) Encoder.instance { case UnscoredQueryResults(total, list, _) => json(total, list) deepMerge Json.obj(nxv.next.prefix -> next.asJson) case ScoredQueryResults(total, maxScore, list, _) => json(total, list) deepMerge Json.obj(nxv.maxScore.prefix -> maxScore.asJson, nxv.next.prefix -> next.asJson) } } } object QueryResultEncoder extends LowPriorityQueryResultsEncoder { implicit def qrsEncoderJson(implicit searchUri: Uri, http: HttpConfig): Encoder[QueryResults[Json]] = Encoder.instance { results => val nextLink = results.token.flatMap(next(searchUri, _)) qrsEncoderJsonLinks[Json](nextLink).apply(results) } implicit def qrsEncoderJson(implicit searchUri: Uri, pagination: FromPagination, http: HttpConfig ): Encoder[QueryResults[SparqlLink]] = Encoder.instance { results => val nextLink = next(searchUri, results.total, pagination) qrsEncoderJsonLinks[SparqlLink](nextLink).apply(results) } private def next(current: Uri, total: Long, pagination: FromPagination)(implicit http: HttpConfig): Option[Uri] = { val nextFrom = pagination.from + pagination.size if (nextFrom < total.toInt) { val params = current.query().toMap + (from -> nextFrom.toString) + (size -> pagination.size.toString) Some(toPublic(current).withQuery(Query(params))) } else None } private def next(current: Uri, afterToken: String)(implicit http: HttpConfig): Option[Uri] = current.query().get(after) match { case Some(`afterToken`) => None case _ => val params = current.query().toMap + (after -> afterToken) - from Some(toPublic(current).withQuery(Query(params))) } private def toPublic(uri: Uri)(implicit http: HttpConfig): Uri = uri.copy(scheme = http.publicUri.scheme, authority = http.publicUri.authority) }
Example 10
Source File: QueryResultEncoderSpec.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.search import java.time.Instant import java.util.regex.Pattern.quote import akka.http.scaladsl.model.Uri import akka.http.scaladsl.model.Uri.Query import ch.epfl.bluebrain.nexus.commons.circe.syntax._ import ch.epfl.bluebrain.nexus.commons.search.QueryResult.{ScoredQueryResult, UnscoredQueryResult} import ch.epfl.bluebrain.nexus.commons.search.QueryResults import ch.epfl.bluebrain.nexus.commons.search.QueryResults.{ScoredQueryResults, UnscoredQueryResults} import ch.epfl.bluebrain.nexus.commons.test.{Randomness, Resources} import ch.epfl.bluebrain.nexus.kg.search.QueryResultEncoder._ import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig import io.circe.Json import io.circe.syntax._ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike class QueryResultEncoderSpec extends AnyWordSpecLike with Matchers with Resources with Randomness { implicit val orderedKeys = ServiceConfig.orderedKeys val org = genString() val proj = genString() val schema = genString() val now = Instant.now() implicit val http = HttpConfig("", 0, "v1", "http://nexus.com") implicit val uri = Uri(s"http://nexus.com/resources/$org/$proj/$schema?type=someType&from=10&size=10") val before = now.minusSeconds(60) "QueryResultsEncoder" should { def json(id: AbsoluteIri, createdAt: Instant): Json = jsonContentOf( "/resources/es-metadata.json", Map( quote("{id}") -> id.asString, quote("{org}") -> org, quote("{proj}") -> proj, quote("{schema}") -> schema, quote("{instant}") -> createdAt.toString ) ) deepMerge Json.obj("_original_source" -> Json.fromString(Json.obj("k" -> Json.fromInt(1)).noSpaces)) "encode ScoredQueryResults" in { val results: QueryResults[Json] = ScoredQueryResults[Json]( 3, 0.3f, List( ScoredQueryResult(0.3f, json(url"http://nexus.com/result1", before)), ScoredQueryResult(0.2f, json(url"http://nexus.com/result2", before)), ScoredQueryResult(0.1f, json(url"http://nexus.com/result3", now)) ), sort(now) ) results.asJson.sortKeys shouldEqual jsonContentOf( "/search/scored-query-results.json", Map( quote("{org}") -> org, quote("{proj}") -> proj, quote("{schema}") -> schema, quote("{before}") -> before.toString, quote("{lastElementCreated}") -> now.toString, quote("{after}") -> after(now) ) ) } "encode UnscoredQueryResults" in { val results: QueryResults[Json] = UnscoredQueryResults[Json]( 3, List( UnscoredQueryResult(json(url"http://nexus.com/result1", before)), UnscoredQueryResult(json(url"http://nexus.com/result2", before)), UnscoredQueryResult(json(url"http://nexus.com/result3", now)) ), sort(now) ) results.asJson.sortKeys shouldEqual jsonContentOf( "/search/unscored-query-results.json", Map( quote("{org}") -> org, quote("{proj}") -> proj, quote("{schema}") -> schema, quote("{before}") -> before.toString, quote("{lastElementCreated}") -> now.toString, quote("{after}") -> after(now) ) ) } } private def sort(instant: Instant): Option[String] = Some(Json.arr(Json.fromString(instant.toString)).noSpaces) private def after(instant: Instant): String = Query("after" -> List(Json.fromString(instant.toString)).asJson.noSpaces).toString() }
Example 11
Source File: PublicApi.scala From affinity with Apache License 2.0 | 5 votes |
import akka.http.scaladsl.model.HttpMethods._ import akka.http.scaladsl.model.HttpResponse import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.model.Uri.{Path, Query} import io.amient.affinity.avro.record.AvroRecord import io.amient.affinity.core.actor.GatewayHttp import io.amient.affinity.core.http.Encoder import io.amient.affinity.core.http.RequestMatchers.{HTTP, PATH} import io.amient.affinity.core.state.KVStore import scala.concurrent.Promise case class ProtectedProfile(hello: String = "world") extends AvroRecord trait PublicApi extends GatewayHttp { private val settings: KVStore[String, ConfigEntry] = global[String, ConfigEntry]("settings") abstract override def handle: Receive = super.handle orElse { case HTTP(GET, uri@PATH("profile", _), query, response) => AUTH_DSA(uri, query, response) { (sig: String) => Encoder.json(OK, Map( "signature" -> sig, "profile" -> ProtectedProfile() )) } case HTTP(GET, uri@PATH("verify"), query, response) => AUTH_DSA(uri, query, response) { _ => Encoder.json(OK, Some(ProtectedProfile())) } } object AUTH_DSA { def apply(path: Path, query: Query, response: Promise[HttpResponse])(code: (String) => HttpResponse): Unit = { try { query.get("signature") match { case None => throw new IllegalAccessError case Some(sig) => sig.split(":") match { case Array(k, clientSignature) => settings(k) match { case None => throw new IllegalAccessError(s"Invalid api key $k") case Some(configEntry) => if (configEntry.crypto.verify(clientSignature, path.toString)) { val serverSignature = configEntry.crypto.sign(clientSignature) response.success(code(serverSignature)) } else { throw new IllegalAccessError(configEntry.crypto.sign(path.toString)) } } case _ => throw new IllegalAccessError } } } catch { case _: IllegalAccessError => response.success(Encoder.json(Unauthorized, "Unauthorized")) case e: Throwable => response.success(handleException(headers = List())(e)) } } } }
Example 12
Source File: AkkaHttpClient.scala From graphql-gateway with Apache License 2.0 | 5 votes |
package sangria.gateway.http.client import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model.HttpHeader.ParsingResult import akka.http.scaladsl.model._ import akka.http.scaladsl.model.Uri.Query import akka.http.scaladsl.model.headers.Location import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.Materializer import akka.util.ByteString import sangria.gateway.util.Logging import scala.concurrent.{ExecutionContext, Future} class AkkaHttpClient(implicit system: ActorSystem, mat: Materializer, ec: ExecutionContext) extends HttpClient with Logging { import AkkaHttpClient._ import HttpClient._ override def request(method: Method.Value, url: String, queryParams: Seq[(String, String)] = Seq.empty, headers: Seq[(String, String)] = Seq.empty, body: Option[(String, String)] = None) = { val m = mapMethod(method) val query = Query(queryParams: _*) val hs = headers.map(header) val uri = Uri(url).withQuery(query) val entity = body.fold(HttpEntity.Empty){case (tpe, content) ⇒ HttpEntity(contentType(tpe), ByteString(content))} val request = HttpRequest(m, uri, hs.toVector, entity) val client = Http().singleRequest(_: HttpRequest) val richClient = RichHttpClient.httpClientWithRedirect(client) logger.debug(s"Http request: ${m.value} $url") richClient(request).map(AkkaHttpResponse(m, url, _)) } override def oauthClientCredentials(url: String, clientId: String, clientSecret: String, scopes: Seq[String]): Future[HttpResponse] = throw new IllegalStateException("Not yet implemented, please use play implementation.") private def contentType(str: String) = ContentType.parse(str).fold( errors ⇒ throw ClientError(s"Invalid content type '$str'", errors.map(_.detail)), identity) private def header(nameValue: (String, String)) = HttpHeader.parse(nameValue._1, nameValue._2) match { case ParsingResult.Ok(_, errors) if errors.nonEmpty ⇒ throw ClientError(s"Invalid header '${nameValue._1}'", errors.map(_.detail)) case ParsingResult.Error(error) ⇒ throw ClientError(s"Invalid header '${nameValue._1}'", Seq(error.detail)) case ParsingResult.Ok(h, _) ⇒ h } def mapMethod(method: Method.Value) = method match { case Method.Get ⇒ HttpMethods.GET case Method.Post ⇒ HttpMethods.POST } object RichHttpClient { import akka.http.scaladsl.model.HttpResponse type HttpClient = HttpRequest ⇒ Future[HttpResponse] def redirectOrResult(client: HttpClient)(response: HttpResponse): Future[HttpResponse] = response.status match { case StatusCodes.Found | StatusCodes.MovedPermanently | StatusCodes.SeeOther ⇒ val newUri = response.header[Location].get.uri // Always make sure you consume the response entity streams (of type Source[ByteString,Unit]) by for example connecting it to a Sink (for example response.discardEntityBytes() if you don’t care about the response entity), since otherwise Akka HTTP (and the underlying Streams infrastructure) will understand the lack of entity consumption as a back-pressure signal and stop reading from the underlying TCP connection! response.discardEntityBytes() logger.debug(s"Http redirect: ${HttpMethods.GET.value} $newUri") client(HttpRequest(method = HttpMethods.GET, uri = newUri)) case _ ⇒ Future.successful(response) } def httpClientWithRedirect(client: HttpClient): HttpClient = { lazy val redirectingClient: HttpClient = req ⇒ client(req).flatMap(redirectOrResult(redirectingClient)) // recurse to support multiple redirects redirectingClient } } case class ClientError(message: String, errors: Seq[String]) extends Exception(message + ":\n" + errors.map(" * " + _).mkString("\n")) } object AkkaHttpClient { case class AkkaHttpResponse(method: HttpMethod, url: String, response: HttpResponse)(implicit mat: Materializer) extends HttpClient.HttpResponse { def asString = Unmarshal(response).to[String] def statusCode = response.status.intValue() def isSuccessful = response.status.isSuccess() def debugInfo = s"${method.value} $url" } }
Example 13
Source File: QueryResultEncoder.scala From nexus-kg with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.search import akka.http.scaladsl.model.Uri import akka.http.scaladsl.model.Uri.Query import ch.epfl.bluebrain.nexus.commons.search.QueryResult.{ScoredQueryResult, UnscoredQueryResult} import ch.epfl.bluebrain.nexus.commons.search.QueryResults.{ScoredQueryResults, UnscoredQueryResults} import ch.epfl.bluebrain.nexus.commons.search.{FromPagination, QueryResult, QueryResults} import ch.epfl.bluebrain.nexus.kg.config.AppConfig.HttpConfig import ch.epfl.bluebrain.nexus.kg.config.Contexts.{resourceCtxUri, searchCtxUri} import ch.epfl.bluebrain.nexus.kg.config.Vocabulary.nxv import ch.epfl.bluebrain.nexus.kg.directives.QueryDirectives.{after, from, size} import ch.epfl.bluebrain.nexus.kg.indexing.SparqlLink import ch.epfl.bluebrain.nexus.rdf.implicits._ import io.circe.syntax._ import io.circe.{Encoder, Json} trait LowPriorityQueryResultsEncoder { implicit def qrsEncoderLowPrio[A: Encoder]: Encoder[QueryResults[A]] = Encoder.instance(qrsEncoderJsonLinks[A](None).apply(_)) private implicit val uriEncoder: Encoder[Uri] = Encoder.encodeString.contramap(_.toString) protected def qrsEncoderJsonLinks[A: Encoder](next: Option[Uri]): Encoder[QueryResults[A]] = { implicit def qrEncoderJson: Encoder[QueryResult[A]] = Encoder.instance { case UnscoredQueryResult(v) => v.asJson.removeKeys(nxv.original_source.prefix) case ScoredQueryResult(score, v) => v.asJson.removeKeys(nxv.original_source.prefix) deepMerge Json.obj(nxv.score.prefix -> Json.fromFloatOrNull(score)) } def json(total: Long, list: List[QueryResult[A]]): Json = Json .obj(nxv.total.prefix -> Json.fromLong(total), nxv.results.prefix -> Json.arr(list.map(qrEncoderJson(_)): _*)) .addContext(searchCtxUri) .addContext(resourceCtxUri) Encoder.instance { case UnscoredQueryResults(total, list, _) => json(total, list) deepMerge Json.obj(nxv.next.prefix -> next.asJson) case ScoredQueryResults(total, maxScore, list, _) => json(total, list) deepMerge Json.obj(nxv.maxScore.prefix -> maxScore.asJson, nxv.next.prefix -> next.asJson) } } } object QueryResultEncoder extends LowPriorityQueryResultsEncoder { implicit def qrsEncoderJson(implicit searchUri: Uri, http: HttpConfig): Encoder[QueryResults[Json]] = Encoder.instance { results => val nextLink = results.token.flatMap(next(searchUri, _)) qrsEncoderJsonLinks[Json](nextLink).apply(results) } implicit def qrsEncoderJson( implicit searchUri: Uri, pagination: FromPagination, http: HttpConfig ): Encoder[QueryResults[SparqlLink]] = Encoder.instance { results => val nextLink = next(searchUri, results.total, pagination) qrsEncoderJsonLinks[SparqlLink](nextLink).apply(results) } private def next(current: Uri, total: Long, pagination: FromPagination)(implicit http: HttpConfig): Option[Uri] = { val nextFrom = pagination.from + pagination.size if (nextFrom < total.toInt) { val params = current.query().toMap + (from -> nextFrom.toString) + (size -> pagination.size.toString) Some(toPublic(current).withQuery(Query(params))) } else None } private def next(current: Uri, afterToken: String)(implicit http: HttpConfig): Option[Uri] = current.query().get(after) match { case Some(`afterToken`) => None case _ => val params = current.query().toMap + (after -> afterToken) - from Some(toPublic(current).withQuery(Query(params))) } private def toPublic(uri: Uri)(implicit http: HttpConfig): Uri = uri.copy(scheme = http.publicUri.scheme, authority = http.publicUri.authority) }
Example 14
Source File: QueryResultEncoderSpec.scala From nexus-kg with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.search import java.time.Instant import java.util.regex.Pattern.quote import akka.http.scaladsl.model.Uri import akka.http.scaladsl.model.Uri.Query import ch.epfl.bluebrain.nexus.commons.circe.syntax._ import ch.epfl.bluebrain.nexus.commons.search.QueryResult.{ScoredQueryResult, UnscoredQueryResult} import ch.epfl.bluebrain.nexus.commons.search.QueryResults import ch.epfl.bluebrain.nexus.commons.search.QueryResults.{ScoredQueryResults, UnscoredQueryResults} import ch.epfl.bluebrain.nexus.commons.test.{Randomness, Resources} import ch.epfl.bluebrain.nexus.kg.config.AppConfig import ch.epfl.bluebrain.nexus.kg.config.AppConfig.HttpConfig import ch.epfl.bluebrain.nexus.kg.search.QueryResultEncoder._ import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import ch.epfl.bluebrain.nexus.rdf.implicits._ import io.circe.Json import io.circe.syntax._ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike class QueryResultEncoderSpec extends AnyWordSpecLike with Matchers with Resources with Randomness { implicit val orderedKeys = AppConfig.orderedKeys val org = genString() val proj = genString() val schema = genString() val now = Instant.now() implicit val http = HttpConfig("", 0, "v1", "http://nexus.com") implicit val uri = Uri(s"http://nexus.com/resources/$org/$proj/$schema?type=someType&from=10&size=10") val before = now.minusSeconds(60) "QueryResultsEncoder" should { def json(id: AbsoluteIri, createdAt: Instant): Json = jsonContentOf( "/resources/es-metadata.json", Map( quote("{id}") -> id.asString, quote("{org}") -> org, quote("{proj}") -> proj, quote("{schema}") -> schema, quote("{instant}") -> createdAt.toString ) ) deepMerge Json.obj("_original_source" -> Json.fromString(Json.obj("k" -> Json.fromInt(1)).noSpaces)) "encode ScoredQueryResults" in { val results: QueryResults[Json] = ScoredQueryResults[Json]( 3, 0.3f, List( ScoredQueryResult(0.3f, json(url"http://nexus.com/result1", before)), ScoredQueryResult(0.2f, json(url"http://nexus.com/result2", before)), ScoredQueryResult(0.1f, json(url"http://nexus.com/result3", now)) ), sort(now) ) results.asJson.sortKeys shouldEqual jsonContentOf( "/search/scored-query-results.json", Map( quote("{org}") -> org, quote("{proj}") -> proj, quote("{schema}") -> schema, quote("{before}") -> before.toString, quote("{lastElementCreated}") -> now.toString, quote("{after}") -> after(now) ) ) } "encode UnscoredQueryResults" in { val results: QueryResults[Json] = UnscoredQueryResults[Json]( 3, List( UnscoredQueryResult(json(url"http://nexus.com/result1", before)), UnscoredQueryResult(json(url"http://nexus.com/result2", before)), UnscoredQueryResult(json(url"http://nexus.com/result3", now)) ), sort(now) ) results.asJson.sortKeys shouldEqual jsonContentOf( "/search/unscored-query-results.json", Map( quote("{org}") -> org, quote("{proj}") -> proj, quote("{schema}") -> schema, quote("{before}") -> before.toString, quote("{lastElementCreated}") -> now.toString, quote("{after}") -> after(now) ) ) } } private def sort(instant: Instant): Option[String] = Some(Json.arr(Json.fromString(instant.toString)).noSpaces) private def after(instant: Instant): String = Query("after" -> List(Json.fromString(instant.toString)).asJson.noSpaces).toString() }
Example 15
Source File: ServeSpec.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.akkaHttp import akka.http.scaladsl.model.Multipart.FormData import akka.http.scaladsl.model.Uri.Query import akka.http.scaladsl.model.{HttpEntity, Uri} import akka.http.scaladsl.server.MissingQueryParamRejection import akka.http.scaladsl.testkit.ScalatestRouteTest import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import ru.tinkoff.tschema.syntax class ServeSpec extends AnyWordSpec with Matchers with ScalatestRouteTest { trait Small import ru.tinkoff.tschema.syntax._ val dsl = syntax val intAnswer = 42 object handler { val int = 42 def repeat(body: String, n: Int) = body * n def multiply(x: Long, y: Double) = f"result is ${x * y}%.2f" def size(args: List[Int]) = args.size def min(args: List[Int]) = args.min } def api = (keyPrefix("int") :> get :> complete[Int]) ~ (keyPrefix("repeat") :> reqBody[String] :> queryParam[Int]("n") :> post :> complete[String]) ~ (keyPrefix("multiply") :> formField[Long]("x") :> formField[Double]("y") :> post :> complete[String]) ~ (keyPrefix("size") :> queryParams[Option[Int]]("args") :> post :> complete[Int]) ~ (keyPrefix("min") :> queryParams[Int]("args") :> post :> complete[Int]) val route = MkRoute(api)(handler) "Simple service" should { "return a simple int" in { Get("/int") ~> route ~> check { responseAs[Int] shouldEqual intAnswer } } "multiply string by n times" in { Post(Uri("/repeat").withQuery(Query("n" -> "5")), "batman") ~> route ~> check { responseAs[String] shouldEqual ("batman" * 5) } } "multiply numbers from formdata" in { Post(Uri("/multiply"), FormData(Map("x" -> HttpEntity("3"), "y" -> HttpEntity("1.211")))) ~> route ~> check { responseAs[String] shouldEqual f"result is ${3.63}%.2f" } } "return size of empty args" in { Post(Uri("/size")) ~> route ~> check { responseAs[Int] shouldEqual 0 } } "return size of non empty args" in { Post(Uri("/size").withQuery(Query(List("1", "2", "3").map("args" -> _): _*))) ~> route ~> check { responseAs[Int] shouldEqual 3 } } "return min of non empty args" in { Post(Uri("/min").withQuery(Query(List("3", "1", "2").map("args" -> _): _*))) ~> route ~> check { responseAs[Int] shouldEqual 1 } } "reject on min with empty args" in { Post(Uri("/min")) ~> route ~> check { rejection shouldEqual MissingQueryParamRejection("args") } } } }