Previous Next

Technical Blog

November 2008

       

The search server web application is responsible for providing searching and browsing functionality for both the storefront and the Commerce Manager (CM) client. At its heart is the Solr search engine, which sits on top of the Lucene indexes. If you wanted to leverage Solr's powerful search capabilities, you could use the Solr search APIs. However, these APIs require extensive knowledge of Solr syntax. Another option might be to use JPQL, which is basically an object oriented SQL. But this requires some JPQL specific knowledge to be able to retrieve data from the database.

 

In Elastic Path 6.1, a new set of APIs were created to allow developers to create complex, platform-independent search queries using a familiar syntax, but with the added benefits of an ecommerce domain-specific language.  The new Elastic Path Query Language (EPQL) gives us the ability to be technology independent and makes the system more flexible.

 

The advanced search feature was introduced in Elastic Path Commerce 6.1, with the ability to handle products, categories, and catalogs initially. Its architecture, however, is extensible, and in the future, it will support searching for other types of domain objects, such as price lists, orders, and customers.  The advanced search functionality is currently available within the CM client and the import-export tool. The CM client integration supports only products at this time, while the import-export tool can use advanced search for looking up sets of products, categories, and catalogs.

 

Advanced search is provided as a library that can be used into any application or a standalone program.

 

The syntax of the Elastic Path Query Language (EPQL) resembles the SQL language. A simple query consists of a single expression. An expression has the following form:

 

FIND Product WHERE <field> <operator> <value>

where

  • <field> is the field you are searching. For example, if you want to look for products of a specific brand, you would include the BrandCode field in your query. The supported fields are described in Supported fields further in this article.
  • <operator> is the operator you are using to perform the comparison.
  • <value> is the literal value you want to compare to the field value.

For example, the following query matches the product whose code is 10030205

 

FIND Product WHERE ProductCode =   '10030205'

 

In addition to searching for field values, you can also search for attribute values. To search for a value in an attribute, the expression has the following form:

 

Attribute{<attribute_name>} <operator> <value>

where <attribute_name> is the name of a product attribute or product SKU attribute.

 

For example, the following query matches all products that have the Header / Model attribute set to MX:

 

FIND Product WHERE Attribute{Header /   Model} = 'MX'

 

Here is a more complicated query that finds all Nike and Adidas products that cost less than $200 USD and belong to catalog A:

 

FIND Product WHERE Catalog = 'A'   AND Price{A}[USD] < 200

AND (BrandName [en] = 'Nike' OR BrandName   [en] = 'Adidas')


You can run queries immediately using the CM client's UI. This is convenient for testing, but it doesn't allow you to schedule actions on the query results. Let's say you want to perform a daily action on products that match the criteria in the previous example. To do that, you would need to create a class that retrieves the products using EPQL and sends that information to a third party system for processing.

 

To use the EPQL search APIs, you need to add com.elasticpath.core.jar and com.elasticpath.ql.jar file to your project's classpath.

 

Next, add the required Spring bean definitions. Create a file named serviceEPQL.xml in the project's conf/spring/service folder and add a reference to it from the Spring application-context.xml. For an example, take a look at the com.elasticpath.cmclient.core RCP plugin or the import/export tool.

 

Create a Java class that will be used to retrieve the products using EPQL. The following code shows how to execute an EPQL query:

 

public boolean doDailyTask() {

// get a search engine instance

EpQLSearchEngine searchEngine =

       getElasticPath().getBean("epQLSearchEngine");

// create a query

String searchString = "FIND Product   WHERE Catalog = 'A' " +

       "AND Price{A}[USD] < 200   AND (BrandName [en] = 'Nike' " +

       "OR BrandName [en] =   'Adidas')";

// get a parser and use it to validate the query

EPQueryParser parser = searchEngine.getEpQueryParser();

try {

   parser.verify(query);

}

catch (EpQLParseException   exception){

   LOG.warn(exception);

return false;

}

// if the query is okay, execute it and   get the results

SolrIndexSearchResult result =   searchEngine.search(searchString);

List<Long> productUids =   result.getSearchResults();

// ... Do some processing on the results

return true;

}

 

The EpQLSearchEngine class has a search method that executes a query and returns the results. Before executing a query, you should make sure that it is syntactically valid.

 

The EPQLQueryParser class provides a verify method that takes a query string as an argument. If there's an error in the query, it throws an exception, including a detailed description to help you fix the problem.  The search result set contains the list of UIDs of the objects that matched the query.

0 Comments 0 References Permalink

       

The search index rebuild process has undergone some substantial changes in Elastic Path 6.1, making it more robust and more usable.

 

In the past, to trigger a search index rebuild, you needed to manually modify the contents of some properties files on the search server. This is no longer supported. Now, Commerce Manager users with the proper permissions can initiate search index rebuilds.

 

In the Activity menu, choose Configuration. In the Configuration page on the left, under System Administration, click Search Indexes.

 

Select an index in the list, and click Rebuild Index. The rebuild should now be scheduled and the status column will show Rebuild is Scheduled.

When the index rebuild begins, the status column for the index being rebuilt will contain Rebuild in Progress. Note that you can rebuild multiple indexes at the same time. When the rebuild is done, the status is changed to Complete.


When the user runs an index rebuild from the Commerce Manager client, this is what happens behind the scenes:

 

  1. The TINDEXNOTIFY table in the database contains a row for each search index. When the user clicks Rebuild Index, the UPDATE_TYPE column for that search index's row is set to REBUILD.
  2. The quartz.xml in com.elasticpath.search/WEB-INF/conf/spring/scheduling defines several Quartz jobs that check to see if the search indexes need to be rebuilt. Each time one of these scheduled jobs is triggered, it calls the method buildIndexJobRunner method in the AbstractIndexService and passes it a search index identifier. This method checks the TINDEXNOTIFY database table to see if the corresponding index needs to be rebuilt (if the value is REBUILD), has never been built, or if a previous rebuild was interrupted and did not complete successfully. If any of those conditions are true, a rebuild of that index is initiated.
  3. When an index rebuild is initiated, the INDEX_STATUS column in the TINDEXBUILDSTATUS table is set to REBUILD_IN_PROGRESS.
  4. After the index has finished rebuilding, the INDEX_STATUS column is set to COMPLETE.

 

You can monitor the status of rebuild process by checking the Status column in the search index list.

 

Finally, search index rebuilds are now more resilient to failures. If an index build is interrupted or fails to complete normally, the system will try to build it again on server startup or at the start of the next quartz job. If there is a rebuild in progress for an index and another rebuild for that index is requested by the user, the system will wait until the first rebuild is complete before processing the second request.

0 Comments 0 References Permalink

     

Elastic Path Commerce 6.1 introduces a number of changes from version 6.0.x. Primary among these are a major change to the store asset directory structure; movement of store configuration information from the file system to the database; and a number of minor changes to the existing database tables. As a result, 6.0.4 deployments with existing data can be upgraded to the 6.1 codebase with relocation of store assets; migration of configuration files into the database; and database upgrade scripts.

 

Note that it's assumed that the codebase has already been upgraded to 6.1; it's up to you to decide how code merge is done. It's also assumed that the existing deployment was already at the latest service release (6.0.4) before upgrading to 6.1.


Store Assets Relocation

Along with the XML configuration files, store-specific visual presentation elements used in the Storefront and emails have been moved from the WAR files into a central assets directory.  These include all Velocity templates, message properties files, images, javascript, css and Power Reviews.

 

  • The simplest way to move storefront assets out of the WAR file is to copy the directories com.elasticpath.sf/template-resources and com.elasticpath.sf/WEB-INF/templates to the new assets directory under a theme folder of your choosing. The assets directory will have the structure:

 

assets/themes/<theme_name>/<store_code>/templates

assets/themes/<theme_name>/<store_code>/template-resources

 

  • Email templates previously located in com.elasticpath.cm/WEB-INF/templates also need to be moved to the assets folder. Email templates and property files that are not connected to any particular store will need to be moved to: assets/cmassets/templates/velocity

 

  • Storefront related emails will be located under their respective theme folders: assets/themes/<theme_name>/<store_code>/templates/velocity

Configuration File Migration

Much of the configuration data previously in XML files within Elastic Path WAR directories has been moved into the database to be managed through the Settings framework in the CM. This includes commerce-config.xml, search-config.xml, urlrewrite.xml, intelligent-browsing.xml. Please consult the settings framework documentation before migrating configuration settings.

 

  • With the exception of web.sf.context.url, all settings previously in commerce-config.xml have been moved to the Settings framework and are no longer required to be in the XML file. Values in these settings (e.g. VFS paths/login) should be updated in the Settings framework through the CM Settings configuration view as new Setting values or inserted into tables TSETTINGVALUE where appropriate. Additional custom settings in commerce-config.xml file should be moved to the Settings framework as new Setting definitions in TSETTINGDEFINITION. A table of where settings in the commerce-config.xml reside in the settings framework is provided in Appendix A.

 

  • Content in intelligent-browsing.xml has been moved to the Settings framework and the file is no longer needed. Its contents should be inserted as a new Setting Value for the setting COMMERCE/STORE/FILTEREDNAVIGATION/filteredNavigationConfiguration

 

The content can also be copied into the CM Store Editor's Filtered Navigation section.

 

  • Content in urlrewrite.xml has been moved to the Settings framework and the file is no longer needed. Its contents should be inserted as a new Setting Value for the setting COMMERCE/SYSTEM/urlRewriteConfig

 

  • Content in search-config.xml has been moved to the Settings framework and the file is no longer needed. If any customization has been made, the Setting values under the paths COMMERCE/SEARCH/<setting> should be updated appropriately.

Database Upgrade

Upgrade SQL scripts are provided along with each release of Elastic Path to capture changes in the database schema between the new release and the latest service release.

Each supported database (MySQL, SQL Server, Oracle) will have its own upgrade script.

 

  • Upgrade scripts are provided in the 6.1 distribution for each database, and should be run by the tools provided by the database vendor.
  • Upgrade scripts will apply schema changes and insert necessary base data on an existing 6.0.x database, but does not change existing data.

 

