The service is consuming google maps api (geocode).
When I execute a GET using default bean configuration for spring resttemplate, I have a value different from when I execute this GET on web browser (Chrome).
Call on Chrome and using resttemplate:
https://maps.googleapis.com/maps/api/geocode/json?key=mykeymykeymykeymykey&address=Rua%20Marques%20de%20Valenca,%20100,%20Alto%20da%20Mooca,%20S%C3%A3o%20Paulo%20-%20SP,%20Brasil&language=pt-BR
When I execute a reverse geocode, the chrome execution is more precise.
Results:
Chrome:
location: {
lat: -23.5577251,
lng: -46.5948733
},
RestTemplate:
location: {
lat: -23.5574375,
lng: -46.5948733
},
I´ve tried use Double, Float and BigDecimal. And I try create a deserializer to get this value before the serialization, but the value is the same.
I´m using Java 8 with Spring Boot 2.0.3.
Anyone knows how to accurate it?
I was using UriComponentsBuilder and when I use toUriString the url was formatted to browser and it was not working correctly.
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(googleHost)
.queryParam("key", apiKey)
.queryParam(input, address)
.queryParam("language", language);
It´s working now using StringUtils.join(...) to build the URI.
String googleurl = StringUtils.join(googleGeocodingHost,
"?key=", apiKey, "&", input, "=", address, "&language=", language);
Related
I have the following method in the Spring REST controller
#PostMapping("/uploadFile", consumes=["multipart/form-data"])
fun uploadFile(#RequestParam("fileType") fileType: FileType?,
#RequestParam("fileContentType") fileContentType: FileContentType?,
#RequestParam("projectId", required=false) projectId: UUID?,
#RequestParam("fileId", required = false) fileId:UUID?,
#RequestParam("description", required=false) description: String?,
#RequestParam("file") file: MultipartFile): UUID {
My objective is to test this service. I need to upload a file and in the same time give to service wrong "fileId", then parse ErrorMessage. Please tell me how to perform such request? What should I use JAX-RS? ResteasyClient? I have tried ResteasyClient
val inputStream: InputStream = Thread.currentThread().contextClassLoader.getResourceAsStream("application.properties")
val upload = MultipartFormDataOutput()
upload.addFormData("file", inputStream, MediaType.MULTIPART_FORM_DATA_TYPE, "mytarfile.tar")
var request = ClientRequest("http://localhost:$port/api/v1.0/files/uploadFile")
request.formParameter("fileId","test")
request.header("Authorization", "Bearer $accessToken")
request.body(MediaType.MULTIPART_FORM_DATA_TYPE, upload)
val response = request.post(String::class.java)
but it doesn't work
java.lang.RuntimeException: RESTEASY003100: You cannot send both form parameters and an entity body
Moreover ClientRequest is depricated and it is recommended to move to JAX-RS 2.0, could you tell me how to do that??
I would like to map this rest interface in OpenApi?
Is there by chance a tool with which I can create an OpenApi from the rest interface without including this tool in my Spring Boot Application? Or is there a template I can use to build the interface myself in Openapi? I would be very grateful for an approach.
#GetMapping("/page")
public Page<FootballTeamLocationEntityView> getPageableFootballTeamList(#PageableDefault(value = 10) Pageable pageable) {
return footballTeamService.getFootballTeams(pageable);
}
I use OpenApi 3.0 and Spring Boot 2
UPDATE 1
default ResponseEntity<FootballTeamLocation> getPageableFootballTeamList(Pageable pageable) {
getRequest().ifPresent(request -> {
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
String exampleString = "{ \"name\" : \"Westfalen-Stadion\", \"locZ\" : 5.962133212312, \"externalId\" : \"externalId\", \"locX\" : 6.02749381870403, \"id\" : 0, \"locY\" : 11.4658129805029452 }";
ApiUtil.setExampleResponse(request, "application/json", exampleString);
break;
}
}
});
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
Consider using springdoc. It is a recent library that is easier to use and way less error-prone than Springfox (the other option for Spring Boot apps). We moved to it 2 years ago and we are very glad we did. There is very good documentation and tutorials online for it:
https://springdoc.org/
https://www.baeldung.com/spring-rest-openapi-documentation
It is also very active and you usually get your issues answered very fast on the github page.
Issue while creating Policy In Android Management API,Iam Using Spring Boot as BackEnd.
this is my request:
{
"name": "testpolicy",
"applications": [
{
"packageName": "com.adobe.reader",
"installType": "REQUIRED_FOR_SETUP",
"defaultPermissionPolicy": "GRANT"
}
],
"kioskCustomization":{
"powerButtonActions": "POWER_BUTTON_ACTIONS_UNSPECIFIED",
"systemErrorWarnings": "SYSTEM_ERROR_WARNINGS_UNSPECIFIED",
"systemNavigation": "SYSTEM_NAVIGATION_UNSPECIFIED",
"statusBar": "STATUS_BAR_UNSPECIFIED",
"deviceSettings": "DEVICE_SETTINGS_UNSPECIFIED"
},
"kioskCustomLauncherEnabled": true
}
This is my response:
JSON parse error: Can not set com.google.api.services.androidmanagement.v1.model.KioskCustomization field com.google.api.services.androidmanagement.v1.model.Policy.kioskCustomization to java.util.LinkedHashMap; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not set com.google.api.services.androidmanagement.v1.model.KioskCustomization field com.google.api.services.androidmanagement.v1.model.Policy.kioskCustomization to java.util.LinkedHashMap (through reference chain: com.google.api.services.androidmanagement.v1.model.Policy["kioskCustomization"])
code written in the controller:
#PostMapping("/policies")
public ResponseEntity<com.google.api.services.androidmanagement.v1.model.Policy> savePolicy(
#RequestBody Policy policy, #RequestParam String enterpriseId) throws Exception {
}
control is not even coming inside the controller
I tried your request in Quickstart and did not encounter any error, the cause of your error may come from your implementation (Parser being used, or the format when typed) , I suggest that you try your request in quickstart to confirm that there is nothing wrong with your request.
Also you can check this documentation for a sample app that demonstrates how to provision a corporate-owned, single-use (COSU) device, and send it a reboot command. The app uses the Android Management API Java client library.
Today I'm doing my API automation testing and performance testing with Jmeter when the server is a REST API.
Now the development changed to graphQL API, and I have two questions about it:
What is the best way to perform the automation API and performance testing?
Does Jmeter support graphQL API?
I use Apollo to build the GraphQL server, and use JMeter to query the GraphQL API as below.
1. Set up HTTP Request
2. Set up HTTP Headers
Depending on your application, you might also need to set up HTTP header Authorization for JWT web tokens, such as:
Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxx
3. Set up HTTP Cookie if needed for your app
4. Run the test
Disclaimer: I work for LoadImpact; the company behind k6.
If you are willing to consider an alternative, I've recently written a blog post about this topic: Load testing GraphQL with k6.
This is how a k6 example looks like:
let accessToken = "YOUR_GITHUB_ACCESS_TOKEN";
let query = `
query FindFirstIssue {
repository(owner:"loadimpact", name:"k6") {
issues(first:1) {
edges {
node {
id
number
title
}
}
}
}
}`;
let headers = {
'Authorization': `Bearer ${accessToken}`,
"Content-Type": "application/json"
};
let res = http.post("https://api.github.com/graphql",
JSON.stringify({ query: query }),
{headers: headers}
);
Looking into Serving over HTTP section of the GraphQL documentation
When receiving an HTTP GET request, the GraphQL query should be specified in the "query" query string.
So you can just append your GraphQL query to your request URL.
With regards to "best practices" - you should follow "normal" recommendations for web applications and HTTP APIs testing, for example check out REST API Testing - How to Do it Right article.
You can try using easygraphql-load-tester
How it works:
easygraphql-load-tester is a node library created to make load testing on GraphQL based on the schema; it'll create a bunch of queries, that are going to be the ones used to test your server.
Examples:
Artillery.io
K6
Result:
Using this package, it was possible to me, to identify a bad implementation using dataloaders on the server.
Results without dataloaders
All virtual users finished
Summary report # 10:07:55(-0500) 2018-11-23
Scenarios launched: 5
Scenarios completed: 5
Requests completed: 295
RPS sent: 36.88
Request latency:
min: 1.6
max: 470.9
median: 32.9
p95: 233.2
p99: 410.8
Scenario counts:
GraphQL Query load test: 5 (100%)
Codes:
200: 295
Results with dataloaders
All virtual users finished
Summary report # 10:09:09(-0500) 2018-11-23
Scenarios launched: 5
Scenarios completed: 5
Requests completed: 295
RPS sent: 65.85
Request latency:
min: 1.5
max: 71.9
median: 3.3
p95: 19.4
p99: 36.2
Scenario counts:
GraphQL Query load test: 5 (100%)
Codes:
200: 295
I am testing our GraphQL Implementation, you will need:
Thread Group
HTTP Header Manager: You need to add as Content-Type: Application/json
https://i.stack.imgur.com/syXqK.png
HTTP Request: use GET and add in the Body Data your query
https://i.stack.imgur.com/MpxAb.png
Response Assertion: You want to count as correct requests only responses without errors
https://i.stack.imgur.com/eXWGs.png
A Listener:
https://i.stack.imgur.com/VOVLo.png
I have recently tried API testing with GraphQl with both GET and POST request in Jmeter
Make sure its POST request for both Query and Mutation
Example Your Graph Ql query
{
storeConfig{
default_title
copyright
}
}
For Jmeter it would be like this
{
"query":"{ storeConfig { default_title copyright } }"
}
Step up HTTP Request
In place of the localhost, your domain name will come. Make sure you don't add https
Example:- https://mydomainname.com
In Jmeter :- mydomainname.com
Setup HTTP Header Manager
For requesting Mutation in Jmeter
Example mutation in Graphql
mutation {
generateCustomerToken(
email: "rd#mailinator.com"
password: "1234567"
) {
token
}
}
In Jemeter mutation will be like this
{
"query":"mutation { generateCustomerToken( email: \"rd#mailinator.com\" password: \"1234567\" ) { token } }"
}
Replace double quotes with (\") as shown in above query
The easiest way will be to use the GraphQL queries directly in JMeter without the need to convert them to JSON.
All you need to do is to pass "Content-Type" as "application/graphql" in the header.
Image Link for: HTTP Request with GraphQL Query as input
Image Link for: Header details
Curious if anyone has got this working as I'm currently struggling.
I have created simple Source and Sink applications to send and receive an Avro schema based message. The schema for the message is held in a Confluent Schema Registry. Both apps are configured to use the ConfluentSchemaRegistryClient class but I think there might be a bug in here somewhere. Here's what I see that makes me wonder.
If I interact with the Confluent registry's REST API I can see that there is only one version of the schema in question (lightly edited to obscure what I'm working on):
$ curl -i "http://schemaregistry:8081/subjects/somesubject/versions"
HTTP/1.1 200 OK
Date: Fri, 05 May 2017 16:13:37 GMT
Content-Type: application/vnd.schemaregistry.v1+json
Content-Length: 3
Server: Jetty(9.2.12.v20150709)
[1]
When the Source app sends off its message over Kafka I noticed that the version in the header looked a bit funky:
contentType"application/octet-stream"originalContentType/"application/vnd.somesubject.v845+avro"
I'm not 100% clear about why the application/vnd.somesubject.v845+avro content type is wrapped up in application/octet-stream but ignoring that, note that it is saying version 845 not version 1.
Looking at the ConfluentSchemaRegistryClient implementation I see that it POSTs to /subjects/(string: subject)/versions and returns the id of the schema not the version. This then gets put into SchemaReference's version field: https://github.com/spring-cloud/spring-cloud-stream/blob/master/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/ConfluentSchemaRegistryClient.java#L81
When the Sink app tries to fetch the schema for the message based upon the header it fails because it tries to fetch version 845 that its plucked out of the header: https://github.com/spring-cloud/spring-cloud-stream/blob/master/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/ConfluentSchemaRegistryClient.java#L87
Anyone have thoughts on this? Thanks in advance.
** UPDATE **
OK pretty convinced this is a bug. Took the ConfluentSchemaRegistryClient and modified the register method slightly to POST to /subjects/(string: subject) (i.e. dropped the trailing /versions) which per Confluent REST API docs returns a payload with the version in it. Works like a charm:
public SchemaRegistrationResponse register(String subject, String format, String schema) {
Assert.isTrue("avro".equals(format), "Only Avro is supported");
String path = String.format("/subjects/%s", subject);
HttpHeaders headers = new HttpHeaders();
headers.put("Accept",
Arrays.asList("application/vnd.schemaregistry.v1+json", "application/vnd.schemaregistry+json",
"application/json"));
headers.add("Content-Type", "application/json");
Integer version = null;
try {
String payload = this.mapper.writeValueAsString(Collections.singletonMap("schema", schema));
HttpEntity<String> request = new HttpEntity<>(payload, headers);
ResponseEntity<Map> response = this.template.exchange(this.endpoint + path, HttpMethod.POST, request,
Map.class);
version = (Integer) response.getBody().get("version");
}
catch (JsonProcessingException e) {
e.printStackTrace();
}
SchemaRegistrationResponse schemaRegistrationResponse = new SchemaRegistrationResponse();
schemaRegistrationResponse.setId(version);
schemaRegistrationResponse.setSchemaReference(new SchemaReference(subject, version, "avro"));
return schemaRegistrationResponse;
}