1

A couple of weeks ago, I asked a question about reading Salesforce data using the SOAP API instead of the REST API (see Trying to use Apache Gobblin to read Salesforce data using SOAP API(s) instead of REST API ), but unfortunately nobody answered it, and so I am trying to implement the solution (with a little help) directly.

Using the REST API, the existing code that reads in a table's definition (by making a call to the REST API) looks like this:

// the URL starts with the Salesforce REST API endpoint, and ends with "/describe"
public String getSchema(String url, String accessToken, HttpClient httpClient) {
    String jsonStr;
    HttpRequestBase httpRequest = new HttpGet(url);
    if (accessToken != null) {
        httpRequest.addHeader("Authorization", "OAuth " + this.accessToken);
    }
    httpRequest.addHeader("Content-Type", "application/json");
    HttpEntity httpEntity = null;
    HttpResponse httpResponse = null;
    try {
        httpResponse = httpClient.execute(httpRequest);
        StatusLine status = httpResponse.getStatusLine();
        httpEntity = httpResponse.getEntity();

        if (httpEntity != null) {
            jsonStr = EntityUtils.toString(httpEntity);
        }

        if (status.getStatusCode() >= 400) {
            System.out.println("There was an error.  Http Status code of " + status.getStatusCode());
            EntityUtils.consumeEntity(httpEntity);
            return null;
        }
        return jsonStr;
    } catch (Exception e) {
       e.printStackTrace();
       return null;
    }
    return jsonStr;
}

I would like to write a method that uses the Salesforce SOAP API (using the generated "partner.wsdl" file) similar to the following incomplete code:

public String getSchemaViaSoap(String tableName) {
    String jsonStr;
    PartnerConnection partnerConnection = ...;
    try {
        DescribeSObjectResult[] dsrArray = partnerConnection.describeSObjects(new String[] { entity });
        // Since we described only one sObject, we should have only
        // one element in the DescribeSObjectResult array.
        DescribeSObjectResult dsr = dsrArray[0];
        String jsonStr = ...;  /* this is where I need help in converting dsr into a similar JSON string. */
    } catch (ConnectionException e) {
        e.printStackTrace();
        log.error("Error getting connection", e);
        System.out.println("Error getting connection" + e);
        return null;
    }
    return jsonStr;
}

Any sort of help in determining how to convert from the DescribeSObjectResult object to a similar JsonString / HttpEntity / StringEntity object would be greatly appreciated.

Relequestual
  • 11,631
  • 6
  • 47
  • 83
Marc K.
  • 11
  • 4

1 Answers1

0

You have consumed the WSDL, right? The DescribeSObjectResult is a normal class in your project. So... my Java is rusty but seems the question is simple "how to convert a Java object to JSON"?

There are libraries for this, right? Jackson for example. This helps? Converting Java objects to JSON with Jackson

I'm not sure if you'll end with identical result but should be close enough.

eyescream
  • 18,088
  • 2
  • 34
  • 46
  • Yes, the wsdl was consumed (to generate "partner.jar", which was imported into the project). The problem is that the `DescribeSObjectResult` object generated by the call to `partnerConnection.describeSObjects` SOAP call is *substantially* different from the REST API version. – Marc K. Aug 29 '20 at 01:09
  • Hm. Sounds like you'd have to hand-craft the translation between the two, royal pain. As I commented in the linked question - I don't think client has technical means to block REST API. You could make-do by logging in using SOAP but then the session id should be perfectly fine to reuse in REST calls? Alternative would be to write an Apex webservice that'd try to return the right format and call it with SOAP? – eyescream Aug 29 '20 at 06:28
  • that is what I ended up doing. Exactly as you described, it was a royal pain, but it works. Thank you for the suggestion. – Marc K. Sep 21 '20 at 06:21