Getting Started¶
A customer implementation involves setting up a development project structure so that JMC can be built and developed for deployment to a customer’s retail environment. JMC is built by a Gradle based build system. JMC base libraries are stored in a Maven repository and pulled in by the customer specific Gradle build.
Development Requirements:
- Java JDK 17
- IntelliJ Community Edition
See the Developer Setup Documentation for more details.
Project Setup¶
The customer implementation project can be set up via a Gradle starter task found in the core commerce GitHub project. To run the startup task you need to:
- Set up core commerce per the developer setup instructions
- Change to the desired releases/N.x branch
- Open a terminal prompt in the commerce-assemble directory
-
Run the following Gradle command providing the project directory and a three letter abbreviation for the customer.
This command will generate a folder structure similar to the setup of commerce itself.> ./gradlew starter -PstarterOutputDir=/Users/cshenso/Downloads/test -PstarterPrefix=tst -
jmc-xxx - root of the project. This is the level that is typically checked into source control
- xxx-base - Custom module, specific to customer. All configuration and data files as well as any customizations will be found here.
CI/CD¶
Jumpmind recommends that each customer have a continuous build that generates artifacts that will be across environments for testing and eventual promotion to production.
Jumpmind will provide starter helm charts for cloud deployments.
Example CI/CD tools are provided by, but are not limited to GitHub, Atlassian, GitLab and Microsoft Azure.
Branching Strategy¶
Each customer will get their own maven repository and a service account for use in their CI/CD pipeline.
Starter Project Structure¶
The meat of the project structure is in the xxx-base project. Under src/main/resources you will find starter data files and starter configuration files.
Before discussing the structure of these files lets discuss the architecture and environments supported by the starter project.
Tiers¶
A typical deployment of JMC includes 2 to 3 tiers of services. Each tier syncs data and makes service calls to and from the next tier. The starter project is geared around three tiers:
central - represents processes that run centrally, normally in the cloud which all use a shared centralized data store.
1. businessunit - A shared (usually) in store service that normally hosts mobile devices.
2. fixed (optional) - A service that typically runs on traditional register hardware.
3. failover - The starter project also provides for a failover server (for the businessunit) that is configured to run at the fixed tier
Environments¶
An environment is a place where an application runs with specific hardware and data and services. You can test an application with conditions that are similar to production in lower environments. A version of an application is typically moved from lower to higher environments until it reaches production. Each environment usually has specific configuration that consists of settings like URLs, usernames and passwords. The starter project supports the following environments by default:
intellij - an environment used from the IntelliJ IDE to run JMC
dev - an environment used by developers to test a new version of the application
qa - an environment used by testers to test a new version of the application
prod - the final environment where the application is used
Configuration Files¶
Configuration is managed in application-xxx.yml files. Default configuration for JMC can be found in the JMC core repository in a project in commerce-server/src/main/resources. The configuration is in application.yml and application-func.yml. The file application-func.yml has most of the business rule configurations along with descriptions of each configuration. The application.yml contains more technical aspects of configuration. Most (but not all) configurations can be overwritten in the database (ctx_config) which allows configuration to be tagged to specific locations/brands/etc.
Application YAML configuration files are a feature of the Spring Framework. You can read more about them and how they are enabled in the Spring Framework documentation (https://www.baeldung.com/spring-yaml).
The application YAML files are activated by Spring profiles. Multiple Spring profiles are activated via a Java System property (-Dspring.profiles.active).
Application YAML files are loaded in the order that Spring profiles are listed. Spring profiles are set in the startup parameters, conf files, and additional layers can be included inside each application YML file. Each configuration is layered on top of another overriding default properties which is how configuration for a specific Tier and/or Environment is set.
For example, the businessunit tier (as installed at the store) is enabled as such in a service conf file:
-Dspring.profiles.active=base,swagger-ui,lab-businessunit,businessunit,foundation-businessunit,adyen,purge-businessunit,env,businessunit-${env},businessunit-bootstrap,override
This means that when loading application YAML files, the following will be loaded in this order: application-base.yml (under source control) application-businessunit.yml (under source control) application-purge-businessunit.yml (under source control) application-businessunit-bootstrap.properties (found in the work directory; created during installation) application-base-{environment}.yml (under source control) application-businessunit-{environment}.yml (under source control) application-override.yml (last ditch opportunity to override; used for “emergencies”)
The application-env.properties file is typically generated during application installation. It includes store specific settings and enables environment specific settings such as API url’s & credentials. It is a best practice to keep application-env.yml as lean as possible. It is also best practice to keep as much of the configuration under source control as possible.
Here is an example of an application-businessunit-bootstrap.properties:
env=dev
openpos.businessunitId=06245
openpos.installationId=06245
auto-update.enabled=false
auto-update.url=https\://update.dev.qe.jumpmind.io/
auto-update.package-name=point-of-sale
Passwords and other secure data can be encrypted using the jasypt library.
Data Files¶
There are other aspects of configuration that are stored in the database. Most of that configuration is called foundation data. It is stored in the CI/CD project and applied by the application when it is started up. The convention for storing data is to put CSV or SQL files in a folder under src/main/resources/data/{module name}/{spring profile name}. JMC modules are responsible for applying data for Spring profiles that are active.
The folders provided under the starter project are as follows:
intellij - data for development in the IDE only
integration - data that is needed to use JMC, but is typically provided by integrations. In the different environments that are higher than intellij (and sometimes dev), this Spring profile will more than likely be turned off
foundation - configuration data that will be tweaked per a customer's requirements. It is typically turned on in the central tier only and SymmetricDS syncs that data down.
Foundation Data (new since 243.6)¶
As of 243.6 the starter project has a dependency on org.jumpmind.jmc.foundation-data:foundation-data. This is not required for customers upgrading, but it is recommended for new projects.
The foundation data module has foundational base data packaged as CSVs are targeted at being applied at the businessunit or corp tiers.
Because this a packaged core JMC resource upgrades will inherit new data changes. In order to tweak the base data set, retailers should use SQL in their layer to massage the data to their needs.
Another change in approach for projects that has been started as of 243.6 is that specific tables are being applied at the retail store now (versus applied globally at corp). This change in approach is to simplify upgrades. Tables such as buttons, form fields and other foundational data typically go with a release, so now that are being applied when the software is upgraded on premise.
Retailers should consider changing to this pattern as part of an upgrade, but it is not required.
3-Tier Configuration & SQL Overrides¶
Customer Layer SQL Overrides:
- Overrides for foundation data go in: resource/data/foundation/foundation
- Other Spring profiles (e.g., intellij, fiscal) go in: data/foundation subfolders
Spring Profile Inclusion:
- Corp instance: includes both foundation-corp and foundation-businessunit profiles
- Business Unit: includes foundation-businessunit profile
- Fixed tiers: include foundation-businessunit profile
- None of the tiers should include the plain foundation profile
Customer SQL Overrides Location:
Customer SQL overrides should be placed in:
- foundation-businessunit
- foundation-corp
Note: The original idea of creating folders under foundation/ did not work
Symmetric Data Handling for Customized Customers¶
- If a .batch file is added in the customer layer, it will still run the base one first
- Using SQL to update custom Symmetric config is appropriate
- A .batch file in the customer layer is acceptable if customer monitors release notes before upgrading
Foundation Data Sync Changes¶
Some tables are now handled similarly to ctx_config and ctx_config_foundation to remove Corp→Businessunit sync for foundation data.
Naming Conventions¶
Data files of type: CSV, SQL and BATCH are supported. Batch files are formatted using the SymmetricDS batch protocol. Typically, only a SymmetricDS configuration extract uses this format.
File names are of the form: {optional version}{post or pre}.}_{table name}.{csv or sql or batch
The version is typically used for sql files so you can see a history of what has been applied from release to release. While developing a release you would iterate on the sql file, but after the release has been put in production you would introduce a new version of the file.
Post or pre is used to indicate when a file is run. Post indicates that the file should be run after the update of the database schema. Pre indicate that the file should be run prior to the database schema being updated. Pre is typically only used to fix data required by a database schema update.
CSV versus SQL¶
CSV files are applied as a kill and fill. When the CSV file is applied an MD5 checksum is stored. If the files checksum changes from release to release the CSV file will be reapplied. CSV files are easier to maintain and have a more predictable outcome than SQL files.
SQL files are also applied when their checksum changes. This means that all SQL files should be re-runnable. SQL files are typically used when only a subset of the data needs to be managed. An example foundation table that is typically managed via SQL is ctx_config. Many times ctx_config will be changed in each environment. When applying a release you don’t want to blow away intentional changes so ctx_config is a more surgical way to update data.
Content¶
Content is images and artifacts that are served by the server and can be tag specific. More static content (like logos) are stored under source control. More dynamic content can be provided via extension points and pulled from an external CMS or other source system.
Theming¶
Themes are (currently) maintained in the core framework. If a customer needs a theme that currently does not exist, then please open a PR to the commerce GitHub project.
Deployments¶
This section will talk about deployment patterns; both to the cloud and on-premise at a business unit location.
Cloud¶
We suggest using kubernetes containers in the cloud. Canned templates and documentation … coming soon.
On-premise¶
The starter project contains a Gradle distribution target that builds a zip file that should be used for installation on an in store device (mobile server or fixed register). JMC provides a service wrapper and scripts to install a tiered service. Configuration of the java process is handled by the _service.conf files found in the conf directory. There are preconfigured service files for the businessunit, fixed and failover tiers in the starter project.
Personalization¶
Personalization is the process of JMC devices being assigned device ids and tags. See the section on personalization in the Commerce Users Guide for more information.
Content¶
Content can be provided through multiple method - The local file-system - The classpath - A remote system
- The configuration show in the screenshot below is an example of how to setup content from the local file system and the classpath

- The configuration at openpos.ui.content.file-system.providerProperties dictates how the file/directory structure should be structured. Our file-system content provider will generate all possible permutations of directory structure and search for the most-specific piece of content that it can find
- For example, here is how the configuration above expects its file-system for content for the home-screen-logo
content/ ├─ home-screen-logo/ │ ├─ {BRAND_1}/ │ │ ├─ {DEVICE_TYPE}/ │ │ │ ├─ en_us/ │ │ │ │ ├─ image1 │ │ │ ├─ es_MX/ │ │ │ │ ├─ image2 │ │ │ ├─ fr_CA/ │ │ │ │ ├─ image3 │ ├─ {BRAND_2}/ │ │ ├─ etc/
- You do not need to create this entire structure for every piece of content. JMC will simply attempt to find the most-specific piece of content that it can
- If you just want to specify the image for 2 separate brands, you could just do the following
content/
├─ home-screen-logo/
│ ├─ {BRAND_1}/
│ │ ├─ brand_1_image.jpg
│ ├─ {BRAND_2}/
│ │ ├─ brand_2_image.jpg/