Showing posts with label salesforce. Show all posts
Showing posts with label salesforce. Show all posts

Using SalesForce.com REST API

I was trying to use salesforce.com REST API for getting data. So i started following the http://wiki.developerforce.com/page/Integrating_Java_Spring_Apps_on_Heroku_with_Force.com_REST_APIs document. But after i followed it i kept getting Unable to get access token exception, more details here

 at com.force.sdk.oauth.connector.ForceOAuthConnector.createTokenInternal(ForceOAuthConnector.java:196)
2013-11-28T05:58:29.294965+00:00 app[web.1]:  at org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:48)
2013-11-28T05:58:29.294965+00:00 app[web.1]: 05:58:29,267 ERROR OAuthAuthenticationProvider:82 - Unable to get access token
2013-11-28T05:58:29.294965+00:00 app[web.1]: java.io.IOException: Missing refresh token on response
2013-11-28T05:58:29.294965+00:00 app[web.1]:  at org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:130)
2013-11-28T05:58:29.294965+00:00 app[web.1]:  at com.force.sdk.springsecurity.OAuthAuthenticationProvider.authenticate(OAuthAuthenticationProvider.java:78)
2013-11-28T05:58:29.300136+00:00 heroku[router]: at=info method=GET path=/_auth?code=aPrxkpHJh6tvoT6FsBbmu3.hEs0MRNTo0tj3P9AWu2oQ3aJeF7rXY._JA1wepFrePIgKkBuF4w%3D%3D&state=https%3A%2F%2Fdry-refuge-2742.herokuapp.com%2Fpeople%2F host=dry-refuge-2742.herokuapp.com fwd="206.218.52.33" dyno=web.1 connect=1ms service=446ms status=401 bytes=1083
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
2013-11-28T05:58:29.294965+00:00 app[web.1]:  at com.force.sdk.oauth.connector.ForceOAuthConnector.getAccessToken(ForceOAuthConnector.java:145)
2013-11-28T05:58:29.294965+00:00 app[web.1]:  at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
2013-11-28T05:58:29.294965+00:00 app[web.1]:  at com.force.sdk.springsecurity.AuthenticationProcessingFilter.doFilter(AuthenticationProcessingFilter.java:109)
2013-11-28T05:58:29.294965+00:00 app[web.1]:  at com.force.sdk.springsecurity.AuthenticationProcessingFilter.attemptAuthentication(AuthenticationProcessingFilter.java:138)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilt
er(SecurityContextPersistenceFilter.java:79)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
2013-11-28T05:58:29.295172+00:00 app[web.1]:  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
2013-11-28T05:58:29.295946+00:00 app[web.1]:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
2013-11-28T05:58:29.295946+00:00 app[web.1]:  at java.lang.Thread.run(Thread.java:679)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1653)
2013-11-28T05:58:29.295946+00:00 app[web.1]:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
2013-11-28T05:58:29.295416+00:00 app[web.1]:  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
2013-11-28T05:58:24.518283+00:00 heroku[router]: at=info method=GET path=/people/ host=dry-refuge-2742.herokuapp.com fwd="206.218.52.33" dyno=web.1 connect=1ms service=5ms status=302 bytes=0
After some googling i found the problem was that in oAuth setting i had to add 2 scopes to Selected oAuth scopes
  1. Full Access(full)
  2. Perform request on your behalf at any time (refresh_token)
Once i set up the oAUth settings properly the sample started working

Using Salesforce SOAP API from Java Code

Recently i had to develop a portlet that talks to SalesForce.com and retrieves some data. I decided to use the SalesForce SOAP API for that, i followed these steps
  1. First step is to get your salesforce.com security token, follow steps as described in Generating Security Token for SalesForce.com post for that
  2. Second step is to login into your salesforce.com account and download the Enterprise .wsdl, Follow steps 1-3 from Accessing SalesForce data using SOAP Service - SoapUi post for that
  3. You should use the Force.com web services connector (WSC) which has helper code that simplify working with Force.com SOAP service.
  4. Once you have WSC project downloaded on your machine and complied into jar copy it in a directory and then also copy your enterprise.wsdl in the same directory, then execute
    
    java -classpath target/force-wsc-29.0.0-jar-with-dependencies.jar com.sforce.ws.tools.wsdlc enterprise.wsdl enterprise.jar
    
    It will generate enterprise.jar file for you
  5. Now create a Java Project and add both enterprise.jar and force-wsc-29.0.0-jar-with-dependencies.jar in your classpath
  6. Last step is to create SFDClient.java class like this Replace userId, password and securitytoken in this file with the values you have
  7. When you run the SFDClient.java class it will display list of contacts in your salesforce.com account

Accessing SalesForce data using SOAP Service - SoapUi

