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
Full Access(full)
Perform request on your behalf at any time (refresh_token)
Once i set up the oAUth settings properly the sample started working
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
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
Now create a Java Project and add both enterprise.jar and force-wsc-29.0.0-jar-with-dependencies.jar in your classpath
Last step is to create SFDClient.java class like this
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
First thing that you would want to do is generate security token for salesforce. Follow these steps for generating security token
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
Now create new SOAP Ui project using the Enterprise WSDL you just downloaded
You will notice that it generates bunch of SOAP operations
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
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
You will need the value of sessionId element and value of serverUrl in subsequent requests. so note it down
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
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
Login into your Salesforce account
Click on your use name and you will get drop down like this, click on My Settings sub menu
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
Once your on the Reset My Security Token button and it will trigger security token generation process
In few minutes it will send email to your address with security token, use that for the subsequent SOAP calls
Recently i was using Jackson JSON Processor for converting java object into JSON. When i did that i noticed JackSon was storing date in the long format i.e. it was converting date.getTime() and using that long value in JSON instead of formatted date. This is how my Contact object looks like
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Note: please ignore line 32 @JsonSerialize(using = CustomDateSerializer.class) for now. I had following code to create object of Contact and converting and then using Jackson to convert it to String and write it on console
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Now i wanted to customize how the date so that it got generated in dd-MMM-yyyy format. In order to do that i started by creating CustomDateSerializer class like this
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Then i had to change the Contact.java class to add @JsonSerialize(using = CustomDateSerializer.class) annotation to getDateOfBirth() field, i could attach it to any other date field that i want. Now when i run JSONTester this the output that it generates
For last few days i am playing around with Mule, its really cool integration framework. You can use it to build integration applications by using small amount of code. I had this requirement where given address i wanted to get the Geo Coding information for that address, I wanted to use Google Maps API for getting GeoCode information for the address.
The way Google Maps API works is it has a REST API, it takes address as query string and it returns JSON structure. Ex. If you copy paste this URL in the browser
http://maps.googleapis.com/maps/api/geocode/json?address=3055 Oak Road,Walnut Creek,CA,94597&sensor=false
You will get a JSON structure with longitude and latitude embedded in lot of other information
Out of all the data returned by Google MAPS api i am only interested in the Lat and Long and i want to return it in GeoJSON format like this
[
-122.0582466,
37.9302299
]
Which is [lng,lat] format, some open source JavaScript Mapping frameworks understand the GeoJSON format.
I built a simple Mule integration application which takes STREETLINE1, CITY, STATE, ZIPCODE as argument and returns geo location in GeoJSON format like this [lng,lat]. I followed these steps to build the application
First i built a Mule Flow which looks like this
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In this flow i have a composite input source that could take input on either VM transport or HTTP transport and then uses the values submitted by user to make a request to Google Maps API. Once the response is returned it uses DataMapper to convert the big response that Google Maps API returns into simple GeoJSON response.
This is how the Data Mapping file looks like
If you look at the script of this file it looks like this
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters