Documentation Home

Getting Started

This section provides a set of steps that can enable MultiTenant capabilities on the Broadleaf Commerce demo site. Going
through this process will help you to get the module running locally and provide a good test bed for amending functionality.

For most cases, it is not intended to be the starting point of your custom development.

Following this process has an added benefit in that if you run into issues that can be recreated in this environment, our
team will be able to assist you in a much more effective way since we will be able to troubleshoot without access to your
specific implementation.

Prerequisites

This getting started guide assumes you have done the following ...

  1. Gone through the Broadleaf Community Edition Getting Started guide to run the demo application locally
  2. Followed the Module Installation documentation for MultiTenant to apply this module to the demo application

Note: It's a good idea to backup your database before you begin so that you can repeat these steps (and experiment with
additional data) but still be able to get back to a known place.

Overview

This guide will help you do the following ...

  • Create sample sites
  • Configure your development environment to test multiple sites
  • Create a site-admin user
  • Create a global-admin user
  • View the admin as a site-admin
  • View the admin as a global-admin

Create sample sites

Typically, you will create sites via code as described in the Site Provisioning section.

For this tutorial, we will create sites via SQL. The following SQL will create a site.

-- First, we create a site.
INSERT INTO BLC_SITE (SITE_ID, NAME, SITE_IDENTIFIER_TYPE, SITE_IDENTIFIER_VALUE, SITE_TYPE) VALUES (1, 'Test Site One', 'DOMAIN_PREFIX', 'site1', 'TEMPLATE');

-- Next, we create a catalog for the site.
INSERT INTO BLC_CATALOG (CATALOG_ID, NAME, OWNING_SITE) VALUES (1, 'site1_catalog', 1);

-- Finally, we associate the catalog with the site
INSERT INTO BLC_SITE_CATALOG (SITE_CATALOG_XREF_ID, SITE_ID, CATALOG_ID) VALUES (1, 1, 1);

You can repeat this to create additional sites. This example shows a one to one mapping for site and catalog and uses the
domain prefix style of site resolution. You'll learn more about these items by reviewing the Key Concepts documentation.

Configure your development environment to test multiple sites

Because the multi-tenant module acts off of the domain or domain prefix, for local testing you will want to modify your
local hosts file. For most systems, this file is located in /etc/hosts. Search StackOverflow for the location on
your specific OS. Most windows users will find the file in C:\Windows\System32\Drivers\etc\hosts.

Add the following line ...

127.0.0.1       site1.localhost.com

You'll need to add an entry for each site you want to test with locally. The example above is for sites using the
DOMAIN_PREFIX style of resolution. The important facts are that the domain is 3 parts (e.g. site1, localhost, com) and
that the first element is site1.

Create a site admin user

In this step, we will create a site admin user. Typically, this would be automated through a site provisioning process.
Creating a site admin involves four steps.

-- Step 1.  Create a Site Security Context for Site 1
INSERT INTO BLC_ADMIN_SEC_CNTXT (ADMIN_SEC_CNTXT_ID, CONTEXT_TYPE, CONTEXT_KEY) VALUES (1, 'SITE', '1');

-- Step 2.  Assign a role to the Security Context (note that "-1" is the out of box 'Admin' role)
INSERT INTO BLC_ADMIN_SEC_CNTXT_ROLE_XREF (ADMIN_SEC_CNTXT_ID, ADMIN_ROLE_ID) VALUES (1, -1);

-- Step 3.  Create the admin user for the site (login site1admin, password admin)
INSERT INTO BLC_ADMIN_USER (ADMIN_USER_ID, ACTIVE_STATUS_FLAG, EMAIL, LOGIN, NAME, PASSWORD) 
  VALUES (1, 1, 'site1admin@yourdomain.com', 'site1admin', 'Site 1 Administrator', 'admin{1}');

Note: The above SQL assumes your demo site is using the default password salt (based on id) and no encryption (which is why the password is in clear text). This would not be true on your production site but does match the demo defaults.

Steps 1 and 2 can be reused to create other site admins for the same site. Similarly, you can create additional site
security contexts by following this pattern for non 'Admin' roles like 'CSR' and 'Merchandiser'.

Create a global-admin user

-- Step 1.  Create the global admin user (note the context-type of GLOBAL)
INSERT INTO BLC_ADMIN_USER (ADMIN_USER_ID, ACTIVE_STATUS_FLAG, EMAIL, LOGIN, NAME, PASSWORD, CONTEXT_TYPE) 
  VALUES (2, 1, 'globaladmin@yourdomain.com', 'globaladmin', 'Global Administrator', 'admin{2}', 'GLOBAL');

