CRM and CX Blogs by SAP
Stay up-to-date on the latest developments and product news about intelligent customer experience and CRM technologies through blog posts from SAP experts.
cancel
Showing results for 
Search instead for 
Did you mean: 
ingo_woesner
Employee
Employee
See also the newer blog "Decentralized OPP (Omnichannel Promotion Pricing) on Docker"

 

SAP Omnichannel Promotion Pricing


“BLACK BOX Concept” - Implementation guidance for non-SAP environments


SAP Omnichannel Promotion Pricing provides a central price and promotion repository that stores all relevant information for the calculation of effective sales prices in all sales and communication channels. The data can be replicated via IDocs to different sales channel applications. The concept and capabilities of OPP is described here and in the SAP Help.

In high-volume retail/consumer sales channels like a web shop and a POS solution it is paramount to perform promotion pricing locally in the respective sales channel.

Here, SAP provides a standard integration with SAP Commerce (on premise editions) with the so-called local (offline) deployment. In addition, there is a standard integration with the SAP’s POS solution “SAP Omnichannel POS by GK”.

However, the integration of 3rd party ecommerce and/or POS solution with SAP Omnichannel Promotion Pricing is to be done on customer project basis.



Figure 1: OPP High-Level Black Box concept

 

This blog provides you implementation guidance for SAP Omnichannel Promotion Pricing (OPP) in a non-SAP/GK POS environment, also known as the OPP “Black Box” deployment.

It is a starting point for installing your Offline Promotion Pricing Service (Offline PPS) and maintaining and running it in a NON-GK POS or NON-Hybris Commerce on-prem environment.

Alternatively, you can use the OPP public cloud service on SAP Cloud Platformhttps://blogs.sap.com/2019/08/16/sap-omnichannel-promotion-pricing-new-cloud-service/, which is available since April 2019.


This blog contains specific information for various tasks and lists the tools that you might use to install and to maintain the Offline PPS, as it is not part of SAP Standard delivery.

It is a collection of additional information related to Offline PPS without claiming to be complete. As such, it is to be considered as an additional guideline to other documentations that are available in the SAP Help Portal, see chapter 6 below "Related Documents".

OPP customers are already live with the OPP black box implementation, for example here.

However, please note:


SAP does not provide standard support for the OPP black box implementation. PLease use the guidance given in this blog to implement your integration on project basis.


 

Target Audience

  • SAP IT administrators

  • Implementation partners of POS systems and non-SAP e-commerce solutions


Glossary


































Term Abbreviation Definition
Apache Tomcat Tomcat Java servlet container to run the OPPS web application
SAP Omnichannel Promotion Pricing OPP An SAP solution that provides the calculation of regular consumer (B2C) prices and discount prices as well as incentives across all sales and communication channels (points of sale, online, mobile, call centers). See also SAP Help.
Promotion Pricing Engine PP Engine/PPE The engine which does the core promotion pricing calculations in OPP.
Promotion Pricing Service PPS The promotion pricing service backend
SAP Hybris Commerce, integration package for SAP for Retail”, IPR, SAP IPR Provides SAP Retail specific enhancements and integration with SAP Hybris Commerce Suite as well as Hybris Data Hub semantics for SAP’s retail master data replication


 

1. Introduction


A 3rd party POS software can make real-time price requests including promotion (price reduction) calculations in an “offline” scenario, which means that no direct internet connection to a SAP CAR application bundle system exists and the pricing and promotion repository (master data) is only updated from time to time.

Use cases for decentralized, offline operations of PPS are:

  • The internet connection to a central server is not stable

  • Responsiveness: in a central scenario, peak traffic or the network latency of the internet connection cause delays a delayed response of a pricing request which are not acceptable.


Promotional rules and regular sales prices are stored in a central SAP CAR system and exported via IDocs using DRFOUT. These IDocs can then be imported into a local database using an IDoc inbound service running on the local java application server. Local database / PPS could be running on the same hardware / local network as for example the POS system.



Figure 2: Overview Offline PPS

The local database is then used by the pricing service to calculate pricing requests, received for example from a POS system. Usage of a local repository means no direct connection to the central repository needs to be available at the point in time the pricing request is processed.
Data distribution could be modelled like data distribution into a local Repository in SAP Hybris Commerce. (see reference link below [OPP_DRFOUT]).

Note:


Regarding the IDoc transfer: In most scenarios there is a one to many relationships between CAR and the POS and there is a middleware/software component, which routes and distributes the CAR outbound IDoc to the active POS systems. This is not reflected in the graphic as the IDoc routing/distribution is not part of the scope of this blog.


 

1.1 Automated build for the Web Archive


The outcome of this chapter is an automated build by Maven of a Web Application Archive (.war-file) containing the PPS with the latest officially released PPE binaries.

1.2 Basic Prerequisites


For every Java project SAP strongly recommends using a version control system/service (like Git or Subversion) and a continuous integration (CI) server (like Jenkins or Bitbucket).

Setting up a complete development landscape including version control and CI cannot be part of this blog. This is highly customer specific (company standards like allowed/recommended software and available licenses) and must therefore be done in the customer project.

Several tools can be used to get an automated build like Apache Maven, Apache Ant or the Gradle Build Tool as starting point to create a CI job.

