Configurations

In this chapter we will see various configuration options available to the Axelor Open Platform applications.

Introduction

The application configuration is provided through various configuration files. These are:

  • application.properties - the application configuration

  • persistence.xml - hibernate/jpa configuration

  • ehcache.xml - ehcache configuration (for hibernate L2-cache)

The most important of them is application.properties.

Application Configuration

The application.properties provides various configuration options for the application. It’s located under src/main/resources directory of the application project.

However, the application configuration can be provided from some external location using a JVM option.

$ export JAVA_OPTS="-Daxelor.config=/path/to/my-app.properties"

Database Settings

We can configure database connection settings with following properties:

# Database settings
# ~~~~~
# See hibernate documentation for connection parameters
db.default.driver = org.postgresql.Driver (1)
db.default.ddl = update (2)
db.default.url = jdbc:postgresql://localhost:5432/my-database (3)
db.default.user = username (4)
db.default.password = secret (5)
1 the JDBC driver (postgresql, mysql & oracle drivers are tested)
2 hbm2ddl option, (update, create, create-drop or validate)
3 the jdbc url to connect to
4 user name to be used to connect to the database server
5 user password to authenticate the user

If you want to use MySQL use following settings:

# Database settings
# ~~~~~
# See hibernate documentation for connection parameters
db.default.driver = com.mysql.jdbc.Driver
db.default.ddl = update
db.default.url = jdbc:mysql://localhost:3306/my_database
db.default.user = username
db.default.password = secret

Others Settings

Key Name

Description

application.name

application name, e.g. axelor-erp

application.name

application name

application.description

application description

application.version

application version

application.author

application author

application.copyright

application copyright

application.logo

header logo. Should be 40px in height with transparent background (default is img/axelor-logo.png)

application.home

home website. Link to be used with header logo.

application.help

link to the online help

application.mode

application deployment mode. Can be prod or dev (default is dev)

application.theme

CSS theme. If not defined, default theme is used.

application.locale

default locale (if not set, system default is used)

session.timeout

session timeout in minutes (default is 60)

file.upload.dir

storage path for upload files for attachments (default is \{user.home}/.axelor/attachments)

file.upload.size

maximum upload size in MB (default is 5 MB)

file.upload.whitelist.pattern

whitelist file name pattern, only matching files will be allowed

file.upload.blacklist.pattern

blacklist file name pattern, matching files will be rejected

file.upload.whitelist.types

whitelist file mime types, detects content type

file.upload.blacklist.types

blacklist file mime types, detects content type

reports.design.dir

external directory for birt report designs (default is \{user.home}/.axelor/reports)

reports.output.dir

external directory for generated pdf reports (default is \{user.home}/.axelor/reports-gen)

data.export.encoding

data export (csv) encoding (default is ISO_8859_1)

data.export.dir

storage path for export action (default is \{user.home}/.axelor/data-export)

data.import.demo-data

whether to import demo data for the application (default is true)

template.search.dir

storage path for templates (default is \{user.home}/.axelor/templates)

view.single.tab

whether to use single tab layout (default is false)

view.menubar.location

set menu style. Can be left, top or both (default is left)

view.toolbar.titles

whether to show button titles in toolbar (default is false)

view.confirm.yes-no

whether show confirm dialog with yes/no buttons (default is Cancel/OK)

view.grid.selection

if set to checkbox, grid widgets will have checkbox selection enabled

All specified path can use specials variables:

  • {user.home}: reference to the home directory, System.getProperty("user.home")

  • {java.io.tmpdir}: reference to the tmp directory, System.getProperty("java.io.tmpdir")

The differences between prod and dev mode are:

  • use minify js/css file.

  • use browser cache.

  • don’t display technical popup.

Example configuration

Here is a complete configuration file with default values

# Application Information
# ~~~~~
application.name = Axelor DEMO
application.description = The Demo Application
application.version = 1.0.0

# Author/Company
# ~~~~~
application.author = Axelor
application.copyright = Copyright (c) {year} Axelor. All Rights Reserved.

# Header Logo
# ~~~~~
# Should be 40px in height with transparent background
application.logo =

# Home Website
# ~~~~~
# Link to be used with header logo
application.home = http://www.axelor.com

# Link to the online help
# ~~~~~
application.help = http://docs.axelor.com/adk

# Application deployment mode
# ~~~~~
# Set to 'dev' for development mode else 'prod'
application.mode = dev

# CSS Theme
# ~~~~~
# Set default CSS theme, for example `blue`
application.theme =

