POST users import v2 internal server error - autodesk-forge

I am working on a fully automatic pipeline for my company where we automatically set up projects, add users and upload files with the different APIs on BIM360. On the stage of adding a user I get a 500 internal server error:
{"code":2000,"message":"no implicit conversion of String into Integer"}
We are using a two-legged authentication approach and as such the header looks like this:
Authorization: Bearer <token> (It has account:write rights)
x-user-id: ************ (uid of my admin account)
Content-Type: application/json
The request content is this:
#"{
""email"": """ + ***#********.** + #""",
""services"": {
""document_management"": {
""access_level"": """ + admin+ #"""
},
""project_administration"": {
""access_level"": """ + admin+ #"""
}
},
""industry_roles"": []}";
I just can't quite seem to figure out what I am doing wrong. Hope someone can help me.
EDIT: Full code for this request
public async static Task<HttpStatusCode> AddUserToProjectEmail(string projectId, string accountId, string accessToken, string userToAddEmail, string userPrivilege, string adminUserId)
{
using (HttpClient httpClient = new HttpClient())
{
using (HttpRequestMessage request = new HttpRequestMessage())
{
//Documentation for what to put in the Http POST: https://forge.autodesk.com/en/docs/bim360/v1/reference/http/projects-project_id-users-import-POST/
request.Method = new HttpMethod("POST");
request.RequestUri = new Uri("https://developer.api.autodesk.com/hq/v2/regions/eu/accounts/" + accountId + "/projects/" + projectId + "/users/import");
//Make the request payload
string jsonPayload = AddPayloadToUserAddEmail(userToAddEmail, userPrivilege);
request.Content = new StringContent(jsonPayload);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
request.Headers.Add("x-user-id", adminUserId);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
//Send request
var response = await httpClient.SendAsync(request);
return response.StatusCode;
}
}
}
And the request payload method:
private static string AddPayloadToUserAddEmail(string userToAddEmail, string userPrivilege)
{
string payload = #"{
""email"": """ + userToAddEmail + #""",
""services"": {
""project_administration"": {
""access_level"": """ + userPrivilege + #"""
},
""document_management"": {
""access_level"": """ + userPrivilege + #"""
}
},
""industry_roles"": []
}";
return payload;
}
I have checked all the IDs through the URL on BIM360, however it's not possible to check the Uid of my account I think.
EDIT 2: I should note that I was getting a different error before I added the x-user-id header, where it just said forbidden which makes sense. This lead me to think it had something to do with the x-user-id header, but I can't figure it out.

Don't be like me and forget to wrap the payload into an array as stated on the docs that it has to be. Using this as payload worked
#"[{
""email"": """ + userToAddEmail + #""",
""services"": {
""project_administration"": {
""access_level"": """ + userPrivilege + #"""
},
""document_management"": {
""access_level"": """ + userPrivilege + #"""
}
},
""industry_roles"": []
}]";

Related

Printing ArrayList values in SpringBoot