We will use Apache Maven (https://maven.apache.org/) in this blog as it is a widely used dependency management and build tool and is supported well in most Java related IDEs and CI servers.

The description is based on Apache Maven 3.3.9 but probably works smoothly also with newer versions of Maven.

It is recommended to work with Java SE 8.

 

1.3 Getting the Pricing and Promotion Engine libraries


Go to https://support.sap.com/ and click on Software Download (https://launchpad.support.sap.com/#/softwarecenter).

Download the latest support package of the latest Hybris Commerce IPR (Integration Package Retail).

Example: the name of version 2.7, patch level 1 is: YRETAILPACKAGE00P_1-80003992.ZIP

Extract all libraries starting matching ppengine*.jar from that archive, folder

YRETAILPACKAGE00P_1-80003992.ZIP\hybris\bin\ext-integration\sapretail\promotionpricing\sapppspricing\lib

Example (here with contained engine version 3.0.11, but could be a newer version):

 



Figure 2: IPR related PPS libraries

In addition, the library ppengine-restapi-3.0.x.jar is required which is only available in the PPS XSA archive. The XSA archive on the other hand does not include ppengine-dataaccess-localdb of IPR.

Download the latest XSA PPS Support package of the latest CARAB feature pack.

Example: for CARAB 2.0, FP02 and patch level 4, the name is: XSACOPPPPS02_4-80002015.ZIP

There are several archives nested within the main zip-archive. At top level, there is a mtar file named like this sap-xsac-opp-pps-1.2.x.mtar. This is a regular zip archive and can be opened with a standard zip decompression tool. Inside the mtar, there is a web archive (.war-file) named ppservice-webapp-central.war. Open this file (it is again a standard zip archive) and go to folder WEB-INF\lib where the restapi jar-library is located amongst other jar-files.

Note


The other jar-libraries in of the lib folder in the web-archive will give a good indication for the required version numbers if maven is used.


 

1.4 Maven upload of ppengine libraries into the local repository


Subsequently two examples of how to load the pricing engine libraries into a (local) maven repository.

 Note


There are two different types of libraries. Some start with ppengine and others with pricing-engine and they have different maven group IDs!


pricing-engine group ID: com.sap.retail.ppservice.pricing-engine

ppengine group ID: com.sap.retail.ppservice

 

Example for uploading the pricing-engine API:

mvn install:install-file -Dfile=pricing-engine-api-3.0.11.jar -DgroupId= com.sap.retail.ppservice.pricing-engine -DartifactId=pricing-engine-api -Dversion=3.0.11 -Dpackaging=jar -DcreateChecksum=true


 

Example for uploading the ppengine API:

mvn install:install-file -Dfile=ppengine-api-3.0.11.jar -DgroupId= com.sap.retail.ppservice -DartifactId=ppengine-api -Dversion=3.0.11 -Dpackaging=jar -DcreateChecksum=true


 

1.5 Maven Project Folder Structure




Figure 3: Maven Project Folder Structure

 

Find the content (and hints) for each file in the appendix chapter 5 "Files to build the sap-offline-pps".

The pom.xml contains the definition of all dependencies.

If you have own custom extensions, they can be included into the web archive simply by adding the corresponding dependencies to the pom.xml file. For sure they need to be present in the Maven repository as part of a (separate) build process or by just uploading the results to the Maven repository which is used to build the Offline PPS.

In this example we added log4j as a logging framework. In general, it is also possible to use another slf4j compatible logging framework.

 

1.6 Build the web-archive


Create the package with command

mvn package


The web archive (sap-offline-pps-1.0.0.war) is created into the (newly created) target folder.

If the project was already build and the target folder exists, run mvn clean package to wipe everything clean before rebuilding the web archive.

 

 

2 Offline Service Bundle


The topic of this chapter is to run the web-archive created in the previous chapter on Apache Tomcat.

Note


This guide does not claim to be complete – especially security aspects are not covered. See chapter 4 Special Considerations.


 

2.1 System requirements


Prerequisites:

  • Database system. Supported DB systems are listed in the compatibility information for SAP INDUSTRY PACK. RETAIL [PAM-IPR]. In general, the DB system must have a JDBC 4.0 compliant driver and must be supported by Eclipselink.
    It is also expected that the DB is installed on the POS system (or at least accessible from there) and that it is properly configured (like open JDBC connection, existing DB user with the required permissions).



  • Java 8 runtime environment is installed on the target system and JAVA_HOME and/or JRE_HOME is properly set as system environment variable in Windows. Usually JAVA_HOME refers to a JDK (Java Development Kit) and JRE_HOME points the Java Runtime Environment (JRE). For a productive system, it is recommended to install only a JRE and make sure that the environment variable JRE_HOME is set accordingly. The JRE needs to contain a bin\server\jvm.dll for later service setup.

  • Apache Tomcat was downloaded and is available (example: apache-tomcat-8.0.43-windows-x64.zip).

  • Offline PPS bundle is available


 

2.2 Tomcat Installation and Configuration


Apache Tomcat is not the only Servlet Container that can run the PPS Web Archive. As Apache Tomcat is also used for internal tests, the reference architecture example is using Tomcat.

As an example, the subsequent chapters describe how to configure and run the Offline PPS with Tomcat on Windows. Apache Tomcat can be downloaded at [WEB_APACHE] for the Windows (64 bit) Operating System, so any directory in the subsequent text is in the Windows notation.

To run PPS, the recommended Java version is Java SE 8.

The Web archive will run with Apache Tomcat 7, 8 and 9.

The reference architecture used in this blog is making the following assumption. The architecture is only an example and need to be adjusted to the actual customer environment:

 

2.2.1 Separation of Tomcat and OPPS


Tomcat can be installed by just extracting the zip-file (official binary distribution) into a folder like C:\Program Files. The variable CATALINA_HOME represents the root of the Tomcat installation like C:\Program Files\apache-tomcat.

 Note


Find a description below, where and how to set the variables.


A specific instance of Tomcat always runs in the folder specified by the CATALINA_BASE variable. It can be the same as for the root installation.

Recommendation


“Using distinct values for the CATALINA_HOME and CATALINA_BASE variables are recommended to simplify further upgrades and maintenance.” (see RUNNING.txt of Tomcat installation).


Following this recommendation, CATALINA_BASE will be a different folder and contains the main subfolders webapp (including the OPPS web application), configuration files (for Tomcat and OPPS) and log files (created at runtime).



Figure 4: Tomcat and OPPS installation scenario

The variables CATALINA_HOME and CATALINA_BASE are consumed as environment variables in Tomcat but there are several ways to set (or override) them. Ways are

  • Set the variable directly in the Windows system environment variables

  • Set the variables in the tomcat/bin/Catalina.bat script

  • If Tomcat is started as Windows Service, the variables must be set in the service configuration (JvmOptions, see chapter 2.4Setup Tomcat as Windows Service [optional].



2.2.2 Basic Installation of Apache Tomcat


Installation Steps:

  1. Extract the Apache Tomcat zip file to C:\Program Files. A subfolder apache-tomcat-<version> will be created. CATALINA_HOME should point to this folder.


 Note


There is no need, but it can be easier for a potential Tomcat update to remove the version information from the subfolder name (apache-tomcat vs. apache-tomcat-8.0.43).




  1. Add special (additionally) required libraries to the lib Folder of the Tomcat installation, like the SQL Server JDBC driver or potentially required security libraries.



  1. Extract the Offline PPS bundle contents to C:\Program Files\SAP\OfflinePPS


Example


Per the above description, the Tomcat variables have these values:


CATALINA_HOME = C:\Program Files\apache-tomcat-8.0.43


CATALINA_BASE = C:\Program Files\SAP\OfflinePPS


 

2.2.3 Catalina Base Folder Structure


This is an example folder structure for a Catalina Base. It does not show files, but at least those which are non-standard.



Figure 5: Catalina Base folder structure

 

The top-level folders (conf, logs, temp, webapps and work) are expected (or will be created) by Tomcat.

The folders work and temp are only used by Tomcat for internal purposes and may be ignored here. They can be created as empty folders initially or are created by Tomcat once it is up and running.

All log files are written to the logs folder. This folder is initially empty and will be filled with log files once Tomcat is up and running.

All web applications are put to the webapps folder. With the default setting the operator puts the sap-offline-pps.war file into the webapps folder and the web archive is extracted to a sap-offline-pps folder on Tomcat startup (or re-extracted and hot deployed depending on the Tomcat server settings). See also 2.3 Update Workflow.

The conf folder contains standard Tomcat config files (modified to the user’s needs) like server.xml, context.xml, web.xml or logging.properties.

The context.xml file can be used to configure JNDI data sources to be used in the PPS configuration and it can be used to “mount” a folder into the web application at runtime which can be used as an extension point for configuration. See details in chapter 2.2.5 Configuration. In this example, folder OfflinePPS\conf\opps is used as such a mount point.

Inside the opps folder, there can be files like META-INF\pps-schema-orm.xml to set a custom database schema for the PPS tables, see chapter 5.2.1 sap-schema-orm.xml.

The PPS specific logging (if log4j is used) can be configured in the log4j file, see chapter 2.2.6 Logging.

ppe-local.properties can be used to configure specific aspects of PPS, see also [DEV_EXT_OPP].

 

2.2.4 Setup Tomcat as Windows Service [optional]


Running Tomcat as a Windows Service comes with the benefits that the Tomcat instance (depending on the configuration) starts automatically when the Operating System is (re-)started and that it runs in the background as a service without visibility of the actual user operating the POS software.

 

The Tomcat installation provides tools to create a Windows service in CATALINA_HOME\bin:

  • exe: the command line-based service configuration and service runner which communicates with the Windows services framework

  • bat: a batch file which simplifies the use of service creation and uses tomcat8w.exe

  • exe: a GUI based GUI service manager. This tool is not needed for a fully automated installation without user interaction


 

The best way to install a new Windows Service is to adapt the existing service.bat file.

Copy:     CATALINA_HOME\bin\service.bat

To:        CATALINA_HOME\bin\service_OfflinePPS.bat

 

Edit service_OfflinePPS.bat and modify these values:

At the beginning, after the setlocal command, set CATALINA_BASE:

Syntax


set "CATALINA_BASE=C:\Program Files\SAP\OfflinePPS"


 

At the place where the service is installed, change Description, DisplayName, LogPath and JvmOptions (changes are highlighted:

 Syntax


"%EXECUTABLE%" //IS//%SERVICE_NAME% ^


    --Description "Offline Promotion Pricing Service" ^


    --DisplayName "SAP Offline PPS" ^


    --Install "%EXECUTABLE%" ^


    --LogPath "%CATALINA_BASE%\logs\wserv" ^


    --StdOutput auto ^


    --StdError auto ^


    --Classpath "%CLASSPATH%" ^


    --Jvm "%JVM%" ^


    --StartMode jvm ^


    --StopMode jvm ^


    --StartPath "%CATALINA_HOME%" ^


    --StopPath "%CATALINA_HOME%" ^


    --StartClass org.apache.catalina.startup.Bootstrap ^


    --StopClass org.apache.catalina.startup.Bootstrap ^


    --StartParams start ^


    --StopParams stop ^


    --JvmOptions "-Dcatalina.home=%CATALINA_HOME%;-


Dcatalina.base=%CATALINA_BASE%;-Djava.endorsed.dirs=%CATALINA_HOME%\endorsed;-Djava.io.tmpdir=%CATALINA_BASE%\temp;-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager;-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties;-Djava.library.path=%CATALINA_HOME%\lib" ^


    --JvmMs 256 ^


    --JvmMx 512


 

LogPath refers to the folder where “Service Logs” are written to. In addition to the Service Logs, Tomcat and the WebApps will write additional log files into the CATALINA_BASE\logs folder based on their configuration.

If the JDBC driver requires additional Windows .dll (dynamic-link library), it is necessary to set the java.library.path. For example, the Microsoft SQL Server JDBC driver in combination with “Integrated Security” requires the sqljdbc_auth.dll file (provided by the driver).

The Jvm settings might need further adjustments based on the available memory at the POS system and the OPPS caching settings.

Finally, the service file can be executed in working directory CATALINA_HOME\bin:

service_OfflinePPS.bat install SAP_Offline_PPS


 

2.2.5 Configuration


The Tomcat configuration files reside in the CATALINA_BASE/conf folder.

General information about the Apache Tomcat configuration can be found at the Tomcat web page. See [WEB_APACHE].

An important aspect of server.xml is the configuration of the connectors like HTTP vs. HTTPS and the port where the service listens to.

 

The file context.xml contains further resources required by the Offline PPS WebApp:

Syntax


<Resources className="org.apache.catalina.webresources.StandardRoot">


  <PreResources className="org.apache.catalina.webresources.DirResourceSet"


          base="${catalina.base}/conf/opps"


          internalPath="/"


          webAppMount="/WEB-INF/classes"


          readOnly="true"


  />


</Resources>


<Resource auth="Container"


    name="jdbc/OfflinePpsDB" type="javax.sql.DataSource"


    driverClassName="my.database.jdbc.driver.class"


    url="jdbc:mydb://localhost:myport"


    initialSize="2"


    maxTotal="50"


/>


 

The first “Resources” definition adds a mount point to the WebApp (at WEB-INF/classes) that allows to place specific OPPS configuration files in the folder CATALINA_BASE\conf\opps. This includes for example

  • OPPS logging configuration: log4j.xml

  • OPPS application settings: ppe-local.properties

  • Setting the database schema: META-INF\pps-schema-orm.xml


 

Schema configuration in ppe-local.properties:

The pps-schema-orm.xml needs specific configuration in ppe-local.properties to be considered:

Syntax


sap.dataaccess-common.custmappingresources=,META-INF/pps-schema-orm.xml




  • META-INF/pps-schema-orm.xml loads the xml file which contains the database schema definition


 

The second “Resource” definition is for the DataSource used by OPPS. Tomcat uses an own implementation of the DataSource which includes Connection Pooling.

If the JDBC driver supports an “integrated security” feature to logon to the database (like the Microsoft SQL Server), it might be necessary to set logon information in the Windows Service for a specific user with access to the database. Otherwise, the “Local System Account” user is used to logon to the database. The Log On information can be set at the command line with the Windows sc command.

Example


sc config SAP_Offline_PPS obj= MyDomain\MyPOSUser password= myPassword


 

2.2.6 Logging


This chapter is only relevant, if log4j is chosen as the logging framework. In general, any logging framework compatible with slf4j (with a corresponding implementation) can be used.

The “mount point” into the PPS web application as described in chapter 2.2.5 Configuration allows to override the default log settings by putting a log4j.xml file there.

It is recommended to override the default settings and create a ppservice.log file in the Tomcat base logs folder:

 log4j.xml


<?xml version="1.0" encoding="UTF-8"?>


<Configuration status="WARN" monitorInterval="30">


<Appenders>


        <Console name="Console" target="SYSTEM_OUT">


              <PatternLayout pattern="%-5level %logger{36} - %msg%n" />


        </Console>


        <RollingFile name="PpsFile" fileName="<catalina_base>\logs\ppservice.log"


               filePattern="<catalina_base>\logs\ppservice.%d{yyyy-MM-dd}.log">


              <PatternLayout>


                     <Pattern>%d{HH:mm:ss} %-5level %c{1.} - %msg%n</Pattern>


              </PatternLayout>


              <Policies>


              <OnStartupTriggeringPolicy />


              <TimeBasedTriggeringPolicy />


              </Policies>


        </RollingFile>


</Appenders>


<!-- Default config - log all messages to stdout -->


<Loggers>


        <Root level="error">


              <AppenderRef ref="Console" />


        </Root>


        <!-- Spring related logging -->


        <Logger name="org.springframework" level="error" additivity="false">


              <AppenderRef ref="Console" />


        </Logger>


        <!-- Persistence related logging -->


        <Logger name="org.eclipse.persistence" level="error"


              additivity="false">


              <AppenderRef ref="Console" />


        </Logger>


        <!-- Server-side request content logging -->


        <Logger name="com.sap.ppengine.web.filter.RequestToSlf4JLogger" level="error" additivity="false">


              <AppenderRef ref="Console" />


        </Logger>


        <!-- Runtime measurements -->


        <Logger name="com.sap.ppengine.core.util.impl.ThreadLocalTimer" level="error" additivity="false">


              <AppenderRef ref="Console" />


        </Logger>


        <!-- PPS related logging -->


        <Logger name="com.sap.ppengine" level="info" additivity="false">


              <AppenderRef ref="PpsFile" />


        </Logger>


</Loggers>


</Configuration>


 

The placeholder <catalina_base> needs to be (manually) replaced with the actual directory, otherwise the log file will not work as expected.

For productive use, further “policies” will help to balance stored information and disc usage (“data growth”) like SizeBasedTriggeringPolicy and a “rollover strategy”. A description can be found here:

See [WEB_ROLLFILE] Description RollingFileAppender.

 

2.3 Update Workflow


An update of the Offline PPS will be necessary if PPS patches (contained in IPR or XSA PPS) are released by product development in the SAP software center.

In this case the web archive (war-file) needs to be rebuild with the new libraries and has to be rolled-out to the target POS systems.

Recommendation


The recommended update process for a war-file is:




  • Stop the Tomcat (Windows) Service

  • [apply changes to the database, if necessary]

  • [apply changes to the configuration like ppe-local.properties, if necessary]

  • Delete the old Offline PPS war-file in CATALINA_BASE\webapps and the corresponding unpacked directory

  • Copy the new Offline PPS version into CATALINA_BASE\webapps

  • Start the Tomcat (Windows) Service


 

Tomcat auto deploy (“hot deployments”) should not be used:

server.xml


<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false" deployOnStartup="true">


 Note 1


Offline PPS requires unpackWARs="true"


 Note 2


If a new version of Offline PPS comes with database table changes, the database must be altered. The easiest way to accomplish this is to reinitialize the database by: dropping the tables, (re-)sending all price/promotion IDocs to the POS systems. As an alternative, it might be possible to apply database changes with SQL DDL commands.


 

 

 3 Guideline for an Automated Installer


This chapter gives an idea how an installer can be created (optional).

This guideline is a starting point to build an automated installer for the Offline PPS solution.

The subsequently described installation process deals with three installation topics:

  • Patching and installing Apache Tomcat

  • Installing the Offline PPS (all content in the folder specified by the CATALINA_BASE)

  • Creating a windows service which can start and stop the Offline PPS


 

The guideline is based on the IzPack installer software. Further details can be found at [WEB_IZPACK]:

 

It does not treat platform security topics (regarding Tomcat) such as

  • Creation and use of certificates for HTTPS (HTTP secure)

  • Configuration of authentication mechanisms like basic authentication or Windows Integrated Authentication (with Kerberos)


 

Prerequisites are

  • Java Runtime Environment (JRE) 8 – required by the installer itself and all other components (Tomcat, Offline PPS)

  • Microsoft SQL Server is installed, the JDBC connection is open, a database user for the connection from the Offline PPS exists and the (logical) Offline PPS database exists. The database tables are created by the service as soon as the first request requires access to database tables.


 

Chapter 3 describes a “how it could be” scenario and serves a s Proof of Concept (POC) to show that the manual installation steps described in the previous chapters are fully automatable.

 

3.1 Installer Generation Process


IzPack can be executed standalone or from a special Maven plugin. To be able to fully integrate into an automated build process, the subsequent description is based on the IzPack Maven Plugin.

As a prerequisite, a Maven project needs to be created in the development landscape.

The Maven project contains the mandatory Maven descriptor file, pom.xml and the source packages in the src/izpack folder.

For further details about the pom.xml, see chapter 5.3.1 Example Maven Descriptor File (pom.xml) for the Installer.

The artifacts to be installed by the installer software can be grouped into so called “packs”. According to the three previously listed topics, there are three packs to be installed/executed during the installation process:

  • Pack 1: Apache Tomcat including additional libraries like the SQL Server JDBC driver

  • Pack 2: The Offline PPS

  • Pack 3: The Windows Service entry create script


The installation process can be separated into 2 phases:

  • Collect all artifacts and prepare the packs in a (temporary) so-called “staging” area

  • Compile the installer software based on the created packs in the staging area




 

Figure 6: Installer Generation Process

The main actors in Figure 6 are the Maven plugins.

To accomplish phase 1), the AntRun and Maven-Dependency plugins copy and prepare the source artifacts to the staging folder.

The Maven dependency plugin can directly access the Maven repository and download the latest build of the Offline PPS package to the staging area.

The AntRun Plugin can execute Apache Ant Tasks (see [WEB_AP_TASK])) inline in the pom.xml plugin definition, such as copy, move or extract zip file.

 

In phase 2), the IzPack Maven plugin compiles the installer software based on the provided packs of phase 1).

