Multitenant System using a table on a database
Introduction
Ontimize allows you to provide the tenants using a table on a database. This is useful when the application will manage a dynamic list of tenants.
Prerequisites
There are 2 options to follow this tutorial, clone the repository with the initial state and follow the tutorial step by step, or download the final example and see which files are new and which have been updated.
Initial project
/$ git clone https://github.com/ontimize/ontimize-examples
/ontimize-examples$ cd ontimize-examples
/ontimize-examples$ git checkout boot-multitenant-by-table-initial
Final example
/$ git clone https://github.com/ontimize/ontimize-examples
/ontimize-examples$ cd ontimize-examples
/ontimize-examples$ git checkout boot-multitenant-by-table
To simplify the code being written, three dots (…) may appear in some parts of the code. This indicates that there may be previous code before and after those dots.
Steps
We will use the existing database for the first tenant, add a new second database for the second tenant and a database to store the tenants table.
Add the script to create the main database and the tenants table
We need a separate database to store a table containing the tenants. This table must provide a column for each tenant property (More information in this link):
templateDB_Main.txt
- ontimize-examples
- projectwiki-api
- src
- main
- java
- com
- ontimize
- projectwiki
- api
- core
- service
- IUserService.java
- service
- core
- api
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- projectwiki-boot
- src
- main
- java
- com
- ontimize
- projectwiki
- ServerApplication.java
- projectwiki
- ontimize
- com
- resources
- public
- index.html
- application.yml
- public
- java
- main
- pom.xml
- src
- projectwiki-model
- src
- main
- db
- templateDB.txt
- templateDB_Main.txt
- java
- com
- ontimize
- projectwiki
- model
- core
- dao
- UserDao.java
- UserRoleDao.java
- service
- UserService.java
- dao
- core
- model
- projectwiki
- ontimize
- com
- resources
- dao
- placeholders.properties
- UserDao.xml
- UserRoleDao.xml
- dao
- db
- main
- pom.xml
- src
- projectwiki-openapi
- src
- main
- ontimize
- marker-ws-ontimize-openapi-generator
- resources
- public
- restapi
- api
- Test.yml
- User.yml
- base
- AdvancedEntityResult.yml
- AdvancedQueryParameter.yml
- ColumnsParameter.yml
- DeleteParameter.yml
- DocumentIdentifier.yml
- EntityResult.yml
- ExportParameter.yml
- FileListParameter.yml
- FilterParameter.yml
- InsertParameter.yml
- MultipartFile.yml
- MultipartFiles.yml
- Number.yml
- Object.yml
- OFile.yml
- OFiles.yml
- Operator.yml
- QueryParameter.yml
- Responses.yml
- SQLOrder.yml
- String.yml
- UpdateFileParameter.yml
- UpdateParameter.yml
- Void.yml
- openapi-rest.yml
- api
- restapi
- public
- ontimize
- main
- pom.xml
- src
- projectwiki-ws
- src
- main
- java
- com
- ontimize
- projectwiki
- ws
- core
- rest
- MainRestController.java
- TestRestController.java
- UserRestController.java
- rest
- core
- ws
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- .gitignore
- pom.xml
- README.md
- projectwiki-api
Deploy the main database and the tenants
In the pom.xml of the model module, we need to replace the old configuration with the below to deploy the new databases:
pom.xml
- ontimize-examples
- projectwiki-api
- src
- main
- java
- com
- ontimize
- projectwiki
- api
- core
- service
- IUserService.java
- service
- core
- api
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- projectwiki-boot
- src
- main
- java
- com
- ontimize
- projectwiki
- ServerApplication.java
- projectwiki
- ontimize
- com
- resources
- public
- index.html
- application.yml
- public
- java
- main
- pom.xml
- src
- projectwiki-model
- src
- main
- db
- templateDB.txt
- templateDB_Main.txt
- java
- com
- ontimize
- projectwiki
- model
- core
- dao
- UserDao.java
- UserRoleDao.java
- service
- UserService.java
- dao
- core
- model
- projectwiki
- ontimize
- com
- resources
- dao
- placeholders.properties
- UserDao.xml
- UserRoleDao.xml
- dao
- db
- main
- pom.xml
- src
- projectwiki-openapi
- src
- main
- ontimize
- marker-ws-ontimize-openapi-generator
- resources
- public
- restapi
- api
- Test.yml
- User.yml
- base
- AdvancedEntityResult.yml
- AdvancedQueryParameter.yml
- ColumnsParameter.yml
- DeleteParameter.yml
- DocumentIdentifier.yml
- EntityResult.yml
- ExportParameter.yml
- FileListParameter.yml
- FilterParameter.yml
- InsertParameter.yml
- MultipartFile.yml
- MultipartFiles.yml
- Number.yml
- Object.yml
- OFile.yml
- OFiles.yml
- Operator.yml
- QueryParameter.yml
- Responses.yml
- SQLOrder.yml
- String.yml
- UpdateFileParameter.yml
- UpdateParameter.yml
- Void.yml
- openapi-rest.yml
- api
- restapi
- public
- ontimize
- main
- pom.xml
- src
- projectwiki-ws
- src
- main
- java
- com
- ontimize
- projectwiki
- ws
- core
- rest
- MainRestController.java
- TestRestController.java
- UserRestController.java
- rest
- core
- ws
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- .gitignore
- pom.xml
- README.md
- projectwiki-api
Add the data access object for the tenants table
TenantDao.java
TenantDao.xml
- ontimize-examples
- projectwiki-api
- src
- main
- java
- com
- ontimize
- projectwiki
- api
- core
- service
- IUserService.java
- service
- core
- api
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- projectwiki-boot
- src
- main
- java
- com
- ontimize
- projectwiki
- ServerApplication.java
- projectwiki
- ontimize
- com
- resources
- public
- index.html
- application.yml
- public
- java
- main
- pom.xml
- src
- projectwiki-model
- src
- main
- db
- templateDB.txt
- templateDB_Main.txt
- java
- com
- ontimize
- projectwiki
- model
- core
- dao
- TenantDao.java
- UserDao.java
- UserRoleDao.java
- service
- UserService.java
- dao
- core
- model
- projectwiki
- ontimize
- com
- resources
- dao
- placeholders.properties
- TenantDao.xml
- UserDao.xml
- UserRoleDao.xml
- dao
- db
- main
- pom.xml
- src
- projectwiki-openapi
- src
- main
- ontimize
- marker-ws-ontimize-openapi-generator
- resources
- public
- restapi
- api
- Test.yml
- User.yml
- base
- AdvancedEntityResult.yml
- AdvancedQueryParameter.yml
- ColumnsParameter.yml
- DeleteParameter.yml
- DocumentIdentifier.yml
- EntityResult.yml
- ExportParameter.yml
- FileListParameter.yml
- FilterParameter.yml
- InsertParameter.yml
- MultipartFile.yml
- MultipartFiles.yml
- Number.yml
- Object.yml
- OFile.yml
- OFiles.yml
- Operator.yml
- QueryParameter.yml
- Responses.yml
- SQLOrder.yml
- String.yml
- UpdateFileParameter.yml
- UpdateParameter.yml
- Void.yml
- openapi-rest.yml
- api
- restapi
- public
- ontimize
- main
- pom.xml
- src
- projectwiki-ws
- src
- main
- java
- com
- ontimize
- projectwiki
- ws
- core
- rest
- MainRestController.java
- TestRestController.java
- UserRestController.java
- rest
- core
- ws
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- .gitignore
- pom.xml
- README.md
- projectwiki-api
Enable the multitenant system
In the application.yml we need to enable the multitenant system and add the settings for the tenant repository (More information in this link):
application.yml
- ontimize-examples
- projectwiki-api
- src
- main
- java
- com
- ontimize
- projectwiki
- api
- core
- service
- IUserService.java
- service
- core
- api
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- projectwiki-boot
- src
- main
- java
- com
- ontimize
- projectwiki
- ServerApplication.java
- projectwiki
- ontimize
- com
- resources
- public
- index.html
- application.yml
- public
- java
- main
- pom.xml
- src
- projectwiki-model
- src
- main
- db
- templateDB.txt
- templateDB_Main.txt
- java
- com
- ontimize
- projectwiki
- model
- core
- dao
- TenantDao.java
- UserDao.java
- UserRoleDao.java
- service
- UserService.java
- dao
- core
- model
- projectwiki
- ontimize
- com
- resources
- dao
- placeholders.properties
- TenantDao.xml
- UserDao.xml
- UserRoleDao.xml
- dao
- db
- main
- pom.xml
- src
- projectwiki-openapi
- src
- main
- ontimize
- marker-ws-ontimize-openapi-generator
- resources
- public
- restapi
- api
- Test.yml
- User.yml
- base
- AdvancedEntityResult.yml
- AdvancedQueryParameter.yml
- ColumnsParameter.yml
- DeleteParameter.yml
- DocumentIdentifier.yml
- EntityResult.yml
- ExportParameter.yml
- FileListParameter.yml
- FilterParameter.yml
- InsertParameter.yml
- MultipartFile.yml
- MultipartFiles.yml
- Number.yml
- Object.yml
- OFile.yml
- OFiles.yml
- Operator.yml
- QueryParameter.yml
- Responses.yml
- SQLOrder.yml
- String.yml
- UpdateFileParameter.yml
- UpdateParameter.yml
- Void.yml
- openapi-rest.yml
- api
- restapi
- public
- ontimize
- main
- pom.xml
- src
- projectwiki-ws
- src
- main
- java
- com
- ontimize
- projectwiki
- ws
- core
- rest
- MainRestController.java
- TestRestController.java
- UserRestController.java
- rest
- core
- ws
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- .gitignore
- pom.xml
- README.md
- projectwiki-api
Configure the tenants properties on the tenants table
templateDB_Main.txt
- ontimize-examples
- projectwiki-api
- src
- main
- java
- com
- ontimize
- projectwiki
- api
- core
- service
- IUserService.java
- service
- core
- api
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- projectwiki-boot
- src
- main
- java
- com
- ontimize
- projectwiki
- ServerApplication.java
- projectwiki
- ontimize
- com
- resources
- public
- index.html
- application.yml
- public
- java
- main
- pom.xml
- src
- projectwiki-model
- src
- main
- db
- templateDB.txt
- templateDB_Main.txt
- java
- com
- ontimize
- projectwiki
- model
- core
- dao
- TenantDao.java
- UserDao.java
- UserRoleDao.java
- service
- UserService.java
- dao
- core
- model
- projectwiki
- ontimize
- com
- resources
- dao
- placeholders.properties
- TenantDao.xml
- UserDao.xml
- UserRoleDao.xml
- dao
- db
- main
- pom.xml
- src
- projectwiki-openapi
- src
- main
- ontimize
- marker-ws-ontimize-openapi-generator
- resources
- public
- restapi
- api
- Test.yml
- User.yml
- base
- AdvancedEntityResult.yml
- AdvancedQueryParameter.yml
- ColumnsParameter.yml
- DeleteParameter.yml
- DocumentIdentifier.yml
- EntityResult.yml
- ExportParameter.yml
- FileListParameter.yml
- FilterParameter.yml
- InsertParameter.yml
- MultipartFile.yml
- MultipartFiles.yml
- Number.yml
- Object.yml
- OFile.yml
- OFiles.yml
- Operator.yml
- QueryParameter.yml
- Responses.yml
- SQLOrder.yml
- String.yml
- UpdateFileParameter.yml
- UpdateParameter.yml
- Void.yml
- openapi-rest.yml
- api
- restapi
- public
- ontimize
- main
- pom.xml
- src
- projectwiki-ws
- src
- main
- java
- com
- ontimize
- projectwiki
- ws
- core
- rest
- MainRestController.java
- TestRestController.java
- UserRestController.java
- rest
- core
- ws
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- .gitignore
- pom.xml
- README.md
- projectwiki-api
Update the data access objects
The multitenant system provides its own datasource and the DAOs must use it, so we need set the datasource property to tenantDatasource.
The tenants table is stored on the main database, you should not modify the TenantDao.xml file.
UserDao.xml and RoleDao.xml
- ontimize-examples
- projectwiki-api
- src
- main
- java
- com
- ontimize
- projectwiki
- api
- core
- service
- IUserService.java
- service
- core
- api
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- projectwiki-boot
- src
- main
- java
- com
- ontimize
- projectwiki
- ServerApplication.java
- projectwiki
- ontimize
- com
- resources
- public
- index.html
- application.yml
- public
- java
- main
- pom.xml
- src
- projectwiki-model
- src
- main
- db
- templateDB.txt
- templateDB_Main.txt
- java
- com
- ontimize
- projectwiki
- model
- core
- dao
- TenantDao.java
- UserDao.java
- UserRoleDao.java
- service
- UserService.java
- dao
- core
- model
- projectwiki
- ontimize
- com
- resources
- dao
- placeholders.properties
- TenantDao.xml
- UserDao.xml
- UserRoleDao.xml
- dao
- db
- main
- pom.xml
- src
- projectwiki-openapi
- src
- main
- ontimize
- marker-ws-ontimize-openapi-generator
- resources
- public
- restapi
- api
- Test.yml
- User.yml
- base
- AdvancedEntityResult.yml
- AdvancedQueryParameter.yml
- ColumnsParameter.yml
- DeleteParameter.yml
- DocumentIdentifier.yml
- EntityResult.yml
- ExportParameter.yml
- FileListParameter.yml
- FilterParameter.yml
- InsertParameter.yml
- MultipartFile.yml
- MultipartFiles.yml
- Number.yml
- Object.yml
- OFile.yml
- OFiles.yml
- Operator.yml
- QueryParameter.yml
- Responses.yml
- SQLOrder.yml
- String.yml
- UpdateFileParameter.yml
- UpdateParameter.yml
- Void.yml
- openapi-rest.yml
- api
- restapi
- public
- ontimize
- main
- pom.xml
- src
- projectwiki-ws
- src
- main
- java
- com
- ontimize
- projectwiki
- ws
- core
- rest
- MainRestController.java
- TestRestController.java
- UserRestController.java
- rest
- core
- ws
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- .gitignore
- pom.xml
- README.md
- projectwiki-api
Testing
To test this functionality we will use the Swagger tool deployed with the application, but we must provide the tenant on the API requests. For this we need to add the X-Tenant parameter on the OpenAPI declaration files.
Modify the OpenAPI declaration files
In the openapi-rest.yml file we need to add a new parameter to provide the tenant and in the User.yml file we need to add a reference to this parameter on each method:
openapi-rest.yml
User.yml
- ontimize-examples
- projectwiki-api
- src
- main
- java
- com
- ontimize
- projectwiki
- api
- core
- service
- IUserService.java
- service
- core
- api
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- projectwiki-boot
- src
- main
- java
- com
- ontimize
- projectwiki
- ServerApplication.java
- projectwiki
- ontimize
- com
- resources
- public
- index.html
- application.yml
- public
- java
- main
- pom.xml
- src
- projectwiki-model
- src
- main
- db
- templateDB.txt
- templateDB_Main.txt
- java
- com
- ontimize
- projectwiki
- model
- core
- dao
- TenantDao.java
- UserDao.java
- UserRoleDao.java
- service
- UserService.java
- dao
- core
- model
- projectwiki
- ontimize
- com
- resources
- dao
- placeholders.properties
- TenantDao.xml
- UserDao.xml
- UserRoleDao.xml
- dao
- db
- main
- pom.xml
- src
- projectwiki-openapi
- src
- main
- ontimize
- marker-ws-ontimize-openapi-generator
- resources
- public
- restapi
- api
- Test.yml
- User.yml
- base
- AdvancedEntityResult.yml
- AdvancedQueryParameter.yml
- ColumnsParameter.yml
- DeleteParameter.yml
- DocumentIdentifier.yml
- EntityResult.yml
- ExportParameter.yml
- FileListParameter.yml
- FilterParameter.yml
- InsertParameter.yml
- MultipartFile.yml
- MultipartFiles.yml
- Number.yml
- Object.yml
- OFile.yml
- OFiles.yml
- Operator.yml
- QueryParameter.yml
- Responses.yml
- SQLOrder.yml
- String.yml
- UpdateFileParameter.yml
- UpdateParameter.yml
- Void.yml
- openapi-rest.yml
- api
- restapi
- public
- ontimize
- main
- pom.xml
- src
- projectwiki-ws
- src
- main
- java
- com
- ontimize
- projectwiki
- ws
- core
- rest
- MainRestController.java
- TestRestController.java
- UserRestController.java
- rest
- core
- ws
- projectwiki
- ontimize
- com
- java
- main
- pom.xml
- src
- .gitignore
- pom.xml
- README.md
- projectwiki-api
Once we have built and launched the project, we can access to the application by opening a web browser and navigating to http://localhost:33333):
We must open the authorization dialog by clicking on the Authorize button, provide the credentials and click on the Authorize button.
Now, we can close the authorization dialog and test the API by providing the dessired tenant using the new parameter.