# Default Locale (language)
# ~~~~~
# Set default application locale (en, fr, fr_FR, en_US)
application.locale =

# Encryption
# ~~~~~
# Set encryption password
encryption.password = MySuperSecretKey

# Set encryption algorithm (CBC or GCM)
#encryption.algorithm = CBC

# Database settings
# ~~~~~
# See hibernate documentation for connection parameters

# PostgreSQL
db.default.driver = org.postgresql.Driver
db.default.ddl = update
db.default.url = jdbc:postgresql://localhost:5432/open-platform-demo
db.default.user = username
db.default.password = secret

# MySQL
#db.default.driver = com.mysql.jdbc.Driver
#db.default.ddl = update
#db.default.url = jdbc:mysql://localhost:3306/axelor_demo_wip
#db.default.user = username
#db.default.password = secret

# Oracle
#db.default.driver = oracle.jdbc.OracleDriver
#db.default.ddl = update
#db.default.url = jdbc:oracle:thin:@localhost:1521:oracle
#db.default.user = username
#db.default.password =

# Date Format
# ~~~~~
date.format = dd/MM/yyyy

# Timezone
# ~~~~~
date.timezone = UTC

# Session timeout (in minutes)
# ~~~~~
session.timeout = 60

# Storage path for upload files (attachments)
# ~~~~~
# use {user.home} key to save files under user home directory, or
# use absolute path where server user have write permission.
file.upload.dir = {user.home}/.axelor/attachments

# Upload filename pattern, default is auto where file is save with same name
# in the given upload dir, if file is already there, a count number is
# appended to file name.
#
# This can be overridden by providing custom name pattern, for example:
#
#   file.upload.filename.pattern = {year}-{month}/{day}/{name}
#   file.upload.filename.pattern = {AA}/{name}
#
# Following placeholders can be used:
#
# {year} - current year
# {month} - current month
# {day} - current day
# {name} - file name
# {A} - first letter from file name
# {AA} - first 2 letter from file name
# {AAA} - first 3 letter from file name
#
#file.upload.filename.pattern = {year}-{month}/{day}/{name}

# Maximum upload size (in MB)
# ~~~~~
file.upload.size = 5

# Whitelist pattern can be used to allow file upload with matching names.
#
# For example: \\.(xml|html|jpg|png|pdf|xsl)$
#
# Regular expression
# ~~~~~
#file.upload.whitelist.pattern = \\.(xml|html|jpg|png|pdf|xsl)$

# Blacklist pattern can be used to block file upload with matching names.
#
# Regular expression
# ~~~~~
#file.upload.blacklist.pattern = ^\\.

# Whitelist content type can be used to allow file upload with matching content.
#
# List of mime-types (plain/text,image/*,video/webm)
# ~~~~~
#file.upload.whitelist.types = plain/text,image/*,video/webm

# Blacklist content type can be used to block file upload with matching content.
#
# List of mime-types (plain/text,image/*,video/webm)
# ~~~~~
#file.upload.blacklist.types =

# The external report design directory
# ~~~~~
# this directory is searched for the rptdesign files
# (fallbacks to designs provided by modules)
reports.design.dir = {user.home}/.axelor/reports

# Storage path for report outputs
reports.output.dir = {user.home}/.axelor/reports-gen

# Data export (csv) encoding
# ~~~~
# Use Windows-1252, ISO-8859-1 or ISO-8859-15 if targeting ms excel
# (excel does not recognize utf8 encoded csv)
data.export.encoding = UTF-8

# Storage path for export action
# ~~~~~
data.export.dir = {user.home}/.axelor/data-export

# Specify whether to import demo data
# ~~~~~
data.import.demo-data = true

# Storage path for templates
# ~~~~~
template.search.dir = {user.home}/.axelor/templates

# LDAP Configuration
# ~~~~~
#ldap.server.url = ldap://localhost:10389

# can be "simple" or "CRAM-MD5"
ldap.auth.type = simple

ldap.system.user = uid=admin,ou=system
ldap.system.password = secret

# group search base
ldap.group.base = ou=groups,dc=example,dc=com

# if set, create groups on ldap server under ldap.group.base
#ldap.group.object.class = groupOfUniqueNames

# a template to search groups by user login id
ldap.group.filter = (uniqueMember=uid={0})

# user search base
ldap.user.base = ou=users,dc=example,dc=com

# a template to search user by user login id
ldap.user.filter = (uid={0})

# CAS configuration
# ~~~~~
#auth.cas.server.url.prefix = https://localhost:8443/cas

# use public accessible url
#auth.cas.service = http://localhost:8080/open-platform-demo/cas