After running the upgrade script, the steps can be done through the CM or directly through the database to get your deployment up and running:

 

  • Reassign supported currency and supported locales to existing stores in the CM, or insert entries in the TSTORESUPPORTEDCURRENCY and TSTORESUPPORTEDLOCALE respectively.
  • Change the display theme of existing stores appropriately by editing the COMMERCE/STORE/theme setting in either the System Configuration section of the CM or the Store Editor.
  • Set the correct value for the search server in the settings framework, under the path COMMERCE/SERVER/SEARCH/searchHost
  • Search indexes need to be rebuilt. This is an automatic step if old indexes are deleted.
  • Set the correct values for the asset VFS in the settings framework under COMMERCE/APPSPECIFIC/RCP/ASSETS/<setting>
  • Gift certificate themes need to be recreated through the CM, and assigned to stores in the CM Store Editor.
  • Be aware that stores can now only be accessed through the URL defined in the CM Store Editor (TSTORE table in the databse), and care should be taken when testing.

Caveats

  • The upgrade process cannot cover all possible database and code customizations to the 6.0.x codebase, and upgrade scripts should be reviewed before running on any schemas that you have customized.
  • Before moving existing storefront assets, be aware that there are changes in these files (Velocity templates, property files) that might not be picked up through a normal code merge due to the change in location.
  • New configuration settings introduced in 6.1 take on their default values after an upgrade, and should be reviewed for correctness.

 

Upgrading to 6.1 from 6.0.4 requires little database change. Configuration files and asset migration make up the bulk of the upgrading effort, and existing customizations to configuration and assets should be reviewed to take advantage of the new settings framework and asset repository.

0 Comments 0 References Permalink

