I'm building an API with Rapture in Scala and having trouble resolving an issue with an implicit not being in scope. Here is the output from the error that I'm receiving.
[error] /Users/Petesta/Documents/scala-project/src/main/scala/scala-project/main.scala:35: an implicit TimeSystem is required; please import timeSystems.numeric or timeSystems.javaUtil
[error] Error occurred in an application involving default arguments.
[error] val response = h.get()
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
[error] Total time: 5 s, completed Oct 16, 2014 3:36:10 PM
Here is the code that it is failing on.
def getUser(userName: String) = {
val h = Http / "some_url" / "user" / userName /? Map('key -> "value")
val response = h.get()
}
I'm not sure what to do because I've tried importing both libraries separately and the error is still the same.
I've also added the -Xlog-implicits flag to see if something else is causing the error but no additional information is outputted.
Is there a good resource anywhere with using the rapture-net library for HTTP requests? I couldn't find one except for Jon Pretty's slides at Scala By The Bay. I couldn't figure out a way to pass in a url with query strings into rapture-uri since it expects function invocation to look like this uri"url_dot_domain_with_query_strings".slurp[Char].
Any ideas?
The compilation error is not entirely correct in this case. You need 1 of the 2 imports AND you need to specify a timeout value.
def getUser(userName: String) = {
import timeSystems.numeric
val h = Http / "some_url" / "user" / userName /? Map('key -> "value")
val response = h.get(timeout = 5000L)
}
I don't really know of a good resource on it, but your basic single code line is correct. The biggest problem with the library is really documentation about the imports required. But this is what I found works for me:
def getGoogle() = {
import rapture.codec._
import rapture.io._
import rapture.uri._
import rapture.net._
import encodings.`UTF-8`
uri"http://google.com".slurp[Char]
}
Related
I am trying to create webapp with http4s that is based on Http4sServlet.
The following code does not compile:
import cats.effect._
import org.http4s.servlet.BlockingServletIo
import org.http4s.servlet.Http4sServlet
import scala.concurrent.ExecutionContext.global
import org.http4s.implicits._
class UserSvcServlet
extends Http4sServlet[IO](service = UserSvcServer.start
, servletIo = BlockingServletIo(4096, Blocker.liftExecutionContext(global)))(IOApp)
the error message:
[error] /home/developer/scala/user-svc/src/main/scala/io/databaker/UserSvcServlet.scala:12:54: Cannot find implicit value for ConcurrentEffect[[+A]cats.effect.IO[A]].
[error] Building this implicit value might depend on having an implicit
[error] s.c.ExecutionContext in scope, a Scheduler, a ContextShift[[+A]cats.effect.IO[A]]
[error] or some equivalent type.
[error] extends Http4sServlet[IO]( service = UserSvcServer.stream
[error] ^
[error] /home/developer/scala/user-svc/src/main/scala/io/databaker/UserSvcServlet.scala:13:36: Cannot find an implicit value for ContextShift[[+A]cats.effect.IO[A]]:
[error] * import ContextShift[[+A]cats.effect.IO[A]] from your effects library
[error] * if using IO, use cats.effect.IOApp or build one with cats.effect.IO.contextShift
[error] , servletIo = BlockingServletIo(4096, Blocker.liftExecutionContext(global)))
[error] ^
[error] two errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed May 29, 2020, 8:45:00 PM
The UserSvcServer is implemented as follows:
import org.http4s.HttpApp
import cats.effect.{ConcurrentEffect, ContextShift, Timer}
import org.http4s.implicits._
import org.http4s.server.middleware.Logger
object UserSvcServer {
def start[F[_] : ConcurrentEffect](implicit T: Timer[F], C: ContextShift[F]): HttpApp[F] = {
val helloWorldAlg = HelloWorld.impl[F]
val httpApp = UserSvcRoutes.helloWorldRoutes[F](helloWorldAlg).orNotFound
Logger.httpApp(true, true)(httpApp)
}
}
How can I import ContextShift implicitly?
Context shift is just cats' wrapper over ExecutionContext. You can create one explicitly as stated in docs:
implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global)
You usually create one context shift at the entry point of your app (probably in the main method).
If your app uses IOApp from cats-effect it would have already implicit for contextShift in scope. It will use execution context, which would have number of threads equal to available processors of your computer.
If you want to use created contextShift "deeper" inside your application you can pass it as an implicit parameter:
def doSomething(implicit cs: ContextShift[IO]): IO[Unit] = ???
So in order to make your code work, you need to make sure that method or class calls constructor of UserSvcServlet has implicit for contextShift:
(implicit cs: ContextShift[IO]).
You could also put it in separate object:
object AppContextShift {
implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global)
implicit val t: Timer[IO] = IO.timer(ExecutionContext.global) //you will probably also need timer eventually
}
Then you can import it when contextShift is needed:
import AppContextShift._
By the way, using a global execution context for Blocker is not good idea.
Blocked is used for blocking operations and using it with ExecutionContext.global might lead to thread starvation in your app.
The most common approach is to use blocker created from cached thread pool:
Blocker.liftExecutorService(Executors.newCachedThreadPool())
I am trying to log extra response information in gatling result through, http.extraInfoExtractor. Below is my code, I am failing to execute the same, also mentioned the error. Please help.
Code :
package cloudnative
import scala.concurrent.duration._
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
class cloudnativems extends Simulation {
val nbUsers = Integer.getInteger("users", 1)
val myRamp = java.lang.Long.getLong("ramp", 0L)
val varPipelineId = sys.env.get("CI_PIPELINE_ID")
println(varPipelineId)
val httpProtocol = http
.baseUrl("https://lXXXXXXXXXX")
.inferHtmlResources()
.contentTypeHeader("application/json")
val scn = scenario("cloudnativems")
.exec(http("account_movement_post")
.post("/XXXXXXX/gatling-poc/demo/movement/account")
.extraInfoExtractor(extraInfo => List(extraInfo.response.statusCode.get))
.body(StringBody("""{
"movementId": "m0001",
"accountId": "a0001",
"amount": 2000,
"movementDate": "2019-02-26T09:34:50.301Z",
"counterparty": "c0001"
}""")))
.exec(http("account_movement_get")
.get("/XXXXXXX/gatling-poc/demo/movement/account/m0001")
)
setUp(scn.inject(atOnceUsers(1)).protocols(httpProtocol))
}
Error
C:\Sopra Project\Tools\gatling-charts-highcharts-bundle-3.0.3\bin>gatling.bat -s cloudnative.cloudnativems
GATLING_HOME is set to "C:\Sopra Project\Tools\gatling-charts-highcharts-bundle-3.0.3"
JAVA = ""C:\Program Files\Java\jdk1.8.0_201\bin\java.exe""
11:56:14.849 [ERROR] i.g.c.ZincCompiler$ - C:\Sopra Project\Tools\gatling-charts-highcharts-bundle-3.0.3\user-files\simulations\cloudnative\cloudnativems.scala:25:8: value extraInfoExtractor is not a member of io.gatling.http.request.builder.HttpRequestBuilder
possible cause: maybe a semicolon is missing before `value extraInfoExtractor'?
.extraInfoExtractor(extraInfo => List(extraInfo.response.statusCode.get))
^
11:56:15.190 [ERROR] i.g.c.ZincCompiler$ - one error found
11:56:15.193 [ERROR] i.g.c.ZincCompiler$ - Compilation crashed
sbt.internal.inc.CompileFailed: null
extraInfoExtractor has been dropped with version 3.0 according to https://gatling.io/docs/current/migration_guides/2.3-to-3.0/:
extraInfoExtractor was dropped as it wasn’t used in any Gatling component
I am not aware of a replacement construct in Gatling 3.0
Greetings,
Matthias
I am looking at this tutorial: http://lollyrock.com/articles/scala-http-requests/.
I'm trying to make a plain HTTP request like the one they have:
val address = url("http://somewebaddress.com/elements")
val x = Http(address OK as.String)
However, for that part of the code I am getting:
type mismatch;
[error] found : (com.ning.http.client.Request, dispatch.OkFunctionHandler[String])
[error] required: akka.actor.ActorSystem
[error] val x = Http(address OK as.String)
[error] ^
Which is quite strange since I'm passing only 1 argument, not 2.
Any idea why this is happening?
I was importing another HTTP library by accident and there was a name clash.
You have typo error in this string:
val response : Future[String] = Http(svc OK as.String)
I'm following the Scalazon example at here to create a Kinesis stream. The following piece of code:
val streamListFuture = for {
s <- Kinesis.streams.list
} yield s
gives the following error:
[error] KinesisStatsWriter.scala:51: value map is not a member of object io.github.cloudify.scala.aws.kinesis.Requests.ListStreams
[error] s <- Kinesis.streams.list
If I don't use a for comprehension and call val createStream = Kinesis.streams.list, there's no error. Can't seem to figure out why.
Similarly, the following bit of code:
val createStream = for {
s <- Kinesis.streams.create(name)
} yield s
produces a similar error:
[error] KinesisStatsWriter.scala:64: value map is not a member of io.github.cloudify.scala.aws.kinesis.Requests.CreateStream
[error] s <- Kinesis.streams.create(name)
Appreciate the help!
Author here, the for-comprehension works only if you include the module that implicitly converts requests to Futures (it's called ImplicitExecution). Try adding the following import statement (looks at the sample code in the library README).
import io.github.cloudify.scala.aws.kinesis.Client.ImplicitExecution._
I copied the instructions on the JSON formatting Guide found here: http://www.scalatra.org/2.2/guides/formats/json.html
Below is MyScalatraServlet.scala file with all of the code I embedded to test out JSON formatting:
package net.example.testapp
import org.scalatra._
import scalate.ScalateSupport
// JSON-related libraries
import org.json4s.{DefaultFormats, Formats}
// JSON handling support from Scalatra
import org.scalatra.json._
class MyScalatraServlet extends TestAppStack with JacksonJsonSupport {
get("/") {
FlowerData.all
}
}
// Sets up automatic case class to JSON output serialization, required by
// the JValueResult trait.
protected implicit val jsonFormats: Formats = DefaultFormats
case class Flower(slug: String, name: String)
object FlowerData {
/**
* Some fake flowers data so we can simulate retrievals.
*/
var all = List(
Flower("yellow-tulip", "Yellow Tulip"),
Flower("red-rose", "Red Rose"),
Flower("black-rose", "Black Rose"))
}
It seems the compiler does not like the following line:
protected implicit val jsonFormats: Formats = DefaultFormats
Here's the error message:
[error] /Users/test/test-app/src/main/scala/net/example/testapp/MyScalatraServlet.scala:22: expected start of definition
[error] protected implicit val jsonFormats: Formats = DefaultFormats
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
[error] Total time: 2 s, completed Jun 17, 2013 4:04:34 PM
>
Your val jsonFormats is just kinda floating there, not tied to a class or anything. A val needs to be defined as part of another construct like a trait, class or object. Try moving it inside of that servlet class, just before the call to get("/")