I want to use the Play WS Standalone (outside a Play Project) to call a simple Hello World RESTfull Web Service.
I'm Using an SBT Poject in Intelij IDEA whith this configuration :
name := "ScalaSbtProject"
version := "1.0"
scalaVersion := "2.11.7"
libraryDependencies += "com.typesafe.play" % "play-ws_2.11" % "2.5.10"
Here's my code :
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import play.api.libs.ws.ahc.AhcWSClient
import scala.util.{Failure, Success}
object Test {
def main(args: Array[String]): Unit = {
import scala.concurrent.ExecutionContext.Implicits._
implicit val actor = ActorSystem()
implicit val materializer = ActorMaterializer()
val wsClient = AhcWSClient()
val response = wsClient
.url("http://localhost:8080/WebService_war_exploded/service/test")
.get()
response.onComplete {
case Success(re) => { println(re.body)}
case Failure(e) => { e.getStackTrace.foreach(println)}
}
wsClient.close()
}
}
which throws this Exception :
Response Is Failed :
http://localhost:8080
org.asynchttpclient.netty.channel.NettyConnectListener.onFailure(NettyConnectListener.java:160)
org.asynchttpclient.netty.request.NettyChannelConnector$1.onFailure(NettyChannelConnector.java:103)
org.asynchttpclient.netty.SimpleChannelFutureListener.operationComplete(SimpleChannelFutureListener.java:28)
org.asynchttpclient.netty.SimpleChannelFutureListener.operationComplete(SimpleChannelFutureListener.java:20)
io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:514)
io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:507)
io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:486)
io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:427)
io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:129)
io.netty.channel.nio.AbstractNioChannel.doClose(AbstractNioChannel.java:458)
io.netty.channel.socket.nio.NioSocketChannel.doClose(NioSocketChannel.java:235)
io.netty.channel.AbstractChannel$AbstractUnsafe.doClose0(AbstractChannel.java:632)
io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:611)
io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:554)
io.netty.channel.nio.NioEventLoop.closeAll(NioEventLoop.java:637)
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:406)
io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
java.lang.Thread.run(Thread.java:745)
Related
TO start with I am very new to Scala and also I don't have any Java experience also. I am trying to call an API using simple Scala code and running into the errors. Code looks like:
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer
import scala.concurrent.Future
import scala.util.{ Failure, Success }
object Client {
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
// needed for the future flatMap/onComplete in the end
implicit val executionContext = system.dispatcher
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "https://akka.io"))
responseFuture
.onComplete {
case Success(res) => println(res)
case Failure(_) => sys.error("something wrong")
}
}
}
Basically, I have just copied the code from Akka documentation and trying to run it.
I get the following errors:
not found: value ActorSystem
implicit val system = ActorSystem()
not found: value ActorMaterializer
implicit val materializer = ActorMaterializer()
Cannot find an implicit ExecutionContext. You might pass
an (implicit ec: ExecutionContext) parameter to your method.
Also 'ActorMaterializer()' now seems to be deprecated. Is this the reason for errors?
Thanks in advance :)
You may need to add akka-streams as a dependency in your build tool.
ActorMaterializer.apply should just be a warning, unrelated to your other error. Might be worth opening an issue on github asking for updated docs for this snippet though.
This should get you going.
In your build.sbt
scalaVersion := "2.13.8"
val akkaVersion = "2.6.19"
val akkaHTTPVersion = "10.2.9"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-stream" % akkaVersion,
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-http" % akkaHTTPVersion
)
The code below is from the latest Doc, with the added line to consume the response entity as described in the Doc.
object HttpClientSingleRequest extends App {
implicit val system: ActorSystem = ActorSystem()
import system.dispatcher
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "https://akka.io"))
responseFuture
.onComplete {
case Success(res) =>
// Even if we don’t care about the response entity, we must consume it
res.entity.discardBytes()
println(s"Success: ${res.status}")
case Failure(ex) => sys.error(s"Something wrong: ${ex.getMessage}")
}
}
i have a problem about running server/client using ScalaPB on spark.
its totally work fine while I running my code using "sbt run". i want running this code using spark coz next ill import my spark model to predict some label. but while I submit my jar to spark, they give me error like this.
Exception in thread "main" io.grpc.ManagedChannelProvider$ProviderNotFoundException:
No functional server found. Try adding a dependency on the grpc-netty artifact
this is my build.sbt
scalaVersion := "2.11.7"
PB.targets in Compile := Seq(
scalapb.gen() -> (sourceManaged in Compile).value
)
val scalapbVersion =
scalapb.compiler.Version.scalapbVersion
val grpcJavaVersion =
scalapb.compiler.Version.grpcJavaVersion
libraryDependencies ++= Seq(
// protobuf
"com.thesamet.scalapb" %% "scalapb-runtime" % scalapbVersion % "protobuf",
//for grpc
"io.grpc" % "grpc-netty" % grpcJavaVersion ,
"com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapbVersion
)
assemblyMergeStrategy in assembly := {
case PathList("META-INF", xs # _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
using shade still not work
assemblyShadeRules in assembly := Seq(ShadeRule.rename("com.google.**" -> "shadegoogle.#1").inAll)
and this my main
import java.util.logging.Logger
import io.grpc.{Server, ServerBuilder}
import org.apache.spark.ml.tuning.CrossValidatorModel
import org.apache.spark.sql.SparkSession
import testproto.test.{Email, EmailLabel, RouteGuideGrpc}
import scala.concurrent.{ExecutionContext, Future}
object HelloWorldServer {
private val logger = Logger.getLogger(classOf[HelloWorldServer].getName)
def main(args: Array[String]): Unit = {
val server = new HelloWorldServer(ExecutionContext.global)
server.start()
server.blockUntilShutdown()
}
private val port = 50051
}
class HelloWorldServer(executionContext: ExecutionContext) {
self =>
private[this] var server: Server = null
private def start(): Unit = {
server = ServerBuilder.forPort(HelloWorldServer.port).addService(RouteGuideGrpc.bindService(new RouteGuideImpl, executionContext)).build.start
HelloWorldServer.logger.info("Server started, listening on " + HelloWorldServer.port)
sys.addShutdownHook {
System.err.println("*** shutting down gRPC server since JVM is shutting down")
self.stop()
System.err.println("*** server shut down")
}
}
private def stop(): Unit = {
if (server != null) {
server.shutdown()
}
}
private def blockUntilShutdown(): Unit = {
if (server != null) {
server.awaitTermination()
}
}
private class RouteGuideImpl extends RouteGuideGrpc.RouteGuide {
override def getLabel(request: Email): Future[EmailLabel] = {
val replay = EmailLabel(emailId = request.emailId, label = "aaaaa")
Future.successful(replay)
}
}
}
thanks
It looks like grpc-netty is not found when an uber jar is made. Instead of using ServerBuilder, change your code to use io.grpc.netty.NettyServerBuilder.
I am trying to write a simple Http client using Akka Http Client API. Towards this I have written the following code
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
import scala.concurrent.duration._
import scala.concurrent.{Await}
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json._
final case class Post(postId: Int, id: Int, name: String, email: String, body: String)
trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
implicit val postFormat = jsonFormat5(Post.apply)
}
class AkkaHttpClient extends App with Directives with JsonSupport {
implicit val system = ActorSystem("my-Actor")
implicit val actorMaterializer = ActorMaterializer()
implicit val executionContext = system.dispatcher
val httpClient = Http().outgoingConnection(host="http://jsonplaceholder.typicode.com/")
val flow = Source.single(HttpRequest(uri = Uri("/comments/1")))
.via(httpClient)
.mapAsync(1)(r => Unmarshal(r.entity).to[Post])
.runWith(Sink.head)
val results = Await.result(flow, 15 seconds)
println(results)
}
My build.sbt file looks like
name := "Akka-Http-Client"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http-experimental" % "2.4.9-RC1",
"com.typesafe.akka" %% "akka-http-spray-json-experimental" % "2.4.9-RC1"
)
When I try to compile my code I get these errors
Error:scalac: missing or invalid dependency detected while loading class file 'Unmarshaller.class'.
Could not access type Unmarshaller in value akka.http.javadsl.unmarshalling,
because it (or its dependencies) are missing. Check your build definition for
missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
A full rebuild may help if 'Unmarshaller.class' was compiled against an incompatible version of akka.http.javadsl.unmarshalling.
I am having the same problem on 2.4.9-RC1, falling back to 2.4.8 solves the problem.
OR you could use this workaround described here: https://github.com/akka/akka/issues/21105
I do a GET HTTP call to a rest service which returns a json. I would like to parse the json to a scala object but here I got stuck. I am using the Akka api and I can't manage to retrieve the content from the Akka's ResponseEntity
Here is my sbt file:
name := "ScalaHttp"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies ++={
val akkaV = "2.4.5"
Seq(
"com.typesafe.akka" %% "akka-http-core" % akkaV,
"com.typesafe.play" %% "play-json" % "2.4.0-M3"
)
}
And here is the app
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.stream.ActorMaterializer
import scala.concurrent.ExecutionContext.Implicits.global
object Sender {
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
Http().singleRequest(HttpRequest(uri = "http://declinators.com/declinator?noun=komunikacja")) foreach {
y => println(y.entity)
println(y.entity.getContentType())
println(y.entity.contentType)
}
}
}
This prints:
HttpEntity.Strict(application/json,{"nominative":"komunikacja","genitive":"komunikacji","dative":"komunikacji","accusative":"komunikację","instrumental":"komunikacją","locative":"komunikacji","vocative":"komunikacjo"})
application/json
application/json
Here come the questions:
1. Why ResponseEntity supplies getContentType() and contentType()? They return the same thing.
2. Getting the contentyType is easy, you have two ways for doing it, but how can I get the content itself, so I can play (i.e. parse it using play) with the json!
You can use entity.data.toString for Binary content type, or the following code piece
data.decodeString(nb.charset.value)
Please follow the HttpEntity.Strict.toString implementation here for detail:
https://github.com/akka/akka/blob/master/akka-http-core/src/main/scala/akka/http/scaladsl/model/HttpEntity.scala#L316
With the following build.sbt:
name := "blah"
version := "1.0"
scalaVersion := "2.11.6"
libraryDependencies ++= Seq("io.reactivex" % "rxscala_2.11" % "0.24.1", "org.scalaj" %% "scalaj-http" % "1.1.4")
and this code:
import rx.lang.scala.Observable
import scala.concurrent.duration._
import scala.language.postfixOps
object Main {
def main(args: Array[String]): Unit = {
println("Ready?")
val o = Observable.interval(200 millis).take(5)
o.subscribe(n => println(s"n = ${n}"))
}
}
When I run it, all that's printed is Ready?; I see no n = ... at all.
I run using sbt run; it's built using Scala 2.6.11 and RxScala 0.24.1, as well as sbt 0.13. Any ideas?
The problem is that your program exits before o fires. Try the following code:
import rx.lang.scala.Observable
import scala.concurrent.duration._
import scala.language.postfixOps
object Main {
def main(args: Array[String]): Unit = {
println("Ready?")
val o = Observable.interval(200 millis).take(5)
o.subscribe(n => println(s"n = ${n}"))
Thread.sleep(5000)
}
}
Alternatively you can replace Thread.sleep with o.toBlocking.last, which cannot return before o terminates.