To do so, the IzPack compiler reads the install.xml descriptor file which contains all necessary information for the compilation.

See chapter 5.3.2 for an example Example IzPack Installation Descriptor (install.xml)

 

Once everything is in place, the installer software can be compiled with the Maven command:

 Syntax


mvn clean package


Upon a successful build, the installer-jar can be found in the project folder “target”.

 

 

3.2  Executing the Installer


This is how the installer can be executed in console mode without user interaction by using an auto-install.xml file

 Syntax


%JAVA_HOME%\bin\java.exe -jar sap-offline-pps-installer-1.0.jar auto-install.xml


 

See chapter 5.3.3 Example for an automated Installation (auto-install.xml)

 

 4 Special Considerations


 Security considerations

The (Offline) Promotion Pricing Service contains no authentication or authorization mechanisms. It is recommended to protect the Offline Promotion Pricing Service against unauthorized price requests by providing a secure configuration of the servlet container (e.g. Apache Tomcat).

This should include, but is not restricted to:

  • Usage of HTTP secure (HTTPS)

  • Usage of an authentication process (for example Integrated Windows authentication, either based on build in Tomcat support or based on third party libraries)


 

Additional points might need to be added based on existing security standards.

 

Version information

  • The PP Engine version can be determined inside the webapp\sap-offline-ppsfolder in the subfolder WEB-INF\lib. The version is the suffix of ppengine- or pricing-engine-prefixed files like for example: ppengine-core-3.0.11.jar (Version 3.0.11).