-- Step 2.  Add roles to the global admin user (note -1  is the out of box Admin role)
-- The -20006 role is the Global Admin Master Access role. This will allow this user to
-- log into the global administration panel, which will be demonstrated below.
INSERT INTO BLC_ADMIN_USER_ROLE_XREF (ADMIN_USER_ID, ADMIN_ROLE_ID) VALUES (2,-1);
INSERT INTO BLC_ADMIN_USER_ROLE_XREF (ADMIN_USER_ID, ADMIN_ROLE_ID) VALUES (2,-20006);

Note: The above SQL assumes your demo site is using the default password salt (based on id) and no encryption (which is why the password is in clear text). This would not be true on your production site but does match the demo defaults.
Note: See the [Security Contexts] documentation for more details about Global users.

View the admin interface for a site

You will now be able to visit http://site1.localhost.com:8081/admin and view the admin panel for site 1. We created an administrator for this site,
and you should be able to log into the admin panel with his credentials, site1admin/admin. Alternatively, you could log into the site with the global
admin user we created, using the credentials globaladmin/admin. Both of these users have the same permissions for interacting with site1 based on the
previously set up data.

Note that you will see all of the normal products from the Heat Clinic demo in this admin panel. This is because those products do not have a value
set for their CATALOG_DISC or SITE_DISC columns. When these columns are null for any given entity, that entity is available to all configured sites.

Please see the Data Partitioning section for more information.

If you set up additional sites in the previous steps of this getting started guide, you would be able to see that creating a new product through the
admin interface automatically associates it to the current site. Therefore, if you logged into a secondary site, any newly created entities would
not be visible in that other site.

View the global admin interface

In addition to the admin panel that is used for managing a particular site, Broadleaf provides an additional global admin panel that allows access
to global admin users and site maintenance. Logging into this panel is controlled by the Global Admin Master Access permission, which our global
admin has (-20006). This panel can be reached through any site URL by visiting http://site1.localhost.com:8081/admin/global. Note that you must be
logged out to visit this URL, and must log in specifically through the previously mentioned URL.

Restrict multitenant influence on certain entities

In some cases, it may be desirable to remove multitenant behavior from some aspects of Broadleaf Commerce that include it by default. For example,
if your use case demands that each tenant maintain a separate catalog, but customers and orders are shared by all "tenants", you may want
to remove the multi tenant treatment that Broadleaf would normally create for customers and orders. This is achieved through
configuration in your applicationContext.xml (this is usually in your implementation's core module, if you are following Broadleaf's
prescribed maven project structure). The main point of this configuration is that you'll want to expose it to any web WAR
file you create (e.g. admin.war and ROOT.war). This is generally achieved through an application context xml file that is
shared by all web modules.

Here's an example configuration that will negate multitenancy for customers and orders:

<bean id="ignoredMultiTenantPatterns" class="org.springframework.beans.factory.config.ListFactoryBean">
    <property name="sourceList">
        <list>
            <bean class="org.broadleafcommerce.common.extensibility.jpa.copy.DirectCopyIgnorePattern">
                <property name="patterns">
                    <array>
                        <value>org\.broadleafcommerce\.profile\.core\.domain\.CustomerImpl</value>
                        <value>org\.broadleafcommerce\.core\.order\.domain\.OrderImpl</value>
                    </array>
                </property>
                <property name="templateTokenPatterns">
                    <array>
                        <value>multiTenantSite</value>
                    </array>
                </property>
            </bean>
        </list>
    </property>
</bean>

<bean class="org.broadleafcommerce.common.extensibility.context.merge.EarlyStageMergeBeanPostProcessor">
    <property name="collectionRef" value="ignoredMultiTenantPatterns"/>
    <property name="targetRef" value="blDirectCopyIgnorePatterns"/>
</bean>

The "patterns" property is a list of regular expressions that will match against fully qualified classnames of entities. Any
matches will be ignored for transformation. Additionally, since Broadleaf employs entity transformation for several modules,
it is further necessary to inform the system specifically which module behavior you want to be ignored. This is defined by
the "templateTokenPatterns" property, which is a list of regular expression patterns for specific functionality to ignore. In
this case, we're only concerned with negating multitenant behavior for sites, so we include the "multiTenantSite" pattern.
Additional patterns available for use can be explored in the org.broadleafcommerce.common.extensibility.jpa.copy.DirectCopyTransformTypes
class.