I created an ArrayList with the json values from an Rest API.
This is the code to read the Rest API:
#RestController
public class exemploclass {
#RequestMapping(value="/vectors")
//#Scheduled(fixedRate = 5000)
public ArrayList<StateVector> getStateVectors() throws Exception {
ArrayList<StateVector> vectors = new ArrayList<>();
String url = "https://opensky-network.org/api/states/all?lamin=41.1&lomin=6.1&lamax=43.1&lomax=8.1";
//String url = "https://opensky-network.org/api/states/all?lamin=45.8389&lomin=5.9962&lamax=47.8229&lomax=10.5226";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", "Mozilla/5.0");
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
JSONObject myResponse = new JSONObject(response.toString());
JSONArray states = myResponse.getJSONArray("states");
System.out.println("result after Reading JSON Response");
for (int i = 0; i < states.length(); i++) {
JSONArray jsonVector = states.getJSONArray(i);
String icao24 = jsonVector.optString(0);
String callsign = jsonVector.optString(1);
String origin_country = jsonVector.optString(2);
Boolean on_ground = jsonVector.optBoolean(8);
//System.out.println("icao24: " + icao24 + "| callsign: " + callsign + "| origin_country: " + origin_country + "| on_ground: " + on_ground);
//System.out.println("\n");
StateVector sv = new StateVector(icao24, callsign, origin_country, on_ground);
vectors.add(sv);
}
System.out.println("Size of data: " + vectors.size());
return vectors;
}
}
The last line " return vectors;" returns a list with the values i parsed and returns it like this:
But i want this more "pretty", i want it to be one Array in each line, how can i achieve this?
P.S. Its on the .html page, not on console
Your return value seems a valid Json Object. If you want it more pretty so you can read it clearly then pass it through an application that makes that json pretty.
If you call your API from Postman, it will give you a pretty Json Object which will be better formatted. This will be because you have annotated your controller with #RestController so it will deliver an application/json response which Postman will know and then it will try to make it prettier.
P.S. Its on the .html page, not on console
So you hit your API from a browser. Most browsers don't expect a Json object to be returned, so they will not make it pretty. You can't force that from your Service either.
Just hit your API from Postman, it will understand it and make it pretty.

Zuora payment-methods/credit-cards api returning 90000011 from java Client but returning success response from postman