Operations considerations

  • Data Growth

    • The log files can be a source of uncontrolled data growth. This can be avoided by properly setting size policies and rollover strategies as described in chapter 2.2.6 Logging

    • The database tables can also grow huge. It is recommended to clean up the database from obsolete promotions and regular prices on a regular base. This keeps the DB access times low and reduces TCO.




 

Free and Open Source Software Vulnerability Tracking

The final web archive contains SAP owned libraries and free and open source software (FOSS) libraries. The FOSS libraries can be split into 2 categories:

  • FOSS which is delivered with the SAP product (contained in the IPR and XSA PPS software bundle). This software is tracked by SAP and critical issues lead to a patch of the software product.

  • FOSS which are additionally added for the offline installation (like Logging or JDBC driver). Tracking of those libraries is in the responsibility of the Offline Promotion Pricing Service operator.


 

 

 5 Appendix


5.1  Files to build the sap-offline-pps


5.1.1    pom.xml


<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

 

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>sap-offline-pps</artifactId>

<version>1.0.0</version>

<packaging>war</packaging>

 

<name>Offline Promotion Pricing Service</name>

<url>http://sap.com</url>

 

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<version.jdk>1.8</version.jdk>

<version.maven.compiler>3.6.1</version.maven.compiler>

<!-- Version of the PP Engine libs -->

