How to create a method which prints the entire Request and Response in Play? - playframework-2.6

I want to create a helper method which could be called from a Controller and prints the different parameters of the Request. I tried to do something like following but I need to pass type parameter to Request. What should I pass for type parameter?
import play.api.mvc.Request
package object utilities {
def printPlayHttpRequest (request:Request): Unit ={ //Request needs type parameter. What should I pass as type parameter?
}
}
Looking at the apply method of Request object, it seems that the type parameter passed corresponds to the Body type. So do I need to pass some body type?
def apply[A](rh: RequestHeader, body: A): Request[A]

From Play documentation, I suppose the A in Request[A] corresponds to type of body and it could be any Scala type as the request body, for example String, NodeSeq, Array[Byte], JsonValue, or java.io.File, as long as we have a body parser able to process it
From documentation
Previously we said that an Action was a Request => Result function. This is not entirely true. Let’s have a more precise look at the Action trait:
trait Action[A] extends (Request[A] => Result) {
def parser: BodyParser[A]
}
First we see that there is a generic type A, and then that an action must define a BodyParser[A]. With Request[A] being defined as:
trait Request[+A] extends RequestHeader {
def body: A
}
The A type is the type of the request body. We can use any Scala type as the request body, for example String, NodeSeq, Array[Byte], JsonValue, or java.io.File, as long as we have a body parser able to process it.
To summarize, an Action[A] uses a BodyParser[A] to retrieve a value of type A from the HTTP request, and to build a Request[A] object that is passed to the action code.
Following is my implementation
import play.api.mvc.{AnyContent, Request}
package object utilities {
def printPlayHttpRequest (request:Request[AnyContent]): Unit ={
println(s"Attr: ${request.attrs}, \n Body: ${request.body}, \n connection: ${request.connection}, \n headers: ${request.headers}, \n method: ${request.method}, \n target: ${request.target}, \n version: ${request.version}, \n mediatype: ${request.mediaType}")
}
}

Related

Use generic-webhook-trigger and pass JSON body as is instead of individual variables

I am using generic-webhook-trigger in Jenkins to trigger job when events happen in Github.
It seems I have to extract each variable I need from the big JSON request body to convert them to env-var.
Is it possible to pass the whole JSON body to the Jenkins job and have it parse it?
You can achieve what you want by assigning the entire body to a specific variable, then read it as Json in your code and parse it by yourself.
For example, if your payload (received post content) is:
{
"ref": "refs/heads/master",
"head_commit": {
"committer": {
"name": "ido",
"email": "ido#test.com"
}
}
}
You can define a single parameter in your generic webhook configuration called payload, set the expression for that parameter to $, set the expressionType JSONPath, and when the job is triggered that parameter will include the entire content of the received post content.
You can then parse it by yourself:
def payloadMap = readJSON text: payload
println "ref value is: ${payloadMap.ref}"
println "committer name is: ${payloadMap.head_commit.committer.name}"
You can see more advanced examples for using the generic-webhook-trigger configurations plugin Here, and especially This one which is more relevant for your requirements.

Nestjs swagger array of strings with one parameter

When I send only one parameter, I got query result like string, not like string[]. This heppend only from UI swagger, if I send from Postman - it works good.
I just want send from swagger-ui one parammeter and got array of string, not string
How I can fix it? Help me please.
Example1: send one paramenter and in my controller I got string like '25'
Example2: when I send 2 parameters in controller I can see array of strings ('25', '21')
export class List {
#ApiProperty({ isArray: true, type: String, required: false })
#IsOptional()
public categories?: string[];
}
You should try to spread your parameter in a const in services
edit:
I don't know how to explain in formal words, but a array of strings of one item, for JAVASCRIPT, seems with the same thing as one string value.
Because array is not a type, but a form of a type....
So, if you, in your controller, before do anything with it, you redeclare as:
#Get(":id")
findManybyId(#Param("id") id: string[]) {
const idArray = [...id];
return await this.service.findManyById(idArray);
}
It will solve your problem about being an array
old answer:
You should try to change in your controller where you make your input decorator.
in your case, i don't know if you are using ID to get, but you must to do as the example:
#ApiOperation({
summary: "Get many categories by ID",
})
async getMany(
#Param("id") ids: string[],
) {
return await this.categoriesService.getMany(id);
}
when you fill a single category the query param will be translated as a string while when you fill in several categories understand it as a array.
to solve this problem I added in DTO :
#Transform(({ value }) => (Array.isArray(value) ? value : Array(value)))
I force the cast to array

Fetching data from a microservice to rest in grails

