System.HttpResponse[Status=Bad Request, StatusCode=400 . Nagging issue. Any thoughts???

This issue is killing us for more than a week now as there is no helpful information from the WC1 server on this issue. We are keep on getting this error System.HttpResponse[Status=Bad Request, StatusCode=400

We are using Salesforce Apex to create the JSON string and the request headers. Here is the code below. No matter whatever we do, your server just responded with 400 bad request with no additional info to debug the issue. We have changed the JSON to many format but all the efforts are in vain.

If your server returning bad request, atleast please give us a clue what you are getting as a request from us.

PLEASE GIVE US SOME INSIGHTS ON WHAT YOUR SERVER IS EXPECTING.

public with sharing class testingscenario
{
public static String generateAuthHeader(String dataToSign)
{
String algorithmName = 'HmacSHA256';
Blob hmacData = Crypto.generateMac(algorithmName, Blob.valueOf(dataToSign), Blob.valueOf('*************************'));
return EncodingUtil.base64Encode(hmacData);
}
@Future(callout = true)
public static void getvalues(String JsonString)
{


String gatewayurl = '/v1/';
String gatewayhost = 'rms-world-check-one-api-pilot.thomsonreuters.com';
String apikey = '***************************';
String apisecret = '*******************************';


String contentType = 'application/json';
String ND=Datetime.now().formatGMT('EEE, dd MMM yyyy HH:mm:ss z');


//String jsonBody = '{\"secondaryFields\":[],\"entityType\":\"INDIVIDUAL\",\"customFields\":[],\"groupId\":\"*********************\",\"providerTypes\":[\"WATCHLIST\"],\"name\":\"george w bush\"}';


JSONGenerator gen = JSON.createGenerator(true);

List<String> str1 = new List<String>();
List<String> str2 = new List<String>();
str2.add('WATCHLIST');


// Write data to the JSON string.
gen.writeStartObject();
gen.writeObjectField('secondaryFields', str1);
gen.writeStringField('entityType', 'INDIVIDUAL');
gen.writeObjectField('customFields',str1);
gen.writeStringField('groupId', '*********************************');
gen.writeObjectField('ProviderTypes', str2);
gen.writeStringField('name', 'george');

gen.writeEndObject();

// Get the JSON string.
String pretty = gen.getAsString();
System.debug('json string:>>>>>>>>>'+pretty );
String content = pretty ;//JSON.serialize(gen);
Integer Contentlength=pretty.length();
System.debug('Contentlengthhhhhh'+Contentlength);



/*
String dataToSign = '(request-target): post' + gatewayurl+ 'cases\n' +
'host: ' + gatewayhost + '\n' +
'date: ' + ND +'\n'+
'content-type: '+contentType +'\n' +
'content-length: '+ Contentlength + '\n' +
content;
*/


String dataToSign1 = '(request-target): post ' + gatewayurl + 'cases\n' +
'host: ' + gatewayhost + '\n' +
'date: ' + ND + '\n' +
'content-type: ' + contentType +'\n' +
'content-length: ' + contentLength + '\n' +
pretty;


String hmac = generateAuthHeader(dataToSign1);


String authorisation = 'Signature keyId=\"' + apikey + '\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date content-type content-length\",signature=\"' + hmac + '\"';




System.debug('authorisation Result'+authorisation);
System.debug('dataToSign Result'+dataToSign1 );
System.debug('hmac Result'+hmac);


HttpRequest request = new HttpRequest();


request.setEndpoint('https://rms-world-check-one-api-pilot.thomsonreuters.com/v1/cases');
request.setMethod('POST');
request.setTimeout(120000);
request.setHeader('Authorization',authorisation);
request.setHeader('Date',ND);
request.setHeader('Cache-Control', 'no-cache');
request.setHeader('Content-Type', 'application/json');
request.setHeader('Content-Length', String.valueOf(contentlength));


Http http = new Http();
HTTPResponse res = http.send(request);





}
}


Best Answer

  • Hi @baskaran.subramanian,

    I don't know your environment, but after the Status should be the Body (header?) of the return request, that will have the error message NOT the Status message or code.

    I suggest you read the manual for your environment.

    Brian

Answers

  • Hi @baskaran.subramanian,

    In below dataToSign1 "application/json" is missing.

    String dataToSign1 = '(request-target): post ' + gatewayurl + 'cases\n' +
    'host: ' + gatewayhost + '\n' +
    'date: ' + ND + '\n' +
    'content-type: ' + contentType +'\n' +
    'content-length: ' + contentLength + '\n' + pretty;


    Please use below line of code and try to execute.


    String dataToSign = "(request-target): post " + gatewayurl+ "cases\n" + "host: " + gatewayhost + "\n" + "date: "+ ND + "\n" + "content-type: " + "application/json"+ "\n" + "content-length: " + contentLength + "\n" + content;

    Thanks,

    Shilpi

  • Hi @shilpi.saha

    Thank you, But we have assigned "application/json" in a variable called ContentType and used it in "dataToSign1". You can view that in the code. Also, if we set the body in the header, then we are getting different error which is 401 unauthorized. We dont know what to do. The issue becoming very critical for us as we are nearing the deadline of the project. Please provide some pointers to narrow down the issue.

  • Hi @baskaran.subramanian,

    >PLEASE GIVE US SOME INSIGHTS ON WHAT YOUR SERVER IS EXPECTING

    I sent you the examples of the GET/POST Java code I tested in Eclipse (although that does not matter). We do not support 3rd party development environments. The the code samples we provide are to help get people started. It you have an error in Salesforce, then it's likely either a coding error or something about the Salesforce environment that is altering the API messsage. You are receiving a 400 not found error, so your authorization code is working. Please check the body of your code for proper groupID, caseID, etc.. and be sure you have no control characters and all line feeds are Unix style LF not CRLF.

    Brian

  • Hi @brian.bourgault

    Thanks for your reply. We got Http 400 bad request. If I understand your comment correctly, you mean to say that our authorization code is working correct and because of that we are getting 400 bad request and the issue would be in JSON message body or incorrect groupid, case id, right?

    Is that possible for you guys to send the request header details that you are receiving from our Salesforce request? Please advice.

    Thanks

  • Hi @baskaran.subramanian

    Remove Custom Fields & Secondary Fields from your request, make a simple request as in the Postman Collect SEQ2b. With only the minimal fields make the request...

    Please make ONLY a simple request first....

    {"groupId":"xxxx","entityType": "INDIVIDUAL","providerTypes": ["WATCHLIST"],"name": "George Bush"}

    If you do not received a 401 Unauthorized Status error message

    then check the status message for HTTP/1.1 404 Not Found, that would be the groupID

    then for HTTP/1.1 400 Bad Request, you need to check the return BODY message not just the Status message. Here are two possible returns....

    HTTP/1.1 400 Bad
    Request

    [{"error":"INVALID_PROVIDER_TYPE","cause":"Provider
    types are invalid and must include at least WATCHLIST."}]

    [ {

    "error" :
    "INVALID_PROVIDER_TYPE",

    "cause" : "Provider types are
    invalid and must include at least WATCHLIST."

    } ]

    HTTP/1.1 400 Bad
    Request

    [{"error":"INVALID_ENTITY_TYPE","cause":"Entity
    type is mandatory and must be one of: INDIVIDUAL, ORGANISATION, VESSEL,
    UNSPECIFIED and must be compatible with each provider type used in screening a
    case."}]

    [ {

    "error" :
    "INVALID_ENTITY_TYPE",

    "cause" : "Entity type is
    mandatory and must be one of: INDIVIDUAL, ORGANISATION, VESSEL, UNSPECIFIED and
    must be compatible with each provider type used in screening a case."

    } ]

  • @baskaran.subramanian,

    Yes, chances are your groupID is incorrect if you did NOT receive a return body from your requests.

    1 - Did you try the simple POST request? (exactly what I gave you in the last response, NO case ID)

    Brian

  • Hi @brian.bourgault

    I tried exactly of what you said above, but I am still getting simply the error below. There is no additional details for the Http 400 bad request error like "invalid error type" or "invalid entity type" etc. Please advice. Thanks.

    System.HttpResponse[Status=Bad Request, StatusCode=400]
  • Hi @brian.bourgault

    Thanks for your valuable notes and guidance. Yes, you are right. The issue is related to Salesforce environment whereas double quotes in java should be replaced with single quote in Salesforce and that is the issue boggling me for more than a week. Now, I am good to proceed. Thanks for all your timely help and pointers to resolve the issue.

    Thanks again