In Elastic Path 6.1, we updated some of our library dependencies to more recent versions. This article outlines the changes, how they impact the application in terms of performance and behaviour, and how they might impact any custom Elastic Path development work you might be doing.

 

  • JUnit has been upgraded from version 3.8.1 to 4.4. Version 4.4 of the JUnit testing framework provides more powerful unit testing features, leveraging Java annotations. The upgrade is fully backwards compatible with tests written against older versions of JUnit. For more information on JUnit 4, go to http://junit.org/.
  • jMock has been upgraded from version 1.1 to 2.5. jMock 2.5 provides better management and creation of mock objects, but is not fully compatible with version 1.1, so both versions still exist as dependencies in Elastic Path 6.1. For more information on jMock 2.5, go to http://www.jmock.org/.
  • For an example of a test class in that uses the features of JUnit 4 together with jMock 2, see com.elasticpath.service.impl.GiftCertificateThemeServiceImplTest in the com.elasticpath.core product.#
  • The Spring framework was upgraded from 2.0.4 to 2.5.5. This upgrade brings improved performance, ease of configuration, and new features. For more information on the changes, see the Spring framework site (http://static.springframework.org/spring/docs/2.5.x/reference/new-in-2.html).  This upgrade is backwards compatible with previous versions of the Spring framework and customizations should not be affected.
  • Url Rewrite Filter was upgraded from 2.5.2 to 3.1. The newer version includes support for wildcard matching, mod_rewrite style configuration, and others new features.  This upgrade is backwards compatible with previous versions and customizations should not be affected. The complete changelog can be found at the Url Rewrite Filter site:http://urlrewritefilter.googlecode.com/svn/trunk/src/doc/manual/3.1/introduction.html#changelog
0 Comments 0 References Permalink

      

Introduction

Asset management has changed significantly in EP 6.1 to make deployment of multiple stores easier. With EP 6.1, multiple stores may be run in a single WAR file, hence there is no need to copy WAR instances to deploy a new store. Asset types, which include images, CSS, JavaScript, email templates, storefront velocity templates, VM_global_libraries and Message Resource property files, have been moved out of the WAR deployment location and into a new directory elsewhere on the file system. The previous structure of the assets directory has also changed.

 

The assets root directory structure is as follows:

 

- assets

+ cmassets

+ digitalassets

+ images

+ import

+ storeassets

+ themes

 

The absolute path for assets is specified in your deployment's COMMERCE/SYSTEM/ASSETS/assetLocation setting. EP6.1 also introduces the "Settings Framework," a new component that contains system and store configuration settings that used to be captured in commerce-config.xml and other files. The COMMERCE/SYSTEM/ASSETS/assetLocation setting value must be configured before you start your storefront application to point at your assets root directory, for example c:\assets or /opt/assets.

 

  • The cmassets directory is also new in EP 6.1 and contains the Commerce Manager specific files, such as user account email templates and the import report email template.
  • The digitalassets directory has been around for several releases and still contains the downloadable digital product files.
  • The images directory is also not new and contains your product display images.
  • The import directory was introduced in EP 6.0 and contains all import CSV files used by the Commerce Manager. Please note that these files are not used by the Import/Export tool, which is a separate component.
  • The storeassets directory is new in EP 6.1 and only contains the PowerReviews required by each store. This directory is specific to each store, but does not form part of a theme.
  • The themes directory is new and serves as the root directory for all themes used by your stores. Themes are used to define the look and feel of stores in EP. You can create multiple themes and associate these with one or more stores. You can also customize theme elements (images, CSS, JavaScript) for individual stores without affecting other stores that use the same theme.

 

 

A theme consists of a set of Velocity templates and resources required to display a storefront (stylesheets, images, properties files, etc.). Each theme is stored in its own directory under the assets/themes directory:

 

- assets

+ cmassets

+ digitalassets

+ images

+ import

+ storeassets

- themes

  + electronics

  + mytheme1

  + mytheme2

  + ...

 

Each theme must contain a default directory. This directory contains the templates and the template-resources directories. The templates directory contains the Velocity templates used by the Velocity Engine to render HTML pages. The template-resources directory contains the stylesheets, Javascript and image files referred to by the rendered HTML pages.

 

- assets

+ cmassets

+ digitalassets

+ images

+ import

+ storeassets

- themes

  - electronics

    - default

      - template-resources

        + images

        + js

        + stylesheet

      - templates

        - velocity

          + index.vm

Within these directories, you can use any directory structure you want to organize files, but keep in mind the file-based fallback mechanism used within themes.

 

 

Themes can be customized to suit the needs of individual stores. To customize a theme for a specific store, create a directory under the theme and set the directory name to the store code. For example, to customize mytheme1 for the SNAPITUP store, create a directory named SNAPITUP under mytheme1. The directory structure should look similar to the following:

 

- assets

+ themes

- mytheme1

  + default

  + SNAPITUP

 

In the store-specific directory, only create copies of the files that you want to customize. The copies must exist in the same relative directory structure within the store-specific directory. For example, to customize the mytheme1/default/template-resources/images/image-not-available.png image for the SNAPITUP store, place the custom version of image-not-available.png in mytheme1/SNAPITUP/template-resources/images.

 

- assets

- themes

  - mytheme1

    - default

      - template-resources

        - images

          + image-not-available.png (default image)

          + ... all other shared images

    - SNAPITUP

      - template-resources

        - images

          + image-not-available.png (store overriding image)

 

It is not necessary to copy the entire contents of the default directory into the store-specific directory. You only need to include copies of the files that you are customizing. The application looks for files in the store-specific directory first; if it does not find a file in the store-specific directory, it then looks for it in the default directory. In other words, your customized copy of the file or image acts as an override for the default file or image. This file-based overriding mechanism is used for images, stylesheet, JavaScript and Velocity template files.  Access to these resources is handled by resource controllers, which in turn use resource retrieval strategies for greater flexibility.

 

WEB-INF/conf/spring/web/url-mapping.xml

<bean id="SimpleUrlHandlerMapping"

    class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

  <property name="mappings">

      <props>

      <prop key="/images/**/*">storeThemeAssetResourceController</prop>

      <prop key="/stylesheet/**/*">storeThemeAssetResourceController</prop>

      <prop key="/js/**/*">storeThemeAssetResourceController</prop>

      </props>

  </property>

</bean>

<!-- Resource controllers for resource retrieval -->

<bean id="storeThemeAssetResourceController"

    class="com.elasticpath.sfweb.controller.impl.AssetResourceControllerImpl"

    parent="abstractEpController">

  <property name="resourceRetrievalStrategy"

            ref="storeThemeAssetRetrievalStrategy"/>

</bean>

Message Sources use a property based overriding mechanism, as opposed to the file based overriding for other types of assets like images. Message Sources are a collection of property files, which associate message keys to message text in different languages. Take, for example, the globals.firstname property key that's located in 2 files, one referencing the English message and the other the French message.

- assets

- themes

  - mytheme1

    - default

      - templates

        + globals.properties  : globals.firstname=First Name

        + globals_fr.properties: globals.firstname=Prenom

 

To override the French globals.firstname message for the SNAPITUPUK store, one need only override one property, not the entire property file. In this case the global_fr.properties file need only contain a single property entry for globals.firstname.

 

- assets

- themes

  - mytheme1

    - default

    - templates

        + globals_fr.properties: globals.firstname=Prenom (default)

    - SNAPITUP

      - templates

        + globals_fr.properties: globals.firstname=Prénom (overriding)

 

In fact, the file name need not even start with "globals" as all properties are loaded into a collection at which point file names are no longer relevant. The only requirement is that it contain the language code. For example, having the globals.firstname property override in a file named no-name-in-particular_fr.properties, will have the same effect. If no language code is present, English is assumed.  For reference, see the Message Source configuration in the Storefront and Commerce Manager web applications.

 

WEB-INF/conf/spring/views/velocity/velocity.xml

<bean id="messageSource"

    class="com.elasticpath.commons.util.impl.StoreThemeMessageSource" >

  <property name="messageSourceCache">

      <ref bean="messageSourceCache"/>

  </property>

  <property name="storeConfig">

      <ref bean="threadLocalStorage"/>

  </property>

  <property name="globalMessageSource">

      <ref bean="globalMessageSource"/>

  </property>

  <!-- True if you want missing messages to show up

        as just the key used to look for them. e.g. user.firstname.

        False will allow exception to be thrown, and stop template render.

  -->

  <property name="useCodeAsDefaultMessage">

      <value>true</value>

  </property>

</bean>

 


Using Store Editor

 

You can select the theme using the new store editor:

1.  In Commerce Manager, choose *Activity*->*Configuration*.

2.  Under *Stores*, click *Stores*.

3.  Select the store, then click *Edit Store*.

4.  Click the *Theme* tab.

5.  In the _Theme_ box, enter the name of the theme folder. For example, if the theme folder is C:/Program Files/Apache Software Foundation/apache-tomcat-5.5.26/assets/themes/mytheme1, enter mytheme1.

6.  In the Commerce Manager toolbar, click *Save*.


Using Advanced Setting Configuration

 

By default, the demo store is mapped to the electronics theme. To change the theme of a store:

 

1.  In Commerce Manager, choose Activity -> Configuration.

2.  Under System Administration, click System Configuration.

3.  In the Property Name list, select COMMERCE/STORE/theme.

4.  Click New (next to the Defined Values list).

5.  Set the values as follows:

·        Context: The store code. For example, for the SnapItUp demo store, the store code is SNAPITUP.

·        Value: The name of the theme folder. For example, if the theme folder is C:/Program Files/Apache Software Foundation/apache-tomcat-5.5.26/assets/themes/mytheme1, enter mytheme1.

6.  Click Save.

 

 

During the development of EP 6.1 it was clear that we had to find a way to make the Velocity engine's VM_global_library store specific since stores do not always share the same library macros.  In EP 6.0, Spring instantiated a VelocityEngine bean directly to inject into the onePageHelper bean, as OnePageHelperImpl requires a Velocity engine for some functionality. This bean is also injected into the velocityConfig bean which is what the VelocityView class uses to get the Velocity engine (it is effectively a factory). The VelocityView class retrieves the Velocity engine once, but we want it to get the appropriate store engine each time the view is asked to render a template.

 

Among other smaller changes, the following classes needed to be added in EP 6.1 to correct the Velocity Engine behavior.

 

<bean id="viewResolver"

class="com.elasticpath.sfweb.view.velocity.StoreVelocityViewResolver">

  <property name="viewClass">

<value>com.elasticpath.sfweb.view.velocity.StoreVelocityViewImpl</value>

  </property>

  <property name="velocityConfigurer" ref="velocityConfigurer"/>

  ...

</bean>

<bean id="velocityConfigurer"

    class="com.elasticpath.sfweb.view.velocity.StoreVelocityConfigurer">

  <property name="storeConfig" ref="threadLocalStorage"/>

  <property name="velocityPropertiesMap" ref="velocityPropertiesMap"/>

</bean>

 

StoreVelocityConfigurer

 

This is a subclass of VelocityConfigurer which keeps a Map of velocity engines keyed by store code. This class just overrides the getVelocityEngine() method and uses an injected store config to retrieve the appropriate VelocityEngine instance from the map. It will call createVelocityEngine() if there is no value for the store currently in the map.

 

StoreVelocityViewResolver

 

This is a subclass of VelocityViewResolver which is store aware. It has setters for a StoreConfig and VelocityConfigurer which will typically be injected by Spring. This class overrides the buildView method and passes the store config and velocity configurer through to the StoreVelocityViewImpl class so it can render the store-specific view.  The old "global" WEB-INF/VM_global_library.vm library has been removed. You now have a VM_global_library in the templates/velocity directory of a theme or store-specific theme override. This will fall back exactly like the other assets.

 

- assets

- themes

  - mytheme1

    - default

      - templates

        - velocity

          + VM_global_library.vm (default fall-back)

    - SNAPITUP

      - templates

        - velocity

            + VM_global_library.vm (store specific override)

 

Store Specific Report Templates

 

Report Design files (*.rptdesign) are typically bundled as part of the Commerce Manager plugin. Packing Slip reports are store specific though, and had to be moved out of the plugin and uses the theme to take advantage of the file-based overriding mechanism.

 

- assets

- themes

  - mytheme1

    - default

      - templates

        - printartifacts

          + packing_slip.rptdesign (default report design)

    - SNAPITUP

      - templates

        - printartifacts

            + packing_slip.rptdesign (store specific override)

 

 

The com.elasticpath.cmweb.controller.impl.CacheInvalidationControllerImpl defined in the CM Server is useful to invalidate caches of various types based on an invalidation strategy. The default configuration, as displayed below and duplicated in the Storefront, uses the TriggeredCacheInvalidationStrategy to invalidate the Velocity engines and message resources.

 

com.elasticpath.cm/WEB-INF/conf/spring/web/url-mapping.xml:

<prop key="/invalidate-cache.ep">cacheInvalidationController</prop>

<bean id="cacheInvalidationController"

    class="com.elasticpath.cmweb.controller.impl.CacheInvalidationControllerImpl">

  <property name="cacheInvalidationStrategy"

            ref="triggeredCacheInvalidationStrategy" />

</bean>

com.elasticpath.cm/WEB-INF/conf/spring/service/serviceCM.xml:

<bean id="triggeredCacheInvalidationStrategy"

class="com.elasticpath.commons.util.impl.TriggeredCacheInvalidationStrategyImpl">

  <property name="invalidatableCaches">

      <bean class="java.util.HashSet">

          <constructor-arg>

              <set>

                  <ref bean="velocityEngineFactory"/>

                  <ref bean="messageSourceCache"/>

              </set>

          </constructor-arg>

      </bean>

  </property>

</bean>

Be sure to have the invalidation URL secured, as it will cause a hit in performance every time the velocity engine is recreated, which reloads all the message property files.

 

 

For information on configuring PowerReviews in Elastic Path, see the PowerReviews Wiki page at https://wiki.elasticpath.com/display/EP61DEPLOY/5+-+PowerReviews+(optional) in the Deployment Guide. For information on the Power Reviews system, see the PowerReviews website at http://www.powerreviews.com.  The Power Reviews component is enabled and disabled by the boolean store-specific setting COMMERCE/STORE/POWERREVIEWS/powerreviewsEnabled. The value of the setting is passed to Velocity code by the powerReviewsEnabledHelper Spring bean defined in com.elasticpath.sf/WEB-INF/conf/spring/service/serviceSF.xml. Power Reviews are rendered by JavaScript code, and examples can be found in the guidedSkuTemplate.vm and productTemplate.vm templates.

 

WEB-INF/conf/spring/web/url-mapping.xml

<bean id="SimpleUrlHandlerMapping"

    class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

  <property name="mappings">

      <props>

      <prop key="/power-reviews/pwr/engine/js/**/*">

            storeAssetResourceController</prop>

      <prop key="/power-reviews/pwr/engine/**/*">

            storeAssetResourceController</prop>

      <prop key="/power-reviews/pwr/content/**/*">

            storeAssetResourceController</prop>

      </props>

  </property>

</bean>

<!-- Resource controllers for resource retrieval -->

<bean id="storeThemeAssetResourceController"

    class="com.elasticpath.sfweb.controller.impl.AssetResourceControllerImpl"

    parent="abstractEpController">

  <property name="resourceRetrievalStrategy"

            ref="storeThemeAssetRetrievalStrategy"/>

</bean>

<bean id="storeAssetResourceController"

    class="com.elasticpath.sfweb.controller.impl.AssetResourceControllerImpl"

    parent="abstractEpController">

  <property name="resourceRetrievalStrategy"

            ref="storeResourceRetrievalStrategy"/>

</bean>

0 Comments 0 References Permalink

There were a number of changes to the database schema in Elastic Path 6.1 compared to the schema in Elastic Path 6.0.4. Some new tables and columns were added to support new functionality, one table that is no longer used was removed, and a few columns were modified to increase data storage efficiency and data integrity.

 

Let's look at the details of these schema changes.

New Tables for Settings Storage

The settings framework feature was added in 6.1, and settings that were previously stored in commerce-config.xml files in 6.0.x have been moved to the database. The new settings-related tables have interdependencies but are not referentially linked to other tables in the system.

 

  • TSETTINGDEFINITION keeps track of all the application setting definitions and their default values.
  • TSETTINGMETADATA has information on how various settings apply to the system.
  • TSETTINGVALUE keeps track of setting values.

New Table for Advanced Search

TADVANCEDSEARCHQUERY stores saved queries that were created for the Advanced Search feature. It has a referential link to TCMUSER.

New Table for Gift Certificate Themes

TGIFTCERTIFICATETHEME stores gift certificate theme definitions, and has no referential links to any other tables.

New Table for PCI Compliance

TPASSWORDHISTORY stores a user's password history, and has a referential link to TCMUSER.

New Table for Index Build Status

TINDEXBUILDSTATUS stores the status of each SOLR/Lucene index, including its last build date and its current status (built, rebuilding, etc).

New Tables for Storefront Supported Locales and Supported Currencies

TSTORESUPPORTEDLOCALE and TSTORESUPPORTEDCURRENCY were added to take the place of the deleted TSTORE.DEFAULTLOCALE and TSTORE.DEFAULTCURRENCY columns. These tables have a foreign key to the TSTORE table.

Unused Table

TPROMOCODE is a legacy table that is not longer referenced by Elastic Path code and is no longer created by the 6.1 database creation scripts. If you are not using it, it can be safely removed.

New or Modified Columns

The following new columns were added to the schema:

  • Store States
    • TSTORE.STORE_STATE - Integer column - keeps track of the state a store is currently in. Value is required but has a default value of 0.

 

  • PCI Compliance
  • TCMUSER.LAST_CHANGED_PASSWORD_DATE - Date column - value not required.
  • TCMUSER.FAILED_LOGIN_ATTEMPTS - Integer column - value required, defaults to 0.
  • TCMUSER.STATUS - Integer column - value required, defaults to 4.
  • TCMUSER.ENABLED - This column was removed, to be replaced with the STATUS field.


  • Miscellaneous
  • TSTORE.DEFAULT_LOCALE is no longer a required column.
  • TSTORE.DEFAULT_CURRENCY is no longer a required column.
  • TSTORE.EMAIL_SENDER_NAME is no longer a required column.
  • TSTORE.EMAIL_SENDER_ADDRESS is no longer a required column.
  • TSTORE.STORE_ADMIN_EMAIL is no longer a required column.
  • TORDERSHIPMENT.SHIPMENT_NUMBER was increased in size from 10 characters to 64.
  • TINVENTORYAUDIT.EVENT_ORIGINATOR was increased in size from 30 to 255.

 

  • Indexes
  • TORDERLOCK.ORDER_UID is now an indexed column.
  • TORDERSHIPMENT.SHIPMENT_NUMBER is now an indexed column.

 

 

 

So, what does this mean for the average developer working on an upgrade from 6.0.4 to 6.1? Not very much. The database upgrade scripts included in the 6.1 distribution take care of all the necessary schema changes.

 

  • Populating the settings tables with the appropriate values is critical to getting your 6.1 install up and running. For more information, see the Elastic Path 6.1 Upgrade Guide at http://docs.elasticpath.com/display/EP61UPGRADE.
  • Increasing the size of a few columns should have minimal impact.
  • Removing the "required" flag on some fields in the STORE table is essential to the Store States feature, but should have no impact on existing systems.
  • TSTORE.STORE_STATE - 6.0.x only had a single store state: OPEN. The OPEN state in 6.1 is represented by an integer value of 200 in this field.
  • TCMUSER.STATUS replaces the ENABLED column but is backward compatible with its values. The value of the STATUS column should be the same as the value of the ENABLED column for every record during upgrade.
  • The new indexes can be added without any problems.
  • Removing the unused TPROMOCODE table should have no impact, but if you have customizations that are using this table, then it can also be left in with no impact.
  • Creating the new TSTORESUPPORTEDCURRENCY and TSTORESUPPORTEDLOCALE tables for Stores, and creating records corresponding to the column values in the corresponding columns that were removed from TSTORE should be fairly easy.

 

Upgrading an Elastic Path database-from 6.0.x to 6.1 is relatively painless. Only one integer field's data must be translated to a new field and removed (TCmUser.Enabled to TCmUser.Status), and only one new integer field (TStore.store_state) must added and populated with data (but every row has the same value for an upgrade). Other schema changes should have no significant impact on a stock EP6.0.x database.

0 Comments 0 References Permalink

Elastic Path offers several types of payment options: credit cards, gift certificates, PayPal, and Google Checkout. The specific implementation of a payment type is referred to as a payment gateway.  New payment types can be added, but a common requirement is to support a new credit card processor. This is the external service used to process your credit card transaction requests. Out of the box, Elastic Path includes support for CyberSource, Verisign, and Authorize.net, as well as a dummy gateway for use during development.

 

This post will show how to add a credit card payment gateway to your implementation.

 

The most difficult aspect is understanding the processor's requirements and communication protocol. Every processor has its own requirements, so you will need to fefer to the developer documentation for your credit card processor for more information on your processor.

 

There are several issues to consider when implementing a gateway for a credit card processor:

 

  • Pre-authorization
  • Settlements, referred to as Captures
  • Refunds
  • Voiding transactions
  • Supported credit cards

 

The Elastic Path framework includes a PaymentGateway interface and a CreditCardPaymentGateway interface, as well as corresponding implementations that cover offer support for all credit card transactions.

 

The CreditCardPaymentGateway also supports 3D Secure authentication, such as Verified-By-Visa and SecureCard from MasterCard with the following methods:

 

checkEnrollment

Used to determine whether or not a credit card account has been   enrolled in a 3D Secure Service.

validateAuthentication

Used to verify the card holder's authentication after they have been   redirected back to your site from the processor's verification site.

 

The Elastic Path storefront already makes use of these methods. Simply implement them to take advantage of the services.

 

Extend the AbstractCreditCardPaymentGatewayImpl and create your credit card payment gateway class as in the following code:

@Entity
1) @DiscriminatorValue("paymentGatewayMyProcessorNameHere")
public class MyProcessorNameHerePaymentGatewayImpl extends AbstractCreditCardPaymentGatewayImpl implements CreditCardPaymentGateway {
 
 
2)  private String type = "paymentGatewayMyProcessorNameHere";
 
