3.0 to 3.1 Migration Notes
These migration notes assumes that you are going from a stock Heat Clinic demo to the 3.1 demo. There might be addtional migration steps for your particular implementation of Broadleaf, please let us know on the forums or by submitting a pull request to this documentation site at https://github.com/BroadleafCommerce/docs.
This document also assumes that you are on the latest 3.0 GA patch version of Broadleaf (like 3.0.8-GA). If you have not upgraded your site to be on the latest 3.0 patch version, please do so before continuing and see the optional migration docs for each 3.0 patch version.
Maven Updates
In the root pom.xml
:
Update the
blc.version
property to3.1.0-GA
:<blc.version>3.1.0-GA</blc.version>
Update the version of the
commons-dbcp
to1.4
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<type>jar</type>
<scope>compile</scope>
Admin Updates
Add the admin.css file to the
blJsFileMap
bean, underneath theadmin.js
entry. This looks like:<bean id="blJsFileMap" class="org.springframework.beans.factory.config.MapFactoryBean"> <property name="sourceMap"> <map> <entry key="admin.js" value-ref="blJsFileList"/> <entry key="admin.css" value-ref="blCssFileList"/> </map> </property> </bean>
Optional: since this no longer just represents JS files, you might want to rename this bean to something more appropriate like
blResourceFileMap
Update the
mvc:resources
definitions inapplicationContext-servlet-admin
to take into account the fact that some resources have been moved to common. The final definition of these entries should look like:<mvc:resources order="-10" location="classpath:/open_admin_style/img/, classpath:/common_style/img/" mapping="/img/**" /> <mvc:resources order="-10" location="classpath:/open_admin_style/fonts/, classpath:/common_style/fonts/" mapping="/fonts/**" /> <mvc:resources order="-10" location="WEB-INF/favicon.ico" mapping="/favicon.ico" /> <mvc:resources order="-10" location="WEB-INF/robots.txt" mapping="/robots.txt" />
Core Updates
- Remove the custom class transformer designed to fix the max offer usage bug. This will effect you only if you are on Broadleaf 3.0.6-GA and above. This is no longer necessary in 3.1.0-GA and above.
Site Updates
Move the
blRequestFilter
andblCustomerStateFilter
into theblPostSecurityFilterChain
located inapplicationContext-filter.xml
. The final version of this looks like:<bean id="blPostSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> <sec:filter-chain-map request-matcher="ant"> <sec:filter-chain pattern="/**" filters=" blRequestFilter, blCustomerStateFilter, blURLHandlerFilter, blTranslationFilter, blCartStateFilter"/> </sec:filter-chain-map> </bean>
You should also remove the
blRequestFilter
from theblPreSecurityFilterChain
(also inapplicationContext-filter.xml
) and removeblCustomerStateFilter
located within the<sec:http>
element inapplicationContext-security.xml
.Add the common fonts to
applicationContext-servlet.xml
:<mvc:resources order="-10" location="/img/, classpath:/common_style/img/" mapping="/img/**" /> <mvc:resources order="-10" location="/fonts/, classpath:/common_style/fonts/" mapping="/fonts/**" /> <mvc:resources order="-10" location="WEB-INF/favicon.ico" mapping="/favicon.ico" />
Note: this is likely an optional step and only required if you depend on Broadleaf's version of FontAwesome and JQuery UI icons.
The
blc:head
Thymeleaf processor is now deprecated with the upgrade to Thymeleaf 2.1. Replace all instances of code like:- <blc:head pageTitle="Account - Broadleaf Demo - Heat Clinic" />
with the following:
<head th:include="/layout/partials/head (pageTitle='Account - Broadleaf Demo - Heat Clinic')"></head>
The feature that allowed for parameterized includes (which eliminated the need for the head processor) is documented in the Thymeleaf 2.1 docs
Remove the custom
blUserDetailsService
definition from `applicationContext-security.xml. This has been replaced by a component in the framework:- <sec:jdbc-user-service data-source-ref="webDS" - id="blUserDetailsService" - users-by-username-query="SELECT USER_NAME,PASSWORD,TRUE FROM BLC_CUSTOMER WHERE USER_NAME=?" - authorities-by-username-query="SELECT c.USER_NAME,r.ROLE_NAME from BLC_CUSTOMER c - JOIN BLC_CUSTOMER_ROLE cr ON c.CUSTOMER_ID = cr.CUSTOMER_ID - JOIN BLC_ROLE r ON cr.ROLE_ID = r.ROLE_ID - WHERE USER_NAME=?" />
EHCache settings
New regions:
- blProducts (ProductAttribute, ProductBundle, Product, Sku, ProductOptionValue, ProductOption, SkuAttribute, SkuBundleItem, SkuFee)
- blCategories (Category, CategoryAttribute, CategoryProductXref, FeaturedProduct, CategorySearchFacet)
- blOffers (Offer, OfferItem, OfferRule)
- blCustomerElements (Customer)
- blConfigurationModuleElements (retrieving subtypes of AbstractModuleConfiguration)
- query.Offer (retrieving lists of offers via daos)
REST API Updates
New/Changed Methods
POST: /cart/items/{itemId}/options in CartEndpoint.java
@Override
@PUT
@Path("items/{itemId}/options")
public OrderWrapper updateProductOptions(@Context HttpServletRequest request,
@Context UriInfo uriInfo,
@PathParam("itemId") Long itemId,
@QueryParam("priceOrder") @DefaultValue("true") boolean priceOrder) {
return super.updateProductOptions(request, uriInfo, itemId, priceOrder);
}
GET: /cart/checkout/payments in CheckoutEndpoint.java
@GET
@Path("payments")
public List<OrderPaymentWrapper> findPaymentsForOrder(@Context HttpServletRequest request) {
return super.findPaymentsForOrder(request);
}
POST: /cart/checkout/payment in CheckoutEndpoint.java
@Override
@Path("payment")
public OrderPaymentWrapper addPaymentToOrder(@Context HttpServletRequest request,
OrderPaymentWrapper wrapper) {
return super.addPaymentToOrder(request, wrapper);
}
DELETE: /cart/checkout/payment in CheckoutEndpoint.java
@Override
@DELETE
@Path("payment")
public OrderWrapper removePaymentFromOrder(@Context HttpServletRequest request,
OrderPaymentWrapper wrapper) {
return super.removePaymentFromOrder(request, wrapper);
}
POST: /cart/checkout in CheckoutEndpoint.java
@Override
@POST
public OrderWrapper performCheckout(@Context HttpServletRequest request) {
return super.performCheckout(request);
}
Note: this was modified to no longer require payments in the checkout invocation. Payments should be added to an order by an earlier invocation to /cart/checkout/payment
Deleted methods
/cart/checkout/payment/response in CheckoutEndpoint.java
To obtain these methods, add method to your
Workflow Updates
- The
blPaymentsWorkflow
along with all ancilliary workflows (likeblAuthorizeWorkflow
,blRefundWorkflow
etc) has been removed. Any customizations or usage for these payment workflows should be migrated to the new way Broadleaf does payments in 3.1 A new activity,
blValidateProductOptionsActivity
has been added with order2000
. This has bumped the ordering of the existing activities up by 1000. The final ordering of activities is:<bean p:order="1000" id="blVerifyCustomerMaxOfferUsesActivity" class="org.broadleafcommerce.core.offer.service.workflow.VerifyCustomerMaxOfferUsesActivity"/> <bean p:order="2000" id="blValidateProductOptionsActivity" class="org.broadleafcommerce.core.checkout.service.workflow.ValidateProductOptionsActivity"/> <bean p:order="3000" id="blValidateAndConfirmPaymentActivity" class="org.broadleafcommerce.core.checkout.service.workflow.ValidateAndConfirmPaymentActivity"> <property name="rollbackHandler" ref="blConfirmPaymentsRollbackHandler" /> </bean> <bean p:order="4000" id="blRecordOfferUsageActivity" class="org.broadleafcommerce.core.offer.service.workflow.RecordOfferUsageActivity"> <property name="rollbackHandler" ref="blRecordOfferUsageRollbackHandler" /> </bean> <bean p:order="5000" id="blCommitTaxActivity" class="org.broadleafcommerce.core.checkout.service.workflow.CommitTaxActivity"> <property name="rollbackHandler" ref="blCommitTaxRollbackHandler" /> </bean> <bean p:order="6000" id="blCompleteOrderActivity" class="org.broadleafcommerce.core.checkout.service.workflow.CompleteOrderActivity"> <property name="rollbackHandler" ref="blCompleteOrderRollbackHandler" /> </bean>
Thymeleaf 2.1 Updates
Braodleaf has changed the Thymeleaf version from 2.0 to 2.1. Depending on how many Thymeleaf processors you have in your codebase this migration step may vary. See the Thymeleaf documentation site for the changes. You might check our migration to Thymeleaf 2.1 for what we had to change in the framework.
Payment Module and Checkout Form Updates
We have completely rewritten the way that payments are treated in Broadleaf. We are still in the process of updating some of our existing payment modules. If there is a payment module written by Broadleaf that you need and has not been updated to the new 3.1 standards, please let us know at info AT broadleafcommerce.com.
For more information on how to ensure that your payment module conforms to the new Broadleaf standards, see [[Checkout Page Design]] and Payment. You might also gain additional insight by looking at the null payment gateway module that we implemented within the 3.1 demo site.
Additional Miscellaneous Items
- The checkout confirmation email should be moved away from the order confirmation controller and instead should be a custom activity within the
blCheckoutWorkflow
- Adding the
disable-url-rewriting="true"
attribute to the<sec:http>
element inapplicationContext-security.xml
will disable any JSESSIONIDs appearing in URLs - The ID field in admin list grids are no longer shown by default. You can re-enable this column with a
showIds=true
query parameter (e.g. /admin/product?showIds=true) - The syntax for a custom
Activity
has changed from something like this:
public class MyCustomActivity extends BaseActivity<CheckoutContext> {
@Override
public CheckoutContext execute(CheckoutContext context) throws Exception {
...
}
}
to:
public class RecordOfferUsageActivity extends BaseActivity<ProcessContext<CheckoutSeed>> {
@Override
public ProcessContext<CheckoutSeed> execute(ProcessContext<CheckoutSeed> context) throws Exception {
...
}
}
Broadleaf Framework Changes Requiring Migration
This section is designed for various components that you might be utilizing in Broadleaf that have been refactored or changed.
ExtensionHandler
s andExtensionManager
s have been moved into commonFieldEnumeration
andFieldEnumerationItem
(along with the correspondingBLC_FIELD_ENUMERATION
andBLC_FIELD_ENUMERATION_ITEM
tables) used in CMSFieldDefinition
s has been deprecated. This has instead been replaced by utilizingDataDrivenEnumeration
instead. You should move any data that you have inBLC_FLD_ENUM
intoBLC_DATA_DRVN_ENUM
and any data inBLC_FLD_ENUM_ITEM
intoBLC_DATA_DRVN_ENUM_VAL
:INSERT INTO BLC_DATA_DRVN_ENUM (SELECT FLD_ENUM_ID AS ENUM_ID, NAME AS ENUM_KEY FROM BLC_FLD_ENUM); INSERT INTO BLC_DATA_DRVN_ENUM_VAL (SELECT FLD_ENUM_ITEM_ID AS ENUM_VAL_ID, NAME AS ENUM_KEY, FRIENDLY_NAME AS DISPLAY, FLD_ENUM_ID AS ENUM_TYPE FROM BLC_FLD_ENUM_ITEM);
Database Changes
There are several DB changes related to the 3.0 to 3.1 upgrade. You can find the history of changes to the database in the Database Model.
We recommend you use a database management tool like Liquibase to manage DB versions. Here is a DB changelog file that was generated that compares a 3.0.x schema to a 3.1.x schema. If you aren't using Liquibase, please consider using it and see our tutorial for more details: Managing DB Versions Migrations With Liquibase
TODO: provide up-to-date link for liquibase import file
Alternatively, here is an example script of the changes that need to be applied for 3.1.
This script is based off of a Liquibase changelog Database diff. You will need to read the data migration section above and appropriately migrate the data if necessary. This script is intended to be non-destructive and does not contain any DROP statements. It is important to note that there will be certain tables that will no longer be used by the system.
TODO: provide instructions for how to go from the liquibase xml to a database-compatible dump (Oracle, Postgres, MySQL)
Data Migration
Data Migration related to Products
All Products should define a DEFAULT_SKU_ID
in BLC_PRODUCT
. This is a performance enhancement (as well as a requirement for Enterprise Broadleaf). Because of the way product and skus are modeled, having a real column reference on both sides removes an unnecessary sql call for every product retrieved.
Here is a liquibase snippet relating to this DB change:
<changeSet author="liquibase (generated)" id="1391122037368-16">
<addColumn tableName="BLC_PRODUCT">
<column name="DEFAULT_SKU_ID" type="BIGINT(19)"/>
</addColumn>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-56">
<addForeignKeyConstraint baseColumnNames="DEFAULT_SKU_ID" baseTableName="BLC_PRODUCT" constraintName="FK5B95B7C96D386535" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="SKU_ID" referencedTableName="BLC_SKU"/>
</changeSet>
Data Migration related to XREF tables
All existing XREF tables that contain @EmbeddedId
have now been refactored to define an explicit key. This is related to the issues discussed in this thread: https://github.com/BroadleafCommerce/BroadleafCommerce/issues/81
The following tables will be affected:
BLC_CATEGORY_PRODUCT_XREF
BLC_CATEGORY_XREF
BLC_PRODUCT_OPTION_XREF
Here is a liquibase snippet relating to this DB change:
<changeSet author="liquibase (generated)" id="1391122037368-13">
<addColumn tableName="BLC_CATEGORY_PRODUCT_XREF">
<column name="CATEGORY_PRODUCT_ID" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-14">
<addColumn tableName="BLC_CATEGORY_XREF">
<column name="CATEGORY_XREF_ID" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-32">
<addColumn tableName="BLC_PRODUCT_OPTION_XREF">
<column name="PRODUCT_OPTION_XREF_ID" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-69">
<createIndex indexName="PRIMARY" tableName="BLC_CATEGORY_PRODUCT_XREF" unique="true">
<column name="CATEGORY_PRODUCT_ID"/>
</createIndex>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-70">
<createIndex indexName="PRIMARY" tableName="BLC_CATEGORY_XREF" unique="true">
<column name="CATEGORY_XREF_ID"/>
</createIndex>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-168">
<dropPrimaryKey tableName="BLC_CATEGORY_PRODUCT_XREF"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-169">
<addPrimaryKey columnNames="CATEGORY_PRODUCT_ID" constraintName="PRIMARY" tableName="BLC_CATEGORY_PRODUCT_XREF"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-170">
<dropPrimaryKey tableName="BLC_CATEGORY_XREF"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-171">
<addPrimaryKey columnNames="CATEGORY_XREF_ID" constraintName="PRIMARY" tableName="BLC_CATEGORY_XREF"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-44">
<addPrimaryKey columnNames="PRODUCT_OPTION_XREF_ID" constraintName="PRIMARY" tableName="BLC_PRODUCT_OPTION_XREF"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-159">
<modifyDataType columnName="DISPLAY_ORDER" newDataType="decimal(10,6)" tableName="BLC_CATEGORY_PRODUCT_XREF"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391122037368-160">
<modifyDataType columnName="DISPLAY_ORDER" newDataType="decimal(10,6)" tableName="BLC_CATEGORY_XREF"/>
</changeSet>
Data Migration for existing Payments
In the 3.1 codebase, we've completely refactored the way Payments are structured and persisted, so there are some data migrations if you intend to migrate from an earlier version.
You can view the new Order Payment model in the Database Model of the docs.
In general, we've made the model more flexible in terms of how Payments and Transactions are structured when integrating with Third Party Payment Gateways. There are a lot of intricasies involved as each Payment Gateway handles communication and transactions differently, so it was imperative to come up with a standardized and flexible solution that can best handle most solutions. You can read more about what all was done in the Payment Refactoctoring section of the docs.
Broadleaf 3.1 no longer uses the following tables:
BLC_AMOUNT_ITEM
BLC_ORDER_PAYMENT_DETAILS
BLC_PAYINFO_ADDITIONAL_FIELDS
BLC_PAYMENT_ADDITIONAL_FIELDS
BLC_PAYMENT_LOG
Each gateway implentation in the 3.0 and earlier codebases persisted data in several different ways into the BLC_ORDER_PAYMENT_DETAILS
, BLC_PAYINFO_ADDITIONAL_FIELDS
, BLC_PAYMENT_ADDITIONAL_FIELDS
depending on your
Payment Gateway Implementation. So, in order to do data migration for payments, some data analysis should be done in order to find the best mapping solution to the new tables.
The new tables include:
BLC_ORDER_PAYMENT_TRANSACTION
BLC_TRANS_ADDITNL_FIELDS
Please read the Payment Domain documentation to learn more about how Payment information should be stored in these new entities.
A good rule of thumb when migrating data for payments is that BLC_ORDER_PAYMENT_DETAILS
-> BLC_ORDER_PAYMENT_TRANSACTION
and both BLC_PAYINFO_ADDITIONAL_FIELDS
and BLC_PAYMENT_ADDITIONAL_FIELDS
are part of the response map associated with a particuar BLC_ORDER_PAYMENT_TRANSACTION
in the BLC_TRANS_ADDITNL_FIELDS
table. You may also wish to migrate BLC_PAYMENT_LOG
entries as they are analagous to an entry in BLC_ORDER_PAYMENT_TRANSACTION
Here is a liquibase snippet relating to this DB change:
<changeSet author="liquibase (generated)" id="1391184025689-5">
<createTable tableName="BLC_ORDER_PAYMENT_TRANSACTION">
<column name="PAYMENT_TRANSACTION_ID" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
<column name="TRANSACTION_AMOUNT" type="DECIMAL(19, 2)"/>
<column name="ARCHIVED" type="CHAR(1)"/>
<column name="CUSTOMER_IP_ADDRESS" type="VARCHAR(255)"/>
<column name="DATE_RECORDED" type="datetime"/>
<column name="RAW_RESPONSE" type="LONGTEXT"/>
<column name="SUCCESS" type="BIT(1)"/>
<column name="TRANSACTION_TYPE" type="VARCHAR(255)"/>
<column name="ORDER_PAYMENT" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
<column name="PARENT_TRANSACTION" type="BIGINT(19)"/>
</createTable>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-12">
<addColumn tableName="BLC_ORDER_PAYMENT">
<column name="ARCHIVED" type="CHAR(1)"/>
</addColumn>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-23">
<addColumn tableName="BLC_ORDER_PAYMENT">
<column name="GATEWAY_TYPE" type="VARCHAR(255)"/>
</addColumn>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-28">
<addColumn tableName="BLC_ORDER_PAYMENT">
<column name="ORDER_PAYMENT_ID" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-29">
<addColumn tableName="BLC_PAYMENT_LOG">
<column name="ORDER_PAYMENT_REF_NUM" type="VARCHAR(255)"/>
</addColumn>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-42">
<addPrimaryKey columnNames="PAYMENT_TRANSACTION_ID" constraintName="PRIMARY" tableName="BLC_ORDER_PAYMENT_TRANSACTION"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-52">
<addForeignKeyConstraint baseColumnNames="PAYMENT_TRANSACTION_ID" baseTableName="BLC_TRANS_ADDITNL_FIELDS" constraintName="FK376DDE4B9E955B1D" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="PAYMENT_TRANSACTION_ID" referencedTableName="BLC_ORDER_PAYMENT_TRANSACTION"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-59">
<addForeignKeyConstraint baseColumnNames="ORDER_PAYMENT" baseTableName="BLC_ORDER_PAYMENT_TRANSACTION" constraintName="FK86FDE7CE6A69DD9D" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="ORDER_PAYMENT_ID" referencedTableName="BLC_ORDER_PAYMENT"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-60">
<addForeignKeyConstraint baseColumnNames="PARENT_TRANSACTION" baseTableName="BLC_ORDER_PAYMENT_TRANSACTION" constraintName="FK86FDE7CEE1B66C71" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="PAYMENT_TRANSACTION_ID" referencedTableName="BLC_ORDER_PAYMENT_TRANSACTION"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-67">
<createIndex indexName="PAYMENTLOG_REFERENCE_INDEX" tableName="BLC_PAYMENT_LOG" unique="false">
<column name="ORDER_PAYMENT_REF_NUM"/>
</createIndex>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-70">
<createIndex indexName="PRIMARY" tableName="BLC_ORDER_PAYMENT" unique="true">
<column name="ORDER_PAYMENT_ID"/>
</createIndex>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-171">
<dropPrimaryKey tableName="BLC_ORDER_PAYMENT"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-172">
<addPrimaryKey columnNames="ORDER_PAYMENT_ID" constraintName="PRIMARY" tableName="BLC_ORDER_PAYMENT"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-173">
<dropIndex tableName="BLC_ORDER_PAYMENT"/>
</changeSet>
<changeSet author="liquibase (generated)" id="1391184025689-174">
<createIndex indexName="ORDERPAYMENT_REFERENCE_INDEX" tableName="BLC_ORDER_PAYMENT">
<column name="REFERENCE_NUMBER"/>
</createIndex>
</changeSet>