Get request to Couchbase Database failing? - scala

I have a scala project that is connected to a couchbase database. I am making a get request to retrieve a document from the couchbase database. My method looks like this:
def findAll(): Future[String] = {
CouchDriver.plannerBucket.get[JsValue]("1").map(result => (result.get \ "area").as[String])
}
I'm invoking it all this in a http-akka router:
complete(
couchbaseRepository.findAll().map(v => {
HttpResponse(200, entity =
HttpEntity(ContentTypes.`application/json`, v))
})
)
However I get the following error:
Error during processing of request: 'java.lang.NullPointerException (No error message supplied)'. Completing with 500 Internal Server Error response. To change default exception handling behavior, provide a custom ExceptionHandler.
java.lang.NullPointerException: null
The odd thing is, when I change the method to this:
CouchDriver.plannerBucket.underlyingBucket.get("1")
And evaluate the expression in Intellij, it gets the document.
Not sure what the issue is!

Related

basic auth respond 500 in postman when it should be OK(Authorized), but 401 Unathorized works fine. using ktor intellij mongodb

java.lang.NoSuchMethodError: kotlinx.coroutines.channels.LinkedListChannel: method ()V not found
this is my database.kt
private val client = KMongo.createClient().coroutine
private val database = client.getDatabase("PestaDanDagangDatabase")
private val users = database.getCollection()
private val posts = database.getCollection()
suspend fun getPostsForUser(email: String) : List<> {
return posts.find(Post::members contains email).toList()
}
i'm following some tutorial... getPostsForUser return List of Post data class(it is disappear.. still need to learn to use stackoverflow), the tutorial project is running even i followed the same. i changed the return to be return posts.find(Post::members contains email).toString and the function return String both my code and my tutorial result ok in postman with same respond org.litote.kmongo.coroutine.CoroutineFindPublisher#44fc57b6(except 44fc57b6).
i tried to change the return to be return posts.find(Post::members contains email) and function return type CoroutineFindPublisher of type Post, it is OK in postman but the event time is keep ticking or running.
I've encountered kinda the same problem, but for me the implementation were updated to latest version (as today kmongo 4.4.0 & coroutines 1.6.0), the error was
kotlinx.coroutines.channels.LinkedListChannel: method 'void <init>() not found
I realized that there was a import conflict with the .toList() method
To solve it I simply, instead of
return posts.find(Post::members contains email).toList()
used
return posts.find(Post::members contains email).publisher.KMongoToList()
with as import
import org.litote.kmongo.coroutine.toList as KMongoToList

Spark throws Not Serializable Exception inside a foreachRDD operation

i'm trying to implement an observer pattern using scala and spark streaming. the idea is that whenever i receive a record from the stream (from kafka) i notify the observer by calling the method "notifyObservers" inside the closure. here's the code:
the stream is provided by the kafka utils.
the method notifyObserver is defined into an abstract class following the rules of the pattern.
the error I think is related on the fact that methods cant be serialize.
Am I thinking correctly? and if it was, what kind of solution should I follow?
thanks
def onMessageConsumed() = {
stream.foreachRDD(rdd => {
rdd.foreach(consumerRecord => {
val record = new Record[T](consumerRecord.topic(),
consumerRecord.value())
//notify observers with the record to compute
notifyObservers(record)
})
})
}
Yes, the classes that are used in the code that is sent to other executors (executed in foreach, etc.), should implement Serializable interface.
also, if you're notification code requires connection to some resource, you need to wrap foreach into foreachPartition, something like this:
stream.foreachRDD(rdd => {
rdd.foreachPartition(rddPartition =>
// setup connection to external component
rddPartition.foreach(consumerRecord => {
val record = new Record[T](consumerRecord.topic(),
consumerRecord.value())
notifyObservers(record)
})
// close connection to external component
})
})

Playframework Scala - Delete Route problems