<version.pps>3.0.11</version.pps>

 

<!-- Versions of PPEngine Dependencies -->

<version.org.slf4j>1.7.25</version.org.slf4j>

<version.org.springframework>4.3.3.RELEASE</version.org.springframework>

<version.org.springframework.integration>4.3.2.RELEASE</version.org.springframework.integration>

<version.spring-plugin>1.2.0.RELEASE</version.spring-plugin>

<version.log4j2>2.16.0</version.log4j2>

<version.commons-lang3>3.5</version.commons-lang3>

<version.commons-dbcp2>2.1.1</version.commons-dbcp2>

<version.eclipselink>2.6.4</version.eclipselink>

<version.derby>10.11.1.1</version.derby>

<version.jpa>2.1.1</version.jpa>

<version.guava>21.0</version.guava>

<version.woodstox>4.4.1</version.woodstox>

<version.jackson>2.8.9</version.jackson>

<version.joda-time>2.9.1</version.joda-time>

<version.commons-collections>3.2.2</version.commons-collections>

<version.commons-lang>2.6</version.commons-lang>

<version.jperf>1.0.3</version.jperf>

<version.restapi>2.0.1</version.restapi>

</properties>

 

<dependencies>

<!-- Logger -->

<dependency>

<groupId>org.apache.logging.log4j</groupId>

<artifactId>log4j-slf4j-impl</artifactId>

<version>${version.log4j2}</version>

</dependency>

<dependency>

<groupId>org.apache.logging.log4j</groupId>

<artifactId>log4j-api</artifactId>

<version>${version.log4j2}</version>

</dependency>

<dependency>

<groupId>org.apache.logging.log4j</groupId>

<artifactId>log4j-core</artifactId>

<version>${version.log4j2}</version>

</dependency>

<!-- Offline PPS specific PPE dependencies -->

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-restapi</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-idocinbound</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-calcengine-gk</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-dataaccess-common</artifactId>

<version>${version.pps}</version>

</dependency>

 

<!-- PPEngine Dependencies -->

<!-- ===================== -->

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-annotations</artifactId>

<version>${version.jackson}</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-core</artifactId>

<version>${version.jackson}</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

<version>${version.jackson}</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.dataformat</groupId>

<artifactId>jackson-dataformat-xml</artifactId>

<exclusions>

<exclusion>

<groupId>com.fasterxml.woodstox</groupId>

<artifactId>woodstox-core</artifactId>

</exclusion>

</exclusions>

<version>${version.jackson}</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.jaxrs</groupId>

<artifactId>jackson-jaxrs-json-provider</artifactId>

<version>${version.jackson}</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.module</groupId>

<artifactId>jackson-module-jaxb-annotations</artifactId>

<version>${version.jackson}</version>

</dependency>

<dependency>

<groupId>com.google.guava</groupId>

<artifactId>guava</artifactId>

<version>${version.guava}</version>

</dependency>

<!-- START: pricing engine-->

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-api</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-client-impl</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-client-interface</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-core</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-dataaccess-interface</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-dataaccess-localdb</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>ppengine-jackson</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice.pricing-engine</groupId>

<artifactId>pricing-engine-api</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice.pricing-engine</groupId>