@Basic
@Column(name = "TYPE", insertable = false)
public String getType() { return type; }
 
protected void setType(final String type) { this.type = type; }
 
 
3)  protected Set<String> getDefaultPropertyKeys() {
                      Set<String> defaultPropertyKeys = new TreeSet<String>();
                      defaultPropertyKeys.add("merchantId");
                      defaultPropertyKeys.add("username");
                      defaultPropertyKeys.add("password");
                      return defaultPropertyKeys;
      }
 
 
4)  public void preAuthorize(final OrderPayment payment, final Address billingAddress) {
 
 
5)                  String merchantId = getPropertiesMap().get("merchantId").getValue();
 
 
6)                  OrderShipment orderShipment = payment.getOrderShipment();
int number = 0;
for (OrderSku orderSku : orderShipment.getShipmentOrderSkus()) {
      addItemToRequest(request, number, orderSku);
      number++;
}
 
 
7)                  Order order = orderShipment.getOrder();
addOrderDetailsToRequest(order);
 
                      ...
 
      }
 
8)  public void capture(final OrderPayment payment) {
                      ...
      }
 
9)  public void sale(final OrderPayment payment, final Address billingAddress) {
                      ...
      }
 
10)  public void refund(final OrderPayment payment, final Address billingAddress) {
                      ...
      }
 