I'm working with playframework for final project at university and I'm getting a problem when routing a delete or put method.
When I'm requesting a DELETE or PUT methods I'm getting:
[info] play.api.Play - Application started (Dev)
[debug] a.ErrorHandler - onClientError: statusCode = 404, uri = /Rest/deleteCity, message ="
My JQuery ajax call is:
$("#scalaDelete").click(function(){
$("#result").empty();
$.ajax({
url: "http://localhost:9000/Rest/deleteCity",
method: "DELETE",
data: {city: "Alvorada"},
dataType: "json",
success: function(result){
$("#result").append("Result: "+result.Result);
},
error: function (request, status, error) {
alert(status);
}
});
});
My Route Play Route:
DELETE /Rest/deleteCity controllers.RestController.deleteCity()
My Controller Method:
case class UserDelete(city:String)
class RestController #Inject()(db: Database, cc: ControllerComponents) extends AbstractController(cc) {
val userDeleteForm = Form(
mapping(
"city" -> text
)(UserDelete.apply)(UserDelete.unapply)
)
def deleteCity = Action{ implicit request=>
val userPar = userDeleteForm.bindFromRequest.get
//DatabaseDelete
Ok(jsonResult)
}
}
I've already activated cross domain in chrome, I've used a CORS extension for it.
Thanks for helping
This seems related to Restful http delete in play, i.e. DELETE with data can be sketchy.
Instead of passing data, I would just move this to the url:
DELETE /Rest/deleteCity/:city controllers.RestController.deleteCity(city: String)
# or with a query string
DELETE /Rest/deleteCity controllers.RestController.deleteCity(city: String)
and then do
http://localhost:9000/Rest/deleteCity/Alvorada
# or with a query string
http://localhost:9000/Rest/deleteCity?city=Alvorada
Personally I prefer the latter.
I agree with #AndyHayden.
Play ignores the body of the DELETE request, that is the correct behavior to my mind, but you can work around by explicitly passing a body parser:
def delete = Action(parse.json) { implicit request =>
val json = request.body
val someProp = (json \ "someprop").as[String]
Ok(s"Prop is: $someProp")
}
(this example was given by one of the developers of the Play itself:
https://github.com/playframework/playframework/issues/4606#issuecomment-109192802.)
About the doubts in comments:
I've seen another post here where a guy said some browsers just support get and post method.
POST and GET are only valid for the method attribute of the form tag.
You are using javascript request, so you can use any method that server supports. i.e. DELETE is completely fine there.
But something interesting for you to know is that playframework uses akka and this framework does not support DELETE request for security reasons, in fact it wasn't well explained on post. Then if you wanna make a DELETE method you gotta make a post method for complete your code.
Akka HTTP supports the DELETE request (as well as Play Framework): https://doc.akka.io/docs/akka-http/current/scala/http/routing-dsl/directives/method-directives/delete.html

Play Framework client server exception handling

I am new to play framework. I am using Play Framework (2.4) with scala. I need your opinion about exception handling.
Our play client controller is calling play server controller. Now we need to introduce custom exceptions which will be thrown from Server and client will catch that exception and do necessary things.
Now when I throw any exception from server it is not reaching client as it is. The reason I found behind this is, Play catches all exceptions and convert them to 500 Internal Server Error
So is it possible to send custom exception to client without modifying it?
Stop play from giving 500 by handling the exception by yourself in the play controller
You can write a custom action builder for this purpose
object ExceptionCatchingAction extends ActionBuilder[Request] {
override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]): Future[Result] = {
block(request).recover { case th =>
//use meaningful http codes instead of OK here based on the exception type
Ok(Json.obj("msg" -> "error occurred", "info" -> "error info"))
}
}
}
Use it like this
object ExampleController extends Controller {
def doStuff = ExceptionCatchingAction { req =>
throw new Exception("foo")
}
}
Your client will no get all the exceptions. So that client can now take decisions on what to do.

How to handle exceptions in Controller constructors in Play

I'm using Play 2.3.7. I have a Global.onError method and it gets called when an exception is raised in an Action. However, it does not get called when an exception is raised in the constructor of a play.api.mvc.Controller. The default error page is served instead.
The code looks something like this:
object MyController extends Controller {
assert(false)
val something = Action { request => ??? }
}
The assertion failure happens the first time a request is routed to the controller. It is logged in the ! Internal server error, for ... format, but not handled by Global.onError. How could I handle this exception?