<artifactId>pricing-engine-common</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice.pricing-engine</groupId>

<artifactId>pricing-engine-core-services</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice.pricing-engine</groupId>

<artifactId>pricing-engine-dataaccess-sap</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice.pricing-engine</groupId>

<artifactId>pricing-engine-impl</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice.pricing-engine</groupId>

<artifactId>pricing-engine-model</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice.pricing-engine</groupId>

<artifactId>pricing-engine-model-default</artifactId>

<version>${version.pps}</version>

</dependency>

<dependency>

<groupId>com.sap.retail.ppservice.pricing-engine</groupId>

<artifactId>pricing-engine-psi-sap</artifactId>

<version>${version.pps}</version>

</dependency>

<!-- END: pricing engine-->

<dependency>

<groupId>commons-collections</groupId>

<artifactId>commons-collections</artifactId>

<version>${version.commons-collections}</version>

</dependency>

<dependency>

<groupId>commons-lang</groupId>

<artifactId>commons-lang</artifactId>

<version>${version.commons-lang}</version>

</dependency>

<dependency>

<groupId>javax.ws.rs</groupId>

<artifactId>javax.ws.rs-api</artifactId>

<version>${version.restapi}</version>

</dependency>

<dependency>

<groupId>joda-time</groupId>

<artifactId>joda-time</artifactId>

<version>${version.joda-time}</version>

</dependency>

<dependency>

<groupId>net.jperf</groupId>

<artifactId>jperf</artifactId>

<version>${version.jperf}</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-lang3</artifactId>

<version>${version.commons-lang3}</version>

</dependency>

<dependency>

<groupId>org.codehaus.woodstox</groupId>

<artifactId>woodstox-core-asl</artifactId>

<version>${version.woodstox}</version>

</dependency>

<dependency>

<groupId>org.eclipse.persistence</groupId>

<artifactId>javax.persistence</artifactId>

<version>${version.jpa}</version>

</dependency>

<dependency>

<groupId>org.eclipse.persistence</groupId>

<artifactId>org.eclipse.persistence.jpa</artifactId>

<version>${version.eclipselink}</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>jcl-over-slf4j</artifactId>

<version>${version.org.slf4j}</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>jul-to-slf4j</artifactId>

<version>${version.org.slf4j}</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-api</artifactId>

<version>${version.org.slf4j}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-beans</artifactId>

<version>${version.org.springframework}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

<exclusions>

<exclusion>

<groupId>commons-logging</groupId>

<artifactId>commons-logging</artifactId>

</exclusion>

</exclusions>

<version>${version.org.springframework}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-support</artifactId>

<version>${version.org.springframework}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

<version>${version.org.springframework}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-orm</artifactId>

<version>${version.org.springframework}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-oxm</artifactId>

<version>${version.org.springframework}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

<version>${version.org.springframework}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>${version.org.springframework}</version>

</dependency>

<dependency>

<groupId>org.springframework.integration</groupId>

<artifactId>spring-integration-http</artifactId>

<version>${version.org.springframework.integration}</version>

<exclusions>

<exclusion>

<groupId>org.springframework.retry</groupId>

<artifactId>spring-retry</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework.integration</groupId>

<artifactId>spring-integration-xml</artifactId>

<exclusions>

<exclusion>

<groupId>org.projectreactor</groupId>

<artifactId>reactor-core</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework.retry</groupId>

<artifactId>spring-retry</artifactId>

</exclusion>

</exclusions>

<version>${version.org.springframework.integration}</version>

</dependency>

<dependency>

<groupId>org.springframework.plugin</groupId>

<artifactId>spring-plugin-core</artifactId>

<version>${version.spring-plugin}</version>

</dependency>

<dependency>

<groupId>org.springframework.plugin</groupId>

<artifactId>spring-plugin-metadata</artifactId>

<version>${version.spring-plugin}</version>

</dependency>

<!-- END OF PPEngine Dependencies -->

<!-- ============================ -->

</dependencies>

 

<build>

<plugins>

<!-- Compiler config -->

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>${version.maven.compiler}</version>

<configuration>

<source>${version.jdk}</source>

<target>${version.jdk}</target>

<fork>true</fork>

<meminitial>512m</meminitial>

<maxmem>2048m</maxmem>

</configuration>

</plugin>

</plugins>

</build>

</project>

 

 

5.1.2              offlineservice-ppe-module-metadata.xml


 

<module xmlns="http://www.sap.com/ppengine/core/module"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.sap.com/ppengine/core/module ppengine-module-0.2.xsd">

 

<name name="offlineservice" vendor="a-customer" />

 

<dependencies>

<module name="dataaccess-localdb" vendor="sap" />

<module name="restapi" vendor="sap" />

<module name="idocinbound" vendor="sap" />

</dependencies>

</module>

 

5.1.3              offlineservice-ppe-module-spring.xml


The yellow highlighted part is up to customer specific DB configuration.

Define a data source as sapDefaultDataSource.

The example configuration below references to a JNDI data source which can be defined and configured in the Tomcat config.xml as a Resource.

 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 

       <alias name="sapDefaultDataSource" alias="sapDataSource" />

       <bean id="sapDefaultDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

              <property name="jndiName" value="java:comp/env/jdbc/OfflinePpsDB" />

       </bean>

</beans>

 

 

5.1.4              ppengine-module-0.2.xsd


This file describes the valid syntax of offlineservice-ppe-module-metadata.xml.

 

<xs:schema attributeFormDefault="unqualified"

elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns="http://www.sap.com/ppengine/core/module" targetNamespace="http://www.sap.com/ppengine/core/module">

 

<xs:complexType name="moduleName">

<xs:attribute type="xs:string" name="name" />

<xs:attribute type="xs:string" name="vendor"

default="sap" />

</xs:complexType>

 

<xs:complexType name="dependencies">

<xs:sequence>

<xs:element type="moduleName" name="module"

maxOccurs="100" minOccurs="0" />

</xs:sequence>

</xs:complexType>

 

<xs:element name="module">

<xs:complexType>

<xs:sequence>

<xs:element maxOccurs="1" minOccurs="1"

type="moduleName" name="name" />

<xs:element maxOccurs="1" minOccurs="0"

type="dependencies" name="dependencies" />

<xs:element maxOccurs="1" minOccurs="0"

type="xs:anySimpleType" name="resource" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:schema>

 

 

5.1.5              log4j2.xml


The logging configuration is completely up to the customer. This is just a starting point.

