Configuring CRISP Addon
Introduction
CRISP configurations are maintained in repository by default in the location at/hippo:configuration/hippo:modules/crispregistry/hippo:moduleconfig.
Since Bloomreach Experience Manager 12.6, the CRISP repository configuration path can be customized by setting crisp.moduleconfig.path property in/WEB-INF/hst-config.properties in the site web applciation like the following example:
# Setting a custom CRISP configuration path.crisp.moduleconfig.path = /crisp/site1/hippo:moduleconfig
where/crisp/site1/hippo:moduleconfig may look like this:
/crisp: jcr:primaryType: nt:unstructured /site1: jcr:primaryType: nt:unstructured /hippo:moduleconfig: jcr:primaryType: crisp:moduleconfig /crisp:resourceresolvercontainer: jcr:primaryType: crisp:resourceresolvercontainer ...
The CRISP configuration can be set like the following for the resource space,demoProductCatalog:
/hippo:moduleconfig: jcr:primaryType: crisp:moduleconfig /crisp:resourceresolvercontainer: jcr:primaryType: crisp:resourceresolvercontainer /demoProductCatalogs: jcr:primaryType: crisp:resourceresolver crisp:beandefinition: <!-- XML Bean definition here for the resource space, 'demoProductCatalogs'. --> crisp:propnames: [commerce.api.base.uri] crisp:propvalues: ['${example.commerce.api.base.uri}'] crisp:sitescopes: []# HST-2 Container Configuration properties file example. e.g, conf/hst.properties# ...example.commerce.api.base.uri = http://localhost:8080/example-commerce/api/v1# ...
If the thecrisp:sitescopes property is not set or set to an empty array, then every application may load the specific ResourceResolver configuration without any filtering.
You can bootstrap configurations into the node, or you can update the configuration there at runtime. Any changes at runtime will be affected right away.
Before going further, let's take a look at how the configuration nodes are structured:
- TheCRISP module configuration node at/hippo:configuration/hippo:modules/crispregistry/hippo:moduleconfig must be of primary node type,crisp:moduleconfig.
- TheCRISP module configuration node has single child node named crisp:resourceresolvercontainer of primary node type,crisp:resourceresolvercontainer, that may contain zero or multiple child node(s) specifying ResourceResolvers, which primary node type iscrisp:resourceresolver, for eachresource space underneath. So, in the example shown above, there is only oneResourceResolver configuration for a resource nameddemoProductCatalogs which is going to be used when invokingResourceServiceBroker APIs.
- AResourceResolver configuration node under/hippo:configuration/hippo:modules/crispregistry/hippo:moduleconfig/crisp:resourceresolvercontainer must be of primary node type,crisp:resourceresolver.
- AResourceResolver configuration node (of primary node type,crisp:resourceresolver) could havecrisp:propnames (string multiple),crisp:propvalues(string multiple) andcrisp:beandefinition (string) properties.
- crisp:propnames (string multiple) andcrisp:propvalues (string multiple) properties define pairs of variable property names, and property values to be first interpolated usingHST-2 Container Configuration, to be interpolated again in thecrisp:beandefinition (string) property value. So, a management UI tool may possibly let administrator edit those pairs of variable properties without having to expose the XML bean definition incrisp:beandefinition (string) property directly.
- crisp:beandefinition (string) property defines Spring Framework Bean definition for aResourceResolver bean in XML format. Find the example bootstrap configurations for details in the demo project.
Adding a ResourceResolver configuration for a new resource space
You can configure aResourceResolver in the repository configuration as explained below.
Since Bloomreach Experience Manager 12.6, you can also configure aResourceResolver directly in a CRISP API Addon's Spring Bean assembly XML file in the delivery tier web application (e.g./site). in which case, theResourceResolver can be accessed only in the same delivery tier web application. TheResourceResolver cannot be accessed from other web application such as/cms if you configure it in a CRISP API Addon's Spring Bean assembly XML file of a delivery tier web application.
Adding a ResourceResolver in repository configuration
By default, there is no ResourceResolver configuration under/hippo:configuration/hippo:modules/crispregistry/hippo:moduleconfig/crisp:resourceresolvercontainer. You can addResourceResolver configuration nodes there for your backend services.
For example, if you want to add a new resource space, 'demoProductCatalogs', then you should add a node by the resource space name, 'demoProductCatalogs' (ie,/hippo:configuration/hippo:modules/crispregistry/hippo:moduleconfig/crisp:resourceresolvercontainer/demoProductCatalogs). And the 'demoProductCatalogs' can look like the following example (in System View XML format):
Bloomreach Experience Manager 16:
<?xml version="1.0" encoding="UTF-8"?><sv:node sv:name="demoProductCatalogs" xmlns:sv="http://www.jcp.org/jcr/sv/1.0"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>crisp:resourceresolver</sv:value> </sv:property> <sv:property sv:name="crisp:beandefinition" sv:type="String"> <sv:value><![CDATA[<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <bean parent="abstractCrispSimpleJacksonRestTemplateResourceResolver" > <property name="cacheEnabled" value="${cache.enabled}" /> <property name="baseUri" value="${commerce.api.base.uri}" /> <property name="restTemplate"> <bean> <property name="requestFactory" ref="org.springframework.http.client.ClientHttpRequestFactory" /> </bean> </property> <property name="resourceLinkResolver"> <bean> <property name="templateSource"> <value>http://www.example.com/products/${(preview == "true")?then("staging", "current")}/sku/${resource.valueMap['SKU']!"unknown"}/overview.html</value> </property> </bean> </property> <property name="resourceDataCache"> <bean> <constructor-arg> <bean 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> </bean> </beans> ]]></sv:value> </sv:property> <sv:property sv:multiple="true" sv:name="crisp:propnames" sv:type="String"> <sv:value>cache.enabled</sv:value> <sv:value>commerce.api.base.uri</sv:value> </sv:property> <sv:property sv:multiple="true" sv:name="crisp:propvalues" sv:type="String"> <sv:value>true<sv:value> <sv:value>http://localhost:8080/example-commerce/api/v1</sv:value> </sv:property></sv:node>Bloomreach Experience Manager 14 & 15:
<?xml version="1.0" encoding="UTF-8"?><sv:node sv:name="demoProductCatalogs" xmlns:sv="http://www.jcp.org/jcr/sv/1.0"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>crisp:resourceresolver</sv:value> </sv:property> <sv:property sv:name="crisp:beandefinition" sv:type="String"> <sv:value><![CDATA[<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <bean parent="abstractCrispSimpleJacksonRestTemplateResourceResolver" > <property name="cacheEnabled" value="${cache.enabled}" /> <property name="baseUri" value="${commerce.api.base.uri}" /> <property name="restTemplate"> <bean> <property name="requestFactory" ref="org.springframework.http.client.ClientHttpRequestFactory" /> </bean> </property> <property name="resourceLinkResolver"> <bean> <property name="templateSource"> <value>http://www.example.com/products/${(preview == "true")?then("staging", "current")}/sku/${resource.valueMap['SKU']!"unknown"}/overview.html</value> </property> </bean> </property> <property name="resourceDataCache"> <bean> <constructor-arg> <bean> <constructor-arg> <bean parent="abstractCrispResourceEhCache"> <property name="cacheName" value="demoProductCatalogsCache" /> <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> </bean> </beans> ]]></sv:value> </sv:property> <sv:property sv:multiple="true" sv:name="crisp:propnames" sv:type="String"> <sv:value>cache.enabled</sv:value> <sv:value>commerce.api.base.uri</sv:value> </sv:property> <sv:property sv:multiple="true" sv:name="crisp:propvalues" sv:type="String"> <sv:value>true<sv:value> <sv:value>http://localhost:8080/example-commerce/api/v1</sv:value> </sv:property></sv:node>The example configuration shown above is going to add aResourceResolver configuration node nameddemoProductCatalogs which is used asresource space name when invokingResourceServiceBroker API.
Adding a ResourceResolver in Spring Bean assembly
Since Bloomreach Experience Manager 12.6, you can configure aResourceResolver bean directly in a CRISP API Addon's Spring Bean XML file instead of doing that in the repository configuration.
To achieve that, define aResourceResolver bean with a unique identifier which is used as aresource spacename.
For example, if you want to define aResourceResolver with aresource space name, "demoProductCatalogs", then you should define a bean with ID, "demoProductCatalogs" like the following in a CRISP API Addon's Spring assembly XML file (e.g,site/components/src/main/resources/META-INF/hst-assembly/addon/crisp/overrides/custom-resource-resolvers.xml):
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <bean parent="abstractCrispSimpleRestTemplateResourceResolver" > <!-- SNIP --> </bean> </beans>
You can define multiple ResourceResolver beans in single Spring assembly XML file as long as each bean has a unique identifier which is used asresource space name.
ResourceResolver Bean Definition
In the example configuration in the previous section, basically theResourceResolver component will be instantiated and registered fordemoProductCatalogsresource space name by thecrisp:beandefinition property configuration in Spring Framework Bean XML configuration.
Note:CRISP Core will create a childApplicationContext from the XML beans configuration in thecrisp:beandefinitionproperty and simply get a bean of type,org.onehippo.cms7.crisp.api.resource.ResourceResolver, to register the bean for theresource space, the name of which is specified by theResourceResolver configuration node name. Therefore, you don't have to set id attribute of theResourceResolver bean definition.
Thecrisp:beandefinition property configuration could be interpolated by the variables set by pairs ofcrisp:propnames andcrisp:propvalues properties, which possibly enables a management UI to be able to give administrator ability to configure those configuration parameters without having to look intocrisp:beandefinition XML bean configuration in detail in most cases.
In the example in the previous section, theResourceResolver component is configured by the bean definition withclass="org.onehippo.cms7.crisp.core.resource.jackson.SimpleJacksonRestTemplateResourceResolver".SimpleJacksonRestTemplateResourceResolver is aResourceResolver implementation that handles any JSON-based REST APIs in a generic way. Also, please note that theResourceResolver bean hasparent="abstractCrispSimpleJacksonRestTemplateResourceResolver", which means the bean definition inherits all the common features provided byCRISP module library by the "parent" bean definition. If possible, it is a good practice to inherits anabstract bean definitions ofCRISP module library to inherit all the goodness provided by theCRISP library wherever possible. For your information, the followingabstract bean definitions forResourceResolver components are defined by default.
<!-- SNIP --> <!-- Basic HTTP Client Enabled Abstract Base Bean Definition --><bean abstract="true"> <property name="clientHttpRequestFactory" ref="org.springframework.http.client.ClientHttpRequestFactory" /></bean> <!-- SNIP --> <!-- Basic JSON Supporting (Jackson Library based) HTTP Client Enabled Abstract Base Bean Definition --><bean abstract="true" parent="abstractCrispHttpRequestResourceResolver"> <property name="cacheEnabled" value="true" /></bean> <!-- SNIP -->
Configuring Http Connection Pool
CRISP API provides the default HTTP connection pool with 600 maximum connections in total and 200 maximum connections per route, which should be good enough in most use cases.
If you want to change this default configuration, add an XML file in site/components/src/main/resources/META-INF/hst-assembly/addon/crisp/overrides/ folder (e.g, custom-crisp-http-client.xml) like the following example:
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- Customizing the default CRISP HttpClientBuilderFactoryBean with custom settings. --> <bean> <property name="useSystemProperties" value="true" /> <property name="maxConnTotal" value="400" /> <property name="maxConnPerRoute" value="200" /> <property name="connectionTimeMillisToLive" value="3600000" /> </bean></beans>
Below are details on each property:
| Property | Description | Default Value |
|---|---|---|
| useSystemProperties | If this is set totrue, it becomes equivalent to calling onHttpClientBuilder.useSystemProperties(), which allows passing system properties when initializing anHttpClient. See its JavaDoc for details. | true |
| maxConnTotal | The maximum HTTP connections in total. | 600 |
| maxConnPerRoute | The maximum HTTP connections per route. | 200 |
| connectionTimeMillisToLive | The time to live milliseconds for each HTTP connection. By default, it is set to -1. If this value is not a positive number, then it means that HTTP connections will never expire. | -1 |