Recently i was trying to figure out how to access SalesForce data from outside. I had two options either to use REST or use SOAP API for accessing the data. I tried both and these are my notes for accessing SalesForce Soap API using Soap client such as SoapUi.
  1. First thing that you would want to do is generate security token for salesforce. Follow these steps for generating security token
  2. Once you have security token, login into the SalesForce console to download the WSDL, Click on Develop -< API and you will see page where you can download all the WSDL's, Download the Enterprise WSDL
  3. Now create new SOAP Ui project using the Enterprise WSDL you just downloaded
    You will notice that it generates bunch of SOAP operations
  4. In order to use the SOAP API you will have to first send a login request to SalesForce and get sessionid once you have it you can use that for making subsequent calls. First call the Login service like this
    
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:urn="urn:enterprise.soap.sforce.com">
       <soapenv:Header>
       </soapenv:Header>
       <soapenv:Body>
          <urn:login>
             <urn:username>replacerwitheuserid</urn:username>
             <urn:password>replacewithpasswordreplacewithsecuritytoken</urn:password>
          </urn:login>
       </soapenv:Body>
    </soapenv:Envelope>
    
    You should replace replacerwitheuserid with your userId (email id that you use for login) and also replace replacewithpassword with your password and use the security token that you got in email to replace replacewithsecuritytoken. Make a request and you will get a response which looks like this
    
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns="urn:enterprise.soap.sforce.com" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <soapenv:Body>
          <loginResponse>
             <result>
                <metadataServerUrl>https://na15.salesforce.com/services/Soap/m/29.0/00Di0000000iKns</metadataServerUrl>
                <passwordExpired>false</passwordExpired>
                <sandbox>false</sandbox>
                <serverUrl>https://na15.salesforce.com/services/Soap/c/29.0/00Di0000000iKns</serverUrl>
                <sessionId>sessionId</sessionId> 
                <userId>userId</userId>
                <userInfo>
                   <accessibilityMode>false</accessibilityMode>
                   <currencySymbol>$</currencySymbol>
                   <orgAttachmentFileSizeLimit>5242880</orgAttachmentFileSizeLimit>
                   <orgDefaultCurrencyIsoCode>USD</orgDefaultCurrencyIsoCode>
                   <orgDisallowHtmlAttachments>false</orgDisallowHtmlAttachments>
                   <orgHasPersonAccounts>false</orgHasPersonAccounts>
                   <organizationId>xxxx</organizationId>
                   <organizationMultiCurrency>false</organizationMultiCurrency>
                   <organizationName>Self</organizationName>
                   <profileId>xxxx</profileId>
                   <roleId xsi:nil="true"/>
                   <sessionSecondsValid>7200</sessionSecondsValid>
                   <userDefaultCurrencyIsoCode xsi:nil="true"/>
                   <userEmail>xxxxx</userEmail>
                   <userFullName>Sunil Patil</userFullName>
                   <userId>xxxxx</userId>
                   <userLanguage>en_US</userLanguage>
                   <userLocale>en_US</userLocale>
                   <userName>sxxxxxx</userName>
                   <userTimeZone>America/Los_Angeles</userTimeZone>
                   <userType>Standard</userType>
                   <userUiSkin>Theme3</userUiSkin>
                </userInfo>
             </result>
          </loginResponse>
       </soapenv:Body>
    </soapenv:Envelope>
    
    You will need the value of sessionId element and value of serverUrl in subsequent requests. so note it down
  5. Next assume that you want to execute query request that will give you list of all the contacts using SELECT Id, FirstName, LastName From Contact query, so use XML that looks like this for the soap request. Replace the replacewithyoursessionid with the sessionId that you got from the login request and also change the URL where SOAP request is made to value of serverUrl
    
    <soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:urn="urn:enterprise.soap.sforce.com">
    
       <soapenv:Header>
          <urn:SessionHeader>
    <urn:sessionId>replacewithyoursessionid</urn:sessionId>
          </urn:SessionHeader>
       </soapenv:Header>
       <soapenv:Body>
          <urn:query>
             <urn:queryString>
    SELECT Id, FirstName, LastName  From Contact<
    /urn:queryString>
          </urn:query>
       </soapenv:Body>
    </soapenv:Envelo
    
    You will get response with list of contacts

Generating Security Token for SalesForce.com

If you want to use SalesForce SOAP API then you will need security token. If you dont have the security token SalesForce will generate Soap fault like this

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:sf="urn:fault.enterprise.soap.sforce.com" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <soapenv:Fault>
         <faultcode>sf:LOGIN_MUST_USE_SECURITY_TOKEN</faultcode>
         <faultstring>LOGIN_MUST_USE_SECURITY_TOKEN: Invalid username, password, security token; or user locked out. Are you at a new location? When accessing Salesforce--either via a desktop client or the API--from outside of your company’s trusted networks, you must add a security token to your password to log in. To receive a new security token, log in to salesforce.com at http://login.salesforce.com and click Setup | My Personal Information | Reset Security Token.</faultstring>
         <detail>
            <sf:LoginFault xsi:type="sf:LoginFault">
               <sf:exceptionCode>LOGIN_MUST_USE_SECURITY_TOKEN</sf:exceptionCode>
               <sf:exceptionMessage>Invalid username, password, security token; or user locked out. Are you at a new location? When accessing Salesforce--either via a desktop client or the API--from outside of your company’s trusted networks, you must add a security token to your password to log in. To receive a new security token, log in to salesforce.com at http://login.salesforce.com and click Setup | My Personal Information | Reset Security Token.</sf:exceptionMessage>
            </sf:LoginFault>
         </detail>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>
Follow these steps to generate a security token
  1. Login into your Salesforce account
  2. Click on your use name and you will get drop down like this, click on My Settings sub menu
  3. On the next page you will get submenu on the side click on Personal side menu, once its expanded click on Reset my security token link
  4. Once your on the Reset My Security Token button and it will trigger security token generation process
  5. In few minutes it will send email to your address with security token, use that for the subsequent SOAP calls