I am getting JsResultException(errors:List((/additional-info,List(JsonValidationError(List(error.path.missing),WrappedArray()))) error though the json structure seems OK to me. What mistake am I making?
I am writing unit tests. The test case is that server should send error message if the client sends message without json.
The server side code which sends the error is Future { Ok(Json.toJson(JsonResultError(messagesApi("error.incorrectBodyType")(langs.availables(0))))) }
The test case is
"User signup request with no body" should {
"return 400 (Bad Request) and the validation text must be 'Incorrect body type. Body type must be JSON'" in {
println("testing with mocked User value",user);
val request = FakeRequest("POST","ws/users/signup")
println("sending request",request)
val result:Future[Result] = controller.signupUser(request)
val bodyAsString = contentAsString(result)
println("body as String: "+bodyAsString)
val bodyAsJson = Json.toJson(bodyAsString)
println("body as json:"+bodyAsJson)
val jsonResultError:JsonResult = bodyAsJson.as[JsonResult]
println("jsonResultError: "+jsonResultError)
(status(result) mustBe OK )
(jsonResultError.message mustBe ("some Error "))
}
}
}
The print messages on console are
body as String: {"result":"error","additional-info":"error.incorrectBodyType"}
body as json:"{\"result\":\"error\",\"additional-info\":\"error.incorrectBodyType\"}"
JsResultException(errors:List((/additional-info,List(JsonValidationError(List(error.path.missing),WrappedArray()))), (/result,List(JsonValidationError(List(error.path.missing),WrappedArray())))))
play.api.libs.json.JsResultException: JsResultException(errors:List((/additional-info,List(JsonValidationError(List(error.path.missing),WrappedArray()))), (/result,List(JsonValidationError(List(error.path.missing),WrappedArray())))))
The implicit conversions between the json and my model is
sealed abstract class JsonResult (val result:String, val message:String)
case class JsonResultError(override val message:String) extends JsonResult(result="error", message)
case class JsonResultSuccess(override val message:String) extends JsonResult(result="success",message)
object JsonResult {
def apply(result:String,additionalInfo:String) = {
if(result== "error") JsonResultError(additionalInfo) else JsonResultSuccess(additionalInfo)
}
def unapply(jsonResult:JsonResult):Option[(String,String)] = {
if(jsonResult == null) None else Some (jsonResult.result,jsonResult.message)
}
}
object JSONMessagesImplicits {
implicit val JsonResultWrites:Writes[JsonResult] = {
((JsPath \ "result").write[String] and
(JsPath \ "additional-info").write[String])(unlift(JsonResult.unapply)) //I suppose `unlift` would convert Option[T] return value of unapply method of JsonResult Extractor object to T.
}
//read from jsvalue i.e. create model from jsvalue
implicit val JsonResultReads:Reads[JsonResult] = {
((JsPath \ "result").read[String] and
(JsPath \ "additional-info").read[String])(JsonResult.apply _)
}
}
It worked when I changed val bodyAsJson = Json.toJson(bodyAsString) to val bodyAsJson = Json.parse(bodyAsString)
Related
I do have a session variable named AuctionId and couldn't replace AuctionId here in the POST request URI. Can you please advise what I am missing here?
object BidSubmission extends HttpUtil {
val orders_feeder = csv("data/Round-1.csv").circular
def orderSubmission: ChainBuilder =
pause(pauseBy(5) seconds)
.repeat(1) {
feed(orders_feeder)
.exec(postToUri("${Constants.orderSubmission_URL}/#{AuctionId}/base-orders/proxy-bid", "")
.queryParam("employeeId", "#{empNo}")
.body(StringBody(session => {
println(session)
println(session.attributes("empNo"))
val empNo = session.attributes("empNo").asInstanceOf[String]
val orderNo = session.attributes("orderNo").asInstanceOf[String]
println(s"\n\n\n $orderNo \n\n\n")
println("\n\n\n ${Constants.bidSubmission_URL}/#{AuctionId}/base-auctions/proxy-
bid \n\n\n")
var slotNos = orderNo.replace("[", "").replace("]", "").split(" +")
println(s"\n\n\n ${generatePayload(empNo, slotNos)} \n\n\n")
generatePayload(empNo, slotNos)
" "
}))
)
}
it prints uri like this instead of replacing AuctionId with the session variable value- https://order.com/golden/base-auction/system-override/auctions/#{AuctionId}/base-auctions/proxy-bid
trait HttpUtil extends StrictLogging {
def postToUri(uri: String, requestName: String, statusCode: Int = 201): HttpRequestBuilder = {
appendHeaders(http(requestName).post(uri)).check(status.is(statusCode))
}
private def appendHeaders(request: HttpRequestBuilder,
authScheme: String = config.auth.plannerToken): HttpRequestBuilder = {
request
.header("Authorization", authScheme)
.header("Content-Type", "application/json")
.header("Accept", "application/prs.hal-forms+json")
}
}
For the below response I need to fetch the rideId and pass it to the next request in Jmeter.Also ,the API that generates below response should be executed until the eventType is HANDSHAKE.
[{"id":90856,"eventType":"HANDSHAKE","parameters":"{\"handshakeExpiration\":1669217518986,\"rideId\":3107}"}]
I am using the code :
import groovy.json.JsonSlurper;
def jsonSlurper=new JsonSlurper();
def apiDetailsArr=jsonSlurper.parse(prev.getResponseData())
def apiDetails=apiDetailsArr.size()>0?apiDetailsArr.get(0):null
def shouldRun = "1"
if(apiDetails!=null)
{
log.info("details",apiDetails.eventType+"")
if(apiDetails.eventType="HANDSHAKE"){
shouldRun="0"
}
def object=jsonSlurper.parseText(apiDetails.parameters)
log.info("xyz",object+"")
def id=object.rideId;
log.info("id",id+"")
vars.put("id", id+"")
}
else{
shouldRun="1"`enter code here`
}
`Condition for while controller : `${__javaScript( "${shouldRun}" != "0",)}``
All your log.info function calls cause syntax errors, you can see it yourself in (surprise!) the jmeter.log file
I fail to see where you're assigning shouldRun JMeter Variable which is used in the While Controller
Suggested code change:
import groovy.json.JsonSlurper;
def jsonSlurper = new JsonSlurper();
def apiDetailsArr = jsonSlurper.parse(prev.getResponseData())
def apiDetails = apiDetailsArr.size() > 0 ? apiDetailsArr.get(0) : null
def shouldRun = "1"
if (apiDetails != null) {
log.info("details", apiDetails.eventType + "")
if (apiDetails.eventType = "HANDSHAKE") {
shouldRun = "0"
}
def object = jsonSlurper.parseText(apiDetails.parameters)
log.info("xyz" + object)
def id = object.rideId;
log.info("id" + id)
vars.put("id", id as String)
} else {
shouldRun = "1"
}
vars.put("shouldRun", shouldRun)
More information on Groovy scripting in JMeter: Apache Groovy: What Is Groovy Used For?
I have created a RetryFlow like below,following this article https://doc.akka.io/docs/akka/current/stream/operators/RetryFlow/withBackoff.html
private val httpFlow: Flow[HttpRequest, HttpResponse, Any] =
Http().outgoingConnection(host, port)
val retryFlow: Flow[HttpRequest, HttpResponse, Any] =
RetryFlow.withBackoff(minBackoff = 10.millis, maxBackoff = 5.seconds, randomFactor = 0d, maxRetries = 20, httpFlow)(
decideRetry = {
case (request: HttpRequest, response) =>
response.status match {
case StatusCodes.OK => Some(request)
case _ => None
}
})
And then processing flow like
val request = Post(Uri(path), some_json_payload)(
stringMarshaller(MediaTypes.`application/json`),
system.executionContext
)
httpClient.processRequest(request, retryFlow) map (...)
My http client looks like below, added a RestartSettings and restarting source on onFailuresWithBackoff
class HttpClient(implicit val system: ActorSystem[_]) {
implicit val materializer: Materializer = Materializer(system)
private def checkSuccess(response: HttpResponse, path: String): Either[Throwable, HttpResponse] =
Either.cond(
response.status == StatusCodes.OK,
response,
new Throwable(s"Could not GET $path, Service returned ${response.status.toString()}"),
)
private def httpRequest(
request: HttpRequest,
flow: Flow[HttpRequest, HttpResponse, Any],
): Future[Either[Throwable, HttpResponse]] =
Source.single(request).via(flow)
.runWith(Sink.head) map { response =>
checkSuccess(response, request.uri.path.toString())
}
private def unmarshallString(response: Either[Throwable, HttpResponse]): Future[Either[Throwable, String]] =
response.fold(
err => Future(err.asLeft[String]),
r => Unmarshal(r.entity).to[String].map(_.asRight[Throwable]),
)
def processRequest(request: HttpRequest, flow: Flow[HttpRequest, HttpResponse, Any]): Future[Enclosed[Json]] =
httpRequest(request, flow) flatMap unmarshallString map (_.flatMap(parse))
}
I am pretty new especially in akka , what I am missing here .
I m using Aqueduct 3.0. I need to learn How to capture post request in Aqueduct 3.0?
My Request: http://127.0.0.1:8888/login/ziD7v0Ul99vmNWnxJRxZIiTY4zakNoq8GjM+oHROYz/YTHnd3NH1XfHRULY0jaHU
Get a Response:
[INFO] aqueduct: GET /login/ziD7v0Ul99vmNWnxJRxZIiTY4zakNoq8GjM+oHROYz/YTHnd3NH1XfHRULY0jaHU 11ms 404
my channel.dart routing
// TODO: connect to Socket **********
router.route('/login/[:value]').link(() {
return new LoginController();
//..contentType = ContentType.TEXT;
});
my LoginController.dart
import 'package:aqueduct/aqueduct.dart';
import 'package:niyaziapi/niyaziapi.dart';
import 'package:niyaziapi/util/niyaziGetPrivate.dart';
import 'package:niyaziapi/util/niyaziSetPrivate.dart';
class LoginController extends Controller {
String _xCustomerToken;
String _xCustomerName;
String _xPrivate;
String _xResult;
String _xRequestValue;
String _xReply;
#override
Future<RequestOrResponse> processRequest(Request request) async {
String tempData = request.toString();
print("tempDate: $tempData"); // can’t print
try {
if (request.path.variables.containsKey('value')) {
_xPrivate = (request.path.variables['value']).trim();
print("_xPrivate: $_xPrivate");
var decryptedData = await getPrivate(_xPrivate);
var decryptedList = decryptedData.split(":_:");
decryptedData = null;
decryptedData = "Q101:_:" + decryptedList[2].toString() + ":_:" + decryptedList[3].toString();
print(decryptedData);
var socket = await Socket.connect('192.168.1.22', 1024);
socket.write("$decryptedData\r\n");
await for (var data in socket) {
_xReply = new String.fromCharCodes(data).trim();
var list = _xReply.split(":_:");
_xCustomerToken = list[2].toString();
_xCustomerName = list[3].toString();
});
_xResult = "$_xCustomerToken:_:$_xCustomerName";
var encryptedData = await setPrivate(_xResult);
return new Response.ok("$encryptedData");
}
} else {
return new Response.ok("404: Wrong Request");
}
} catch (e) {
return new Response.ok("404: $e.errorMessage");
}
}
}
when I testing I found that my code works. Only reason that I am sending 3DES data and has + and / character in it.
If you look at closely in first request, there is a + and / character in data which give me an error.
/login/ziD7v0Ul99vmNWnxJRxZIiTY4zakNoq8GjM+oHROYz/YTHnd3NH1XfHRULY0jaHU 19ms 404
on the other hand if I remove those character than I get perfect response.
/login/ziD7v0Ul99vmNWnxJRxZIiTY4zakNoq8GjMoHROYzYTHnd3NH1XfHRULY0jaHU 13 ms 200
So, question comes how to send encrypted (3DES) data into aqueduct without getting any error?
Going to Like Aqueduct twice :)
It was very simple:
var _xPrivate = (request.path.variables['value']).trim(); change to:
var _xPrivate = request.path.remainingPath;
print("request: $_xPrivate");
The problem is that when i to save the data(in greek) on the server the title field data look's like this ??????????? but it must be Καλώς ορίσατε.
ControllerCode
#Secured(['ROLE_EDITOR'])
def saveArticle = {
def member = springSecurityService.currentUser
if(request.post){
params.member = member
def post = new Post(params)
if(post.save())
{
redirect(action: "page",id: post.id)
}
else
{
return post.errors
}
}
else
{
redirect(action: "addArticle")
}
}
Post domain class
class Post {
String title
String body
Members member
Date created_at = new Date()
static constraints = {}
}
the strange is that the field body returns correctly greek language and not like title.
the answer is jdbc:mysql://localhost/dev?useUnicode=yes&characterEncoding=UTF-8
the ?useUnicode=yes&characterEncoding=UTF-8 in the connection string..