<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="WARN" monitorInterval="30">

<Appenders>

<Console name="Console" target="SYSTEM_OUT">

<PatternLayout pattern="%-5level %logger{36} - %msg%n" />

</Console>

</Appenders>

<!-- Default config - log all messages to stdout -->

<Loggers>

<Root level="error">

<AppenderRef ref="Console" />

</Root>

<!-- Spring related logging -->

<Logger name="org.springframework" level="error" additivity="false">

<AppenderRef ref="Console" />

</Logger>

<!-- Persistence related logging -->

<Logger name="org.eclipse.persistence" level="error"

additivity="false">

<AppenderRef ref="Console" />

</Logger>

<!-- PPS related logging -->

<Logger name="com.sap.ppengine" level="info" additivity="false">

<AppenderRef ref="Console" />

</Logger>

<!-- Server-side request content logging -->

<Logger name="com.sap.ppengine.web.filter.RequestToSlf4JLogger" level="error" additivity="false">

<AppenderRef ref="Console" />

</Logger>

<!-- Runtime measurements -->

<Logger name="com.sap.ppengine.core.util.impl.ThreadLocalTimer" level="error" additivity="false">

<AppenderRef ref="Console" />

</Logger>

 

</Loggers>

</Configuration>

 

 

5.1.6              applicationContext.xml


Space for customer specific adjustments. Can remain empty.

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

 

 

5.1.7              web.xml


Example for a web.xml. Again, the yellow highlighted part is optional and depending on the Database configuration.

<web-app xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="

http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

version="3.0">

<display-name>Offline Promotion Pricing Service (PPS)</display-name>

 

<!-- One dispatcher servlet for price calculation requests as well as iDoc inbound processing -->

<servlet>

<servlet-name>Dispatcher</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<init-param>

<!-- Name of the servlet context attribute holding the PPS web app context -->

<param-name>contextAttribute</param-name>

<param-value>SAP_PPS_WEBAPPCONTEXT</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>Dispatcher</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

 

<!-- Create & initialize PPS web app context on startup -->

<listener>

<listener-class>com.sap.ppengine.core.spring.impl.PPSWebAppContextLoaderListener</listener-class>

</listener>

 

       <!-- Make the JNDI Data Source available to the WebApp -->

       <resource-ref>

              <description>SAP Offline PPS Data Source</description>

              <res-ref-name>jdbc/OfflinePpsDB</res-ref-name>

              <res-type>javax.sql.DataSource</res-type>

              <res-auth>Container</res-auth>

       </resource-ref>

 

<!-- Filter to enable logging of ingoing requests via SLF4J - log level

of filter class must be set to TRACE to become effective -->

<filter>

<filter-name>sapRequestLogger</filter-name>

<filter-class>com.sap.ppengine.web.filter.RequestToSlf4JLogger</filter-class>

<init-param>

<param-name>maxPayloadLength</param-name>

<param-value>10000</param-value>

</init-param>

<init-param>

<param-name>includePayload</param-name>

<param-value>true</param-value>

</init-param>

<init-param>

<param-name>includeQueryString</param-name>

<param-value>true</param-value>

</init-param>

<init-param>

<param-name>beforeMessagePrefix</param-name>

<param-value>REQUEST BEFORE PROCESSING---></param-value>

</init-param>

<init-param>

<param-name>afterMessagePrefix</param-name>

<param-value>REQUEST AFTER PROCESSING---></param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>sapRequestLogger</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

</web-app>

 

 

5.2  Files to build CATALINA_BASE


.5.2.1              sap-schema-orm.xml


<entity-mappings

xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm

http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd"

version="2.4">

 

<persistence-unit-metadata>

<persistence-unit-defaults>

<schema>MY_SCHEMA</schema>

</persistence-unit-defaults>

</persistence-unit-metadata>

 

</entity-mappings>

 

 

5.3  Files for an installer


5.3.1              Example Maven Descriptor File (pom.xml) for the Installer


pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

 

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>sap-offline-pps-installer</artifactId>

<version>1.0</version>

<packaging>jar</packaging>

 

<name>Offline Promotion Pricing Service</name>

<url>http://sap.com</url>

 

<properties>

<!-- List of constants (versions and folders) -->

 

<version.pps>2.0.0</version.pps>

<version.offline-pps>1.0.0</version.offline-pps>

<version.tomcat>8.0.44</version.tomcat>

<version.izpack>5.1.1</version.izpack>

<version.maven.antrun-plugin>1.8</version.maven.antrun-plugin>

<version.maven.dependency-plugin>3.0.1</version.maven.dependency-plugin>

 

<tomcat.zip.file>apache-tomcat-${version.tomcat}-windows-x64.zip</tomcat.zip.file>

<izpack.staging>${project.build.directory}/staging</izpack.staging>

</properties>

 

<dependencies>

<!-- The Offline PPS dependency to be downloaded from the Maven repository by the Maven-Dependency-Plugin -->

<dependency>

<groupId>com.sap.retail.ppservice</groupId>

<artifactId>sap-offline-pps</artifactId>

<version>${version.offline-pps}</version>

<classifier>bin</classifier>

<type>zip</type>

</dependency>

</dependencies>

 

 

<build>

<plugins>

<!-- The AntRun plugin can execute Ant-Tasks (like copy, move, extract) -->

<plugin>

<artifactId>maven-antrun-plugin</artifactId>

<version>${version.maven.antrun-plugin}</version>

<executions>

<execution>

<id>create-staging-area</id>

<phase>process-resources</phase>

<goals>

<goal>run</goal>

</goals>

<configuration>

<tasks>

<!-- Copy all basically required resources to the staging area -->

<copy todir="${izpack.staging}"><fileset dir="${basedir}/src/izpack/resources"/></copy>

</tasks>

</configuration>

</execution>

</executions>

</plugin>

 

 

<plugin>

<artifactId>maven-dependency-plugin</artifactId>

<version>${version.maven.dependency-plugin}</version>

<configuration>

<excludeTransitive>false</excludeTransitive>

<stripVersion>true</stripVersion>

<overWriteReleases>true</overWriteReleases>

<overWriteSnapshots>true</overWriteSnapshots>

<overWriteIfNewer>true</overWriteIfNewer>

</configuration>

<executions>

<execution>

<!-- copy Offline PPS bin.zip to izpack staging lib -->

<id>copy-product-dependencies</id>

<phase>compile</phase>

<goals>

<goal>copy-dependencies</goal>

</goals>

<configuration>

