CX Works

A single portal for curated, field-tested and SAP-verified expertise for your SAP C/4HANA suite. Whether it's a new implementation, adding new features, or getting additional value from an existing deployment, get it here, at CX Works.

Developing SAP Commerce Cloud Locally

Developing SAP Commerce Cloud Locally

SAP Commerce Cloud provides a standardized, automated end-to-end build and deployment solution for Commerce projects to release code from the repository to the cloud.

Many aspects of SAP Commerce Cloud overlap with the capabilities of continuous integration (CI) and continuous delivery (CD) solutions such as Jenkins. However, SAP Commerce Cloud is not a wholesale replacement for Jenkins, which supports many other capabilities and use cases beyond the scope of SAP Commerce Cloud.

This article outlines the best practices of using SAP Commerce Cloud as part of your project, as well as being covered in this video.

Table of Contents


General Development Best Practices

Before starting this article, you should read through the general best practices and guidelines for working with SAP Commerce Cloud that are covered in the product documentation. These practices can be found here. The following article will cover the development practices for implementing SAP Commerce Cloud solutions.

Release Cadence

As outlined in "Getting Started with SAP Commerce Cloud", your SAP Commerce Cloud solution may consist of a few different code bases that are are all merged as part of the build and deploy process:

Automatically Upgraded:

  • SAP Commerce Cloud automation (release notes) - feature releases typically occur each month, patches ongoing.
  • SAP Commerce Cloud Extension Packs (release notes, documentation) - available only for Commerce Cloud on Public Cloud customers. Releases occur each month.

Requires the use of a compatible version:

  • SAP Commerce (release notes) -  See the release notes for the most up to date version. Previously, there were new releases every quarter, but this will be reduced going forward to as little as one release per year.
  • Spartacus Javascript storefront (documentation) - ongoing. Pull code for the latest.
  • Industry accelerators (documentation) - dependent on the industry accelerator.
  • Data Hub (documentation) - dependent on the SAP Commerce release.

In some cases, there is a dependency on the correct code version to ensure compatibility with your SAP Commerce Cloud solution. You should check the compatibility page to ensure you are using the right version for each code base. You have the ability to determine when to upgrade certain portions of your solution.


Connect your Code Repository

SAP Commerce Cloud takes into account your code customizations which are stored in a Git-based code repository. Once you have access to the SAP Commerce Cloud portal, it is essential that you connect your code repository as shown in the following video:

https://enable.cx.sap.com/media/Connect+Your+Code+Repository+to+Cloud+Portal+-+SAP+Commerce+Cloud/1_df6ptanl/89743531.

We strongly recommend that you do not store any private properties (for example, passwords) in your source code repository. Instead, to define these sensitive properties, you should leverage the Service Configuration option in the SAP Commerce Cloud portal for each endpoint.

Third-Party Java Libraries

To keep the source repository footprint small and to make library updates simple and reliable, each Commerce Platform extension is able to use Maven to manage them.


Ant Customize

Sometimes, it may appear necessary to customize the platform code delivered as part of Commerce. This may be because you are unable to extend or override the code, or you need a different jar file, or you are required to patch certain files in your existing SAP Commerce suite. This would normally be done using the "ant customize" target.  Please be aware SAP Commerce Cloud does not currently support running the "customize" target.


If you think you can only solve your issue through running ant customize, please engage SAP CX Services before doing so.

Configuration Reuse

When moving from local development to cloud environments, it is important to consider how you can reuse your configurations. As outlined in this page of the product documentation, the following local configurations can be linked in your manifest.json file:

  • Solr
  • Properties
  • Extensions
  • Languages

Solr

As outlined in Getting Started with SAP Commerce Cloud, SAP Commerce Cloud typically uses a cloud setup of Apache Solr which includes three Zookeeper nodes and two Solr nodes. You can configure your code repository to customize how Solr is configured (for example, solrconfig.xml) to ensure it works the way you need it to. Keep in mind, that any changes you make to your Solr configuration could break your search functionality. If you need to customize Solr for your SAP Commerce Cloud solution, please see this section in the product documentation. It covers the compatibility requirements, repository setup and manifest.json configuration. If you're looking for more information on improving your search functionality, please see Search and Navigation in SAP Commerce Cloud - An In-depth Series.

