Broadleaf Microservices
  • v1.0.0-latest-prod

Broadleaf Initializr

Note
The Broadleaf Manifest and Initializr is compatible with Broadleaf Release Train 1.8.2 and above.

Overview

The Broadleaf Initializr (https://start.broadleafcommerce.com) is the primary starting point for developers to create, manage, and evolve a Broadleaf Microservices project. This tool is built using Spring Initializr and is customized to produce a project structure specifically catered for your needs. It does this by creating a Manifest containing the most common configurability options typical for a Broadleaf implementation into a single YAML file (i.e. manifest.yml). This along with a few Broadleaf Maven plugins allow you to generate the appropriate project structure and directories needed for your implementation. This tool is optimized for the full-stack or backend commerce API developer journey, so that they may work on, extend, and run the full Java and Spring Microservices ecosystem on their own local machine with little friction.

Here are some of the notable items and enhancements introduced with Broadleaf Initializr:

Streamlined Project Setup

Broadleaf’s Project Initializr simplifies project creation. It provides a user-friendly interface to configure your Broadleaf Commerce project with essential dependencies, plugins, and settings. You can choose from various options, such as database type, Broadleaf Release Train version, and extended Broadleaf Commerce modules. This streamlines the setup process, saving you time and effort.

Streamlined Project Evolution

In addition to providing a project generation tool, there are several concepts introduced that support a smoother project evolution workflow. Initializr projects provide a Manifest concept that gives you the ability to evolve your Flex Package compositions and influence both docker-compose and helm chart generation to make DevOps and Cloud Engineers lives easier

Improved Documentation

The Broadleaf developer documentation has been revamped to align with the new Initializr setup. It now offers clearer instructions, examples, and best practices. You’ll find detailed explanations for each configuration option, making it easier to tailor your project to your specific needs.

Enhanced Security Posture

Every installation of Broadleaf Initializr is cryptographically unique. Broadleaf generates an initial starting point that produces sensible and secure defaults allowing you the implementor to easily dial up the security needs if needed, or make a conscious choice to dial down certain security measures when it seems appropriate for your needs.

Flexible Version Management

The manifest and dependency override concepts allows for easier Broadleaf Commerce library version management, allowing you to choose the most suitable version for your needs. It also allows you to easily upgrade or downgrade your project holistically or by adjusting individual microservice version settings independently.

Introducing the Broadleaf Manifest

If you’ve downloaded a project from (https://start.broadleafcommerce.com) you will notice that it generated a simple Java project structure that includes the file src/main/resources/manifest.yml. This manifest file will be your hub to configuring the resources and components needed to run your Broadleaf implementation. The specific configurations and dependencies that you picked on the Initializr UI will have been applied to the manifest.yml file in the project that you just downloaded.

Tip
the generated manifest project from the Initializr will also contain a HELP.md file that should be referenced when first generating your project.

If you are building a Broadleaf project from scratch, some typical project setup questions that often come up include:

  • Which Database should I use for my relational data store? How do I switch to a different DB?

  • Which Broker should I used for the underlying messaging system?

  • How do I configure the java group and package name specific to my company?

  • Which ports do these microservice deployments need to listen on?

  • How can I configure my project for a different Flex Package composition?

The goal of the manifest.yml is to provide a single configurable file that contain the answers to the questions above, as well as provide you a single place to easily evolve your configuration over time.

CLI Support

In addition to the UI on https://start.broadleafcommerce.com, the Broadleaf Initializr is also setup for command line usage.

Here are some example cURL commands to directly download a manifest project:

A standard project with all the defaults (balanced + postgres + kafka + no demo data)

curl -G https://start.broadleafcommerce.com/starter.zip -o manifest.zip

A standard project with all the defaults + intent of customizing the catalog and catalogbrowse microservices

curl -G https://start.broadleafcommerce.com/starter.zip -d extensions=catalog,catalogbrowse -o manifest.zip

A "local" project setup using the Mono configuration + MySQL + Google PubSub + Demo Hot Sauce Data

curl -G https://start.broadleafcommerce.com/starter.zip -d blcFlexPackage=one -d dependencies=mysql,gcppubsub -d demoExtensions=heatclinic -o manifest.zip

Project Generation Process

Now that you have your manifest.yml configured the way you want it, Broadleaf provides several Maven plugins to help generate a project structure based on the state of your manifest.

Note
Prior to Initializr and the Broadleaf Manifest, clients would receive a somewhat large starter project that included a lot of pre-defined Flex Packages, a separate project folder for every granular service, and many configuration files that are likely not applicable for your specific implementation. With Initializr, you can now dynamically generate a more streamlined project containing only the dependencies and components that you want.

flex:generate

In order to generate the project structure, you can run mvn clean install flex:generate in the root of your manifest project. After the plugin runs, you should see a couple project folders created in the same directory as the manifest folder.

Initializr Project Generation

Running flex:generate will produce two types of projects depending on the configuration specified in your manifest.yml:

  • Flex Package Project: this type of project represents an actual deployable Spring Boot application consisting of different combinations of "Flex Units". For example, if you chose the Balanced Flex Package composition. The plugin will generate the following flex package projects: auth, browse, cart, processing, and supporting. You will notice that pom.xml for these flex package projects contain references to specific microservice libraries or library overrides that are defined in your implementation. This project will also contain reference Docker configuration to support containerization needed for the application.

  • Library Override Project: a library project is not meant to be a standalone runnable application by itself. It is structured to produce a library JAR which will be referenced and used in a Flex Package Project. An override library project can be generated for any of the Broadleaf microservices by setting the enabled property to true for the relevant component in your manifest.yml. For example, if you would like to extend Broadleaf’s CATALOG microservice, you would set the enabled property for the catalog component in your manifest, run mvn flex:generate which will produce a new library override project called catalogComponent. The artifact identifiers for your override will automatically be updated and referenced in the appropriate Flex Package Project

docker-compose:generate

In order to generate a docker-compose.yml file based on configuration in your manifest.yml run mvn docker-compose:generate in the root of your manifest project. A resulting docker-compose.yml will be emitted to the target/docker directory of the manifest project.

docker-compose:up and docker-compose:down

Once you’ve generated the docker-compose files based on your manifest, you can then run mvn docker-compose:up to launch the generated docker-compose file and conversely terminate all containers using the mvn docker-compose:down plugin command.

Evolving Your Project Structure

As your implementation progresses and the understanding of your overall project needs evolve, you may find yourself needing to tweak and modify the manifest.yml file directly after you’ve already generated the initial project structure. Further modification of the manifest.yml directly is supported and encouraged. Once you’ve modified the manifest to change project structure, you can run flex:generate again and the plugin will create the appropriate project changes to support the updated configuration.

Note
Changes made during subsequent flex:generate calls are cautious. The plugin won’t delete code or directories. Furthermore, it will create a backup of the current pom file before editing it for the flex:generate run. Any pom.xml file edits will not remove custom elements that may have been added before (including any custom dependencies).

Notable Project Callouts

If you were familiar with the older MicroservicesDemo project structure, here are some improvements and changes worth noting:

Simplified POMs

Each of generated projects have a simplified POM. Here is an example of the pom for the AUTH flex package microservices project.

Initializr AUTH pom.xml
Callouts:
  • POM inherits from broadleaf-microservices-flex-parent

  • The parent pom defines useful Maven Properties such as:

    • <skip-schema>false</skip-schema> allowing you to generate the liquibase schema as part of the build! (no longer have to run UtilitiesIT manually anymore). Note that this property only makes sense in a library override project, not a flex package project.

    • <skip-mapper-cache>false</skip-mapper-cache> allowing you to generate the ModelMapper cache as part of the build! (no longer have to run the IntegrationTest manually to generate the cache). Note that this property only makes sense for a flex package project - not a library override project.

  • Where do you define the Release Train? The parent now contains a lot of the "definition" that was previously expected to be defined in the old project structure. The version of the flex-parent pom will contain a reference to the appropriate Release Train version.

  • What about specific library version overrides? You can explicitly override any Broadleaf or third-party library version that is specified in the inherited Release Train BOM by declaring it in the <dependencyManagement> section. This is the same process as it was before.

No Boilerplate Configuration

Each of generated projects no longer contain boilerplate configuration files (e.g. application-*.yml files).

Initializr boilerplace comparison
Callouts:
  • No need to define DB properties (hostname, port, composite, etc…​)

  • No need to define messaging broker properties

  • No need to configure inter-service communication (e.g. client URL properties)

  • There is a Spring Application Runtime Environment Post Processor that will figure out the correct values to set based on the configurations specified in your manifest.yml file.

Introducing the Data Module

One of the goals with the new Initializr setup is to allow implementors the ability to de-couple liquibase from the application startup lifecycle. There are many reasons why this can be beneficial in certain scenarios (e.g. in production environments running multiple replicas of Balanced or Granular Flex Packages on a Kubernetes cluster). With this setup, we’ve moved any liquibase schema interactions to a separate Data module that can be run independent of the Flex Package microservices.

Running mvn flex:generate will by default produce a data module that contains a simple Spring Boot Command Line Runner application.

Initializr Data Module

You can run this program to update and initialize the database prior to any application startup. This application can be run in an interactive or headless fashion.

To run the data module locally, run mvn spring-boot:run. Below is an example of running the data module in interactive mode.

Disabling the Data Module

If you do not wish to use the data module and instead revert to having liquibase run on application startup. Enable the following ENV properties (or add this back as spring application properties)

Below are example ENV variables that you can pass in for a Balanced Flex Package composition (assumes you want the liquibase tables like DATABASECHANGELOG and DATABASECHANGELOGLOCK be in the public schema).

For Auth:
    # Enable old liquibase compatibility behaviour with new Initializr
    - name: SPRING_LIQUIBASE_ENABLED
      value: 'true'
    - name: SPRING_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
For Browse Flex Package:
    # Enable old liquibase compatibility behaviour with new Initializr
    # flexUnits: asset,catalog,catalogbrowse,content,menu,offer,pricing,ratings,vendor
    - name: SPRING_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_ASSET_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_ASSET_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_CATALOG_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CATALOG_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_CONTENT_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CONTENT_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_MENU_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_MENU_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_OFFER_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_OFFER_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_PRICING_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_PRICING_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_RATINGS_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_RATINGS_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_VENDOR_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_VENDOR_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
For Cart Flex Package:
    # Enable old liquibase compatibility behaviour with new Initializr
    # flexUnits: cart,cartops,customer,fulfillment,inventory,order,orderops,paymenttransaction,shipping,creditaccount
    - name: SPRING_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CART_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CART_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_CUSTOMER_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CUSTOMER_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_FULFILLMENT_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_FULFILLMENT_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_INVENTORY_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_INVENTORY_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_ORDER_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_ORDER_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_ORDEROPERATION_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_ORDEROPERATION_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_PAYMENTTRANSACTION_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_PAYMENTTRANSACTION_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_SHIPPING_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_SHIPPING_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_CREDITACCOUNT_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CREDITACCOUNT_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
For Processing Flex Package:
    # Enable old liquibase compatibility behaviour with new Initializr
    # flexUnits: import,indexer,scheduledjob,inventory,catalog,offer,pricing,customer,order,menu,content
    - name: SPRING_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_DATAIMPORT_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_DATAIMPORT_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_INDEXER_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_INDEXER_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_SCHEDULEDJOB_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_SCHEDULEDJOB_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_SEARCH_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_SEARCH_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_INVENTORY_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_INVENTORY_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_CATALOG_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CATALOG_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_OFFER_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_OFFER_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_PRICING_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_PRICING_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_CUSTOMER_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CUSTOMER_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_ORDER_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_ORDER_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_MENU_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_MENU_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_CONTENT_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_CONTENT_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
For the Supporting Flex Package:
    # Enable old liquibase compatibility behaviour with new Initializr
    # flexUnits: adminnav,adminuser,metadata,notification,sandbox,search,tenant
    - name: SPRING_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_ADMINNAVIGATION_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_ADMINNAVIGATION_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_ADMINUSER_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_ADMINUSER_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_METADATA_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_METADATA_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_NOTIFICATION_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_NOTIFICATION_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_SANDBOX_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_SANDBOX_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_SEARCH_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_SEARCH_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'
    - name: BROADLEAF_TENANT_LIQUIBASE_ENABLED
      value: 'true'
    - name: BROADLEAF_TENANT_LIQUIBASE_LIQUIBASESCHEMA
      value: 'public'

Better Seed vs Required Data Organization

Started Baseline Changelogs

Initializr now starts with an optimized "starter" liquibase baseline across all microservices.

Note
Prior to Initializr and Release Train 1.8.2, MicroservicesDemo and prior accelerator projects pointed to a baseline that included not only required schema but also both seed data and demo data (certain demo data could be disabled using liquibase-contexts).

We wanted to re-organize how schema, required seed data, and demo data were being included into a project with the intent of being more explicit about how and when demo data is included.

The new starter baselines follow the naming convention of: [service].starter.[database].changelog-master.yaml

Below is a sample comparison of the older Catalog baseline vs. the new Catalog starter baseline.

Initializr Liquibase Baseline

Required Data Changelogs

Actual required seed data has been explicitly defined through liquibase change sets. These required changelogs follow the naming convention: [service].starter.required.data.changelog.xml

Below is an example of the Auth microservices required data

Initializr Auth Required Data
Note
prior to Initializr, certain microservices like Auth relied on DataInitializers to insert some required data. These "DataInitializers" are now deprecated in favor of the required data change-logs.
Callouts:
  • Required Data is now maintained in a structured XML file in a single location per microservice

  • XML Changelogs support DB platform idiosyncrasies when generating appropriate SQL

  • XML Changelogs support the ability to override certain values based on Environment using Liquibase parameters

  • Supports "backward compatibility" allowing clients that may have created required data by other means using Liquibase preConditions

Demo Data

Prior to Initializr, data to support a storefront like the Heat Clinic Hot Sauce demo store was included in the older baseline liquibase files.

Demo data is now enabled by inclusion of a specific Storefront demo JAR (e.g. a Heat Clinic JAR). To include demo data via the Initializr - you can check the Hot Sauce Demo checkbox which will enable it on your manifest and will include the appropriate demo JAR on your project.

Generally, we recommend not including demo data when you want to start your own actual implementation project. The demo data (and components that may be specific to the demo e.g. Hot Sauce Store) is out-of-the-way, and you can start on your own domain and concepts in earnest. With that said, the storefront will be empty and not accessible right away as no application data is loaded. The admin will launch with a single Master admin. From there, you will have the ability to provision applications and catalogs per your specific implementation.

If you are just experimenting, we recommend enabling the demo data in order to get acquainted with the structure and concepts in a typical working scenario. The demo extension can then be commented/removed from the manifest and any subsequent mvn flex:generate runs will update the project poms to remove the demo data influence when ready.

Introducing the Security Project

Security in a system is an important consideration and Broadleaf is no exception. There are varying degrees in which you can choose to apply security as it can depend on several factors including:

  • Internal Corporate Policies

  • Industry or Regulatory Requirements

  • Environments that you are trying to deploy to

Broadleaf generates an initial starting point that produces sensible and secure defaults allowing you the implementor to easily dial up the security needs if needed or make a conscious choice to dial down certain security measures when it seems appropriate for your needs.

Initializr Security Folder Generation

Running the flex:generate command will create a security folder that contains important security related files and information needed for your installation that will holistically tie the system together. Note that the contents of these generated files are cryptographically unique upon generation.

Initializr Security Folder Screenshot
Important
the contents of the security directory should NOT be stored in source control, but instead should be uploaded and managed in a secure location such as an encrypted vault.

More details around the contents of the security folder can be found on the initializr security production considerations page.

Introducing the Config Server

We highly recommend the inclusion of a Spring Cloud Config server into your microservices ecosystem. With initializr, the generated project comes defaulted with a config service that works in conjunction with both the regular application properties and secure sensitive properties that get generated as part of the security module as described above.

After running a flex:generate command with the config component enabled, you will notice a few things:

  • Your project should contain a new config directory containing both a secure and insecure folder. These folders are intended to hold and store their respective types of properties. It is important to read the README contained in the config directory as you should not immediately check these folders into source control. It is best practice to limit the scope of who can manage and view some of these properties (the README details various best practice approaches).

  • You should also notice that the properties in the secure directory are encrypted. These secure properties were generated and encrypted as part of the security flex:generate process.

  • After running docker-compose:generate, you will notice that your generated target/docker/docker-compose.yml will contain an entry for the config resource that uses Broadleaf’s production docker image: image: repository.broadleafcommerce.com:5001/broadleaf/broadleaf-config-server-platform:X.X.X-GA This docker-compose configuration is set up in such a way to load the configurations (both secure and insecure directories) on your local filesystem. The system will detect and mount both of these folders appropriately to run the project on a local machine.

Broadleaf provides a production ready docker image which can be used, deployed, and configured out-of-box. More details and documentation around what this config service is capable of can be found here on our enhanced ENV configuration support page.