How to send FormData In Http Post using Spray - scala

I want with my Spray Client Send a post Request with this Content Type
Content-Type: application/x-www-form-urlencoded
I belive that i need to use the object FormData for it :
var fD = new FormData(Seq("UserID:" -> "123", "PWD" -> "123" , "Brand" -> "123"))
But i'm open for other solutions to .
Edit :
I tried sending it this way :
implicit val system = ActorSystem("Client")
var fD = FormData(Map("UserID" -> "123", "PWD" -> "123" , "Brand" -> "123"))
import system.dispatcher // execution context for futures below
val log = Logging(system, getClass)
log.info("Sending test Msg")
val pipeline = sendReceive ~> unmarshal[FormData]
var startTimestamp = System.currentTimeMillis()
val responseFuture = pipeline {
Post(url, fD)
}
responseFuture.onComplete(x=> println(s"Request completed in ${System.currentTimeMillis() - startTimestamp} millis.\n" +
s"Recived :"+x.get)
)
And I'm Getting this error :
spray.httpx.PipelineException: UnsupportedContentType(Expected 'application/x-www-form-urlencoded')
What I'm Done Wrong ? Thank to helpers.

You've basically answered your own question -- you'll want to stick with FormData. A couple of minor things though:
Since you're using the FormData case class, you can drop the
"new".
The companion object for FormData will allow you to pass in
a Map instead of a Seq of tuples.

Related

crashed with 'j.u.NoSuchElementException: No attribute named 'notStartedRefIds' is defined'

I am working with Gatling and have received this error which occurs claiming 'notStartedRefIds' is defined.
I am new to Gatling and am confident that the value has been declared properly already, however I cannot see why it is not being recognised.
The code which contains reference to the value is below:
case object StudentAssignmentScenario {
private val notStartedRefIdsSession = "notStartedRefIds"
private val studentAssignmentRefIdSession = "studentAssignmentRefId"
private val endpoint: String = environmentAssignmentsUrls + "/v2/studentAssignments"
private val startAssignment = http("Start StudentAssignment")
.put(endpoint + "/${studentAssignmentRefId}/start")
.headers(getHeaderMap)
.check(status.is(200))
private val submitAssignment = http("Submit StudentAssignment")
.put(endpoint + "/${studentAssignmentRefId}/submit")
.headers(getHeaderMap)
.check(status.is(200))
private val startAndSubmitAssignments = exec { session =>
val refId = session(notStartedRefIdsSession).as[Seq[String]].apply(0)
session.set(studentAssignmentRefIdSession, refId)
}.exec(startAssignment).exec(submitAssignment)
private val startAssignments = exec { session =>
val refId = session(notStartedRefIdsSession).as[Seq[String]].apply(1)
session.set(studentAssignmentRefIdSession, refId)
}.exec(startAssignment)
def readStudentAssignments = exec(http("Get Not Started StudentAssignments")
.get(endpoint)
.headers(getHeaderMap)
.queryParamMap(Map[String, String]("inclExpired" -> "true",
"context" -> "basel",
"sort" -> "dueDate,title",
"limit" -> "25", "offset" -> "0",
"status" -> "NOT_STARTED"))
.check(status.is(200),
// save refIds
jsonPath("$.items[?(#.status == 'NOT_STARTED')].refId").findAll.optional.saveAs("notStartedRefIds")))
private val studentAssignmentWorkflow = exec(startAndSubmitAssignments)
.exec(startAssignments)
val studentAssignmentWorkflowSetup: ChainBuilder = exitBlockOnFail(
group("Student Assignment Workflow") {
studentAssignmentWorkflow
})
}
The only place you seem to be populating notStartedRefIds is in readStudentAssignments where you extract it from the response thanks to a jsonPath.
However, you've configured this check as optional meaning you expect it to sometimes not be here. If that's the case, it's not surprise it can be undefined when calling session(notStartedRefIdsSession).

How filter a JSLookup/JSObject with the Scala Play library

