In this blog I describe how to create and run a local version of the promotion pricing service (PPS) based on the artifacts delivered with SAP Customer Activity Repository application bundle (CARAB). This delivery offers the central PPS as part of the omnichannel promotion pricing (OPP) module.
Previously
In a previous blog (https://blogs.sap.com/2018/10/11/sap-opp-black-box-concept-implementation-guidance-for-non-sap-envir…), my colleague ingo.woesner described how to assemble a custom Java Web Application containing both the price calculation and the upload of regular prices and promotions. This stand-alone application could then be used for various purposes, for example, easy prototyping, developing, or debugging custom extensions to the SAP standard logic.
To bring all needed artifacts together for this approach, you had to have both the central PPS to access the database of the corresponding SAP Customer Activity Repository (SAP CAR) installation, as well as the SAP Commerce, integration package for SAP for Retail containing the SAP Commerce extension “sapppspricing”. This extension offers an embedded version of the price calculation and the upload of IDocs for regular prices and promotions.
With SAP Customer Activity Repository application bundle 5.0 SPS06 the situation has changed. The central PPS of this shipment comes with all artifacts that are needed to create a stand-alone version of a local PPS box, formerly known as “Black Box”.
Besides the necessary artifacts, this delivery also allows the simple creation of a running application. Therefore, the previous blog by Ingo can be replaced by the following steps described in this blog.
Disclaimer
The local PPS box is not an official SAP product! Any productive usage is outside of any SAP support contract. Therefore, there is no responsibility on SAP side for any issue you may be facing during the usage of the local PPS box. If you encounter an issue and rank it as a bug, make sure you can reproduce it with an official SAP standard product, like for example:
-
- Using of the central PPS with SAP CAR
-
- Using of the cloud offering SAP Omnichannel Promotion Pricing (Note that a separate license is required. If you do not have a license, keep in mind that SAP offers a free trial.)
If this is not possible, you cannot rely on any SAP support.
For more information about things to be considered when using the local PPS box, see section “Gaps”.
Prerequisites
Note that the following procedure is based on a specific environment setup. For this blog, I am using the following programs:
-
- Windows 11
-
- Apache Maven 3.8.8
-
- SapMachine 11
-
- WSL2 running Ubuntu 22.04 using Docker as a service.
-
- Insomnia
-
- H2 2.2.224
-
- MS Edge
For the extraction of data, I am using WinRar which is associated with the file extensions “.zip”, “.mtar” and “.war”. Obviously, many other tools can be used to open the archives as well, including Windows built-in functionality.
If you are using a different setup, the prerequisites and the procedure may differ from the description below.
To create your local PPS box, you need to fulfill the following:
-
- You have a valid license of the central PPS. Without this, you are neither allowed to use the central PPS nor the local PPS box reusing parts of the central PPS. If you are in doubt, please contact your SAP account executive. Note that the license is not bound to a specific SAP CARAB release. Even if you are on a lower CARAB release or feature pack, you can download the newest version of the central PPS and build your local PPS box.
-
- You have Apache Maven installed (https://maven.apache.org/).
-
- You have Java installed with a version greater or equal to 8. I recommend using Sap Machine (https://sap.github.io/SapMachine/).
-
- You have Docker available. This could be Docker for Windows (https://www.docker.com/products/docker-desktop/), Docker in WSL2 (https://learn.microsoft.com/en-us/windows/wsl/about) or Docker in a Virtual Machine running Linux.
Note that Docker is not needed to BUILD the web application, but it greatly facilitates the creation of a stable runtime environment (including Java, Apache Tomcat with proper configuration etc.)
- You have Docker available. This could be Docker for Windows (https://www.docker.com/products/docker-desktop/), Docker in WSL2 (https://learn.microsoft.com/en-us/windows/wsl/about) or Docker in a Virtual Machine running Linux.
-
- You have any modern web browser available.
-
- Optionally, you have any HTTP client (Postman, Insomnia, CURL) to test if the local PPS box is running.
-
- Optionally, you have H2 installed (https://www.h2database.com/html/download.html) so you can investigate the DB content.
From Zero to Hero
Step 0
The italic paragraphs in this procedure contain additional information, which is not necessarily needed to create your local PPS box. If you just want to get it running, you can skip those paragraphs.
Step 1
Visit https://me.sap.com/softwarecenter/search/xsac_opp_pps_2 and download the Software Component archive of your choice.
Keep in mind, only support packages >= SP07 (which are shipped with SAP CARAB 5.0 SP6) contain all needed artifacts for the local PPS box. The patch level may be different from the screenshot. If you are not sure which version of the central PPS belongs to which CARAB delivery, see the following overview about OPP-related versions: https://help.sap.com/docs/CARAB/e95c8443f589486bbfec99331049704a/ea5a162ff18d49b2bc41fc0cd447407a.ht… – note that there may be newer versions of the page available in the meantime, make sure you select the newest CARAB version to see the most complete list:
Step 2
On your computer, create a folder of your choice. This will later contain temporary data, as well as the database file etc. For this blog I am using the folder C:my_local_pps_box
This folder will later be accessed from the web application running in a Docker container. Make sure this folder is not protected.
Step 3
Open the downloaded software component archive (XSACOPPPPSxx_xx-xx.ZIP) and in that, open the contained MTA archive (sap-xsac-opp-pps-x.xx.mtar). Extract the following folders to C:my_local_pps_box:
-
- additional
-
- localppsresources
-
- sampleproject
Additionally, open the web application archive (“WAR”) file ppservice-webapp-central.war and navigate to folder WEB-INFlib. Extract the files ppengine* and pricing* to folder “additional” in C:my_local_pps_box
With this, you have extracted all necessary information from the delivery to your local disk. The JAR files in folder “additional” are required for the Maven build of the local PPS box. The folder “sampleproject” contains a Maven module from which the local PPS box will be built. The folder “localppsresources” contains configuration files. When running the local PPS box, also the application log and the DB file will be stored there. The file ppe-local.properties in this folder contains a reasonable default configuration proposed by SAP if you want to start from a greenfield. This slightly deviates from the default configuration of the standard delivery which has the priority to avoid any incompatibilities during upgrade.
Step 4
Open a command rompt, cd to folder “additional” and execute the command
install_jars.bat.
This will install the program code, Javadoc and sources to your local maven repository which is sufficient for the purpose of this blog. Most likely, you want to also upload these files to the artifact repository of your company (Nexus / Artifactory or similar). This step is not described here.
Note, if you have access to the SAP internal artifact repository, you should skip this step.
If you use maven > 3.8, add the parameter -DgeneratePom=true to each statement in install_jars.bat.
If you run on unix or mac, you can remove all the “call” commands and execute the file as follows: source install_jars.bat.
Step 5
cd to folder sampleproject and execute the command mvn install
With this, you have created the web application archive and installed it in your local maven repository. The sample project contains the bare minimum needed to create a working web application:
-
- The pom.xml with all mandatory dependencies as a flat list of direct dependencies
-
- In addition, the following maven dependencies:
-
- H2 driver to support an embedded H2 database
-
- Apache DBCP2 as a database connection pool
-
- Log4j2 as logging implementation of slf4j
-
- In addition, the following maven dependencies:
-
- A web.xml exposing the endpoint, triggering the startup of the application context etc
-
- A datasource factory class using Apache DBCP2
-
- An additional PPS module in the webapp exposing the datasource factory as another spring bean
If you want to use the local PPS box more than once, you probably want to adjust the pom.xml to your needs, including adjustment of. groupId, artifactId, version etc.
Step 6
Start Docker in your Linux environment, and execute the following command (note, we are accessing a file in the Windows file system from Linux here):
docker build /mnt/c/my_local_pps_box/localppsresources -t tomcat-for-localpps
To execute the Java web application, you need a stable runtime environment. The command above creates a Docker image with a well-defined Java and Tomcat installation. In addition, an additional folder within the Docker container (“/extern”) is mounted to the Java classpath and much more. See the comments in the Dockerfile (located in folder C:my_local_pps_boxlocalppsresources) for more information.
Step 7
Start a Docker container for the image you just created. This should only take a few seconds.
docker run -it –name myLocalPPS -p 8888:8080 -v /mnt/c/my_local_pps_box/localppsresources:/extern tomcat-for-localpps
With this you have started the Tomcat running within the Docker container. The http port 8080 exposed by default is forwarded to port 8888 on the host machine (i.e. your Windows machine running WSL2). The folder /extern within the Docker image – which is added to the Tomcat classpath – is mapped to the folder /mnt/c/my_local_pps_box/localppsresources (which is identical to C:my_local_pps_boxlocalppsresources)
Hint: Have a look at the Dockerfile. There, you can also see how to execute the container in debug mode!
Step 8
Deploy the Java web application into Tomcat. In your browser, open the following URL: http://localhost:8888/manager. When prompted for user and password, enter “opp” and “opp”.
In section „Deploy“ > „WAR file to deploy”, press “Choose File” and select the WAR you created in the sampleproject folder:
Then, press “Deploy”. After some waiting, you should see the following:
Congratulations, you have the local PPS box running! This should also become visible in folder localppsresources, where you can see the application log and the DB file:
Trying it out
Let’s see if the local PPS box indeed works. To do so, we upload an IDoc with a promotion and see if it is considered during the price calculation. Afterwards, we will also have a look at the database.
First, upload a single promotion. This is done via a POST request against http://localhost:8888/localpps-0.0.1-SNAPSHOT/idocinbound
As XML payload, you can use this one:
<?xml version="1.0" encoding="utf-8"?>
<_-ROP_-PROMOTION05>
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<DOCNUM>0000000000084229</DOCNUM>
<IDOCTYP>/ROP/PROMOTION05</IDOCTYP>
<MESTYP>/ROP/PROMOTION</MESTYP>
</EDI_DC40>
<_-ROP_-E1_PROMOTION SEGMENT="1">
<CHANGED_ON>20210208141329</CHANGED_ON>
<EFFECTIVE_DATE>20230601000000</EFFECTIVE_DATE>
<EXPIRY_DATE>20230630235959</EXPIRY_DATE>
<LOGSYS>CHANGEME</LOGSYS>
<MIN_PPS_RELEASE>11000000</MIN_PPS_RELEASE>
<ORIGIN>01</ORIGIN>
<PROMOTION_ID>757575</PROMOTION_ID>
<STATUS_TCD>AC</STATUS_TCD>
<_-ROP_-E1_PROMOTION_BU SEGMENT="1">
<BU_ID>SO|DC</BU_ID>
<BU_TYPE>2001</BU_TYPE>
</_-ROP_-E1_PROMOTION_BU>
<_-ROP_-E1_PROMOTION_RULE SEGMENT="1">
<ELIGIBILITY_ID>757575</ELIGIBILITY_ID>
<PRICE_RULE_ID>757575</PRICE_RULE_ID>
<PROMO_RULE_ID>757575</PROMO_RULE_ID>
<SALE_RETURN_TCD>00</SALE_RETURN_TCD>
<SEQUENCE>757575</SEQUENCE>
<_-ROP_-E1_ELIGIBILITY SEGMENT="1">
<EFFECTIVE_DATE>20230601000000</EFFECTIVE_DATE>
<EXPIRY_DATE>20230630235959</EXPIRY_DATE>
<ELIGIBILITY_ID>757575</ELIGIBILITY_ID>
<THRESHOLD_TCD>QUT</THRESHOLD_TCD>
<LIMIT_QTY>10.000</LIMIT_QTY>
<PARENT_ELIGIB_ID>757575</PARENT_ELIGIB_ID>
<PROMO_RULE_ID>757575</PROMO_RULE_ID>
<ROOT_ELIGIB_ID>757575</ROOT_ELIGIB_ID>
<STATUS_TCD>AC</STATUS_TCD>
<THRESHOLD_QTY>1.000</THRESHOLD_QTY>
<TYPE_CODE>ITEM</TYPE_CODE>
<ITEM_ID>MY_ITEM</ITEM_ID>
<UOM_ISO_CODE>EA</UOM_ISO_CODE>
</_-ROP_-E1_ELIGIBILITY>
<_-ROP_-E1_PRICE_RULE SEGMENT="1">
<CALCULATION_BASE>00</CALCULATION_BASE>
<CALC_BASE_SEQUENCE>1-</CALC_BASE_SEQUENCE>
<CONSIDER_PREVIOUS_RULES>X</CONSIDER_PREVIOUS_RULES>
<CURRENCY_ISO_CODE>EUR</CURRENCY_ISO_CODE>
<DISC_METHOD_TCD>00</DISC_METHOD_TCD>
<ITEM_METHOD>00</ITEM_METHOD>
<PRICE_MODIF_PERC>13.000</PRICE_MODIF_PERC>
<PRICE_RULE_ID>757575</PRICE_RULE_ID>
<ROUNDING_METHOD>00</ROUNDING_METHOD>
<ROUND_DECIMALS>2</ROUND_DECIMALS>
<ROUND_DESTINATION>1</ROUND_DESTINATION>
<RULE_CTRL_CODE>PO</RULE_CTRL_CODE>
<STATUS_TCD>AC</STATUS_TCD>
<TYPE_CODE>RB</TYPE_CODE>
<PRICE_MODIF_CODE>RP</PRICE_MODIF_CODE>
</_-ROP_-E1_PRICE_RULE>
</_-ROP_-E1_PROMOTION_RULE>
</_-ROP_-E1_PROMOTION>
</IDOC>
</_-ROP_-PROMOTION05>
You should see a success message:
Will it be considered for a price calculation? Let’s see – send a POST request against http://localhost:8888/localpps-0.0.1-SNAPSHOT/restapi with the following payload:
<PriceCalculate xmlns="http://www.sap.com/IXRetail/namespace/" InternalMajorVersion="10" InternalMinorVersion="0">
<ARTSHeader ActionCode="Calculate" MessageType="Request">
<MessageID>1</MessageID>
<DateTime>2240-02-20T00:00:00.0</DateTime>
<BusinessUnit TypeCode="DistributionChain">SO|DC</BusinessUnit>
<MasterDataSourceSystemID>CHANGEME</MasterDataSourceSystemID>
</ARTSHeader>
<PriceCalculateBody TransactionType="SaleTransaction">
<TransactionID>1</TransactionID>
<DateTime>2023-06-07T15:10:00.0</DateTime>
<ShoppingBasket>
<LineItem>
<SequenceNumber>0</SequenceNumber>
<Sale ItemType="Stock" FixedPriceFlag="true">
<RegularSalesUnitPrice Currency="EUR">100.00</RegularSalesUnitPrice>
<ItemID>MY_ITEM</ItemID>
<Quantity Units="1" UnitOfMeasureCode="EA">1</Quantity>
</Sale>
</LineItem>
</ShoppingBasket>
</PriceCalculateBody>
</PriceCalculate>
Voilà, a discount is granted:
How about the database content? To examine it, stop the Docker container first (simultaneous access to the DB file from the UI and the web application is not supported) and start the UI of the H2 database via command h2.bat:
In the browser window, enter the following:
And here it is:
Gaps
Besides not being covered by any SAP support agreement, the local PPS box is also lacking essential aspects, which you would expect from a production-ready-product. This includes but is not limited to the following:
-
- Security
-
- There is no security guide telling what to keep in mind from a security point of view.
-
- HTTPS communication is not enforced.
-
- There is no authentication/authorization in place. Anyone can use any exposed endpoint.
-
- Credentials for the database access are stored in clear text in an unprotected file.
-
- There is no protection against excessive usage including denial-of-service attacks.
-
- The credentials being used allow any change to the database, including deletion of the whole schema.
-
- The database content is not encrypted. If someone has access to the DB files, full access to the data is given.
-
- Security
-
- Performance
-
- There is no sizing procedure available giving hints about the needed hardware to handle the intended load and data volume.
-
- There is no support to find the right system configuration related to cache size, heap size, stack size, suitable garbage collection strategy etc.
-
- No connection to an application performance monitoring system is foreseen.
-
- Any adjustment to variations of load (e.g. due to increased number calculation requests) must be done manually. Also, there is no dispatching of requests to several instances or load balancing foreseen.
-
- There is no support to find the appropriate DB indices. The choice of indices heavily depends on the used DB platform and the load and is essential to achieve a good calculation performance.
-
- There is no guarantee that an updated version of the local PPS box will achieve a similar performance on the same load.
-
- Performance
-
- Software Lifecycle
-
- There is no “reference landscape” including a list of supported operating systems, Java versions, databases, Tomcat versions. What comes closest to this is the Docker image defined by the delivery of the central PPS.
If you encounter an issue, you should double-check if the issue persists in the SAP provided environment.
- There is no “reference landscape” including a list of supported operating systems, Java versions, databases, Tomcat versions. What comes closest to this is the Docker image defined by the delivery of the central PPS.
-
- Any update is a purely manual task, there is no automated process for this.
-
- There is no support for distributing software changes in case you have several instances of the local PPS box running.
-
- There is no guarantee that SAP will continue delivering versions of the local PPS box.
-
- Software Lifecycle
- Operations / Data Lifecycle
-
- There is no documentation available about how to “operate” the local PPS box. What to monitor on a regular basis, any cleanup activities to perform etc.
-
- There is no connection foreseen to any business process/integration monitoring (e.g. to keep track of the uploaded data).
-
- There is no connection to any monitoring of the system availability/health state foreseen.
-
- There is no concept for data aging (deletion/archiving of obsolete data). Over time, this will lead to a guaranteed collapse of the system.
-
- There is no backup and recovery concept in place.
-
- There is no support for any high-availability scenario.
-
- There is no connection to any application performance monitoring foreseen (e.g. warning about any anomalies from a performance point of view).
-