openxava / documentation / Multitenancy

Table of contents

Multitenancy
Creating a new organization
Customization
JDBC inside organizations (new in v5.6)
Shared users between organizations (new in v5.6)
Visual theme by organization (new in v6.4)
Multitenancy allows you to deploy an application once and this single application can serve several companies at the same time, where each company has access only to its own data. This is perfect for SaaS (Software as a Service), so you can deploy your application in the cloud and rent it to many customers. Also it's very useful for creating multimunicipality applications for public administration. Even if you're not interested in multicompany applications having several isolated datasets allows you do interesting things, such as having a production and testing databases without effort.
XavaPro supports multitenancy out-of-the-box.

Creating a new organization

To support multitenancy XavaPro uses organizations. You will find the Organizations module in the Admin folder. This module allows you to create a new organization just specifying its name and clicking a button:
multitenancy_en010.png
After clicking on the button "Create new organization", the new organization is ready to be used in the specified URL. The creation process creates a new schema in the database, creates all the application tables and populates the admin tables. Since v6.1 folders, roles and rights for the new organization are copied from root organization.
You can go to the company URL (/YourAplication/o/YourCompany) directly or to the application URL (/YourApplication). In the later case the sign in form will ask you for the company with a combo:
multitenancy_en030.png
Each organization has its own users, passwords, roles and rights, of course.

Customization

The syntax for creating and removing schemas depends on your database. Your can specify the syntax for your database with the createSchema and dropSchema (new in v5.7.1) properties en naviox.properties:
# Multitenancy: Only available in XavaPro (http://www.openxava.org/xavapro)
 
# The create schema sentence used for creating a new organization
# This is the default one
createSchema=CREATE SCHEMA ${schema}
# These are by database vendor, you can add yours using the database name
# as suffix (actually the first token of connection.getMetaData().getDatabaseProductName())
createSchema.PostgreSQL=CREATE SCHEMA ${schema}
createSchema.HSQL=CREATE SCHEMA ${schema} AUTHORIZATION DBA
 
# The drop schema sentence used for removing an existing organization
# This is the default one
dropSchema=DROP SCHEMA ${schema} CASCADE
# These are by database vendor, you can add yours using the database name
# as suffix (actually the first token of connection.getMetaData().getDatabaseProductName())
dropSchema.MySQL=DROP SCHEMA ${schema}

If you want to make additional customization, like populating the application tables, creating some initial roles and users, giving a specific modules and folders structure, etc. you can define your own action to create the organization. The original action for creating a new organization is createNewOrganization in the Organization controller defined in Addons/xava/controllers.xml. Therefore to define your own action for create a new organization you have to define a Organization module in your application and assign to it your own controller with your own action.
First, add the Organization module to your application.xml:
<module name="Organization">
    <model name="Organization" />
    <controller name="MyOrganization" />
</module>
Then add your MyOrganization controller to your controllers.xml:
<controller name="MyOrganization">
    <extends controller="Organization"/>
    <action name="createNewOrganization" mode="detail" takes-long="true"
        class="com.yourcompany.yourapp.actions.CreateMyNewOrganizationAction"/>
</controller>
Finally, write the code for your CreateMyNewOrganizationAction action:
package com.yourcompany.yourapp.actions;

import com.openxava.naviox.actions.*;

public class CreateMyNewOrganizationAction extends CreateNewOrganizationAction {

    public void execute() throws Exception {
        super.execute(); // This creates the new organization
        // HERE YOU OWN CODE TO REFINE THE NEW ORGANIZATION
    }
    
}
Note as we extend CreateNewOrganizationAction that contains the original logic to create a new organization.

You can hide the combo with the list of organizations on sign in adding the next entry to naviox.properties (new in v5.6):
showOrganizationOnSignIn=false
Also you have the option of using a simple text field instead of a combo to entering the organization name, in this way the user has not access to the list of all organizations. Add the next entry to naviox.properties (new in v6.3):
showListOfOrganizationsOnSignIn=false

JDBC inside organizations (new in v5.6)

Any JPA or Hibernate code (Hibernate since v5.6) from your actions, calculators, entities, etc. goes against the correct schema for the current organization, however that is not the case for JDBC. If you want that your JDBC code goes against the schema of the current organization you have to add the next entry in xava.properties:
connectionRefinerClass=com.openxava.naviox.util.SetCatalogFromPersistenceSchemaConnectionRefiner
This works for databases where catalog and schema are synonymous, such as MySQL.

Shared users between organizations (new in v5.6)

When you use multitenancy with XavaPro each organization has its own group of users totally independent from other organizations. This is OK for many cases, however some applications need to have the same group of users for all the organizations. You can configure your application to work in this way, just check the corresponding option in the configuration module:
multitenancy_en040.png
With "Shared users" activated the users and passwords for all the organizations are those of the root application. You have to create the users in the root application only and when one of these users try to access to an organization he has the option to join:
multitenancy_en050.png
There is a joined role in each organization to define the rights for these users.
When the user sign in with "Shared user" activated, the list of his organizations are shown in order to choose:
multitenancy_en060.png
The user can go to any of his organizations without login again.

Visual theme by organization (new in v6.4)

You can assign a different visual style to each organization. For that, go to the Organizations module and edit an organization. There you have a property called theme with a combo to choose from the available themes, thus:
multitenancy_en070.png
Choose one and click on Modify, afterwards that organization will use that theme with no possibility to change it by the user. If you don't define a theme for an organization all the themes will be available to be chosen by the user in that organization.
All the available themes are defined in xava.properties with the themes property, in this way:
themes=terra.css, light.css, dark.css, black-and-white.css, blue.css
Learn more about themes in the visual style documentation.