Language Packs

You should try to include only the languages you will support, as unnecessary languages can slow down the build and deploy cycle. If you the use of language packs, you can have them deployed using the following:

  1. In the root of your code repository, create a folder for storing language packs, such as "_LANGUAGES_”.
  2. Add your language pack zip files to this folder.
  3. Add the following property to your manifest.json with only the languages you have.


        "useConfig":
    {
    		...
            "languages" : {
                "location": "_LANGUAGES_"
            }
    }

Extensions

In order to keep your configurations in sync between your local and the SAP Commerce Cloud environments, you should configure your manifest.json file to point to your localextensions.xml file as covered in this page of the product documentation. If you have some extensions you use locally, you should make use of the "exclude" option to ensure they are not deployed in your SAP Commerce Cloud environments.


Not all extensions are supported by SAP Commerce Cloud. Before including an extension in your localextensions.xml, please consult the Compatibility Matrix page to determine if it is supported.

HTTP Session Failover

Sessions, used by clients that are bound to an individual cluster node, stick with the cluster node. Consequently, an SAP Commerce Cloud cluster uses sticky sessions. In addition, SAP Commerce Cloud offers a session failover mechanism. For more details, see HTTP Session Failover.


Enable the following property in your local development environment for logging when a non-serializable object is added to an HTTP session: session.serialization.check=true

Complete Manifest.json

This page of the product documentation covers the many different components of a manifest.json file. There are also many different example manifest files for a variety of common scenarios.  Below (in JSON) is a complete manifest.json file that reflects different properties files per environment and aspect. It also reflects a custom Solr configuration, languages packs, multiple add-ons, the definition of the aspects, and the ability to run various types of tests.

NOTE: We have not provided a full list of tests in order to keep the size of the code smaller.


manifest.json
{
    "commerceSuiteVersion": "1808.5",
    "useConfig": {
        "properties": [
            {
                "location": "/config/local.properties"
            },
            {
                "location": "/config/local-dev.properties",
                "persona": "development"
            },
            {
                "location": "/config/local-prod.properties",
                "persona": "production"
            },
            {
                "location": "/config/local-backoffice-prod.properties",
                "persona": "production",
                "aspect": "backoffice"
            },
            {
                "location": "/config/local-backoffice.properties",
                "aspect": "backoffice"
            }
        ],
        "extensions": {
            "location": "/config/localextensions.xml",
            "exclude": [
                "ycommercewebservicestest"
            ]
        },
        "solr": {
            "location": "/config/solr"
        },
        "languages" : {
            "location": "_LANGUAGES_"
        },
    }
    "storefrontAddons" : [
        {
            "addon": "commerceorgsamplesaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "promotionenginesamplesaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "textfieldconfiguratortemplateaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "assistedservicestorefront",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "assistedservicepromotionaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "customerticketingaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "orderselfserviceaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "adaptivesearchsamplesaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "pcmbackofficesamplesaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "personalizationsearchsamplesaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "smarteditaddon",
            "storefront": "yacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "commerceorgsamplesaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "promotionenginesamplesaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "textfieldconfiguratortemplateaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "assistedservicestorefront",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "assistedservicepromotionaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "customerticketingaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "orderselfserviceaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "adaptivesearchsamplesaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "pcmbackofficesamplesaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "personalizationsearchsamplesaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon": "smarteditaddon",
            "storefront": "yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon":"b2bacceleratoraddon",
            "storefront":"yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon":"commerceorgaddon",
            "storefront":"yb2bacceleratorstorefront",
            "template": "yacceleratorstorefront"
        },
        {
            "addon":"acceleratorwebservicesaddon",
            "storefront":"ycommercewebservices",
            "template":"ycommercewebservices"
        }
    ],
    "aspects": [
        {
            "name": "backoffice",
            "properties": [
                {
                    "key": "backoffice.test.property.1",
                    "value": "backoffice.test.property.1.value"
                },
                {
                    "key": "backoffice.test.property.2",
                    "value": "backoffice.test.property.2.value"
                }
            ],
            "webapps": [
                {
                    "name": "hac",
                    "contextPath": "/hac"
                },
                {
                    "name": "mediaweb",
                    "contextPath": "/medias"
                },
                {
                    "name": "backoffice",
                    "contextPath": ""
                }
            ]
        },
       { 
            "name": "accstorefront",
            "properties": [
                {
                    "key": "spring.session.enabled",
                    "value": "true"
                },
                {
                    "key": "spring.session.yacceleratorstorefront.save",
                    "value":"async"
                },
                {
                    "key": "spring.session.yacceleratorstorefront.cookie.name",
                    "value": "JSESSIONID"
                },
                {
                    "key": "spring.session.yacceleratorstorefront.cookie.path",
                    "value": "/yacceleratorstorefront"
                },
                {
                    "key": "spring.session.yb2bacceleratorstorefront.save",
                    "value":"async"
                },
                {
                    "key": "spring.session.yb2bacceleratorstorefront.cookie.name",
                    "value": "JSESSIONID"
                },
                {
                    "key": "spring.session.yb2bacceleratorstorefront.cookie.path",
                    "value": "/yb2bacceleratorstorefront"
                }
            ],
            "webapps": [
                {
                    "name": "hac",
                    "contextPath": "/hac"
                },
                {
                    "name": "mediaweb",
                    "contextPath": "/medias"
                },
                {
                    "name": "yb2bacceleratorstorefront",
                    "contextPath": "/yb2bacceleratorstorefront"
                },
                {
                    "name": "yacceleratorstorefront",
                    "contextPath": "/yacceleratorstorefront"
                },
                {
                    "name": "acceleratorservices",
                    "contextPath": "/acceleratorservices"
                }
            ]
        },
        {
            "name": "backgroundProcessing",
            "properties": [],
            "webapps": [
                {
                    "name": "hac",
                    "contextPath": ""
                },
                {
                    "name": "mediaweb",
                    "contextPath": "/medias"
                }
            ]
        }
    ],
    "tests": {
        "extensions": ["customerticketingaddon", "yacceleratorstorefront", "commerceservicesbackoffice"],
        "annotations": ["UnitTests", "IntegrationTests"],
        "packages": ["de.hybris.*"]
    },
    "webTests": {
        "extensions": ["yacceleratorstorefront"],
        "excludedPackages": ["de.hybris.platform.*"]
    }
}


