Hello Account (Java without wsc)

Java で Hello Account。

$ java -classpath ./:/usr/local/axis-1_4/lib/axis-ant.jar:/usr/local/axis-1_4/lib/commons-discovery-0.2.jar:/usr/local/axis-1_4/lib/jaxrpc.jar:/usr/local/axis-1_4/lib/wsdl4j-1.5.1.jar:/usr/local/axis-1_4/lib/axis.jar:/usr/local/axis-1_4/lib/commons-logging-1.0.4.jar:/usr/local/axis-1_4/lib/log4j-1.2.8.jar:/usr/local/axis-1_4/lib/saaj.jar org.apache.axis.wsdl.WSDL2Java partner.wsdl

$ javac -classpath ./:/usr/local/axis-1_4/lib/axis-ant.jar:/usr/local/axis-1_4/lib/commons-discovery-0.2.jar:/usr/local/axis-1_4/lib/jaxrpc.jar:/usr/local/axis-1_4/lib/wsdl4j-1.5.1.jar:/usr/local/axis-1_4/lib/axis.jar:/usr/local/axis-1_4/lib/commons-logging-1.0.4.jar:/usr/local/axis-1_4/lib/log4j-1.2.8.jar:/usr/local/axis-1_4/lib/saaj.jar com/sforce/soap/partner/*.java

$ find com/ | grep "class$" | xargs jar -cvf partner.jar

$ javac -classpath ./:/usr/local/axis-1_4/lib/axis-ant.jar:/usr/local/axis-1_4/lib/commons-discovery-0.2.jar:/usr/local/axis-1_4/lib/jaxrpc.jar:/usr/local/axis-1_4/lib/wsdl4j-1.5.1.jar:/usr/local/axis-1_4/lib/axis.jar:/usr/local/axis-1_4/lib/commons-logging-1.0.4.jar:/usr/local/axis-1_4/lib/log4j-1.2.8.jar:/usr/local/axis-1_4/lib/saaj.jar HelloAccount.java

$ java -classpath ./:/usr/local/axis-1_4/lib/axis-ant.jar:/usr/local/axis-1_4/lib/commons-discovery-0.2.jar:/usr/local/axis-1_4/lib/jaxrpc.jar:/usr/local/axis-1_4/lib/wsdl4j-1.5.1.jar:/usr/local/axis-1_4/lib/axis.jar:/usr/local/axis-1_4/lib/commons-logging-1.0.4.jar:/usr/local/axis-1_4/lib/log4j-1.2.8.jar:/usr/local/axis-1_4/lib/saaj.jar HelloAccount
import com.sforce.soap.partner.LoginResult;
import com.sforce.soap.partner.QueryResult;
import com.sforce.soap.partner.SessionHeader;
import com.sforce.soap.partner.SforceServiceLocator;
import com.sforce.soap.partner.SoapBindingStub;
import com.sforce.soap.partner.sobject.SObject;

public class HelloAccount {
  public static void main(String[] args) {
    try {
      SoapBindingStub binding = (SoapBindingStub) new SforceServiceLocator().getSoap();
      LoginResult loginResult = binding.login(<user name>, <password>);
      
      SessionHeader sh = new SessionHeader();
      sh.setSessionId(loginResult.getSessionId());      
      binding._setProperty(SoapBindingStub.ENDPOINT_ADDRESS_PROPERTY, loginResult.getServerUrl());
      binding.setHeader(new SforceServiceLocator().getServiceName().getNamespaceURI(), "SessionHeader", sh);
  
      QueryResult queryResult = binding.query("SELECT Id, Name FROM Account");
      for (SObject sobj : queryResult.getRecords()) {
        System.out.println(sobj.getId() + ", " + sobj.get_any()[1].getValue());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Hello Account (Java with WSC)

Java (WSC) で Hello Account。

$ wget https://sfdc-wsc.googlecode.com/files/wsc-23.jar
$ java -classpath wsc-23.jar com.sforce.ws.tools.wsdlc partner.wsdl partner-wsc.jar
$ javac -classpath ./:wsc-23.jar:partner-wsc.jar HelloAccount.java
$ java -classpath ./:wsc-23.jar:partner-wsc.jar HelloAccount
import com.sforce.soap.partner.*;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;
import java.io.FileNotFoundException;

public class HelloAccount {
  private PartnerConnection connection;
  
  private String authEndpoint = "https://test.salesforce.com/services/Soap/u/30.0";
  private String userName = <user name>;
  private String password = <password>;
  private String query = "SELECT Id, Name FROM Account";
  
  public static void main(String[] args) throws FileNotFoundException {
    HelloAccount helloAcct = new HelloAccount();
    if (helloAcct.login()) {
      helloAcct.getAccounts();
    }
  }
  
  private boolean login() throws FileNotFoundException {
    boolean success = false;
    ConnectorConfig config = new ConnectorConfig();
    config.setUsername(userName);
    config.setPassword(password);
    config.setAuthEndpoint(authEndpoint);
    config.setTraceFile("trace.log");
    config.setTraceMessage(true);
    config.setPrettyPrintXml(true);
    try {
      connection = Connector.newConnection(config);
      success = true;
    } catch (ConnectionException e) {
      e.printStackTrace();
    }
    return success;
  }
  
  private void getAccounts() {
    QueryResult queryResult;
    try {
      queryResult = connection.query(query);
      for (SObject sobj : queryResult.getRecords()) {
        System.out.println(sobj.getId() + ", " + sobj.getField("Name"));
      }
    } catch (ConnectionException e) {
      e.printStackTrace();
    }
  }
}

cURL で Bulk API を叩く

  1. セッション ID を取得
  2. ユーザ名とパスワードを login.xml にする。

    <?xml version="1.0" encoding="utf-8" ?>
      <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
    
        <env:Body>
          <n1:login xmlns:n1="urn:partner.soap.sforce.com">
            <n1:username>username@domain.com</n1:username>
            <n1:password>password</n1:password>
          </n1:login>
        </env:Body>
    </env:Envelope>
    


    認証のエンドポイントは SOAP(Partner)側にして、”SOAPAction: login”。

    $ curl https://test.salesforce.com/services/Soap/u/28.0 -H "Content-Type: text/xml; charset=UTF-8" -H "SOAPAction: login" -d @login.xml
    


    XML で serverurl と sessionid が確認できる。serverurl のインスタンス名を使用したものが、今後のエンドポイントとなる。

    <?xml version='1.0' encoding='utf-8'?>
    <soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <soapenv:body>
        <loginresponse>
          <result>
            ...
            <serverurl>
              https://cs6.salesforce.com/services/Soap/u/28.0/00DNxxxxxxxxxxx
            </serverurl>
            <sessionid>
              00DNxxxxxxxxxxx!AQUAQN8QhONTb7BTHDeXsS3TwD6nLtZrYSbp9nnd64nnOJsRIvaV2vomczOdxlsTL1qdh0DWYYkasAE20zGMqmgGXHa4YlCG
            </sessionid>
            ...
          </result>
        </loginresponse>
      </soapenv:body>
    </soapenv:envelope>
    
  3. ジョブの作成
  4. オペレーションとその対象オブジェクトを “job.xml” に書く。例えば、Contact オブジェクトに insert する。

    <?xml version="1.0" encoding="UTF-8"?>
    <jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">
      <operation>insert</operation>
      <object>Contact</object>
      <contentType>CSV</contentType>
    </jobInfo>
    


    “/services/async/28.0/job” でジョブ操作用のエンドポイントとなる。

    $ curl https://cs6.salesforce.com/services/async/28.0/job -H 'X-SFDC-Session: 00DNxxxxxxxxxxx!AQUAQN8QhONTb7BTHDeXsS3TwD6nLtZrYSbp9nnd64nnOJsRIvaV2vomczOdxlsTL1qdh0DWYYkasAE20zGMqmgGXHa4YlCG' -H "Content-Type: application/xml; charset=UTF-8" -d @job.xml
    


    ジョブが作成されれば、JobId が確認できる。

    <?xml version="1.0" encoding="UTF-8"?>
    <jobInfo
       xmlns="http://www.force.com/2009/06/asyncapi/dataload">
     <id>750xxxxxxxxxxxxxxx</id>
     ...
    </jobInfo>
    
  5. バッチの作成
  6. サンプルとして 2 件のレコードを “data.csv” として用意。

    FirstName,LastName,Department,Birthdate,Description
    Tom,Jones,Marketing,1940-06-07Z,"Self-described as ""the top"" branding guru on the West Coast"
    Ian,Dury,R&D,,"World-renowned expert in fuzzy logic design.Influential in technology purchases."
    


    エンドポイントに JobId を指定する。

    $ curl https://cs6.salesforce.com/services/async/28.0/job/750xxxxxxxxxxxxxxx/batch -H 'X-SFDC-Session: 00DNxxxxxxxxxxx!AQUAQN8QhONTb7BTHDeXsS3TwD6nLtZrYSbp9nnd64nnOJsRIvaV2vomczOdxlsTL1qdh0DWYYkasAE20zGMqmgGXHa4YlCG' -H "Content-Type: text/csv; charset=UTF-8" --data-binary @data.csv
    


    バッチが作成されれば BatchId が確認できる。状態は Queued なので実行待ち。

    <?xml version="1.0" encoding="UTF-8"?>
      <batchInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">
        <id>751xxxxxxxxxxxxxx</id>
        <jobId>750xxxxxxxxxxxxxx</jobId>
        <state>Queued</state>
        ...
      </batchInfo>
    
  7. ジョブのクローズ
  8. 無事 Batch が完了すれば、ジョブをクローズする。
    クローズのオペレーションを “close_job.xml” に書く。

    <?xml version="1.0" encoding="UTF-8"?>
    <jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">
      <state>Closed</state>
    </jobInfo>
    


    エンドポイントには JobId を指定。

    $ curl https://cs6.salesforce.com/services/async/28.0/job/750xxxxxxxxxxxxxxx -H 'X-SFDC-Session: 00DNxxxxxxxxxxx!AQUAQN8QhONTb7BTHDeXsS3TwD6nLtZrYSbp9nnd64nnOJsRIvaV2vomczOdxlsTL1qdh0DWYYkasAE20zGMqmgGXHa4YlCG' -H "Content-Type: application/xml; charset=UTF-8" -d @close_job.xml
    


    “Closed” の状態になっていることが確認できる。

    <?xml version="1.0" encoding="UTF-8"?>
      <jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">
        <id>750xxxxxxxxxxxxxxx</id>
        <operation>insert</operation>
        <object>Contact</object>
        ...
        <state>Closed</state>
        ...
      </jobInfo>