Unable to Test POST request In Scala HTTP Akka - scala

Although the problem seems to be easy, but I am unable to get a OK 200 response while trying to register an Instance.
def register(InstanceString: String) : server.Route = {
post
{
log.debug(s"POST /register has been called, parameter is: $InstanceString")
try {
val paramInstance : Instance = InstanceString.parseJson.convertTo[Instance](instanceFormat)
handler.handleRegister(paramInstance) match {
case Success(id) =>
complete{id.toString}
}}}
Above is the method that executes the request.
Following is its API configuration:
paths:
/register:
post:
tags:
- Basic Operations
summary: Register a new instance at the registry
operationId: addInstance
parameters:
- in: body
name: InstanceToRegister
required: true
schema:
$ref: '#/definitions/Instance'
responses:
'200':
description: The ID of the registered instance
schema:
type: integer
format: int64
example: 42
Following is the test case that I am trying to execute but I get 400 Bad Request did not equal 200 OK.
"The Server" should {
"Successfully Register" in {
Post("/register", HttpEntity(ContentTypes.`application/json`,"""{"InstanceString":"hallo"}""")) ~> Route.seal(routes) ~> check {
assert(status === StatusCodes.OK)

Try this:
Post("/register", requestBody.toJson).withHeaders("if Any") ~> Route.seal(routes) ~> check {
status shouldBe StatusCodes.OK
}
I can see that you have Json reader for your request body, so use Json writer like this new InstanceString("hello").toJson you get request body.
I see that your your request content type is application/json and you are passing String.

Related

API gateway blocking requests with content in body

I'm trying to post a request through AWS API gateway with postman.
I have aws IAM on and it appears to be working. I can send a request with nothing in the body I get a 200 response back from my lambda function.
I would like to send a binary file in the body however whenever I add anything, form-data, raw or binary data to the body of the request I get this message:
{
"message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n'POST\ ..."
}
I have tried adding
image/png and application/octect-stream to Binary Media Types
and also tried specifying a model with just one field in it and that doesn't work either.
Any help would be much appreciated. I tried posting on AWS forums but there is no "post", "ask a question" or "create" button to actually ask a question, so back to old trusty stackoverflow.
Cheers. Mitch.
Edit API gateway setup:
openapi: 3.0.1
info:
title: AlarmEndpoints
version: '2019-03-02T03:22:39Z'
servers:
- url: https://602wer34n1.execute-api.ap-southeast-2.amazonaws.com/{basePath}
variables:
basePath:
default: /dev
paths:
/alarm/message:
post:
responses:
'200':
description: 200 response
content:
application/json:
schema:
$ref: '#/components/schemas/Empty'
security:
- sigv4: [
]
x-amazon-apigateway-integration:
uri: arn:aws:apigateway:ap-southeast-2:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-2:962000000000:function:alarm_message/invocations
responses:
default:
statusCode: '200'
passthroughBehavior: when_no_match
httpMethod: POST
contentHandling: CONVERT_TO_TEXT
type: aws
components:
schemas:
Empty:
title: Empty Schema
type: object
securitySchemes:
sigv4:
type: apiKey
name: Authorization
in: header
x-amazon-apigateway-authtype: awsSigv4
x-amazon-apigateway-policy:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: arn:aws:iam::962000000000:user/alarm_user
Action: execute-api:Invoke
Resource: arn:aws:execute-api:ap-southeast-2:962000000000:*/*/*
Lambda Function:
import json
import os
import boto3
def lambda_handler(event, context):
var = os.environ.get("a_variable")
return {
'statusCode': 200,
'body': json.dumps({'message': 'Hello from Lambda 2!',
'echo': event,
'data': var})
}

Akka HTTP, Spray Json and Option Fields Failing as Required

I have a case class:
case class OpcTagPlaybook(name: String, tags: Seq[OpcTagAtTime], looped: Boolean, enabled: Option[String])
With an optional enabled field that will contain a date.
Spray Json describes encoding/decoding:
implicit val opcTagPlaybookFormat = jsonFormat4(OpcTagPlaybook)
And a route in akka http:
post {
entity(as[OpcTagPlaybook]) { playbook =>
val playbookCreated: Future[_] =
(opcTagPlaybookActor ? UpsertPlaybook(playbook))
onSuccess(playbookCreated) { _ =>
log.info("Created playbook [{}]", playbook.name)
complete((StatusCodes.Created, "ok"))
}
}
})
For some reason posting without the createdAt field fails:
Posting:
{"name": "test1",
"tags":[{"offset": 100, "tag": "hello", "value": "yo"}],
"looped": true
}
Fails:
The request content was malformed:
Object is missing required member 'enabled'
And if I post created it gives me another error:
{"name": "test1",
"tags":[{"offset": 100, "tag": "hello", "value": "yo"}],
"looped": true,
"enabled": "2018-08-08"
}
gives
The request content was malformed:
spray.json.JsString cannot be cast to scala.Option
I'm assuming this is some interplay between akka http and so I'm going to just deal with the input more manually but I'd just like to understand what I'm doing wrong here.

Swagger Validator complaining about seemingly well-formed request

I'm using the swagger-express-validator to validate inputs to a small API server (using Swagger 2 format)
My path definition is as follows
/api/v1/users:
post:
produces:
- "application/json"
parameters:
- in: body
name: ids
description: Array of user ids to be processed
required: true
schema:
$ref: "#/definitions/ArrayOfIds"
responses:
200:
description: success
ArrayOfIds is defined as follows
Id:
type: string
ArrayOfIds:
type: array
items:
$ref: "#/definitions/Id"
Sending a post request to the server as follows:
POST /api/v1/users HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: localhost:3000
Connection: close
User-Agent: Paw/3.1.7 (Macintosh; OS X/10.13.6) GCDHTTPRequest
Content-Length: 35
{
"ids": ["abcd12345"]
}
Results in an error
Request Invalid: POST /api/v1/users
[ { keyword: 'type',
dataPath: '',
schemaPath: '#/type',
params: { type: 'array' },
message: 'should be array' } ]
I am however able to access req.body.ids in my Express route controller code and it contains the correct value ['1234abc'].
Do you have any idea as to why the validator is complaining about the request? It looks fine to me.
Your request body does not match the definition. According to the definition, the array in the request body must be unwrapped:
POST /api/v1/users HTTP/1.1
Content-Type: application/json
...
["abcd12345"]
If the array needs to be wrapped into the ids wrapper property, the request body should be defined as type: object with the property ids that contains the array:
parameters:
- in: body
name: ids
description: Array of user ids to be processed
required: true
schema:
type: object
properties:
ids:
$ref: "#/definitions/ArrayOfIds"

How to have multiple parameters for body in Swagger

So I'm having problem with how I pass my data.
This is my WCF rest method
[WebInvoke(UriTemplate = "/GetCustomFieldValues",
Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)]
Dictionary<string, Object> GetCustomFieldValues(string pwaUrl, string projectUid, List<string> customFieldNames);
On Swagger this is my declaration for it
/GetCustomFieldValues:
post:
parameters:
- name: Param
in: body
description: The custom field value you want to get
required: true
schema:
$ref: "#/definitions/GetCustomFieldValues"
responses:
200:
description: Getting custom field value using name
summary: GetCustomFieldValues
description: GetCustomFieldValues
operationId: GetCustomFieldValues
definitions:
GetCustomFieldValues:
type: object
properties:
pwaUrl:
type: string
projectUid:
type: string
customFieldNames:
type: array
items:
type: string
When I used my Advanced Rest Client or Powershell the method works, the only difference is how I assemble the body.
For Swagger I need to use a definition since I can't do multiple parameters on body.
I'm also putting this at the top of the swagger
schemes:
- http
consumes:
- application/json
produces:
- application/json
Weird thing about WCF,
CORS needs to be both Global.asx and web.config, this works on mine
CORS enabled but response for preflight has invalid HTTP status code 404 when POSTing JSON

Cannot save a document in Mongoose - Validator required failed for path error

Following is my schema:
var userSchema = new Schema({
username: {
type: String,
required: true
},
password: {
type: String,
required: false
}
});
Now, when I attempt to save a document of the above schema, I get the following error:
{ message: 'Validation failed',
name: 'ValidationError',
errors:
{ username:
{ message: 'Validator "required" failed for path username',
name: 'ValidatorError',
path: 'username',
type: 'required' } } }
The above is the error object returned by mongoose upon save. I searched for this error but could not understand what is wrong. The document that I am trying to save is as follows:
{
username: "foo"
password: "bar"
}
Any idea what this means? I searched the mongoose docs too but could not find anything under the validation section.
First, you are missing a comma (,) after foo.
Now, is { username: "foo", password: "bar" } JSON sent via http, our an actual object in your server-side code ?
If it is, try to console.log(youVariable.username) and see if it shows undefined or the value foo. If you see undefined, then your object is not parsed properly.
You can make sure that whom ever is sending the POST request is sending a "application/json" in the header, you could be receiving something else, thus your JSON isn't parsed to a valid javascript object.