Example with Salesforce REST API
Overview
This page provides an example configuration for integrating the Salesforce REST API as a backend using a ResourceResolver bean. The configuration demonstrates how to set connection details, configure the RestTemplate object, enable OAuth2 authentication, define the ResourceLinkResolver, and control caching.
You can apply this ResourceResolver Spring bean configuration at the following repository path for a resource space named demoSalesForce:
/hippo:configuration/hippo:modules/crispregistry/hippo:moduleconfig/crisp:resourceresolvercontainer/demoSalesForce/@crisp:beandefinition
ResourceResolver Configuration
brXM 16
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://www.springframework.org/schema/security" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <bean parent="abstractCrispSimpleJacksonRestTemplateResourceResolver" class="org.onehippo.cms7.crisp.core.resource.jackson.SimpleJacksonRestTemplateResourceResolver"> <property name="cacheEnabled" value="${cache.enabled}" /> <property name="baseUri" value="${salesforce.baseUrl}/services/data/v20.0" /> <property name="resourceDataCache"> <bean class="org.onehippo.cms7.crisp.core.resource.SpringResourceDataCache"> <constructor-arg> <bean class="org.springframework.cache.caffeine.CaffeineCache" factory-bean="caffeineCacheInstanceFactory" factory-method="createSpringCacheInstance"> <constructor-arg value="demomarketoCache" /> <constructor-arg value="initialCapacity=10,maximumSize=1000,expireAfterWrite=100s,expireAfterAccess=100s" /> </bean> </constructor-arg> </bean> </property> <property name="clientHttpRequestInterceptor"> <list value-type="org.springframework.http.client.ClientHttpRequestInterceptor"> <bean class="org.onehippo.cms7.crisp.core.interceptor.SimpleOAuth2AuthorizedClientInterceptor" autowire="constructor"> <property name="authorizedClientService" ref="authorizedClientService" /> <property name="clientRegistrationId" value="salesforce-login" /> <property name="contextAttributesMap" ref="credentials" /> </bean> </list> </property> </bean> <util:map id="credentials" map-class="java.util.HashMap"> <entry key="org.springframework.security.oauth2.client.OAuth2AuthorizationContext.USERNAME"> <value>${salesforce.username}</value> </entry> <entry key="org.springframework.security.oauth2.client.OAuth2AuthorizationContext.PASSWORD"> <value>${salesforce.password}</value> </entry> </util:map> <s:client-registrations> <s:client-registration registration-id="salesforce-login" client-id="${salesforce.clientId}" client-secret="${salesforce.clientSecret}" client-authentication-method="post" authorization-grant-type="password" provider-id="salesforce"/> <s:provider provider-id="salesforce" authorization-uri="${salesforce.baseUrl}/services/oauth2/token" token-uri="${salesforce.baseUrl}/services/oauth2/token"/> </s:client-registrations> <bean id="authorizedClientService" class="org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService" autowire="constructor"/> <bean id="authorizedClientRepository" class="org.springframework.security.oauth2.client.web.AuthenticatedPrincipalOAuth2AuthorizedClientRepository"> <constructor-arg ref="authorizedClientService"/> </bean> </beans>
brXM 14 & 15
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://www.springframework.org/schema/security" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <bean parent="abstractCrispSimpleJacksonRestTemplateResourceResolver" class="org.onehippo.cms7.crisp.core.resource.jackson.SimpleJacksonRestTemplateResourceResolver"> <property name="cacheEnabled" value="${cache.enabled}" /> <property name="baseUri" value="${salesforce.baseUrl}/services/data/v20.0" /> <property name="resourceDataCache"> <bean class="org.onehippo.cms7.crisp.core.resource.SpringResourceDataCache"> <constructor-arg> <bean class="org.springframework.cache.ehcache.EhCacheCache"> <constructor-arg> <bean parent="abstractCrispResourceEhCache"> <property name="cacheName" value="demoSalesForceCache" /> <property name="maxEntriesLocalHeap" value="1000" /> <property name="maxEntriesLocalDisk" value="0" /> <property name="timeToLiveSeconds" value="60" /> <property name="timeToIdleSeconds" value="60" /> </bean> </constructor-arg> </bean> </constructor-arg> </bean> </property> <property name="clientHttpRequestInterceptor"> <list value-type="org.springframework.http.client.ClientHttpRequestInterceptor"> <bean class="org.onehippo.cms7.crisp.core.interceptor.SimpleOAuth2AuthorizedClientInterceptor" autowire="constructor"> <property name="authorizedClientService" ref="authorizedClientService" /> <property name="clientRegistrationId" value="salesforce-login" /> <property name="contextAttributesMap" ref="credentials" /> </bean> </list> </property> </bean> <util:map id="credentials" map-class="java.util.HashMap"> <entry key="org.springframework.security.oauth2.client.OAuth2AuthorizationContext.USERNAME"> <value>${salesforce.username}</value> </entry> <entry key="org.springframework.security.oauth2.client.OAuth2AuthorizationContext.PASSWORD"> <value>${salesforce.password}</value> </entry> </util:map> <s:client-registrations> <s:client-registration registration-id="salesforce-login" client-id="${salesforce.clientId}" client-secret="${salesforce.clientSecret}" client-authentication-method="post" authorization-grant-type="password" provider-id="salesforce"/> <s:provider provider-id="salesforce" authorization-uri="${salesforce.baseUrl}/services/oauth2/token" token-uri="${salesforce.baseUrl}/services/oauth2/token"/> </s:client-registrations> <bean id="authorizedClientService" class="org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService" autowire="constructor"/> <bean id="authorizedClientRepository" class="org.springframework.security.oauth2.client.web.AuthenticatedPrincipalOAuth2AuthorizedClientRepository"> <constructor-arg ref="authorizedClientService"/> </bean> </beans>
Configuration Properties
Define the following properties at the /hippo:configuration/hippo:modules/crispregistry/hippo:moduleconfig/crisp:resourceresolvercontainer/demoSalesForce node using the crisp:propnames and crisp:propvalues properties for the demoSalesForce resource space.
| Property Name | Example Value |
|---|---|
| cache.enabled | true |
| salesforce.clientId | someClientId |
| salesforce.clientSecret | someClientSecret |
| salesforce.username | [email protected] |
| salesforce.password | somePassword |
| salesforce.securityToken | someSecurityToken |
| salesforce.baseUrl | https://na1.salesforce.com |
cacheEnabled: Enables or disables caching at theResourceResolverlevel.baseUri: Sets the base URI for the Salesforce REST API backend. TheResourceServiceBrokeruses this as the base for relative resource paths when invoking the backend API.resourceDataCache: Specifies aResourceDataCacheinstance for thisResourceResolver. If set and the resource is cacheable, theResourceServiceBrokercaches resource data in the defined cache. If not set, cacheable resources use a globally shared cache by default.clientHttpRequestInterceptor: Configures theSimpleOAuth2AuthorizedClientInterceptorfor OAuth2 authentication. Salesforce REST API requires OAuth2, so you must register an OAuth2 client in theOAuth2AuthorizedClientRepositorywith the necessary credentials.
Note: The spring-security-oauth2 project is deprecated. Related libraries will be removed in future versions.
Example: SimpleOAuth2AuthorizedClientInterceptor Implementation
Below is an example implementation of the SimpleOAuth2AuthorizedClientInterceptor class. This interceptor manages OAuth2 authentication for requests to the Salesforce REST API.
package org.onehippo.cms7.crisp.core.interceptor; import ... public class SimpleOAuth2AuthorizedClientInterceptor implements ClientHttpRequestInterceptor { private ClientRegistrationRepository clientRegistrationRepository; private OAuth2AuthorizedClientService authorizedClientService; private AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager; private String clientRegistrationId; private Authentication principal; private Map<String, Object> contextAttributesMap; public SimpleOAuth2AuthorizedClientInterceptor(ClientRegistrationRepository clientRegistrationRepository) { Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); this.clientRegistrationRepository = clientRegistrationRepository; } public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { if (this.authorizedClientManager == null) { final OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder() .clientCredentials() .refreshToken() .password() .authorizationCode() .build(); this.authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(this.clientRegistrationRepository, this.authorizedClientService); this.authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); this.authorizedClientManager.setContextAttributesMapper(oAuth2AuthorizeRequest -> contextAttributesMap); } final OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest .withClientRegistrationId(this.clientRegistrationId) .principal(getPrincipal()) .build(); final OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(oAuth2AuthorizeRequest); final HttpHeaders headers = request.getHeaders(); headers.setBearerAuth(authorizedClient.getAccessToken().getTokenValue()); return execution.execute(request, body); } ... }
Summary
This example demonstrates how to configure a ResourceResolver for integrating the Salesforce REST API using OAuth2 authentication and caching in Bloomreach Content. Adjust the configuration and property values as needed for your environment.
For more information about CRISP API configuration and advanced scenarios, refer to the CRISP API documentation.