Error: javax.ws.rs.NotFoundException: HTTP 404 Not Found - scala

I am trying to test my code that gets all the user details from Keycloak using the Keycloak library. But I keep seeing this error. can anyone help me with this?
Test code:
trait Setup {
val keycloak: Keycloak = mock[Keycloak]
val keycloakBuilder: KeycloakBuilder = mock[KeycloakBuilder]
val service = new NewUserService(conf)
val restEasy: ResteasyClientBuilder = mock[ResteasyClientBuilder]
val restEasyClient: ResteasyClient = mock[ResteasyClient]
val realmResource: RealmResource = mock[RealmResource]
val usersResource: UsersResource = mock[UsersResource]
}
"NewUserService#getAllUsers" should {
"return all users" in new Setup {
when(restEasy.build()) thenReturn restEasyClient
when(keycloakBuilder.build()) thenReturn keycloak
when(restEasy.build()) thenReturn restEasyClient
when(keycloak.realm(any[String])) thenReturn realmResource
when(realmResource.users()) thenReturn usersResource
when(usersResource.list()) thenReturn List(any[UserRepresentation]).asJava
whenReady(service.getAllUsers) { result =>
assert(result.isRight)
}
}
}
NewUserService.scala:
class NewUserService(conf: Config)(implicit val ec: ExecutionContext, logger: LoggingAdapter) {
def getAllUsers: Future[Either[NewUserServiceError, util.List[idm.UserRepresentation]]] = {
val keycloakConf = conf.getConfig("keycloak")
val serverUrl = keycloakConf.getString("realmServerURL")
val realm = keycloakConf.getString("realmName")
val userName = keycloakConf.getString("username")
val password = keycloakConf.getString("password")
val clientId = keycloakConf.getString("clientId")
val clientSecret = keycloakConf.getString("clientSecret")
val keycloakBuild = KeycloakBuilder
.builder()
.serverUrl(serverUrl)
.realm(realm)
.username(userName)
.password(password)
.clientId(clientId)
.clientSecret(clientSecret)
.resteasyClient(new ResteasyClientBuilder().connectionPoolSize(20).build())
.build()
val usersList = Future(Try(keycloakBuild.realm("knoldus").users().list()))
usersList.map {
case Success(users) =>
users.asRight
case Failure(exception) =>
logger.error(s"Unable to get user details $exception")
NewUserServiceError.UserNotFoundError.asLeft
}
}
}
object NewUserService {
sealed trait NewUserServiceError
object NewUserServiceError {
case object UserNotFoundError extends NewUserServiceError
case object InternalServerError extends NewUserServiceError
}
}
I get the connection refused error when i donot start my keycloak server at 8080 port. And when i start it on 8080 port i see user not found error. Please tell me what am i doing wrong.
Error:
Unable to get user details javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:8080 [/127.0.0.1] failed: Connection refused
Unable to get user details javax.ws.rs.ProcessingException: javax.ws.rs.NotFoundException: HTTP 404 Not Found

Related

Why am I getting this timeout during unit test of akka-stream?

I have an akka-gRPC service BiDirectional stream and I am testing it on a unit test. The service has uses akka-stream and I use the TestSink.probe to test the reply message. I am receiving back the messages from the service, but there is an error related to timeout that I cannot figure out what is the reason. This is the test:
object GreeterServiceConf {
// important to enable HTTP/2 in server ActorSystem's config
val configServer = ConfigFactory.parseString("akka.http.server.preview.enable-http2 = on")
.withFallback(ConfigFactory.defaultApplication())
val configString2 =
"""
|akka.grpc.client {
| "helloworld.GreeterService" {
| host = 127.0.0.1
| port = 8080
| }
|}
|""".stripMargin
val configClient = ConfigFactory.parseString(configString2)
}
class GreeterServiceImplSpec extends TestKit(ActorSystem("GreeterServiceImplSpec", ConfigFactory.load(GreeterServiceConf.configServer)))
with AnyWordSpecLike
with BeforeAndAfterAll
with Matchers
with ScalaFutures {
implicit val patience: PatienceConfig = PatienceConfig(scaled(5.seconds), scaled(100.millis))
// val testKit = ActorTestKit(conf)
val serverSystem: ActorSystem = system
val bound = new GreeterServer(serverSystem).run()
// make sure server is bound before using client
bound.futureValue
implicit val clientSystem: ActorSystem = ActorSystem("GreeterClient", ConfigFactory.load(GreeterServiceConf.configClient))
val client = GreeterServiceClient(
GrpcClientSettings
.fromConfig("helloworld.GreeterService")
.withTls(false)
)
override def afterAll: Unit = {
TestKit.shutdownActorSystem(system)
TestKit.shutdownActorSystem(clientSystem)
}
"GreeterService" should {
"reply to multiple requests" in {
import GreeterServiceData._
val names = List("John", "Michael", "Simone")
val expectedReply: immutable.Seq[HelloReply] = names.map { name =>
HelloReply(s"Hello, $name -> ${mapHelloReply.getOrElse(name, "this person does not exist =(")}")
}
val requestStream: Source[HelloRequest, NotUsed] = Source(names).map(name => HelloRequest(name))
val responseStream: Source[HelloReply, NotUsed] = client.sayHelloToAll(requestStream)
val sink = TestSink.probe[HelloReply]
val replyStream = responseStream.runWith(sink)
replyStream
.requestNext(HelloReply(s"Hello, John -> I killed Java"))
.requestNext(HelloReply(s"Hello, Michael -> We are the Jacksons 5"))
.requestNext(HelloReply(s"Hello, Simone -> I have found a job to work with Scala =)")) // THIS IS THE LINE 122 ON THE ERROR
// .request(3)
// .expectNextUnorderedN(expectedReply) // I also tested this but it did not work
.expectComplete()
}
}
}
The error is:
assertion failed: timeout (3 seconds) during expectMsg while waiting
for OnComplete java.lang.AssertionError: assertion failed: timeout (3
seconds) during expectMsg while waiting for OnComplete at
scala.Predef$.assert(Predef.scala:223) at
akka.testkit.TestKitBase.expectMsg_internal(TestKit.scala:459) at
akka.testkit.TestKitBase.expectMsg(TestKit.scala:436) at
akka.testkit.TestKitBase.expectMsg$(TestKit.scala:436) at
akka.testkit.TestKit.expectMsg(TestKit.scala:969) at
akka.stream.testkit.TestSubscriber$ManualProbe.expectComplete(StreamTestKit.scala:479)
at
com.example.helloworld.GreeterServiceImplSpec.$anonfun$new$5(GreeterServiceImplSpec.scala:121)
I got it to work based on the project akka-grpc-quickstart-scala.g8. I am executing runForeach to run the graph and have a materialized Sink on the response stream. Then, when the response is done I am doing an assert inside the Future[Done].
"reply to multiple requests" in {
import GreeterServiceData._
import system.dispatcher
val names = List("John", "Martin", "Michael", "UnknownPerson")
val expectedReplySeq: immutable.Seq[HelloReply] = names.map { name =>
HelloReply(s"Hello, $name -> ${mapHelloReply.getOrElse(name, "this person does not exist =(")}")
}
// println(s"expectedReplySeq: ${expectedReplySeq.foreach(println)}")
val requestStream: Source[HelloRequest, NotUsed] = Source(names).map(name => HelloRequest(name))
val responseStream: Source[HelloReply, NotUsed] = client.sayHelloToAll(requestStream)
val done: Future[Done] = responseStream.runForeach { reply: HelloReply =>
// println(s"got streaming reply: ${reply.message}")
assert(expectedReplySeq.contains(reply))
}
// OR USING Sink.foreach[HelloReply])(Keep.right)
val sinkHelloReply = Sink.foreach[HelloReply] { e =>
println(s"element: $e")
assert(expectedReplySeq.contains(e))
}
responseStream.toMat(sinkHelloReply)(Keep.right).run().onComplete {
case Success(value) => println(s"done")
case Failure(exception) => println(s"exception $exception")
}
}
Just to keep the reference of the whole code, the GreeterServiceImplSpec class is here.

Akka gRPC + Slick application causes "IllegalStateException: Cannot initialize ExecutionContext; AsyncExecutor already shut down"

I try to develop gRPC server with Akka-gRPC and Slick. I also use Airframe for DI.
Source code is here
The issue is that it cause failure if it receive request when execute as gRPC server.
If it doesn't start as a gRPC server, but just reads resources from the database, the process succeeds.
What is the difference?
At Follows, It read object from database with slick.
...Component is airframe object. It will use by main module.
trait UserRepository {
def getUser: Future[Seq[Tables.UsersRow]]
}
class UserRepositoryImpl(val profile: JdbcProfile, val db: JdbcProfile#Backend#Database) extends UserRepository {
import profile.api._
def getUser: Future[Seq[Tables.UsersRow]] = db.run(Tables.Users.result)
}
trait UserResolveService {
private val repository = bind[UserRepository]
def getAll: Future[Seq[Tables.UsersRow]] =
repository.getUser
}
object userServiceComponent {
val design = newDesign
.bind[UserResolveService]
.toSingleton
}
Follows is gRPC Server source code.
trait UserServiceImpl extends UserService {
private val userResolveService = bind[UserResolveService]
private val system: ActorSystem = bind[ActorSystem]
implicit val ec: ExecutionContextExecutor = system.dispatcher
override def getAll(in: GetUserListRequest): Future[GetUserListResponse] = {
userResolveService.getAll.map(us =>
GetUserListResponse(
us.map(u =>
myapp.proto.user.User(
1,
"t_horikoshi#example.com",
"t_horikoshi",
myapp.proto.user.User.UserRole.Admin
)
)
)
)
}
}
trait GRPCServer {
private val userServiceImpl = bind[UserServiceImpl]
implicit val system: ActorSystem = bind[ActorSystem]
def run(): Future[Http.ServerBinding] = {
implicit def ec: ExecutionContext = system.dispatcher
val service: PartialFunction[HttpRequest, Future[HttpResponse]] =
UserServiceHandler.partial(userServiceImpl)
val reflection: PartialFunction[HttpRequest, Future[HttpResponse]] =
ServerReflection.partial(List(UserService))
// Akka HTTP 10.1 requires adapters to accept the new actors APIs
val bound = Http().bindAndHandleAsync(
ServiceHandler.concatOrNotFound(service, reflection),
interface = "127.0.0.1",
port = 8080,
settings = ServerSettings(system)
)
bound.onComplete {
case Success(binding) =>
system.log.info(
s"gRPC Server online at http://${binding.localAddress.getHostName}:${binding.localAddress.getPort}/"
)
case Failure(ex) =>
system.log.error(ex, "occurred error")
}
bound
}
}
object grpcComponent {
val design = newDesign
.bind[UserServiceImpl]
.toSingleton
.bind[GRPCServer]
.toSingleton
}
Follows is main module.
object Main extends App {
val conf = ConfigFactory
.parseString("akka.http.server.preview.enable-http2 = on")
.withFallback(ConfigFactory.defaultApplication())
val system = ActorSystem("GRPCServer", conf)
val dbConfig: DatabaseConfig[JdbcProfile] =
DatabaseConfig.forConfig[JdbcProfile](path = "mydb")
val design = newDesign
.bind[JdbcProfile]
.toInstance(dbConfig.profile)
.bind[JdbcProfile#Backend#Database]
.toInstance(dbConfig.db)
.bind[UserRepository]
.to[UserRepositoryImpl]
.bind[ActorSystem]
.toInstance(system)
.add(userServiceComponent.design)
.add(grpcComponent.design)
design.withSession(s =>
// Await.result(s.build[UserResolveService].getUser, Duration.Inf)) // success
// Await.result(s.build[UserServiceImpl].getAll(GetUserListRequest()), Duration.Inf)) // success
s.build[GRPCServer].run() // cause IllegalStateException when reciece request.
)
}
When UserResolveService and UserServiceImpl are called directly, the process of loading an object from the database is successful.
However, when running the application as a gRPC Server, an error occurs when a request is received.
Though I was thinking all day, I couldn't resolve...
Will you please help me to resolve.
It resolved. if execute async process, It has to start gRPC server with newSession.
I fix like that.

PSQLException: FATAL: sorry, too many clients already Akka HTTP

I have an application with a connection to PostgreSQL database, API and Akka stream usage to extract tweets using Twitter4J. Extracted tweets are written to the database and then they are queried using Slick. Using Akka HTTP I have created an API to send queries to db. So my problem is that after a few requests I get this error:
I am not sure where is the problem and why it is happening as I am closing Actor system on complete.
object Main extends ApiRoute {
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
implicit val executionContext = system.dispatcher
val twitterStream = TwitterStreamFilters.configureTwitterStream()
val counter = new Counter
twitterStream.addListener(counter)
val bindingFuture = Http().bindAndHandle(routes, "localhost", 8080)
println("Server started!")
StdIn.readLine()
bindingFuture
.flatMap(_.unbind())
.onComplete(_ => system.terminate())
}
And application.conf file:
scalaxdb = {
dataSourceClass = "slick.jdbc.DatabaseUrlDataSource"
properties = {
driver = "org.postgresql.Driver"
url = "jdbc:postgresql://localhost/twitter2.0?user=user&password=password"
}
}
I would be grateful for any help!
Can you try the following configuration?
scalaxdb = {
dataSourceClass = "slick.jdbc.DatabaseUrlDataSource"
properties = {
driver = "org.postgresql.Driver"
url = "jdbc:postgresql://localhost/twitter2.0?user=user&password=password"
}
numThreads = 10
}
So with the numThreads, I'm limiting my connections to 10.
You should also probably show the code where you do the communication with the database?

Echo simple HTTP server with Akka Http in Scala

I am developing a simple HTTP server using Akka-Http in Scala.
My code is as given below:
object HttpServer extends App {
override def main(args: Array[String]): Unit = {
implicit val system = ActorSystem("my-system")
implicit val materializer = ActorMaterializer()
implicit val executionContext = system.dispatcher
val route : Route = post {
path("echo") {
val json = ???
complete((StatusCodes.OK, json))
}
}
val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
StdIn.readLine()
bindingFuture.flatMap(_.unbind())
port.onComplete(_ => system.terminate())
}
}
I do not know Scala enough yet. For that, I need some help.
I do not know how I can get JSON from Http POST body to give back that json to client.
You only need to add an extractor to your route definition:
val route : Route = post {
path("echo") {
entity(as[String]) { json =>
complete(json)
}
}
Note that you don't need to set the status code explicitly, as akka-http will automatically set status 200 OK for you when you pass a value to complete

MockServer in org.specs2 tests

I use playframework 2.2.6 scala.
I want to write integration tests for my application. But my application requests some service by http and I want to mock it with mockServer. But I don't know when to start and stop mockServer cause tests use futures
#RunWith(classOf[JUnitRunner])
class AppTest extends Specification with Around {
def around[T](t: => T)(implicit e: AsResult[T]): Result = {
val port = 9001
val server = new MockServer()
server.start(port, null)
val mockServerClient = new MockServerClient("127.0.0.1", port)
// mockServerClient rules
val result = AsResult.effectively(t)
server.stop()
result
}
"Some test" should {
"some case" in new WithApplication {
val request: Future[SimpleResult] = route(...).get
status(request) must equalTo(OK)
contentAsString(request) must contain(...)
}
"some other case" in new WithApplication {
//
}
}
}
With this code I have java.net.ConnectException: Connection refused: /127.0.0.1:9001. And I can't do this without server.stop cause that server must be run in different tests.
I found solution, I looked source code of WithApplication (it extends Around) and wrote abstract class WithMockServer:
abstract class WithMockServer extends WithApplication {
override def around[T: AsResult](t: => T): Result = {
Helpers.running(app) {
val port = Play.application.configuration.getInt("service.port").getOrElse(9001)
val server = new MockServer(port)
val mockServerClient = new MockServerClient("127.0.0.1", port)
// mockServer rules
val result = AsResult.effectively(t)
server.stop()
result
}
}
}
And in each test cases I replaced in new WithApplication with in new WithMockServer