I have a rest and a microservice.In microservice i have a table and i want that table data to be fetched to rest and i have written the below way in a rest demoController.
def result = restBuilder().post("http://localhost:2222/api/microservice/fetchData"){
header 'authorization', 'fdgtertddfgfdgfffffff'
accept("application/json")
contentType("application/json")
json "{'empId':1,'ename':'test1'}"
}
But it throws an error "No signature of method: demoController.restBuilder() is applicable for argument types: () values: []".How should i fetch data from a microservice to rest?
You are calling a method named restBuilder() and that method does not exist. If you want that to work, you will need to implement that method and have it return something that can deal with a call to post(String, Closure).
You probably are intending to use the RestBuilder class. The particulars will depend on which version of Grails you are using but you probably want is something like this...
RestBuilder restBuilder = new RestBuilder()
restBuilder.post('http://localhost:2222/api/microservice/fetchData'){
header 'authorization', 'fdgtertddfgfdgfffffff'
accept 'application/json'
json {
empId = 1
name = 'test1'
}
}
You may need to add a dependency on grails-datastore-rest-client in your build.gradle.
compile "org.grails:grails-datastore-rest-client"
I hope that helps.

Parsing JSON response using Citrus framework for URLEncode

I'm using Citrus to automate our RESTful services where service1's input param is passed onto service2' input after URLEncoding.
Below is the code snippet, to explain the ways I tried but somehow unable to URLEncode, on top of designer.traceVariables().
Owing to the limitation (possible known!) that the response params can't be passed outside of context, I had to call multiple send(), receive() calls, defined in the same Gherkin method as below.
I'm able to print the variable myVar (extracted from payLoad) using designer.traceVariables() but unable to process & persist it for further use, to pass onto the next service call.
#When("^I call CPAuth service for ChasePay$")
public void i_call_CPAuth_service_for_ChasePay() throws Throwable {
designer.send("CitrusContext")
.messageType(MessageType.JSON)
.header(X_JPMC_CSRF_TOKEN_HEADER, csrfToken)
.header(HTTP.CONTENT_TYPE, APPLICATION_JSON)
.header(COOKIE, ConnRoutePNames.DEFAULT_PROXY + "=" + proxy)
.header("citrus_endpoint_uri", authUrl +"/auth/fcc/login")
.message(new HttpMessage("<large_string=no_issues_here>").method(HttpMethod.POST));
designer.receive("CitrusContext").messageType(MessageType.JSON)
.validate("$.response", "secauth")
.validate("$.newstoken", false)
.validate("$.smtoken", "void")
.extractFromPayload("$.spid", "myVar");
String request = URLEncoder.encode("appStoreBundleId=com.testmerchant.sampleapp&version=APP%2BBUILD%2BVERSION&channelId=MPD&spid=**${myVar}**&type=json&chasePayMerchantId=1390xxx", CharEncoding.UTF_8);
System.out.println("request: "+request);
designer.send("CitrusContext")
.messageType(MessageType.JSON)
.header(X_JPMC_CSRF_TOKEN_HEADER, csrfToken)
.header(HTTP.CONTENT_TYPE, APPLICATION_JSON)
.header(COOKIE, ConnRoutePNames.DEFAULT_PROXY + "=" + proxy)
.header("citrus_endpoint_uri", hostUrl +"/pwc/provisioning/pos/otp/contact/v20160313/list.action")
.message(new HttpMessage(request).method(HttpMethod.POST));
Result:
Before encoding: MSZp2V/czcKsxej+Q04Da/QeVlo=MCwCFAqrBN/6/J8WZENecE7JQlEODnecAhQCcnXGBjMoiQ7deunlyXKacFo/lQ== (This should be the string, to be encoded.)
After encoding: %3D%24%7BmyVar%7D%26
Any help would be greatly appreciated, Thanks.
The encode operation destroys the "${myVar}" expression before Citrus is able to parse and interpret the expression as part of the message payload. You need to execute the encode operation as a Citrus function. How to write this function is described here: http://citrusframework.org/docs/custom-functions/
You end up having something like:
designer.send("CitrusContext")
.messageType(MessageType.JSON)
.message(new HttpMessage("custom:urlEncode('appStoreBundleId=com.testmerchant.sampleapp&version=APP%2BBUILD%2BVERSION&channelId=MPD&spid=**${myVar}**&type=json&chasePayMerchantId=1390xxx')").method(HttpMethod.POST));

Jersey POST operation with PathParam and JSON Object

By design, GET operation should be used only for read Only operation. Howeevre,i am looking for a plausible way of implementaion of following.Implement a POST operation that can be called as it is mentioned below
POST /my-store/order/D : where D is the day the customer place an order
Request: POST /my-store/order/14
{
"customer" : "XYZ",
"order" : {
"item1" : 2
}
}
I tried implementing using below function
#Path("/D")
#POST
#Consumes({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
#Produces({ MediaType.APPLICATION_JSON })
public Response submitOrder(#PathParam("D") int elapsedDays, #Context UriInfo uriInfo, Order orderInfo){
..........
}
But the above implementation does not seem to working. When I try to test the implementation using MyEclipse REST explorer ,it does not offer option to pass in Order object but allow 'D' parameter only. However, if #PathParam and #Path is removed then it works perfectly fine i.e. allows to consume JSON Order object.
But,the requirement is to pass the days as Path parameter and Order object as JSON input in POST request.
Looking for suggestion on implementation approach and design approach.
Thanks in advance
For one thing, your path should be configured like this:
#Path("/{D}")
I assume your extended ellipses means you have some method parameter that represents the deserialization of your order.

Resources