I am in the middle of integration zuora apis with my application. These are the below 3 three apis I am using through following steps -
Step 1 Requesting for auth token
Service api (Test)- https://rest.apisandbox.zuora.com/oauth/token
Request Headers - Content-Type:application/x-www-form-urlencoded
Authorization:Basic YWYzNTg5ZWMtNTFmMC00YTc2LWFlZjEtYjk0YzZmYWE0Y2ViOlJDdGV5OGlTWFFUc00xQytTPTFYWD1POE9tRWM1c0FBWVBaaE5vV24=
Request Body - grant_type:client_credentials
Response Body - {
"access_token": "41947f41d664437a98a9da38a293c89d",
"token_type": "bearer",
"expires_in": 3598,
"scope": "entity.a083d63b-b3f5-8626-f793-65cec903f9ca platform.write service.events.read service.events.write service.genesis.read service.genesis.write service.notifications.read service.notifications.write service.usage.delete service.usage.update service.usage.write tenant.41231 user.2c92c094738e5b090173902066c201ba",
"jti": "41947f41d664437a98a9da38a293c89d"
}
Use access_token or jti value from auth token response and pass it on to the headers parameters as Authorization: Bearer
Step 2 : - Request for hmac-signatures for making payment
Service api (Test) - https://rest.apisandbox.zuora.com/v1/hmac-signatures
Request Headers - Content-Type:application/json
Authorization:Bearer 41947f41d664437a98a9da38a293c89d
Request Body - {
"accountKey": "A00000485",
"method": "POST",
"uri": "https://rest.apisandbox.zuora.com/v1/payment-methods/credit-cards"
}
Response Body - {
"signature": "MDgzN2ZkYjAzOTQ5NmQ5NDQyZjc5YTU3NjUwMDgxOGIxNTY3YWM2Mw==",
"token": "C41mzDTudB2uc0Jc6vwrhQGvwq3JTxsF",
"success": true
}
The signature needs to be added in Make Payment header asSignature:MDgzN2ZkYjAzOTQ5NmQ5NDQyZjc5YTU3NjUwMDgxOGIxNTY3YWM2Mw==
The token needs to be added in Make Payment header as Token:C41mzDTudB2uc0Jc6vwrhQGvwq3JTxsF
Step 3:- Make payment request –
Service Api - https://apisandbox-api.zuora.com/rest/v1/payment-methods/credit-cards
Headers Parameters –
Host:apisandbox-api.zuora.com
Signature:MDgzN2ZkYjAzOTQ5NmQ5NDQyZjc5YTU3NjUwMDgxOGIxNTY3YWM2Mw==
Token:C41mzDTudB2uc0Jc6vwrhQGvwq3JTxsF
Content-Type:application/json
Origin:www.test.gov.uk
Cache-Control:no-cache
Request Parameters – {
"defaultPaymentMethod": true,
"cardHolderInfo":
{"addressLine1": "77 Fallon Glen",
"addressLine2": "",
"zipCode": "94020",
"state": "California",
"phone": "4155551234",
"country": "USA",
"cardHolderName": "Bill Thiebault",
"city": "Fremont",
"email": "bill#testaddress.com"},
"expirationMonth": "10",
"accountKey": "A00000485",
"creditCardType": "Visa",
"expirationYear": "2021",
"creditCardNumber": "4012888888881121",
"securityCode": "123"
}
Response Body – {
"success": true,
"**paymentMethodId": "2c92c0fb73ad855c0173b8c3316b36a1"**
}
When I use the same steps using postman I am able to get a success response. And the Payment Method id is also getting generated. Using java client the first two services are being executed. But the issue appears when I hit the request for Payment-Method / credit cards,
It always returns -
{
"success" : false,
"processId" : "84AD9CF25EC6623A",
"reasons" : [ {
"code" : 90000011,
"message" : "this resource is protected, please sign in first"
} ]
}
Please suggest me if I missed anything here.
I missed to set the header value. Here I am posting the method that I used -
It consists Oauth token generation -> generation hmac signature -> making request for payment-method / credit card. It worked for me.
public void testSpringZuorPaymentCreditCardDifferent() {
HTTPHelper httpHelper = null;
String urlOAuthToken = "https://rest.apisandbox.zuora.com/oauth/token";
String resp = null;
try {
String userNameAndPassword ="c59b646b-53c6-45fb-b9c3-d3ea0978033d" + ":" +"6VLNxA=Fbaorb7yqXO3YRaiS2a+WUfLtwOiVugLqQ";
String authorizationHeaderValue = "Basic " + new String(Base64.encode(userNameAndPassword.getBytes()));
httpHelper = new HTTPHelper(new URL(urlOAuthToken));
Map<String, String> hdmp = new HashMap<String, String>();
hdmp.put("Authorization", authorizationHeaderValue);
hdmp.put("Content-Type", "application/x-www-form-urlencoded");
httpHelper.setHeaders(hdmp);
String req = "grant_type=client_credentials";
System.out.println("REQUEST: " + req);
resp = httpHelper.post(req, 60000, 60000);
System.out.println("OAuth token response : " + resp);
}catch(Exception e) {
e.printStackTrace();
}
String[] arrOfStr = resp.split("\\W+");
System.out.println("Bearer token---------" + arrOfStr[2]);
String urlHmacSignatureUrl = "https://rest.apisandbox.zuora.com/v1/hmac-signatures";
try {
httpHelper = new HTTPHelper(new URL(urlHmacSignatureUrl));
Map<String, String> hdmp = new HashMap<String, String>();
hdmp.put("Authorization", "Bearer " + new String(Base64.encode(arrOfStr[2].getBytes())));
hdmp.put("Content-Type", "application/json");
hdmp.put("cache-control", "no-cache");
httpHelper.setHeaders(hdmp);
String req = "{\n \"accountKey\": \"A00000194\", \n \"method\": \"POST\", \n \"uri\": \"https://rest.apisandbox.zuora.com/v1/payment-methods/credit-cards\"\n}";
System.out.println("REQUEST: " + req);
resp = httpHelper.post(req, 60000, 60000);
System.out.println("Hmac Signature response : " + resp);
}catch(Exception e) {
e.printStackTrace();
}
arrOfStr = resp.split("\\W+");
System.out.println("signature : - "+arrOfStr[2]);
System.out.println("token : - "+arrOfStr[4]);
String serverURI = "https://apisandbox-api.zuora.com/rest/v1/payment-methods/credit-cards";
try {
java.util.Map<String, String> headers = new java.util.HashMap<String, String>();
httpHelper = new HTTPHelper(new URL(serverURI));
headers.put("Content-Type", "application/json");
// headers.put("Signature", arrOfStr[2]+"==");
headers.put("Signature", new String(Base64.encode("YjM4MDY5MDliZmVkYmZiOGFkNmQ1YzFhYzFmNzMyOGI3NjExM2JlNQ==".getBytes())));
headers.put("Token", new String(Base64.encode(arrOfStr[4].getBytes())));
httpHelper.setHeaders(headers);
String req = "{\r\n" +
" \"defaultPaymentMethod\":true,\r\n" +
" \"cardHolderInfo\":{\r\n" +
" \"addressLine1\":\"77 Fallon Glen\",\r\n" +
" \"addressLine2\":\"\",\r\n" +
" \"zipCode\":\"94020\",\r\n" +
" \"state\":\"California\",\r\n" +
" \"phone\":\"4155551234\",\r\n" +
" \"country\":\"USA\",\r\n" +
" \"cardHolderName\":\"Bill Thiebault\",\r\n" +
" \"city\":\"Fremont\",\r\n" +
" \"email\":\"bill#testaddress.com\"\r\n" +
" },\r\n" +
" \"expirationMonth\":\"10\",\r\n" +
" \"accountKey\":\"A00000485\",\r\n" +
" \"creditCardType\":\"Visa\",\r\n" +
" \"expirationYear\":\"2021\",\r\n" +
" \"creditCardNumber\":\"4012888888881121\",\r\n" +
" \"securityCode\":\"123\"\r\n" +
"}";
System.out.println("Req: " + req);
resp = httpHelper.post(req, 60000, 60000);
System.out.println("Payment Method - Credit Cards: " + resp);
}catch(Exception e) {
e.printStackTrace();
}
}

