Skip to main content
Back to AutoCore Hub

ACES/PIES Data Lifecycle — End-to-End Service Trace

A complete, numbered trace of how ACES/PIES automotive catalog data flows through the AutoCore plugin: from import → indexing → B2C retrieval.


Interactive Lifecycle Trace

📥 AutoCore Data Lifecycle Trace

Data Ingestion Phase

Legacy ERP/ADW data is ingested via CSV and mapped to OFBiz entities.

Under the Hood
  • Orchestrator: DataImportWrapperServices.importGlobalProducts()
  • Key Services: storeBrand (ProductCategory), storeProduct (Product), storeProductFeature (ProductFeature), storeGoodIdentification (GoodIdentification)
  • Entities: Product, ProductCategory, ProductFeatureAndAppl, GoodIdentification
  • Logic: Synchronous chain of dispatcher.runSync calls per row.
Trace Context
{
"service": "DataImportServices.importGlobalProducts",
"action": "Entity Engine Writer",
"impact": "Creates core PIES item records in OFBiz DB",
"bridge": "wdPartyId provides the context scoping for brands/categories"
}
Trace Insight
Did you know? All imports are synchronous to ensure data integrity, but this is why they are the slowest part of the pipeline.

Architecture Overview

End-to-End Data Flow ArchitectureUse mouse wheel to zoom, drag to pan • Pull bottom edge to resize

Phase 1: Data Import (ACES/PIES → Entity DB)

Entry point: DataImportWrapperServicesDataImportServices

Pattern: dispatcher.runSync("serviceName", context) chains

Numbered Flow

StepServiceMethodWhat It Does
1.1DataImportWrapperServicesimportGlobalProducts()Orchestrator. Reads raw import rows from DataImportGlobalProduct, iterates in batches, calls Step 1.2 for each record. Tracks pass/fail scorecard.
1.2DataImportServicesimportGlobalProducts()Entity Writer. For a single import row, fans out to 10 sub-services via dispatcher.runSync:
1.2aDataImportServicesstoreBrandCreates/updates ProductCategory (type=AAIA_BRAND)
1.2bDataImportServicesstoreSubBrandCreates/updates ProductCategory (type=AAIA_SUB_BRAND)
1.2cDataImportServicesstoreTerminologyCreates/updates ProductCategory (type=AAIA_TERMINOLOGY) — ACES part type hierarchy
1.2dDataImportServicesstoreNPCStores Normalized Part Code metadata
1.2eDataImportServicesstoreProductCreates/updates Product entity — core PIES item record
1.2fDataImportServicesstoreProductNameCreates content record for PRODUCT_NAME
1.2gDataImportServicesstoreProductFeatureCreates ProductFeature + ProductFeatureAppl for SAT/PADB attributes
1.2hDataImportServicesstoreProductCategoryMemberLinks product to terminology/brand/sub-brand categories
1.2iDataImportServicesstoreGoodIdentificationStores EAN/UPCA/UPC identifiers in GoodIdentification
1.2jDataImportServicescreateProductPackageStores PIES package dimensions (weight, height, width, GTIN)
1.3DataImportWrapperServicesimportMemberProduct()Same pattern for member-specific parts. Calls DataImportServices.importMemberProduct()storeProduct, storeProductPrice, etc.
1.4DataImportWrapperServicesimportParts()Imports interchange/association data. Calls DataImportServices.importParts()storeProductAssoc (OE_SUBSTITUTE, COMPETITIVE_SUBSTT).

[!IMPORTANT] All imports are synchronous (dispatcher.runSync). A single importGlobalProducts wrapper call can trigger 10+ nested sync calls per row. This is the primary reason import is the slowest phase.


Phase 2: Solr Indexing (Entity DB → Solr Cores)

Entry point: ProductSolrServicesIndexingServices

Pattern: Build SolrInputDocument in Java → IndexingServices.addIndexes() → HTTP push to Solr

Numbered Flow

StepServiceMethodWhat It Does
2.1ProductSolrServicescreateGlobalProductIndex()Reads Product entities, builds SolrInputDocument with fields: productId, partNumber, stdPartNumber, brandId, subBrandId, terminologyId, images, prices, features.
2.2IndexingServicesaddIndexes()Receives List<SolrInputDocument> and core name globalproducts. Opens HttpSolrClient, calls client.add(docs) + client.commit(). Target: Solr core globalproducts.
2.3ProductSolrServicescreatePartIndex()Builds member/part-specific Solr docs from Product + ProductAssoc + ProductPrice. Includes facility, inventory, and availability metadata.
2.4IndexingServicesaddIndexes()Pushes part docs → Solr core parts.
2.5ProductSolrServicescreatePartInterchangeIndex()Builds interchange docs from ProductAssoc (type=OE_SUBSTITUTE / COMPETITIVE_SUBSTT). Maps OE numbers, competitive cross-references.
2.6IndexingServicesaddInterchangeIndexes()Pushes interchange docs → Solr core interchange (separate host/core config via getInterchageSolrHost()).

[!NOTE] Solr host resolution uses EntityUtilProperties — the Solr URL is read from import.properties per-core, not hardcoded. getSolrHost() and getInterchageSolrHost() are separate methods, meaning interchange can be on a different Solr instance entirely.

Delete Operations

ServiceMethodPurpose
IndexingServicesdeleteIndexByIdList()Removes specific docs by ID list before re-index
IndexingServicesdeleteIndexByQuery()Bulk purge by Solr query (e.g., full reindex scenarios)

Phase 3: B2C API Retrieval (Storefront → Data)

This phase has two parallel paths depending on what the consumer is asking for:

Path A: Product Details & Availability (PIES data)

StepServiceMethodWhat It Does
3A.1AutoCoreB2CProductServicesgetProductDetails()Entry point. Takes productSku, queries Product entity directly (NOT Solr). Hydrates a full product map:
3A.1aEntityQuery("Product")Resolves allianceProductIdproductId
3A.1bEntityQuery("ProductCategory")Fetches brand (AAIA_BRAND), sub-brand, terminology hierarchy
3A.1cEntityQuery("ProductCategoryRollupDetails")Walks category → subcategory → terminology tree
3A.1dEntityQuery("GoodIdentification")Fetches EAN/UPCA GTIN
3A.1eEntityQuery("ProductContentAndInfo")Images (ACA_DEF_THU, ACA_DEF_IMAGE, DIGITAL_ASSET, P04, LGO, MSD)
3A.1fEntityQuery("ProductPrice")Price waterfall: ZAP → LST → JOBBER → QOT → USR → WD1 → fallback 1234.56
3A.1gEntityQuery("ProductFeatureAndAppl")SAT_ATTRIBUTE and PADB_ATTRIBUTE features
3A.1hEntityQuery("ProductPackage")Package dimensions + GTIN
3A.1iEntityQuery("ProductAssoc")Part interchange (OE_SUBSTITUTE, COMPETITIVE_SUBSTT)
3A.1jdispatcher.runSync("getBrandImageUrl")Fetches brand logo URLs (logo_100, logo_400)
3A.2AutoCoreB2CProductServicescheckProductAvailability()Takes partNumber + manufacturerCode + locationId.
3A.2adispatcher.runSync("checkPartAvailability")External call to AES (Alliance Inventory System). Sends JSON basket, receives real-time inventory: quantityAvailable, unitCostPrice.
3A.3AutoCoreB2CProductServicescheckSITMOptionAvailability()Checks if "Ship It To Me" is enabled for any facility in the product store. Reads FacilityShipmentSetting for SHIP_IT_TO_ME method type.
3A.4AutoCoreB2CProductServicesgetSITMInventoryAvailability()Aggregates SITM inventory across all non-store-locator facilities. Also calls checkPartAvailability (AES).
StepServiceMethodWhat It Does
3B.1AutoCoreB2CVehicleServicesgetYears()Queries BaseVehicleAndType → returns distinct years for region + vehicle type. Direct EntityQuery, no Solr.
3B.2AutoCoreB2CVehicleServicesgetMakes()Queries BaseVehicleAndType + Make → returns makes for year/region/type.
3B.3AutoCoreB2CVehicleServicesgetModels()Queries BaseVehicleAndType + Model → returns models for year/make/region/type.
3B.4AutoCoreB2CVehicleServicesgetBaseVehicleID()Queries BaseVehicle → resolves Y/M/M to BaseVehicleID.
3B.5AutoCoreB2CVehicleServicesgetSubModels()Queries Vehicle + Submodel → returns submodels for baseVehicleId.
3B.6AutoCoreB2CVehicleServicesgetEngineConfigurations()Queries VehicleVehicleToEngineConfigEngineConfigAndTypeDescriptionFuelDeliveryConfigFuelSystemDesign. Builds human-readable engine string (e.g., "V6 3.5L 3458cc Gas DI Naturally Aspirated").
3B.7AutoCoreB2CVehicleServicestestFitmentForPart()Fitment validation. Calls OpticatSearchServices.sendOpticatSearchRequest() with getAutoCareSearchResults. Returns fitmentStatus: True/False.
3B.8AutoCoreB2CVehicleServicesgetOpticatSearchResults()Full fitment search. Calls Opticat twice: first for total count, then with includeParts=true + facets. Returns productSkuList + fitmentFacets.
3B.9AutoCoreB2CVehicleServicesgetOpticatPartApplicationDetails()Part application details. Calls OpticatSearchServices.sendOpticatSearchRequest() with getAutoCarePartApplications. Parses ACES attributes, notes, positions, engine base applications.
3B.10OpticatSearchServicessendOpticatSearchRequest()HTTP proxy to Opticat. Static POST to webservice.opticatonline.com/autocare/v1/services/Catalog.jsonEndpoint. Uses Basic Auth + API key. Returns parsed JSON response.

[!WARNING] Vehicle DNA queries (steps 3B.1–3B.6) read directly from the VCDb entity tables, not from Solr. The VCDb data (BaseVehicle, Make, Model, Submodel, EngineConfig) is a separate dataset from the product catalog — it's the ACES reference database for vehicle identification.


Summary: Two Worlds, One Plugin

PIES vs ACES Service DomainsUse mouse wheel to zoom, drag to pan • Pull bottom edge to resize
DimensionPIES (Product)ACES (Fitment)
ImportDataImportServices → entity DBVCDb reference tables (pre-loaded)
IndexProductSolrServices → Solr coresNot indexed — queries external Opticat API
RetrieveAutoCoreB2CProductServices → entity DB directAutoCoreB2CVehicleServices → entity DB + Opticat HTTP
External dependencyAES (inventory check)Opticat (webservice.opticatonline.com)
CouplingZero cross-talk with ACES servicesZero cross-talk with PIES services

[!CAUTION] The integration between ACES and PIES happens exclusively at the data/entity level, not at the service level. There is no dispatcher.runSync call between VCDBServices/AutoCoreB2CVehicleServices and DataImportServices/AutoCoreB2CProductServices. The SKU generated by getOpticatSearchResults (step 3B.8) is the bridge: stdPartNumber-brandCode-subBrandCode — this SKU is then used client-side to call getProductDetails (step 3A.1) for the full PIES product data.