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:
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:
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:
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:
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:
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:
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