Skip to content

Commit 6c8b062

Browse files
First workaround to use RosHTTP Client
1 parent 8b45fe1 commit 6c8b062

File tree

11 files changed

+77
-165
lines changed

11 files changed

+77
-165
lines changed

build.sbt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ lazy val `evaluator-client` = (crossProject in file("client"))
3434
"io.circe" %% "circe-generic" % v('circe),
3535
"io.circe" %% "circe-parser" % v('circe),
3636
"org.log4s" %% "log4s" % v('log4s),
37-
"org.scalaj" %% "scalaj-http" % v('scalajhttp),
3837
"org.slf4j" % "slf4j-simple" % v('slf4j),
3938
// Testing libraries
4039
"org.scalatest" %% "scalatest" % v('scalaTest) % "test"
4140
)
42-
}
43-
)
41+
},
42+
libraryDependencies += "fr.hmil" %%% "roshttp" % "1.1.0"
43+
)
4444
.jsSettings(scalaJSSettings: _*)
4545

4646
lazy val `evaluator-client-jvm` = `evaluator-client`.jvm
@@ -75,4 +75,4 @@ lazy val `evaluator-server` = (project in file("server"))
7575
.settings(compilerDependencySettings: _*)
7676

7777
onLoad in Global := (Command.process("project evaluator-server", _: State)) compose (onLoad in Global).value
78-
addCommandAlias("publishSignedAll", ";evaluator-shared/publishSigned;evaluator-client/publishSigned")
78+
addCommandAlias("publishSignedAll", ";evaluator-sharedJS/publishSigned;evaluator-sharedJVM/publishSigned;evaluator-clientJS/publishSigned;evaluator-clientJVM/publishSigned")

client/shared/src/main/scala/org/scalaexercises/evaluator/EvaluatorAPI.scala

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,13 @@ package org.scalaexercises.evaluator
77

88
import cats.free.Free
99
import org.scalaexercises.evaluator.EvaluatorResponses.EvaluationResponse
10-
import org.scalaexercises.evaluator.free.algebra.{EvaluatorOp, EvaluatorOps}
10+
import org.scalaexercises.evaluator.free.algebra.EvaluatorOps
1111

12-
import scala.concurrent.duration.Duration
13-
14-
class EvaluatorAPI[F[_]](url: String,
15-
authKey: String,
16-
connTimeout: Duration,
17-
readTimeout: Duration)(implicit O: EvaluatorOps[F]) {
12+
class EvaluatorAPI[F[_]](url: String, authKey: String)(
13+
implicit O: EvaluatorOps[F]) {
1814

1915
def evaluates(resolvers: List[String] = Nil,
2016
dependencies: List[Dependency] = Nil,
2117
code: String): Free[F, EvaluationResponse[EvalResponse]] =
22-
O.evaluates(
23-
url,
24-
authKey,
25-
connTimeout,
26-
readTimeout,
27-
resolvers,
28-
dependencies,
29-
code)
18+
O.evaluates(url, authKey, resolvers, dependencies, code)
3019
}

client/shared/src/main/scala/org/scalaexercises/evaluator/EvaluatorClient.scala

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,30 @@
66
package org.scalaexercises.evaluator
77

88
import cats.data.XorT
9-
import cats.{MonadError, ~>}
9+
import cats.~>
10+
import cats._, cats.std.all._
1011
import org.scalaexercises.evaluator.EvaluatorResponses.{EvalIO, EvaluationException, EvaluationResponse, EvaluationResult}
1112
import org.scalaexercises.evaluator.free.algebra.EvaluatorOp
1213

13-
import scala.concurrent.duration._
14-
import scala.concurrent.duration.Duration
14+
import scala.concurrent.Future
15+
import scala.concurrent.ExecutionContext.Implicits.global
1516

16-
class EvaluatorClient(url: String,
17-
authKey: String,
18-
connTimeout: Duration = 1.second,
19-
readTimeout: Duration = 10.seconds) {
17+
class EvaluatorClient(url: String, authKey: String) {
2018

21-
lazy val api: EvaluatorAPI[EvaluatorOp] =
22-
new EvaluatorAPI(url, authKey, connTimeout, readTimeout)
19+
lazy val api: EvaluatorAPI[EvaluatorOp] = new EvaluatorAPI(url, authKey)
2320

2421
}
2522

2623
object EvaluatorClient {
2724

28-
def apply(url: String,
29-
authKey: String,
30-
connTimeout: Duration = 1.second,
31-
readTimeout: Duration = 10.seconds) =
32-
new EvaluatorClient(url, authKey, connTimeout, readTimeout)
25+
def apply(url: String, authKey: String) =
26+
new EvaluatorClient(url, authKey)
3327

3428
implicit class EvaluationIOSyntaxXOR[A](
3529
evalIO: EvalIO[EvaluationResponse[A]]) {
3630

37-
def exec[M[_]](implicit I: (EvaluatorOp ~> M),
38-
A: MonadError[M, Throwable]): M[EvaluationResponse[A]] =
31+
def exec(
32+
implicit I: (EvaluatorOp ~> Future)): Future[EvaluationResponse[A]] =
3933
evalIO foldMap I
4034

4135
def liftEvaluator: XorT[EvalIO, EvaluationException, EvaluationResult[A]] =

client/shared/src/main/scala/org/scalaexercises/evaluator/EvaluatorResponses.scala

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ import io.circe.parser._
1313
import io.circe.generic.auto._
1414
import org.scalaexercises.evaluator.free.algebra.EvaluatorOp
1515

16-
import scala.language.higherKinds
17-
import scalaj.http.HttpResponse
16+
import scala.concurrent.Future
17+
import scala.concurrent.ExecutionContext.Implicits.global
18+
19+
import fr.hmil.roshttp.HttpResponse
20+
import fr.hmil.roshttp.HeaderMap
1821

1922
object EvaluatorResponses {
2023

@@ -24,7 +27,7 @@ object EvaluatorResponses {
2427

2528
case class EvaluationResult[A](result: A,
2629
statusCode: Int,
27-
headers: Map[String, IndexedSeq[String]])
30+
headers: Map[String, String])
2831

2932
sealed abstract class EvaluationException(msg: String,
3033
cause: Option[Throwable] = None)
@@ -37,24 +40,30 @@ object EvaluatorResponses {
3740

3841
case class UnexpectedException(msg: String) extends EvaluationException(msg)
3942

40-
def toEntity[A](response: HttpResponse[String])(
41-
implicit D: Decoder[A]): EvaluationResponse[A] = response match {
42-
case r if r.isSuccess
43-
decode[A](r.body).fold(
44-
e
45-
JsonParsingException(e.getMessage, r.body).left[EvaluationResult[A]],
46-
result
47-
Xor.Right(EvaluationResult(result, r.code, r.headers.toLowerCase))
48-
)
49-
case r
50-
UnexpectedException(
51-
s"Failed invoking get with status : ${r.code}, body : \n ${r.body}")
52-
.left[EvaluationResult[A]]
53-
}
43+
def toEntity[A](futureResponse: Future[HttpResponse])(
44+
implicit D: Decoder[A]): Future[EvaluationResponse[A]] =
45+
futureResponse map {
46+
case r if isSuccess(r.statusCode)
47+
decode[A](r.body).fold(
48+
e
49+
JsonParsingException(e.getMessage, r.body)
50+
.left[EvaluationResult[A]],
51+
result
52+
Xor.Right(
53+
EvaluationResult(result, r.statusCode, r.headers.toLowerCase))
54+
)
55+
case r
56+
UnexpectedException(
57+
s"Failed invoking get with status : ${r.statusCode}, body : \n ${r.body}")
58+
.left[EvaluationResult[A]]
59+
}
5460

55-
implicit class HeadersLowerCase[A](headers: Map[String, A]) {
61+
private[this] def isSuccess(statusCode: Int) =
62+
statusCode >= 200 && statusCode <= 299
5663

57-
def toLowerCase: Map[String, A] = headers.map(e (e._1.toLowerCase, e._2))
64+
implicit class HeadersLowerCase[A >: String](headers: HeaderMap[A]) {
5865

66+
def toLowerCase: Map[String, A] =
67+
headers.iterator.map(t => (t._1.toLowerCase, t._2)).toList.toMap
5968
}
6069
}

client/shared/src/main/scala/org/scalaexercises/evaluator/api/Evaluator.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import org.scalaexercises.evaluator.http.HttpClient
1111
import io.circe.generic.auto._
1212
import io.circe.syntax._
1313

14-
import scala.concurrent.duration.Duration
14+
import scala.concurrent.Future
1515

1616
class Evaluator {
1717

@@ -21,16 +21,12 @@ class Evaluator {
2121

2222
def eval(url: String,
2323
authKey: String,
24-
connTimeout: Duration,
25-
readTimeout: Duration,
2624
resolvers: List[String] = Nil,
2725
dependencies: List[Dependency] = Nil,
28-
code: String): EvaluationResponse[EvalResponse] =
26+
code: String): Future[EvaluationResponse[EvalResponse]] =
2927
httpClient.post[EvalResponse](
3028
url = url,
3129
secretKey = authKey,
32-
connTimeout = connTimeout,
33-
readTimeout = readTimeout,
3430
data = EvalRequest(resolvers, dependencies, code).asJson.noSpaces)
3531

3632
}

client/shared/src/main/scala/org/scalaexercises/evaluator/free/algebra/EvaluatorOps.scala

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ import cats.free.{Free, Inject}
99
import org.scalaexercises.evaluator.{Dependency, EvalResponse}
1010
import org.scalaexercises.evaluator.EvaluatorResponses.EvaluationResponse
1111

12-
import scala.concurrent.duration._
13-
import scala.concurrent.duration.Duration
14-
1512
sealed trait EvaluatorOp[A]
1613
final case class Evaluates(url: String,
1714
authKey: String,
18-
connTimeout: Duration,
19-
readTimeout: Duration,
2015
resolvers: List[String] = Nil,
2116
dependencies: List[Dependency] = Nil,
2217
code: String)
@@ -27,21 +22,12 @@ class EvaluatorOps[F[_]](implicit I: Inject[EvaluatorOp, F]) {
2722
def evaluates(
2823
url: String,
2924
authKey: String,
30-
connTimeout: Duration,
31-
readTimeout: Duration,
3225
resolvers: List[String] = Nil,
3326
dependencies: List[Dependency] = Nil,
3427
code: String
3528
): Free[F, EvaluationResponse[EvalResponse]] =
3629
Free.inject[EvaluatorOp, F](
37-
Evaluates(
38-
url,
39-
authKey,
40-
connTimeout,
41-
readTimeout,
42-
resolvers,
43-
dependencies,
44-
code))
30+
Evaluates(url, authKey, resolvers, dependencies, code))
4531

4632
}
4733

client/shared/src/main/scala/org/scalaexercises/evaluator/free/interpreters/Interpreter.scala

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,25 @@
55

66
package org.scalaexercises.evaluator.free.interpreters
77

8-
import cats.{ApplicativeError, Eval, MonadError, ~>}
8+
import cats.~>
99
import org.scalaexercises.evaluator.api.Evaluator
1010
import org.scalaexercises.evaluator.free.algebra.{Evaluates, EvaluatorOp}
1111

12-
import scala.language.higherKinds
12+
import scala.concurrent.Future
1313

1414
trait Interpreter {
1515

16-
implicit def interpreter[M[_]](
17-
implicit A: MonadError[M, Throwable]
18-
): EvaluatorOp ~> M = evaluatorOpsInterpreter[M]
19-
2016
/**
2117
* Lifts Evaluator Ops to an effect capturing Monad such as Task via natural transformations
2218
*/
23-
def evaluatorOpsInterpreter[M[_]](
24-
implicit A: ApplicativeError[M, Throwable]): EvaluatorOp ~> M =
25-
new (EvaluatorOp ~> M) {
19+
implicit def evaluatorOpsInterpreter: EvaluatorOp ~> Future =
20+
new (EvaluatorOp ~> Future) {
2621

2722
val evaluator = new Evaluator()
2823

29-
def apply[A](fa: EvaluatorOp[A]): M[A] = fa match {
30-
case Evaluates(
31-
url,
32-
authKey,
33-
connTimeout,
34-
readTimeout,
35-
resolvers,
36-
dependencies,
37-
code)
38-
A.pureEval(
39-
Eval.later(
40-
evaluator.eval(
41-
url,
42-
authKey,
43-
connTimeout,
44-
readTimeout,
45-
resolvers,
46-
dependencies,
47-
code)))
24+
def apply[A](fa: EvaluatorOp[A]): Future[A] = fa match {
25+
case Evaluates(url, authKey, resolvers, dependencies, code)
26+
evaluator.eval(url, authKey, resolvers, dependencies, code)
4827
}
4928

5029
}

client/shared/src/main/scala/org/scalaexercises/evaluator/http/HttpClient.scala

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ package org.scalaexercises.evaluator.http
88
import io.circe.Decoder
99
import org.scalaexercises.evaluator.EvaluatorResponses
1010
import org.scalaexercises.evaluator.EvaluatorResponses.EvaluationResponse
11-
12-
import scala.concurrent.duration._
13-
import scala.concurrent.duration.Duration
11+
import scala.concurrent.Future
1412

1513
object HttpClient {
1614

@@ -26,17 +24,11 @@ class HttpClient {
2624
url: String,
2725
secretKey: String,
2826
method: String = "post",
29-
connTimeout: Duration,
30-
readTimeout: Duration,
3127
headers: Headers = Map.empty,
3228
data: String
33-
)(implicit D: Decoder[A]): EvaluationResponse[A] =
29+
)(implicit D: Decoder[A]): Future[EvaluationResponse[A]] =
3430
EvaluatorResponses.toEntity(
35-
HttpRequestBuilder(
36-
url = url,
37-
httpVerb = method,
38-
connTimeout = connTimeout,
39-
readTimeout = readTimeout)
31+
HttpRequestBuilder(url = url, httpVerb = method)
4032
.withHeaders(headers + (authHeaderName -> secretKey))
4133
.withBody(data)
4234
.run)

client/shared/src/main/scala/org/scalaexercises/evaluator/http/HttpRequestBuilder.scala

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,30 @@ package org.scalaexercises.evaluator.http
77

88
import org.scalaexercises.evaluator.http.HttpClient._
99

10-
import scala.concurrent.duration.Duration
11-
import scalaj.http.{Http, HttpOptions}
10+
import scala.concurrent.Future
11+
12+
import fr.hmil.roshttp.body.Implicits._
13+
import fr.hmil.roshttp.{HttpRequest, Method, HttpResponse}
14+
import fr.hmil.roshttp.body.JSONBody
1215

1316
case class HttpRequestBuilder(
1417
url: String,
1518
httpVerb: String,
16-
connTimeout: Duration,
17-
readTimeout: Duration,
18-
followRedirects: Boolean = true,
1919
headers: Headers = Map.empty[String, String],
20-
body: Option[String] = None
20+
body: String = ""
2121
) {
2222

2323
def withHeaders(headers: Headers) = copy(headers = headers)
2424

25-
def withBody(body: String) = copy(body = Option(body))
25+
def withBody(body: String) = copy(body = body)
26+
27+
def run: Future[HttpResponse] = {
2628

27-
def run = {
28-
val request = Http(url).method(httpVerb).headers(headers)
29+
val request = HttpRequest(url)
30+
.withMethod(Method(httpVerb))
31+
.withHeaders(headers.toList: _*)
32+
.withHeader("content.type", "application/json")
2933

30-
body
31-
.fold(request)(
32-
request
33-
.option(HttpOptions.connTimeout(connTimeout.toMillis.toInt))
34-
.option(HttpOptions.readTimeout(readTimeout.toMillis.toInt))
35-
.postData(_)
36-
.header("content-type", "application/json"))
37-
.asString
34+
request.post(JSONBody(body))
3835
}
3936
}

0 commit comments

Comments
 (0)