# login url, if not given prepared from server & service url
#auth.cas.login.url = https://localhost:8443/cas/login?service=http://localhost:8080/open-platform-demo/cas

# logout url, if not given prepared from server & service url
#auth.cas.logout.url = https://localhost:8443/cas/logout?service=http://localhost:8080/open-platform-demo/

# CAS validation protocol (CAS, SAML)
#auth.cas.protocol = SAML

# the attribute to map to user display name
#auth.cas.attrs.user.name = name

# the attribute to map to user email
#auth.cas.attrs.user.email = mail

# Quartz Scheduler
# ~~~~~
# quartz job scheduler

# Specify whether to enable quartz scheduler
quartz.enable = false

# total number of threads in quartz thread pool
# the number of jobs that can run simultaneously
quartz.threadCount = 3

# SMPT configuration
# ~~~~~
# SMTP server configuration
#mail.smtp.host = smtp.gmail.com
#mail.smtp.port = 587
#mail.smtp.channel = starttls
#mail.smtp.user = user@gmail.com
#mail.smtp.pass = secret

# timeout settings
#mail.smtp.timeout = 60000
#mail.smtp.connectionTimeout = 60000

# IMAP configuration
# ~~~~~
# IMAP server configuration
# (quartz scheduler should be enabled for fetching stream replies)
#mail.imap.host = imap.gmail.com
#mail.imap.port = 993
#mail.imap.channel = ssl
#mail.imap.user = user@gmail.com
#mail.imap.pass = secret

# timeout settings
#mail.imap.timeout = 60000
#mail.imap.connectionTimeout = 60000

# CORS configuration
# ~~~~~
# CORS settings to allow cross origin requests

# regular expression to test allowed origin or * to allow all (not recommended)
#cors.allow.origin = *
#cors.allow.credentials = true
#cors.allow.methods = GET,PUT,POST,DELETE,HEAD,OPTIONS
#cors.allow.headers = Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers

# View configuration
# ~~~~~

# Set to true to enable single view mode
view.single.tab = false

# Set menu style (left, top, both)
view.menubar.location = both

# Set to false to hide advance search filter share option
#view.adv-search.share = true

# Logging
# ~~~~~
# Custom logback configuration can be provided with `logging.config` property pointing
# to a custom `logback.xml`. In this case, all the logging configuration provided here
# will be ignored.
#
# Following settings can be used to configure logging system automatically.
#
#logging.path = {user.home}/.axelor/logs
#logging.pattern.file = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n
#logging.pattern.console = %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n

# Global logging
logging.level.root = ERROR

# Axelor logging

# Log everything.
logging.level.com.axelor = INFO

# Hibernate logging

# Log everything. Good for troubleshooting
#logging.level.org.hibernate = INFO

# Log all SQL DML statements as they are executed
#logging.level.org.hibernate.SQL = DEBUG
#logging.level.org.hibernate.engine.jdbc = DEBUG

# Log all SQL DDL statements as they are executed
#logging.level.org.hibernate.tool.hbm2ddl = INFO

# Log all JDBC parameters
#logging.level.org.hibernate.type = ALL

# Log transactions
#logging.level.org.hibernate.transaction = DEBUG

# Log L2-Cache
#logging.level.org.hibernate.cache = DEBUG

# Log JDBC resource acquisition
#logging.level.org.hibernate.jdbc = TRACE
#logging.level.org.hibernate.service.jdbc = TRACE

# Log connection pooling
#logging.level.com.zaxxer.hikari = INFO

JPA/Hibernate Configuration

The persistence.xml located under src/main/resources/META-INF provides JPA/Hibernate configuration.

A minimal persistence xml file is required to confirm JPA requirements:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence version="2.1"
  xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
  </persistence-unit>
</persistence>

Using non-jta DataSource

By default, Axelor Open Platform applications uses local database connections but sometime it’s desirabled to use container managed non-jta datasource as the database connection.

Benefits of using non-jta-datasource are:

  • no need to store db user/passwd in application source

  • no need to configure database connection pool

In order to use non-jta-datasource, change the application configuration like this:

First, remove all the database settings from application.properties.

Second, change the META-INF/persistence.xml as follows:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
  http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source>java:comp/env/ds/AxelorDS</non-jta-data-source>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
      <property name="hibernate.dialect" value="com.axelor.db.hibernate.dialect.PostgreSQLDialect" />
      <property name="hibernate.hbm2ddl.auto" value="update" />
    </properties>
  </persistence-unit>
</persistence>

Now, configure the tomcat installation with required datasource.

  • Configure a new global resource in conf/server.xml