Add a JSON string inside JSON string on Arduino

I'm developing a project that uses the ESP8266 with ArduinoJson library.
On my webserver I need create a http response with a JSON (read from a file) inside another JSON.
Something like this:
String data = "";
String success = "0";
File loadFile = SPIFFS.open(filename, "r");
if (!loadFile){
Serial.println("Il file non esiste: " + filename);
} else {
size_t size = loadFile.size();
if ( size == 0 ) {
Serial.println("File vuoto: " + filename);
} else {
while (loadFile.available()){
data += char(loadFile.read());
}
success = "1";
}
loadFile.close();
}
String json;
json = "{\"success\":\"" + String(success) + "\",";
json += "\"form\":\"" + data + "\"}";
server->send(200, "application/json", json);
The content of "data" variable is correct but the on client I get:
{
"success": 1,
"data": { }
}
Data is empty.
What is the right way to add a JSON string inside another JSON string in "arduino and esp8266"?

Parsing json in apex

Hello I have created a RESTful web services which returns the responce in below format :
[
{"empId":1,"empName":"A"},
{"empId":2,"empName":"B"},
{"empId":3,"empName":"C"},
{"empId":4,"empName":"D"},
{"empId":5,"empName":"E"}
]
I have written the simple visualforce page to call the method named 'lookup' on button click action. My Apex class is given below.
public class REST {
public PageReference lookup()
{
string resp;
// Note this version of the API is only for the US
string endpoint ='http://localhost:8080/RESTfulExample/rest/json/metallica/get';
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setMethod('GET');
req.setEndpoint(endpoint);
try {
res = http.send(req);
} catch (Exception e) {
system.debug(LoggingLevel.Error, 'Error HTTP response code = '+res.getStatusCode()+'; calling '+endpoint );
return null;
}
resp = res.getBody();
JSONParser parser = JSON.createParser(resp);
// Parsing The JSON & set the list of values to the variables 'empid' & 'empname'
return null;
}
}
Can anyone help me how I can use JSON parser to parse the JSON and to store the values to the variables.
Thank You !!!
If you would like to use JSONParser here is an example from the Salesforce documentation on JSONParser(https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_json_jsonparser.htm):
public class JSONParserUtil {
#future(callout=true)
public static void parseJSONResponse() {
Http httpProtocol = new Http();
// Create HTTP request to send.
HttpRequest request = new HttpRequest();
// Set the endpoint URL.
String endpoint = 'https://docsample.herokuapp.com/jsonSample';
request.setEndPoint(endpoint);
// Set the HTTP verb to GET.
request.setMethod('GET');
// Send the HTTP request and get the response.
// The response is in JSON format.
HttpResponse response = httpProtocol.send(request);
System.debug(response.getBody());
/* The JSON response returned is the following:
String s = '{"invoiceList":[' +
'{"totalPrice":5.5,"statementDate":"2011-10-04T16:58:54.858Z","lineItems":[' +
'{"UnitPrice":1.0,"Quantity":5.0,"ProductName":"Pencil"},' +
'{"UnitPrice":0.5,"Quantity":1.0,"ProductName":"Eraser"}],' +
'"invoiceNumber":1},' +
'{"totalPrice":11.5,"statementDate":"2011-10-04T16:58:54.858Z","lineItems":[' +
'{"UnitPrice":6.0,"Quantity":1.0,"ProductName":"Notebook"},' +
'{"UnitPrice":2.5,"Quantity":1.0,"ProductName":"Ruler"},' +
'{"UnitPrice":1.5,"Quantity":2.0,"ProductName":"Pen"}],"invoiceNumber":2}' +
']}';
*/
// Parse JSON response to get all the totalPrice field values.
JSONParser parser = JSON.createParser(response.getBody());
Double grandTotal = 0.0;
while (parser.nextToken() != null) {
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
(parser.getText() == 'totalPrice')) {
// Get the value.
parser.nextToken();
// Compute the grand total price for all invoices.
grandTotal += parser.getDoubleValue();
}
}
system.debug('Grand total=' + grandTotal);
}
}
Although from what you say in your question I think it would be simpler to do JSON Deserialization.
Here is an example on how to do it:
Wrapper Class
public class EmployeeWrapper {
public Integer empId {get;set;}
public String empName {get;set;}
}
JSON Deserialization
String jsonContent = '[{"empId": 1,"empName": "A"}, {"empId": 2,"empName": "B"}, {"empId": 3,"empName": "C"}, {"empId": 4,"empName": "D"}, {"empId": 5,"empName": "E"}]';
List<EmployeeWrapper> employeeWrapperList = (List<EmployeeWrapper>)JSON.deserialize(jsonContent, List<EmployeeWrapper>.class);
System.debug(employeeWrapperList);
//Do actions to WrapperList

