Migrating the IBM Websphere Commerce Version 7 Feature Pack 6 Elite store

Complete this task to migrate your IBM Websphere Commerce Version 7 Feature Pack 6 Elite store to HCL Commerce Version 9. After migration, your store will remain a local store.

The store migration process involves exporting the following assets as archive files, and then importing the archive files:
  • Custom static store assets
  • Custom Java code
  • Custom JSP files
Stores that are migrated from IBM Websphere Commerce Version 7 or IBM Websphere Commerce Version 8 to HCL Commerce Version 9.0, are deployed to the Transaction server, where they serve live traffic. Stores that are created onHCL Commerce Version 9.0 follow the new programming model and are deployed to a separate Store server. For more information about migrating or creating a store on HCL Commerce Version 9.0, see:

Procedure

  1. Export the Stores dynamic web project from your Feature Pack 6 development environment workspace.
    1. Open your Feature Pack 6 development environment workspace, then open the J2EE perspective.
    2. From the Enterprise Explorer view, right-click the Stores project, then click Export > Export....
      The Export window appears.
    3. Expand the General folder, then click Archive File > Next.
    4. Under the Stores directory, clear the Stores check box, and select the following subdirectories.
      • WebContent
      • src
    5. Ensure the Create only selected directories option is selected.
    6. Click Browse and define a path where the archive file is to be exported.
    7. Under Options, ensure that the following export option is defined.
      • Create only selected directories
    8. Click Finish.
      A Stores.zip file is created and is ready to be imported into your HCL Commerce Version 9 development environment.
    9. Copy the exported Stores.zip file to your HCL Commerce Version 9 development environment.
  2. Importing your custom project.
    1. Open your HCL Commerce Version 9 development environment workspace, and then open the Java EE perspective.
    2. From the Enterprise Explorer view, right-click the Stores project, then click Import > Import....
      The Import window appears.
    3. Expand the General folder, then click Archive File > Next.
    4. Click Browse, then select the Stores.zip file that you exported from your Feature Pack 6 development environment.
    5. Under WebContent, expand WEB-INF and clear the lib directory. This results in the WEB-INF/lib/Foundation-TagLib.jar file not being imported into the new environment, as it is not supported in HCL Commerce Version 9.
    6. Click the Overwrite existing resources without warning check box.
    7. Click Finish.
  3. Migrate your search BOD services to be REST services.

    All the getData tags use BOD services that are provided by the search or transaction servers. Replace the search BOD services with REST services that are used in the current search architecture. The search BOD services have specific patterns in JSP files, where the value of the type attribute is CatalogNavigationViewType in the getData tags.

    1. Find the following string to identify which JSP files require updates. Files that contain this string use BOD services for search.
      
      com.ibm.commerce.catalog.facade.datatypes.CatalogNavigationViewType
      
      Note each file that contains this string, so that you can update them all accordingly. For example, this sample will be used to demonstrate how to change getData tag to REST tag.
      Before:
      
      <wcf:getData type="com.ibm.commerce.catalog.facade.datatypes.CatalogNavigationViewType" var="catalogNavigationView"
          expressionBuilder="getCatalogEntrySearchResultsByIDView" scope="request" varShowVerb="showCatalogNavigationView"
          maxItems="100" recordSetStartNumber="0" scope="request">
          <c:forEach var="marketingSpotData" items="${marketingSpotDatas.baseMarketingSpotActivityData}">
              <c:if test='${marketingSpotData.dataType eq "CatalogEntryId"}'>
                  <wcf:param name="UniqueID" value="${marketingSpotData.uniqueID}"/>
              </c:if>
          </c:forEach>
          <wcf:contextData name="storeId" data="${WCParam.storeId}" />
          <wcf:contextData name="catalogId" data="${WCParam.catalogId}" />
      </wcf:getData>
      <c:set var="eSpotCatalogIdResults" value="${catalogNavigationView.catalogEntryView}"/>
      
    2. Create the EnvironmentSetup.jspf file for your Elite store.
      1. Download the following file: EnvironmentSetupJspf.zip
      2. Extract the EnvironmentSetup.jspf to the Stores/WebContent/Elite/include directory.
    3. Update the imports to include the EnvironmentSetup.jspf file:
      
      <%@ include file="/Elite/include/EnvironmentSetup.jspf"%>
      
    4. Ensure that there are no duplicate import files. That is, review the EnvironmentSetup.jspf and ensure that the imports listed in the file are not also imported in each JSP file.
    5. Review the value of the expressionBuilder in each getData tag. Map these services to a REST API.
      Typically, 1 BOD service will map to 2 REST services, where one is used to get single product information and the other is used to get multiple products. For example:
      • store/{storeId}/productview/byId/{productId}
      • store/{storeId}/productview/byIds
      Use whichever REST services suit your business needs.
    6. Replace the wcf:getData tag with the wcf:rest tag.
      1. Set the url attribute to the REST API URL by appending the searchHostNamePath and searchContextPath variables before the URI and replace placeholders with their corresponding variables. For example:
        
        <wcf:rest var="catalogNavigationView" url="${searchHostNamePath}${searchContextPath}/store/${storeId}/productview/byIds" >
        
      2. Change the wcf:contextData tag to wcf:param within the wcf:getData tag. Ensure that you change the data attribute in wcf:contextData tag to value in the wcf:param tag.
      3. Keep the c:forEach statement inside the getData tag as-is.
      4. Change the name="UniqueID" values to name="id" inside the wcf:param tag.
      5. Add other optional parameters that are defined in the REST API. If the optional parameters are not specified, the REST API service will fetch them from the environment context. It is recommended that you add them to the specific queries that require them. For example:
        
        <wcf:param name="LangId" value="${langId}" />
        <wcf:param name="currency" value="${env_currencyCode}" />
        <wcf:param name="responseFormat" value="json" />
        <wcf:param name="catalogId" value="${catalogId}" />
        
      6. Review the getData tag's searchProfile value to find the correct search profile to use for the REST service. If the searchProfile attribute is not specified, find the default value in the BOD service in the definition configuration file: Stores/WebContent/WEB-INF/config/com.ibm.commerce.catalog-fep/get-data-config.xml. The value should be located in the expression builder block.
        For example:
        
        <expression-builder>
           <param>
              <name>searchProfile</name>
              <value>IBM_findCatalogEntryByID</value>
           </param>
        </expression-builder>
        
        Note the BOD search profile to be updated to the new value.
      7. Update the BOD search profile to be the new REST search profile value. For more information about the service mappings, see Mapping of REST services to BOD services.
        For example, the IBM_findCatalogEntryByID BOD search profile is deprecated by the IBM_findProductByIds_Summary REST search profile, resulting in:
        
        <wcf:param name="profileName" value="IBM_findProductByIds_Summary" />
        
      8. Use a c:catch tag to embrace your wcf:rest tag and specify searchServerException as the value of the var attribute.
        For example, the resulting code should resemble the following example:
        
        <c:catch var="searchServerException">
           <wcf:rest var="catalogNavigationView" url="${searchHostNamePath}${searchContextPath}/store/${storeId}/productview/byIds" >
              <c:forEach var="marketingSpotData" items="${marketingSpotDatas.baseMarketingSpotActivityData}">
                 <c:if test='${marktingSpotData.dataType eq "CatalogEntryId"}'>
                    <wcf:param name="id" value="${fn:trim(marketingSpotData.uniqueID)}"/>
                 </c:if>
              </c:forEach>
              <wcf:param name="LangId" value="${langId}" />
              <wcf:param name="currency" value="${env_currencyCode}" />
              <wcf:param name="responseFormat" value="json" />
              <wcf:param name="catalogId" value="${catalogId}" />
              <wcf:param name="profileName" value="IBM_findProductByIds_Summary" />
           </wcf:rest>
        </c:catch>
        
      9. Test that your pages can be loaded successfully. To help with this, sse the wcf:json tag to output the JSON data on the page. Replace .value.value with .value after objects. If you do not do this replacement, errors occur, such as javax.el.PropertyNotFoundException: Property 'value' not found on type java.lang.String.
  4. Remove the nonexistent filter in your web.xml file.
    1. Open the following file for editing.
      • WCDE_installdir/workspace/Stores/WebContent/WEB-INF/web.xml
    2. Remove the following block of code.
      <filter>
          </icon>
          <filter-name>LikeMindsFilter</filter-name>
          <filter-class>com.ibm.commerce.likeminds.filter.LikeMindsFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>LikeMindsFilter</filter-name>
          <servlet-name>Stores Request Servlet</servlet-name>
      </filter-mapping>
      
    3. Save and close the file.
  5. Remove the remote store configuration from your foundation wc-component.xml file.
    1. Open the following file for editing.
      • workspace_dir/WC/xml/config/com.ibm.commerce.foundation/wc-component.xml
    2. Remove the following block of code.
      <_config:configgrouping name="RemoteStoreConfiguration">
          <!-- value to remote store web host name -->
          <_config:property name="wc.store.remote.webHostName" value="store"/>
          <!-- value to remote store web host HTTP port number -->
          <_config:property name="wc.store.remote.webNonSSLPort" value="8080"/>
          <!-- value to remote store web host HTTPS port number -->
          <_config:property name="wc.store.remote.webSSLPort" value="8443"/>
          <!-- value to remote store context root -->
          <_config:property name="wc.store.remote.webContextPath" value="/shop"/>
          <!-- value to remote store preview context root -->
          <_config:property name="wc.store.remote.previewContextPath" value="/webapp/remote/preview/servlet"/>
          <!-- value to kafka servers connection string -->
          <_config:property name="wc.store.remote.kafka" value=""/>
          <!-- value to kafka servers topic prefix -->
          <_config:property name="wc.store.remote.kafka.topicPrefix" value="sampleprefix"/>
          <!-- value to remote store web alias -->
          <_config:property name="wc.store.remote.webAlias" value="/wcsstore"/>
          <!-- value to remote store app host name (used for invoking email JSPs in remote store) -->
          <_config:property name="wc.store.remote.appHostName" value="localhost"/>
          <!-- value to remote store app host HTTPS port number (used for invoking email JSPs in remote store) -->
          <_config:property name="wc.store.remote.appSSLPort" value="8443"/>
      </_config:configgrouping>
    3. Save and close the file.
  6. Remove EJB from the store preview header.
    1. Open the /Stores/WebContent/tools/preview/StorePreviewerHeader.jsp file for editing.
    2. Locate the following string:
      
      pageContext.setAttribute("workspaceId", abWorkspace.getWorkspaceIdInEJBType().toString());
      
      Replace it with the following string:
      
      pageContext.setAttribute("workspaceId", abWorkspace.getWorkspaceIdInEntityType().toString());
      
    3. Locate the following string:
      
      <%@page import="com.ibm.commerce.catalog.facade.server.helpers.SolrSearchWorkspaceHelper"%>
      
      Replace it with the following string:
      
      <%@page import="com.ibm.commerce.foundation.internal.server.services.search.util.SolrSearchWorkspaceHelper"%>
      
    4. Save and close the file.
  7. Update your RegistrationUpdateCommonPage.jsp file to resolve a potential HCL Commerce Version 9 parsing error that occurs when the Personal information page loads.
    1. Open the following file for editing.
      • /Stores/WebContent/Elite/UserArea/AccountSection/RegistrationSubsection/RegistrationUpdateCommonPage.jsp
    2. Around line 120, locate the following line of code.
      <fmt:param><fmt:formatDate type="both" dateStyle="long" value="${CommandContext.user.lastSessionInEJBType}"/></fmt:param>
    3. Update the line of code with the following.
      <fmt:param><c:out value="${CommandContext.user.lastSession}"/></fmt:param>
    4. Save and close the files.
  8. Update your WishListResultDisplay.jsp file to resolve a potential HCL Commerce Version 9 error that prevents the wish list page from opening.
    1. Open the following file for editing.
      • /Stores/WebContent/Elite/UserArea/ServiceSection/InterestItemListSubsection/WishListResultDisplay.jsp
    2. Use CatalogEntryAccessBean.findBySKUNumberAndStore to replace CatalogEntryCache.findBySKUNumberAndStore and remove the import statement of CatalogEntryCache.
    3. Around line 566, locate the following code:
      
      <%@ page import="java.util.Enumeration" %>
      <%@ page import="com.ibm.commerce.catalog.objects.CatalogEntryAccessBean" %>
      <%@ page import="com.ibm.commerce.catalog.objects.CatalogEntryCache" %>
      …
          CatalogEntryAccessBean abCatalogEntry = null;
          String[] strStoreId = (String[])request.getAttribute("storeId");
          Enumeration e = CatalogEntryCache.findBySKUNumberAndStore((String)request.getAttribute("itemPartNumber"),new Integer(strStoreId[0]));
          abCatalogEntry = (CatalogEntryAccessBean) e.nextElement();
         …
      
    4. Update the code with the following:
      
      <%@ page import="java.util.Enumeration" %>
      <%@ page import="com.ibm.commerce.catalog.objects.CatalogEntryAccessBean" %>
      …
          CatalogEntryAccessBean abCatalogEntry = new CatalogEntryAccessBean();
          String[] strStoreId = (String[])request.getAttribute("storeId");
          Enumeration e = abCatalogEntry.findBySKUNumberAndStore((String)request.getAttribute("itemPartNumber"),new Integer(strStoreId[0]));
          abCatalogEntry = (CatalogEntryAccessBean) e.nextElement();
        …
      
    5. Save and close the files.
  9. Update your payments and billing JSPF files to handle the Apple Pay payment method.
    1. Open the following files for editing.
      • /Stores/WebContent/Elite/ShoppingArea/CheckoutSection/CheckoutPaymentsAndBillingAddress.jspf
      • /Stores/WebContent/Elite/ShoppingArea/CheckoutSection/CheckoutPaymentsAndBillingAddress.jspf
    2. Around line 500, locate the following code.
      <c:if test="${currentPaymentMethodName != 'PayInStore' && currentPaymentMethodName 
      != 'CompatiblePayment' && (currentPaymentMethodName ne 'SimplePunchout' or (currentPaymentMethodName 
      eq 'SimplePunchout' and punchoutPaymentAllowed))}">
    3. Update the code by adding currentPaymentMethodName != 'ApplePay' method.
      The following example shows how the code looks after your update.
      <c:if test="${currentPaymentMethodName != 'ApplePay' && currentPaymentMethodName 
      != 'PayInStore' && currentPaymentMethodName != 'CompatiblePayment' && 
      (currentPaymentMethodName ne 'SimplePunchout' or (currentPaymentMethodName eq 'SimplePunchout' 
      and punchoutPaymentAllowed))}">
    4. Save and close the files.
  10. Update your JSP files to point to the correct search server.
    1. Open the following files for editing.
      • /Stores/WebContent/Elite/include/JSTLEnvironmentSetupExtForSearch.jspf
      • /Stores/WebContent/Elite/Snippets/Search/AutoSuggestSerialize.jsp
    2. Change all instances of CommonsHttpSolrServer to HttpSolrServer.
    3. Save and close the files.
  11. Update your JSPF files to fix subscription links.
    1. Open the following file for editing: Stores/WebContent/Elite/include/JSTLEnvironmentSetupExtForRemoteWidgets.jspf
    2. Remove the following snippet from the file:
      
          <c:when test="${!empty restNonSSLPort}">
                <c:set var="restURLPort" value="${restNonSSLPort}" scope="request"/>
                 <c:set var="restURLScheme" value="http" scope="request"/>
          </c:when>
      
    3. Save and close the file.
  12. Update your JSPF files to fix category-level previews.
    1. Open the following file for editing: /opt/WebSphere/AppServer/profiles/default/installedApps/localhost/ts.ear/Stores.war/tools/preview/StorePreviewer.jspf
    2. Locate the following code snippet:
      <c:set var="entitledOrgId" value="${entitledOrg.organizationIdInEntityType}"/>
    3. Update the organizationIdInEntityType value to organizationIdInEntityType, as illustrated in the following example:
      <c:set var="entitledOrgId" value="${entitledOrg.organizationIdInEntityType}"/>
    4. Locate the following code snippet:
      <c:set var="entitledOrgId" value="${entitledOrgs.entitledOrganizations[0].organizationIdInEntityType}"/>
    5. Update the organizationIdInEntityType value to organizationIdInEntityType, as illustrated in the following example:
      <c:set var="entitledOrgId" value="${entitledOrgs.entitledOrganizations[0].organizationIdInEntityType}"/>
    6. Save and close the file.
  13. Update your B2BMyAccountParticipantRole.jspf file to resolve a potential error when you view your history from the My account page.
    1. Open the following files for editing.
      • /Stores/WebContent/Elite/UserArea/AccountSection/B2BMyAccountParticipantRole.jspf
    2. Change all instances of organizationIdInEJBType to organizationIdInEntityType.
    3. Save and close the files.
  14. Update your Struts configuration XML file to fix the RefreshExternalContent scheduler.
    1. Open the following file for editing: Stores/WebContent/WEB-INF/struts-config-catalog-fep.xml
    2. Add the following action to the file:
      
      <action parameter="com.ibm.commerce.catalog.facade.server.commands.ScheduledExternalContentRefreshCmd" path="/RefreshExternalContent" type="com.ibm.commerce.struts.BaseAction">
      <set-property property="https" value="0:1"/>
      <set-property property="authenticate" value="0:0"/>
      </action>
      HCL Commerce Version 9.0.1.0 or later
      <action class="com.ibm.commerce.struts.v2.BaseAction" name="RefreshExternalContent">
      <param name="authenticate">0:0</param>
      <param name="https">0:1</param>
      <param name="parameter">com.ibm.commerce.catalog.facade.server.commands.ScheduledExternalContentRefreshCmd</param>
      </action>
    3. Save and close the file.
  15. Ensure that your store model is supported in your HCL Commerce configuration file.
    1. Open the following file:
      • workspace_dir/WC/xml/config/wc-server.xml
    2. Locate the <supportedStoreType> property, and ensure that your store model is listed, as illustrated in the following example:
      <supportedStoreType>
          <wca storeType="B2B"/>
          <wca storeType="B2C"/>
      <supportedStoreType/>
      
      Note: You can find your store model by querying your STORETYPE column of your STORE table.
      Failure to complete this step can lead to the following Accelerator error message at login: You do not currently have access to store using the HCL Commerce Accelerator. Contact the system administrator to verify your access control.
    3. If you modified the file, save and close the file.
  16. Local stores after migration are still local stores. Update your STORECONF table to indicate this.
    1. Open a command prompt to your HCL Commerce Version 9 development database.
    2. Run the following SQL command to retrieve the store IDs for your specific type of store:
      select store_id from store where directory in ('store_name');
      Where
      store_name
      The base name of your store, for example, Elite.
    3. For each extended site store ID retrieved, insert a corresponding record into your STORECONF table by running the following command:
      Insert into storeconf values(STOREENT_ID, 'wc.store.isRemote','0',0);
      Where:
      STOREENT_ID
      The ID of the store that you retrieved from the previous SQL command.