SAP Commerce Cloud Architecture Overview
Comprehensive guide to SAP Commerce Cloud architecture: platform services, CCv2 aspects, deployment pipeline, cluster topology, and integration patterns.
SAP Commerce Cloud (formerly Hybris) is a Java-based e-commerce platform built on Spring Framework, deployed on a managed cloud infrastructure (CCv2). This guide covers the core architectural patterns that every commerce architect and developer must understand: platform services, the extension system, CCv2-specific deployment model, and integration patterns.
Platform Services Architecture#
The SAP Commerce platform is built around a service-oriented architecture with three key layers:
- Type System: dynamic data model with runtime type definition
- Service Layer: business logic, transactions, validation
- Facades: simplified API for frontend/integration consumption
Type System#
SAP Commerce uses a custom type system defined in *-items.xml files. Types are compiled into JaLo classes (legacy) and Models (current standard).
<itemtype code="Product" extends="GenericItem">
<deployment table="products" typecode="1"/>
<attributes>
<attribute qualifier="code" type="java.lang.String">
<modifiers unique="true" optional="false"/>
<persistence type="property"/>
</attribute>
<attribute qualifier="name" type="localized:java.lang.String">
<persistence type="property"/>
</attribute>
<attribute qualifier="catalogVersion" type="CatalogVersion">
<modifiers optional="false"/>
<persistence type="property"/>
</attribute>
</attributes>
</itemtype>
Key type system concepts:
- Deployment: table name + typecode (numeric identifier for serialization)
- Attributes: can be stored (persisted to DB) or dynamic (calculated at runtime)
- Relations: one-to-many and many-to-many via separate relation items
- Interceptors: validate, prepare, or react to model changes (lifecycle hooks)
- Localization: attributes can be localized per language via
localized:prefix
Service Layer#
Business logic lives in service beans. Services are Spring-managed, transactional, and testable:
@Service
public class DefaultProductService implements ProductService {
@Resource
private FlexibleSearchService flexibleSearchService;
@Resource
private ModelService modelService;
@Override
public ProductModel getProductForCode(String code) {
final FlexibleSearchQuery query = new FlexibleSearchQuery(
"SELECT {pk} FROM {Product} WHERE {code} = ?code"
);
query.addQueryParameter("code", code);
return flexibleSearchService.searchUnique(query);
}
@Override
@Transactional
public void updateProduct(ProductModel product) {
modelService.save(product);
}
}
Service layer best practices:
- Use FlexibleSearch for queries (platform-managed SQL abstraction)
- Transaction boundaries via
@Transactional(Spring TX) - Validation via Interceptors and Validators
- No UI concerns. Service layer is backend-only
- Avoid direct DAO access. Use ModelService for CRUD
Facades#
Facades simplify service layer complexity for frontends and integrations. They convert Models to DTOs (Data Transfer Objects):
@Component
public class DefaultProductFacade implements ProductFacade {
@Resource
private ProductService productService;
@Resource
private Converter<ProductModel, ProductData> productConverter;
@Override
public ProductData getProductForCode(String code) {
final ProductModel product = productService.getProductForCode(code);
return productConverter.convert(product);
}
}
Facades return DTOs (Data Transfer Objects), never models directly. DTOs are serialization-safe, versioned, and decouple the API from internal models.
Extension System#
SAP Commerce is modular. All functionality ships as extensions. Core platform extensions:
| Extension | Purpose |
|---|---|
core | Platform kernel, type system, Spring context |
catalog | Catalogs, categories, classification |
basecommerce | Product, price, stock fundamentals |
commercefacades | Standard facades + DTOs |
commerceservices | Standard services (cart, order, customer) |
commercewebservices | OCC REST API (headless commerce) |
backoffice | Admin UI framework |
acceleratorservices | B2C/B2B storefront foundation |
acceleratorstorefrontcommons | Storefront web layer (controllers, tags) |
Extension Structure#
myextension/
├── extensioninfo.xml # extension metadata, dependencies
├── project.properties # build config, cache regions
├── resources/
│ ├── myextension-items.xml # type system definitions
│ ├── myextension-spring.xml # Spring bean wiring
│ ├── localization/ # i18n bundles
│ └── impex/ # initial data, migrations
├── src/ # Java source
├── testsrc/ # unit/integration tests
└── web/ # web UI (storefront/backoffice)
Extensions declare dependencies in extensioninfo.xml:
<extension name="myextension">
<requires-extension name="commerceservices"/>
<requires-extension name="commercefacades"/>
<coremodule generated="true" packageroot="com.example.myextension"/>
<webmodule webroot="/myextension"/>
</extension>
Build order is calculated from dependency graph. Circular dependencies are rejected at compile time.
CCv2 Architecture (SAP Commerce Cloud v2)#
CCv2 is the managed cloud platform for SAP Commerce. It introduces aspects, independently scalable deployment units.
Aspect Model#
An aspect is a logical deployment unit with a specific role. CCv2 supports:
| Aspect | Purpose | Scalability |
|---|---|---|
accstorefront | Customer-facing storefront (B2C/B2B) | Horizontal (auto-scale) |
backoffice | Admin UI for content/catalog management | Vertical (fixed instances) |
backgroundProcessing | Async jobs (cronjobs, indexing, batch) | Horizontal (job-based) |
api | OCC REST API (headless commerce) | Horizontal (auto-scale) |
datahub | Legacy integration layer (deprecated) | Vertical (fixed) |
Each aspect runs as a separate cluster of nodes with isolated configuration.
Aspect Configuration#
Aspects are configured via manifest.json in the cloud portal repository:
{
"commerceSuiteVersion": "2211.24",
"aspects": [
{
"name": "accstorefront",
"properties": [
{
"key": "spring.session.store-type",
"value": "redis"
},
{
"key": "cluster.node.groups",
"value": "integration,yHotfolderCandidate"
}
],
"webapps": [
{
"name": "mystorefront",
"contextPath": ""
}
]
},
{
"name": "backgroundProcessing",
"properties": [
{
"key": "cluster.node.groups",
"value": "integration,yHotfolderCandidate,backgroundProcessing"
}
]
}
],
"extensions": ["mystorefront", "mycore"]
}
Key aspect config patterns:
- cluster.node.groups: controls which cronjobs run on which aspect
- spring.session.store-type: session replication strategy (redis, jdbc, none)
- webapps: which web applications deploy to this aspect (storefront, backoffice)
CCv2 Build Process#
CCv2 builds are triggered via Git push to the cloud portal repository. Build pipeline:
graph LR
A[Git Push] --> B[Cloud Portal Webhook]
B --> C[Build Server: ant clean all]
C --> D[Docker Image Build]
D --> E[Image Push to Registry]
E --> F[Deployment to Environment]
F --> G[Health Check]
G --> H[Traffic Cutover]
Build stages:
- Source checkout: Cloud portal clones the repository
- Ant build:
ant clean allcompiles extensions, builds datahub - Docker image: Platform + extensions packaged into Docker image
- Image push: Image pushed to CCv2 registry (GCR/ACR)
- Deployment: Rolling deployment to target environment
- Health check: Platform readiness probe (Spring Boot actuator)
- Traffic cutover: Load balancer switches to new pods
Build artifacts:
hybris/bin/platform: compiled platformhybris/data: initial data (ImpEx, media)manifest.json: aspect configurationsolr/: Solr core config (if using embedded Solr)
CCv2 Deployment Environments#
CCv2 provides isolated environments for each stage of the SDLC:
| Environment | Purpose | Refresh Strategy |
|---|---|---|
| Development | Feature development, integration testing | Database reset nightly |
| Staging | Pre-production testing, UAT | Database cloned from production monthly |
| Production | Live customer traffic | Blue/green deployment |
Each environment has:
- Dedicated database (Azure SQL, AWS RDS)
- Dedicated Redis (session store, cache)
- Dedicated Solr cluster (search index)
- Dedicated blob storage (media files)
Environment Variables#
CCv2 injects environment-specific config via environment variables:
# project.properties
db.url=${HYBRIS_DB_URL}
db.driver=com.mysql.jdbc.Driver
db.username=${HYBRIS_DB_USER}
db.password=${HYBRIS_DB_PASSWORD}
media.default.url.strategy=azure
media.azure.storage.account.connection-string=${AZURE_STORAGE_CONNECTION_STRING}
cluster.node.groups=${CLUSTER_NODE_GROUPS}
CCv2 sets these at runtime via pod environment:
HYBRIS_DB_URL,HYBRIS_DB_USER,HYBRIS_DB_PASSWORDAZURE_STORAGE_CONNECTION_STRING(or S3 equivalent)CLUSTER_NODE_GROUPS(aspect-specific)SPRING_PROFILES_ACTIVE(environment-specific Spring profiles)
Data Model Patterns#
Product Model#
Products in SAP Commerce are hierarchical:
- Product (base type): sku, name, description
- VariantProduct (extends Product): color, size variants
- ApparelProduct / ElectronicsProduct: domain-specific extensions
Products belong to Catalogs and Categories. Classification via ClassificationClass and ClassificationAttribute for faceted navigation.
Catalog versioning:
- Staged: content editing, not visible to customers
- Online: published content, customer-facing
Price Model#
Pricing is multi-dimensional via PriceRow:
PriceRow: product + user group + currency + unit + date range → price
Price calculation via PriceFactory and PriceService. Discounts/promotions via Promotion Engine (CAP, Context-Aware Pricing).
Price resolution order:
- User-specific price (B2B negotiated pricing)
- User group price (customer segment)
- Base price (fallback)
Order Model#
Order lifecycle:
- Cart (OrderModel with versionID): shopping cart
- Order (OrderModel submitted): placed order
- ConsignmentEntry: fulfillment/shipment
Order calculation via CalculationService applies totals, taxes, and discounts in sequence:
- Item prices
- Discounts (order-level, line-level)
- Delivery cost
- Taxes
- Payment cost
Cluster Topology#
CCv2 runs SAP Commerce in a clustered environment. Key clustering patterns:
Session Replication#
Session replication strategies:
| Strategy | Mechanism | Use Case |
|---|---|---|
redis | External Redis cache | Production (CCv2 default) |
jdbc | Database-backed sessions | Legacy on-premise |
none | No replication (sticky sessions) | Development only |
Redis session config:
spring.session.store-type=redis
spring.redis.host=${REDIS_HOST}
spring.redis.password=${REDIS_PASSWORD}
Media Storage#
Media files (images, documents) must be shared across nodes:
- On-premise: Shared filesystem (NFS)
- CCv2: Azure Blob Storage or AWS S3
Azure Blob config:
media.default.url.strategy=azure
media.azure.storage.account.connection-string=${AZURE_STORAGE_CONNECTION_STRING}
media.azure.storage.container.name=commerce-media
Task Engine#
The Task Engine runs background jobs (cronjobs). In a cluster:
- Tasks are locked at the database level (distributed lock)
- Only one node executes a given task at a time
- Node groups control which aspect executes which cronjob
Node group assignment:
cluster.node.groups=integration,yHotfolderCandidate,backgroundProcessing
Integration Patterns#
OCC (Omnichannel Commerce REST API)#
Standard REST API for headless storefronts:
- Base path:
/occ/v2/{baseSiteId}/ - Endpoints:
/products,/carts,/users,/orders - OAuth2 authentication (client credentials, password grant)
- Extensible via custom controllers and DTOs
OCC endpoint example:
GET /occ/v2/electronics/products/1234?fields=FULL
Authorization: Bearer <token>
Response:
{
"code": "1234",
"name": "Sample Product",
"price": {
"value": 99.99,
"currencyIso": "USD"
},
"stock": {
"stockLevel": 10
}
}
ImpEx#
Data import/export DSL (Domain-Specific Language):
INSERT_UPDATE Product; code[unique=true]; name; catalogVersion(catalog(id),version)
; product123 ; "Sample Product" ; Default:Staged
; product456 ; "Another Product" ; Default:Staged
INSERT_UPDATE Category; code[unique=true]; name; catalogVersion(catalog(id),version)
; cat001 ; "Electronics" ; Default:Staged
INSERT_UPDATE CategoryProductRelation; source(code,catalogVersion(catalog(id),version)); target(code,catalogVersion(catalog(id),version))
; cat001:Default:Staged ; product123:Default:Staged
Used for:
- Initial data load (essential data, sample data)
- Migrations (data model changes)
- Test data setup (integration tests)
- Bulk operations (price updates, catalog sync)
Event System#
SAP Commerce publishes Business Events for async processing:
@Component
public class OrderPlacedEventListener extends AbstractEventListener<OrderPlacedEvent> {
@Resource
private EmailService emailService;
@Override
protected void onEvent(OrderPlacedEvent event) {
final OrderModel order = event.getOrder();
emailService.sendOrderConfirmation(order);
}
}
Events are:
- Async: processed via Spring
@Asyncthread pool - Transactional: committed only after the originating transaction commits
- Persistent: can be replayed for auditing
Common events:
OrderPlacedEventProductModifiedEventCustomerRegisteredEventCartModifiedEvent
Performance Considerations#
Caching#
SAP Commerce uses multi-layer caching:
| Cache Type | Mechanism | Scope |
|---|---|---|
| Region Cache | Ehcache | Type system, catalogs, CMS |
| FlexibleSearch Cache | Query result cache | Read-heavy queries |
| CMS Page Cache | Pre-rendered pages | Storefront performance |
Cache regions per extension in project.properties:
regioncache.myextension.size=10000
regioncache.myextension.evictionpolicy=LFU
Database Optimization#
- Use FlexibleSearch with proper indexing (not raw SQL)
- Avoid N+1 queries. Fetch relations in one query
- Partition large tables (
OrderEntry,PriceRow,CustomerReview) - Monitor slow queries via DB Performance Monitoring in HAC
Index example:
CREATE INDEX idx_product_code ON products(p_code);
CREATE INDEX idx_order_user ON orders(p_user);
Clustering Best Practices#
- Session replication: Use Redis in production (not JDBC)
- Media storage: External blob storage (Azure/S3), not filesystem
- Task Engine: Assign cronjobs to
backgroundProcessingaspect only - Health checks: Configure readiness/liveness probes for k8s
- Logging: Centralized logging (ELK, Splunk) for distributed tracing
Next Steps#
These deeper guides are in development. Topics planned:
- OCC API Integration Patterns
- Backoffice Customization
- Promotion Engine (CAP) deep dive
- Spartacus / Composable Storefront architecture
- CCv2 deployment troubleshooting