Monitoring and Troubleshooting

Application Performance Monitoring (APM)

Each node in each environment includes Dynatrace agents that are used to monitor the health of the environment as well as to help troubleshoot issues. You can access the full stack monitoring capabilities of Dynatrace through the SAP Commerce Cloud Portal. See this page in the documentation for more. If you need assistance with the performance of your site, please contact your Customer Engagement Executive, or contact SAP CX Services to find the nearest available SAP Customer Experience representative.

For more on the Dynatrace solution, please watch this video: Dynatrace Observability Solution for SAP Commerce Cloud.

Centralized Logging

Each environment of SAP Commerce Cloud comes with its own centralized logging endpoint which launches Kibana. This provides a single point to review logs for the aspects defined in your manifest.json file. This video covers the centralized logging with instructions. 

If you are unfamiliar with Kibana or are looking for a quick start, we have attached the Commerce Cloud Kibana Example.json to this page. This contains some helpful dashboards, searches and visualizations. To use it:

  1. Follow steps #1 and 2 from the product documentation to launch Kibana.
  2. Download Commerce Cloud Kibana Example.json.
  3. Select Management → Saved Objects → Import.





  4. Upload the JSON file you downloaded in the step above.
  5. Click on the "Dashboard" option in the left panel to select one of three dashboards:


Dashboard - Cloud: Overview of what is occurring across all servers:



Dashboard - Console Logs: Overview of what is occurring in the console logs:


You can click on the word "cloud" or "pie chart" to filter down to a particular aspect and/or log level.



Dashboard - Access Log: Overview of access logs for your storefront and backoffice servers:


You can click on the word "cloud" or "pie chart" to filter down to a particular aspect and/or HTTP Status.




Conclusion

If you are familiar with developing SAP Commerce solutions, then the move to SAP Commerce Cloud will mostly require an adjustment to how your code is structured in your repository. Additionally, it will require an adjustment as to how best to configure your manifest.json file and how to use logging to your advantage. By understanding what you can and cannot do with SAP Commerce Cloud, you will be better positioned to deliver a successful SAP Commerce Cloud solution.