11)  public void reversePreAuthorization(final OrderPayment payment) {
                      ...
      }
 
12)  public void voidCaptureOrCredit(final OrderPayment payment) {
                      ...
      }
 
13)  public PayerAuthenticationEnrollmentResult checkEnrollment(
final ShoppingCart shoppingCart, final OrderPayment payment) {
                      ...
      }
 
14)  public boolean validateAuthentication(final OrderPayment payment, final String paRes) {
                      ...
      }
}

 

  1. The DiscriminatorValue must be set to the value specified for the gateway's type property.
  2. The type property must be set to a value unique among all payment gateways.
  3. getDefaultPropertyKeys must implemented to return a Set of property keys. The Set can be empty if there are no properties.
  4. The preAuthorize method must be implemented to make a pre-authorization transaction request to the payment processor.
  5. Properties can be accessed from the gateway's properties map.
  6. Access the shipment details through OrderPayment's orderShipments property.
  7. Access the order details through the order property of OrderPayment's orderShipment.
  8. The capture method must be implemented to make a settlement transaction request to the payment processor.
  9. The sale method must be implemented. Its purpose is to perform a combination of pre-authorization and capture at the same time. Some processors offer such a transaction. If not, then this method could make pre-authorization and capture transaction requests
    However, there is currently no logic using it in Elastic Path. So, it can be ignored
  10. The refund method must be implemented to make refund transaction requests to the processor.
  11. The reversePreAuthorization method must be implemented to make transaction requests to the processor that reverse the pre-authorization.
    Some credit card processors support this feature, but others do not. Refer to your processor's developer documentation for more information.
  12. The voidCaptureOrCredit method must be implemented to make transaction requests to the processor that void a previous capture or credit transaction.  Void transactions typically only work on transactions made the same day.
  13. The checkEnrollment method must be implemented to make requests to the processor to determine whether or not a credit card has been enrolled in the 3D Secure program.
  14. The validateAuthentication method must be implemented to make requests to the processor to verify a 3D Secure payment response after the customer has authenticated themselves on the processor's 3D Secure server.

 