Say I have some params coming from our API clients like this:
val params = (request \ "params")
I want to filter them and remove certain key/values. Like if I get:
{
"foo": "bar",
"hello": "world"
}
I want to filter it to
{
"foo": "bar"
}
Here's my WIP code but, as more advanced Scala people will probably tell right away, it doesn't work.
val params = (request \ "params").get.as[List[JsObject]]
val blacklistedParams = Seq("foo")
val approvedParams = params.filter((param: JsObject) => {
!blacklistedParams.contains(param)
})
That first line always fails. I've tried doing .get.as in all sorts of types but always get errors. I'm still new to Scala and types in general.
I think I figured out a way:
val params = (request \ "params").get.as[Map[String, JsValue]]
val blacklistedParams = Seq("foo")
val approvedParams = params.filter((param) => {
!blacklistedParams.contains(param._1)
})
My only annoyance with this method is that ._1. To me its not very clear for the next person that this is the key of the key/val pair of the params.
You can use -
val filtered = (request \ "params").as[JsObject] - "hello"
Full example:
def index = Action{
val json = Json.obj(
"params" -> Json.obj(
"foo" -> "bar",
"hello" -> "world"))
val filtered = (json \ "params").as[JsObject] - "hello"
Ok(filtered)
}
output:
{
foo: "bar"
}

How to retrieve body string of request generated by scala-dispatch

I have a request generated by putting map of parameters
val reqUrl = url("http://example.com")
val req = reqUrl << Map("key" -> "value")
I need to get request body in order to calculate it's hash. I'm trying this way
val data = req.toRequest.getStringData
println(data)
but it results null.
The request you currently defined is a GET request which normally has no body. So null is the expected body value.
You could try using a POST as described here : http://dispatch.databinder.net/HTTP+methods+and+parameters.html.
val reqUrl = url("http://example.com")
val postReq = reqUrl.POST
val req = postReq << Map("key" -> "value")
req.toRequest.getStringData

Setting a cookie for HTTP POST in Scala with Dispatch

I can't seem to set a cookie using Dispatch. The server resends a new session ID implying that the one I tried to send didn't get sent in the right way. Here is the code:
val domain = "myhost.com"
val host_req = host(domain).secure
val request = host_req / "path" / "path"
def post = request << Map("key" -> "SomeValue")
val response: Either[Throwable, Map[String, String]] =
Http(post OK asHeaders).either()
//The cookie comes down in the form "Set-Cookie: SESSIONID=<somesession>; Path=/path/; HttpOnly"
//successfully retrieves the session id...
val sessionId = getSessionId(response)
println(sessionId)
val sessionCookie = new com.ning.http.client.Cookie(domain, "SESSIONID", sessionId, "/path/", -1, true)
request.POST.addCookie(sessionCookie)
def establishPost = request << Map("key" -> "SomeValue")
establishPost.addCookie(sessionCookie)
val establishResponse: Either[Throwable, Map[String, String]] =
Http(establishPost OK asHeaders).either()
//Server sends down new SESSIONID...
//sessionId != getSEssionId(establishPost)
This is using the newest version of Dispatch. I'm trying to learn Scala as I go, and the only thing I can't figure out how to do either is inspect the establishPost object for its headers before it is sent as a request.
This should be better:
def reqWithParams = request << Map("key" -> "SomeValue")
val reqWithCookies = reqWithParams.addCookie(sessionCookie)
addCookie method returns the new object (the one with a cookie), but your code didn't use it.

Using Solr from Scala/ Play

How can use Solr from within Scala/ Play? Specifically how do I add/ update documents?
Update: see my newer answer refer https://stackoverflow.com/a/17315047/604511
Here is code I wrote which uses Play's JSON library and Dispatch HTTP client. Its not perfect, but it should help you get started.
package controllers
import play.api._
import play.api.mvc._
import play.api.libs.json.Json
import play.api.libs.json.Json.toJson
import dispatch._
object Application extends Controller {
def index = Action {
val addDocument = Json.toJson(
Map(
"add" ->
Seq(
//a document
Map(
"id" -> toJson("123"),
"subject" -> toJson("you have been served")
)
)
))
val toSend = Json.stringify( addDocument)
val params = Map( "commit" -> "true", "wt" -> "json")
val headers = Map( "Content-type" -> "application/json")
val solr = host( "127.0.0.1", 8983)
val req = solr / "solr" / "update" / "json" <<?
params <:< headers << toSend
val response = Http(req)()
Ok( toSend + response.getResponseBody)
//Redirect(routes.Application.tasks)
}
def tasks = TODO
def newTask = TODO
def deleteTask(id: Long) = TODO
}
You might consider using the SolrJ Java Lib, which uses a binary protocol to communicate with the Solr Server which performs better than using the XML way.
Adding a document to the index is done this:
http://wiki.apache.org/solr/Solrj#Adding_Data_to_Solr
Not directly related to updating documents, but a nice query DSL for Solr in Scala build by foursquare is described in their engineering blog article: http://engineering.foursquare.com/2011/08/29/slashem-a-rogue-like-type-safe-scala-dsl-for-querying-solr/