<!-- Download the Offline PPS bundle to the staging area -->

<outputDirectory>${izpack.staging}/bin-zip</outputDirectory>

<includeArtifactIds>sap-offline-pps</includeArtifactIds>

</configuration>

</execution>

</executions>

</plugin>

 

 

<plugin>

<artifactId>maven-antrun-plugin</artifactId>

<version>${version.maven.antrun-plugin}</version>

<executions>

<execution>

<id>extract-catalina-base</id>

<phase>prepare-package</phase>

<goals>

<goal>run</goal>

</goals>

<configuration>

<tasks>

<!-- Execute a list of Ant tasks to prepare the installer "packs" for the installer compilation -->

 

<!-- Unzip (original) Tomcat archive and remove version suffix -->

<unzip src="${izpack.staging}/${tomcat.zip.file}" dest="${izpack.staging}"/>

<!-- Remove the version information -->

<move todir="${izpack.staging}/apache-tomcat"><fileset dir="${izpack.staging}/apache-tomcat-${version.tomcat}"/></move>

<!-- Patch Tomcat with required libs -->

<move todir="${izpack.staging}/apache-tomcat"><fileset dir="${izpack.staging}/tc_patches"/></move>

 

<!-- Unzip the Offline PPS zip file -->

<unzip src="${izpack.staging}/bin-zip/sap-offline-pps-bin.zip" dest="${izpack.staging}/bin-zip"/>

<!-- Remove the version information -->

<move todir="${izpack.staging}/offline-pps"><fileset dir="${izpack.staging}/bin-zip/sap-offline-pps-${version.offline-pps}"/></move>

<!-- Delete the temporary bin-zip folder -->

<delete dir="${izpack.staging}/bin-zip"/>

</tasks>

</configuration>

</execution>

</executions>

</plugin>

 

 

<!-- Compile the installer software -->

<plugin>

<groupId>org.codehaus.izpack</groupId>

<artifactId>izpack-maven-plugin</artifactId>

<version>${version.izpack}</version>

<executions>

<execution>

<phase>package</phase>

<goals><goal>izpack</goal></goals>

<configuration>

<!-- base directory for the compiler, pointing to the staging area where the packs are -->

<baseDir>${izpack.staging}</baseDir>

<!-- Reference to the IzPack compiler descriptor file -->

<installFile>${basedir}/src/izpack/install.xml</installFile>

</configuration>

</execution>

</executions>

<dependencies>

<dependency>

<groupId>org.codehaus.izpack</groupId>

<artifactId>izpack-panel</artifactId>

<version>${version.izpack}</version>

</dependency>

</dependencies>

</plugin>

 

</plugins>

</build>

</project>

 

 

5.3.2              Example IzPack Installation Descriptor (install.xml)


install.xml

 

<izpack:installation version="5.0"

xmlns:izpack="http://izpack.org/schema/installation"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://izpack.org/schema/installation http://izpack.org/schema/5.0/izpack-installation-5.0.xsd">

 

<variables>

<variable name="RESOURCEROOT" value="src/izpack"/>

</variables>

 

<!-- General information about the installer software -->

<info>

<appname>SAP Offline PPS</appname>

<appversion>1.0</appversion>

<appsubpath>opps</appsubpath>

<javaversion>1.8</javaversion>

</info>

 

<locale>

<langpack iso3="eng"/>

</locale>

 

<guiprefs width="800" height="600" resizable="no">

<laf name="substance">

<os family="windows" />

</laf>

<modifier key="useHeadingPanel" value="no" />

</guiprefs>

 

<!-- General structure of the installation process.

Panel basically refers to front-end screens because the installer software

always comes with a front-end.

However, the installer can also run fully automated in the background.

-->

<panels>

<!-- Panel to select a installation target folder -->

<panel classname="TargetPanel"/>

<!-- Panel to select the packs for the installation -->

<panel classname="PacksPanel"/>

<!-- Panel which displays a progress bar during the installation -->

<panel classname="InstallPanel"/>

<!-- Panel to show a summary and to offer the generation of an auto-installation script -->

<panel classname="FinishPanel"/>

</panels>

 

<!-- Definition of packs for the installation -->

<packs>

<!-- Apache Tomcat installation pack -->

<pack name="Apache Tomcat" required="yes">

<description>Apache Tomcat</description>

<fileset dir="apache-tomcat" targetdir="${INSTALL_PATH}\apache-tomcat" override="true"/>

</pack>

<!-- Offline PPS installation pack -->

<pack name="SAP Offline PPS" required="yes">

<description>SAP Offline PPS</description>

<fileset dir="offline-pps" targetdir="${INSTALL_PATH}\sap-offline-pps" override="true"/>

</pack>

<!-- Installation pack which executes the Windows Service create script -->

<pack name="Windows Service Entry" required="no">

<description>Create a Windows Service entry</description>

<file src="ServiceScript\service_wrapper.bat" targetdir="${INSTALL_PATH}\sap-offline-pps\bin" override="true"/>

<file src="ServiceScript\service.bat" targetdir="${INSTALL_PATH}\sap-offline-pps\bin" override="true"/>

<file src="ServiceScript\uninstall-service.bat" targetdir="${INSTALL_PATH}\sap-offline-pps\bin" override="true"/>

<executable targetfile="${INSTALL_PATH}\sap-offline-pps\bin\service_wrapper.bat" type="bin" stage="postinstall" failure ="warn" keep="true">

<os family="windows" />

<args>

<arg value="${INSTALL_PATH}"/>

</args>

</executable>

</pack>

</packs>

 

</izpack:installation>

 

 

5.3.3              Example for an automated Installation (auto-install.xml)


auto-install.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<AutomatedInstallation langpack="eng">

<com.izforge.izpack.panels.target.TargetPanel id="TargetPanel_0">

<installpath>C:\Program Files\opps</installpath>

</com.izforge.izpack.panels.target.TargetPanel>

<com.izforge.izpack.panels.packs.PacksPanel id="PacksPanel_1">

<pack index="0" name="Apache Tomcat" selected="true"/>

<pack index="1" name="SAP Offline PPS" selected="true"/>

<pack index="2" name="Windows Service Entry" selected="true"/>

</com.izforge.izpack.panels.packs.PacksPanel>

<com.izforge.izpack.panels.install.InstallPanel id="InstallPanel_2"/>

<com.izforge.izpack.panels.finish.FinishPanel id="FinishPanel_3"/>

</AutomatedInstallation>

 

 

6  Related Documents



 
18 Comments