Error Handling

Errors occasionally happen. With credit cards, they can frequently happen. Elastic Path implements several exceptions to account for the most common problems. These exceptions should be thrown from the preAuthorize or capture methods when appropriate.

 

CardDeclinedException

Thrown when the card number is declined.

CardExpiredException

Thrown when the card has expired.

CardErrorException

Thrown for any "generic" errors.

InsufficientFundException

Thrown when the card account does not have sufficient funds to cover   the request.

InvalidAddressException

Thrown when the processor determines the billing address is invalid.

AmountLimitExceededException

Thrown when the card has exceeded its limit.

InvalidCVV2Exception

Thrown when the CVV number supplied is invalid.

 

To add your own exceptions, extend one of the following exception classes, and throw it as appropriate:

 

PaymentProcessingException

Extended for general processing errors such as insufficient funds.

CardErrorException

Extended for card errors, such as declined.

 

Configuring the Payment Gateway Factory

In order to use your new credit card gateway, you'll need to make the payment gateway factory aware of it. The paymentGatewayFactory bean defined in the domainModel.xml file must include a new entry.

 

<bean id="paymentGatewayFactory"

      class="com.elasticpath.domain.payment.impl.PaymentGatewayFactoryImpl">

      <property name="paymentGateways">

                      <map>

                                      ...

                                                <entry key="paymentGatewayMyProcessorNameHere">

                                                                <value>

com...MyProcessorNameHerePaymentGatewayImpl

</value>

                                                </entry>

                                      ...

                      </map>

      </property>

</bean>

The entry's key must be set to the payment gateway's type property that was specified in the implementation class.

 

Using the Payment Gateway

To use your new credit card gateway implementation, you will first need to create a new payment gateway configuration in the CM Client, and then configure your store to use it.

 

In the CM Client:

  • Open the Configuration activity
  • Select Payment Gateways
  • Click Create Gateway
  • Type in your gateway name
  • Select your new gateway implementation the Type dropdown

 

To use the new payment gateway in your store:

  • Open the Configuration activity
  • Select Stores
  • Edit your store
  • Select the Payments tab
  • Select your new Payment Gateway in the Credit Card Payment Gateway dropdown
  • Choose the options for enabling the CCV value, saving credit card numbers, and the supported card types.

Caveats

Many processors will provide a testing infrastructure. Occasionally, this means a test merchant account, test card numbers, and possibly a different URL from what should be used in production.  Refer to your processor's development documentation to understand how to test it.  When moving to production, the first thing you will want to do is to test it. This means using a live credit card. There aren't many ways around this. However, you should have access to a console to manage your merchant account, and be able to cancel any transactions.

0 Comments 0 References Permalink