I have the following spring cloud contract:
package contracts.teams
import org.springframework.cloud.contract.spec.Contract
Contract.make {
name"d Find team roles by filters"
description "Find team roles by filters"
request {
method "POST"
url "api/team/findTeamRolesByFilters"
headers {
contentType applicationJson()
accept applicationJson()
header"Authorization", execute('bearerOfAccessToken()')
}
body execute('getRequestForFindTeamRolesByFilters()')
}
response {
status OK()
headers {
contentType applicationJson()
}
body execute('getResponseForFindTeamRolesByFilters()')
}
}
I call the getResponseForFindTeamRolesByFilters() at the response in order to generate a dynamic response from the server. The reason could for example be an auto generated id that is coming from the DB.
The generated string from the getResponseForFindTeamRolesByFilters() is a valid JSON that unfortunately is ignored and returns always true when the test run.
I have noticed this when I replace the execute method with a static response like the following one:
"""
{
"success": "false"
}
"""
In this case the response is being validated correctly and fails the test in case it does not match.
What I said is being confirmed by the test generated code as it can be seen here:
// then:
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.header("Content-Type")).matches("application/json.*");
// and:
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
getResponseForFindTeamRolesByFilters();
As you can see there is no assertion. It simply calls the method that generates the json.
How am I supposed to make the test check the dynamic json response?
Thank you!
I call the getResponseForFindTeamRolesByFilters() at the response in order to generate a dynamic response from the server.
You should not do it. Contract tests should not access the database.
For the consumer you should do
request {
method "POST"
url "api/team/findTeamRolesByFilters"
headers {
contentType applicationJson()
accept applicationJson()
header"Authorization", execute('bearerOfAccessToken()')
}
body $(producer(execute('getRequestForFindTeamRolesByFilters()')), consumer("some value to be put on the consumer side"))
}
For the producer
response {
status OK()
headers {
contentType applicationJson()
}
body $(producer(execute('getResponseForFindTeamRolesByFilters()')), consumer("something in the stub"))
}
Related
I am trying to access the POST API from my spring app to angular but little bit confused how to use and access the given API in my angular app.
Spring REST API
#RequestMapping(value = "/getWelcomeMessage", method = RequestMethod.POST)
public String getLoginWelcomeMessage() {
return details.getLoginWelcomeMessage();
}
The given API is fetching the welcome message details from my oracle DB and returning a string value. I am trying to access the given REST API in my angular code through services. I had define the post service as follows
export class LoginService {
constructor(private http : HttpClient) { }
welcomeMessageService(){
const headers = {'content-type':'application/text'}
return this.http.put("http://localhost:8080/API/getWelcomeMessage",null,
{'headers':headers});
}
}
As the post method requires three arguments URL, Body and header. But in my case my spring REST API doesn't contain any body and returning a string. So, I had define the body as null and change the header type to text as it is JASON by default.
At last, I am trying to access the given service method by injecting it in my component as follows-
export class LoginComponent implements OnInit {
message:string;
constructor(private loginService : LoginService) { }
ngOnInit(): void {
this.loginService.welcomeMessageService().subscribe(
response =>{
console.log(response);
this.message = response;
}
)
}
}
But when I am trying to assign the response to the string I am getting the error that string cannot be assigned to the object. I am little bit confused why this error is occurring as I had also changed the header type to string while defining my service but still getting the error.
It can be a great help if anybody guide me regarding this as I am new to angular and little bit confused with integration part of API with angular.
Use { responseType: 'text' } and also send an empty body not null
export class LoginService {
constructor(private http : HttpClient) { }
welcomeMessageService(){
return this.http.put("http://localhost:8080/API/getWelcomeMessage",{},
{ responseType: 'text' });
}
}
Maybe you have copied the function wrong but check also here
#RequestMapping(value = "/getWelcomeMessage", method = RequestMethod.POST)
public String getLoginWelcomeMessage() {
return details.getLoginWelcomeMessage();
}
This is a Post method not a put that you are trying to call
As for cors error add the following to the backend just above #Controller or #RestControler whatever you have
#CrossOrigin(value = {"http://localhost:4200"}, methods = {GET,POST,PUT,DELETE})
I am using javax.ws.rs.* classes for REST API.
HttpConnection Class and URLConnection for connection.
I have one method As
#POST
#Path("/{containerId}/{caseDefId}/customcasestart")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response claimTasks(#Context HttpHeaders headers, #PathParam("containerId") String containerId,
#PathParam("caseDefId") String caseDefId,String payload) {}
{
logger.info("Payload : "+payload)
}
This payload is not fetching data from request body .
I am passing data from postman-Body-Raw as Follow :
{
"userId":"123",
"date":"2020/07/15"
}
But it gives null. And I have no idea how to fetch body parameter using any method or class?
Anyone please help here.
I need to invoke a form-data typed API using Rest Assured. Here is my code.
private Map<String, String> getFormParamsMap() {
Map<String, String> formParams = new HashMap<>();
formParams.put("creatorId", "Instructor1");
formParams.put("creatorPlatform", "Web");
formParams.put("creatoredSource", "File");
formParams.put("creatoredType", "Auto");
formParams.put("deckId", "5a605b472e02d86561172dad");
formParams.put("userId", "kind");
return formParams;
}
public void invoke() {
response = given()
.header("Content-Type", "application/form-data")
.header(AUTHORIZATION_HEADER_NAME, accessToken) //Some API contains access token to run with the API
.headers(headers)
.formParams(getFormParamsMap()) // requestParamsMap here.
.when()
.post(invokingEndpoint);
}
When I execute this, I am getting the below error.
Message: java.lang.IllegalArgumentException: Don't know how to encode creatorPlatform=Web&creatoredType=Auto&deckId=5a605b472e02d86561172dad&creatorId=Instructor1&creatoredSource=File&userId=kind as a byte stream.
Please use EncoderConfig (EncoderConfig#encodeContentTypeAs) to specify how to serialize data for this content-type.
For example: "given().config(RestAssured.config().encoderConfig(encoderConfig().encodeContentTypeAs("application/form-data", ContentType.TEXT))). .."
Stack Trace:
io.restassured.internal.http.EncoderRegistry.encodeStream(EncoderRegistry.java:130)
When I use .config(RestAssured.config().encoderConfig(encoderConfig().encodeContentTypeAs("application/form-data", ContentType.TEXT))) in the invoke() method, it gives the result as below.
{
"status": 400,
"message": "Content type 'application/x-www-form-urlencoded;charset=ISO-8859-1' not supported",
"error": "Bad Request",
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException"
}
My request is not x-www-form-urlencoded type, it is form-data type. I can execute it using postman.
Appreciate your support on this.
Thanks.
I have solve this issue by using encodeContentTypeAs("multipart/form-data", ContentType.TEXT)
Ex:-
public void invoke() {
response = given()
.config(
RestAssured.config()
.encoderConfig(
encoderConfig()
.encodeContentTypeAs("multipart/form-data", ContentType.TEXT)))
.headers(headers)
.formParams(formParams)
.when()
.post(oAuthBaseURI).then().extract().response();
}
Please add the consumer as well.
See here for the encoders available for Rest Assured.
This might be causing the problem -
encodeContentTypeAs("application/form-data", ContentType.TEXT)
You can also try this -
.encoderConfig(encoderConfig().appendDefaultContentCharsetToContentTypeIfUndefined(false).encodeContentTypeAs("application/form-data", ContentType.TEXT));
As far as I can tell, headers(headers) method replaces all headers, and then RestAssured uses x-www-form-urlencoded content type as default.
Try adding "Content-Type" header after the call to headers(headers).
I get null when I send a POST. Please someone know how to pass value with Angular using #HeaderParam in Jersey?
I have this in backend:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Users loginUser(#HeaderParam("username")String username,#HeaderParam("password") String password){
System.out.println("What happen"+userService.loginService(username, password));
return userService.loginService(username, password);
}
and this in front-end, using Angular:
$scope.getUserFunction = function () {
$http({
method : 'POST',
url : 'http://localhost:8080/JersyBackEnd/resources/login'+data,
contentType:'application/json',
data : {username: "akram",password:"yes"},
})
.then(function(data) {
console.log(data);
});
};
I get 204 because of the null data.
Can anyone help me, either using HeaderParam, PathParam or FormParm annotations in Jersey?
data is sent as the request body. What you really want is headers.
From the docs:
data – {string|Object} – Data to be sent as the request message data.
headers – {Object} – Map of strings or functions which return strings representing HTTP headers to send to the server. If the return value of a function is null, the header will not be sent. Functions accept a config object as an argument.
Example:
$http({
...
headers: {
username: "akram",
password: "yes"
}
})
When you use #HeaderParam, you have to pass the values from .JS using headers: { 'something': 'anything' }. As i can see currently you are using data : {username: "akram",password:"yes"}. try to use headers: { 'something': 'anything' } instead of this.
Please try header, hope it will solve your null issue.
I am trying to send a JSON string as a request to my application. This is my code:
#RequestMapping(
value = "/mylink/upload",
method = RequestMethod.POST,
consumes ="application/json",
produces = "application/json")
public
#ResponseBody
List<Upload> upload(
#RequestParam(value = "hdfsLocation") String hdfsLocation
) throws Exception {
return S3HdfsTransfer.uploadFromHDFS(hdfsLocation);
}
I am trying to send a request with Postman. The method I use is POST, the header contains: Accept "application/json",Content-Type "application/json", the request body is the following:
{
"hdfsLocation" : "hdfs://145.160.10.10:8020"
}
This is the response I get. If I put the parameter in the URL, it works.
{
"httpStatus": 500,
"appErrorId": 0,
"message": "Required String parameter 'hdfsLocation' is not present",
"trackingId": "8c6d45fd-2da5-47ea-a213-3d4ea5764681"
}
Any idea what I am doing wrong?
Thanks,
Serban
Looks like you have confused #RequestBody with #RequestParam. Do either of following :
Pass the request param as a request param(not as a body). Like, (encoded)
http://example.com?hdfsLocation=http%3A%2F%2Fexample.com%3FhdfsLocation%3Dhdfs%3A%2F%2F145.160.10.10%3A8020
Replace the #RequestParam with #RequestBody. If you are sending a body, don't send it along with request param. Those are two different things.
I guess you over looked :)
Shouldn't it be #RequestBody instead of #RequestParam?
Also, even after using #RequestBody, the whole of the JSON string:
{
"hdfsLocation" : "hdfs://145.160.10.10:8020"
}
will be the value of String hdfsLocation and not just the hdfs url. Hence, you'll have to JSON parse that JSON by yourself to get just the hdfs url.