How post messages to the yammer private group

I can able to get the messages from yammer private group using this link
https://www.yammer.com/api/v1/messages/in_group/3248147.json?access_token= + rawtoken)
but I used the same link for posting messages to the private group in yammer, for this I have wrote the below code. but it is behaving as get method only, I am unable to post the messages to the private group.
WebClient wc = new System.Net.WebClient();
Uri uri = new Uri("https://www.yammer.com/api/v1/messages/in_group/3248147.json?access_token=" + rawtoken);
student ns = new student();
// wc.Headers["Authorization"] = "Bearer" + rawtoken; //use discoEN token here
// String data1 = "group-id=" + ns.group_id + "&body=" + ns.body;
String data = "body=" + "hello";
wc.UploadStringCompleted += new UploadStringCompletedEventHandler(wc_UploadStringCompleted);
wc.Headers["Content-Type"] = "application/x-www-form-urlencoded";
wc.Encoding = Encoding.UTF8;
wc.UploadStringTaskAsync(uri,"post",data);
private void wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
MessageBox.Show(e.Result);
}
Structure your post url like below, and keep the auth in the headers with the Bearer token format.
Notice that body is wrapped inside of query in the post format.
auth = "Bearer " + token
HTTParty.post("https://www.yammer.com/api/v1/messages.json?group_id=3248147",
{
:headers => { "Authorization" => auth},
:query => {"body" => 'hello' }
})