Add the following <Resource> element to <GlobalNamingResources>.

<Resource name="ds/AxelorDS" auth="Container"
  type="javax.sql.DataSource"
  factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
  maxActive="100"
  maxIdle="30"
  maxWait="10000"
  username="username"
  password="password"
  driverClassName="org.postgresql.Driver"
  url="jdbc:postgresql://localhost:5432/open-platform-demo"/>
  • Configure a datasource context for the WAR in conf/server.xml

To link the name ds/AxelorDS to the jndi global name ds/AxelorDS for WAR consumption, add the following <Context> element inside the <Host> element.

The docBase is very important, it must match the WAR file or the application directory name deployed under webapps.
<Context reloadable="true" docBase="open-platform-demo" path="/open-platform-demo">
  <ResourceLink
  global="ds/AxelorDS"
  name="ds/AxelorDS"
  type="javax.sql.DataSource"/>
</Context>

See tomcat documentation on for more details.

Finally, build the application war and deployed it on the configured tomcat instance.

Logging Configuration

The logging can be configured from application.properties using the following properties:

# Logging
# ~~~~~
# Custom logback configuration can be provided with `logging.config` property pointing
# to a custom `logback.xml`. In this case, all the logging configuration provided here
# will be ignored.
#
# Following settings can be used to configure logging system automatically.
#
#logging.path = {user.home}/.axelor/logs
#logging.pattern.file = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n
#logging.pattern.console = %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n

# Global logging
logging.level.root = ERROR

# Axelor logging

# Log everything.
logging.level.com.axelor = DEBUG

# Hibernate logging

# Log everything. Good for troubleshooting
#logging.level.org.hibernate = INFO

# Log all SQL DML statements as they are executed
#logging.level.org.hibernate.SQL = DEBUG
#logging.level.org.hibernate.engine.jdbc = DEBUG

# Log all SQL DDL statements as they are executed
#logging.level.org.hibernate.tool.hbm2ddl = INFO

# Log all JDBC parameters
#logging.level.org.hibernate.type = ALL

# Log transactions
#logging.level.org.hibernate.transaction = DEBUG

# Log L2-Cache
#logging.level.org.hibernate.cache = DEBUG

# Log JDBC resource acquisition
#logging.level.org.hibernate.jdbc = TRACE
#logging.level.org.hibernate.service.jdbc = TRACE

# Log connection pooling
#logging.level.com.zaxxer.hikari = INFO

The logging.path can be used to save logs to file. The logging.pattern.file can be used to change log message format for file logging The logging.pattern.console can be used to change log message format for console logging

We can set logging for any package using logging.level.<package.name> keys.

EhCache Configuration

The ehcache.xml located under src/main/resources provides ehcache configuration.

Please see ehcache documentation for more details.

Global Context Configuration

Besides the static configuration values, we can also provide configuration for the dynamic global context with context. prefix. It’s used by actions and script handlers when evaluating expressions and domain filters. The values can be referenced from expressions with special variable __config__.

# Custom context
# ~~~~~

# instance
context.hello = com.axelor.script.TestContext

# instance method
context.world = com.axelor.script.TestContext:hello

# static method
context.some = com.axelor.script.TestContext:staticMethod

# static field
context.thing = com.axelor.script.TestContext:STATIC_FIELD

# static values
context.flag = true
context.string = some static text value
context.number = 100

Now, we can use them in expressions like this:

<field ... value="#{__config__.hello.message}" /> (1)
<field ... value="#{__config__.world}" /> (2)
<field ... value="#{__config__.some}" /> (3)
<field ... value="#{__config__.thing}" /> (4)
<field ... value="#{__config__.flag}" /> (5)
1 calls getter on the instance
2 calls an instance method
3 calls a static method
4 public static final field value
5 any constant value

A special context setting context.appLogo can be used to dynamically change header logo per user. For example:

context.appLogo = com.axelor.custom.LogoService:getLogo

The getLogo() method then can return link to user specific application logo.

Custom Style

A special context setting context.appStyle can be used to provide custom style for web ui. For example:

context.appStyle = com.axelor.custom.StyleService:getStyle

and the code:

public class StyleService {

  public String getStyle() {
    // we can even read the style from database
    return "header .navbar .nav .fa-bars { color: #86bc25; }"; (1)
  }
}
1 change the color of sidebar toggle icon

The getStyle() method should return custom style as String value.

The custom style is applied in following order:

  1. default style

  2. user theme if available

  3. custom style if provided

So the custom style will always override default and theme styles.