You are viewing the documentation for Blueriq 17. Documentation for other versions is available in our documentation directory.

This functionality is only available with the Multi Tenancy License. Please contact Blueriq Support.

To prepare your setup for multi tenancy you will need to execute some steps per component.

Most components in a setup make use of one or more Databases (SQL and/or NoSQL). Furthermore, AMQP can be used to communicate between the components.

In order to make sure that no tenant can access data of another tenant, each tenant will need their own databases. Thus, you will need to create them for each tenant. Simply use the delivered create scripts to create the dedicated databases for each tenant.

For AMQP, you should also create the neccessary queues and exchanges per tenant for each component and configure the vHost to make sure that the correct messages are being sent to the correct tenant.

Enabling Multi tenancy

To enable multi-tenancy, it is necessary to activate multi-tenancy mode and define the permitted tenants. These defined tenants will subsequently be utilized in configuring additional multi-tenancy-related properties.
application.properties
blueriq.multi-tenancy.enabled=true
blueriq.multi-tenancy.allowed-tenants=google,apple

These properties are used in each component that is mentiond on this page.

X-Tenant-ID

Enabling multi-tenancy requires that requests include an additional X-TENANT-ID header containing the name of the desired tenant. If this header is missing or the tenant name is not on the allowed list, a message will be logged indicating that the tenant could not be identified, and an HTTP status 400 (Bad Request) will be returned.

It is possible to change the name of the header using the following property

application.properties
blueriq.multi-tenancy.http-header=http-tenant-id

This property can be used in each component that is mentiond on this page.

We advise to set up an HTTP server (for example NGINX or Apache HTTPD) which can be configured to add this HTTP header depending on, for instance, the url from which the Runtime is called.

AMQP Tenant Id

AMQP messages will contain a X-Tenant-ID header when multi-tenancy is enabled. Specific for AMQP messages the header name can be configured using the following property:
application.properties
blueriq.multi-tenancy.amqp-header=amqp-tenant-id

We only support multi-tenancy where each tenant uses the same database vendor per component. You are not able to mix, for example, an Oracle tenant with an Microsoft SQL Server tenant. 

Property Configuration

To enable multi-tenancy, it is essential to modify existing properties and add new ones for each tenant across all JDBC, JNDI, RabbitMQ, and MongoDB connections.

The primary adjustment involves inserting tenants.<tenantName> between the property prefix and the actual property value. An example of this structure is provided below.

application.properties
# RabbitMQ Host property for the Trace Event Publisher

# Single Tenant
blueriq.trace.event.publisher.channel.amqp.rabbitmq.host=localhost

# Multi Tenant Google
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.google.host=localhost

# Multi Tenant Apple
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.apple.host=apple.com

Default configuration

Default Multi-tenant RabbitMQ, Datasource & Mongodb properties

A default properties mechanism was added with Blueriq 16.74 because it can be tedious to configure all components of the Runtime with the same properties.

The following example shows default rabbitmq properties in a multi-tenant setup. There you can see how you can configure rabbitmq properties per tenant which will then be used for each component that uses rabbitmq instead of specifying it per component.

Because queue and exchange names are specific per component you still need to configure them as stated above.

This configuration will be used for each component that has no specific properties configured (except the queue and/or exchange names). 

When neither specific nor default properties are configured for a tenant, the component will try to use the default rabbitmq properties for this tenant.

application.properties
blueriq.default.rabbitmq.tenants.google.host=localhost
blueriq.default.rabbitmq.tenants.google.port=5672
blueriq.default.rabbitmq.tenants.google.username=google
blueriq.default.rabbitmq.tenants.google.password=welcome
blueriq.default.rabbitmq.tenants.google.virtualHost=google
blueriq.default.rabbitmq.tenants.google.ssl.enabled=true

blueriq.default.mongodb.tenants.google.host=localhost
blueriq.default.mongodb.tenants.google.port=27017
blueriq.default.mongodb.tenants.google.username=google
blueriq.default.mongodb.tenants.google.password=welcome

blueriq.default.datasource.tenants.google.url=jdbc:oracle:thin:@localhost:1521:orcl
blueriq.default.datasource.tenants.google.username=google
blueriq.default.datasource.tenants.google.password=welcome


blueriq.default.rabbitmq.tenants.apple.host=localhost
blueriq.default.rabbitmq.tenants.apple.port=5672
blueriq.default.rabbitmq.tenants.apple.username=apple
blueriq.default.rabbitmq.tenants.apple.password=welcome
blueriq.default.rabbitmq.tenants.apple.virtualHost=DefaultEverest
blueriq.default.rabbitmq.tenants.apple.ssl.enabled=true

blueriq.default.mongodb.tenants.apple.host=localhost
blueriq.default.mongodb.tenants.apple.port=27017
blueriq.default.mongodb.tenants.apple.username=apple
blueriq.default.mongodb.tenants.apple.password=welcome

blueriq.default.datasource.tenants.apple.url=jdbc:oracle:thin:@localhost:1521:orcl
blueriq.default.datasource.tenants.apple.username=apple
blueriq.default.datasource.tenants.apple.password=welcome

Parameters can be configured at three levels for RabbitMQ or SQL-Datasources and MongoDB:

  1. default properties
    blueriq.default.rabbitmq.*
    blueriq.default.datasource.*
    blueriq.default.mongodb.*
  2. default tenant-specific properties for all sources for that tenant:
    blueriq.default.rabbitmq.tenants.<tenant_name>.*
    blueriq.default.datasource.tenants.<tenant_name>.*
    blueriq.default.mongodb.tenants.<tenant_name>.*
  3. tenant and component specific properties
    blueriq.<component>.<path>.rabbitmq.tenants.<tenant_name>.*
    blueriq.datasource.<component>.tenants.<tenant_name>.*
    blueriq.<component>.mongodb.tenants.<tenant_name>.*

The properties supersede each other from general to more specific. So any properties from the most general level (default properties) will be overwritten by the other more specific levels. Example configuration:

application.properties
# Generic level, all sources share the same host and port
blueriq.default.rabbitmq.host=localhost
blueriq.default.rabbitmq.port=5672
blueriq.default.rabbitmq.ssl.enabled=true
 
# a different user and virtual host is used for each tenant (for all queue connections at this tenant)
blueriq.default.rabbitmq.tenants.google.username=google
blueriq.default.rabbitmq.tenants.google.password=welcome
blueriq.default.rabbitmq.tenants.google.virtualHost=google
 
blueriq.default.rabbitmq.tenants.apple.username=apple
blueriq.default.rabbitmq.tenants.apple.password=welcome
blueriq.default.rabbitmq.tenants.apple.virtualHost=apple
 
# different components use different queues, which is most the specific level
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.google.exchangeName=traceEvents
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.apple.exchangeName=traceEvents
 
# for one specific connection, all settings are overwritten
blueriq.audit.rabbitmq.tenants.google.host=host_x
blueriq.audit.rabbitmq.tenants.google.port=8080
blueriq.audit.rabbitmq.tenants.google.username=google
blueriq.audit.rabbitmq.tenants.google.password=welcome
blueriq.audit.rabbitmq.tenants.google.virtualHost=google
blueriq.audit.rabbitmq.tenants.google.exchangeName=auditEvents
# blueriq.audit.rabbitmq.tenants.google.exchangeName=auditEvents --> no need to specify exchange name because it's taken from blueriq.audit.rabbitmq.exchangeName
 
blueriq.audit.rabbitmq.tenants.google.host=host_x
blueriq.audit.rabbitmq.tenants.google.port=8080
blueriq.audit.rabbitmq.tenants.google.username=google
blueriq.audit.rabbitmq.tenants.google.password=welcome
blueriq.audit.rabbitmq.tenants.google.virtualHost=google
blueriq.audit.rabbitmq.tenants.google.virtualHost=google
blueriq.audit.rabbitmq.tenants.google.exchangeName=googleAuditEvents

This works for all components that use Datasource,RabbitMQ or MongoDB configuration


Runtime

Configuration

The datasources for the components can be configured either in the  application-externaldatasources.properties file or the application-jndidatasources.properties. When configuring external datasources, the externaldatasources profile should be enabled. When configuration JNDI datasources the jndidatasources profile should be enabled.

JDBC datasources

application-externaldatasources.properties
### Comments SQL Store ###
blueriq.datasource.comments-sql-store.tenants.google.url=jdbc:oracle:thin:@localhost:1521:orcl
blueriq.datasource.comments-sql-store.tenants.google.username=google
blueriq.datasource.comments-sql-store.tenants.google.password=welcome
blueriq.datasource.comments-sql-store.tenants.apple.url=jdbc:oracle:thin:@localhost:1521:orcl
blueriq.datasource.comments-sql-store.tenants.apple.username=apple
blueriq.datasource.comments-sql-store.tenants.apple.password=welcome
blueriq.datasource.comments-sql-store.driverClassName=oracle.jdbc.driver.OracleDriver
blueriq.hibernate.comments-sql-store.hbm2ddl.auto=validate
blueriq.hibernate.comments-sql-store.dialect=org.hibernate.dialect.Oracle12cDialect

### Process SQL Store ###
blueriq.datasource.process-sql-store.tenants.google.url=jdbc:oracle:thin:@localhost:1521:orcl
blueriq.datasource.process-sql-store.tenants.google.username=google
blueriq.datasource.process-sql-store.tenants.google.password=welcome
blueriq.datasource.process-sql-store.tenants.apple.url=jdbc:oracle:thin:@localhost:1521:orcl
blueriq.datasource.process-sql-store.tenants.apple.username=apple
blueriq.datasource.process-sql-store.tenants.apple.password=welcome
blueriq.datasource.process-sql-store.driverClassName=oracle.jdbc.driver.OracleDriver
blueriq.hibernate.process-sql-store.hbm2ddl.auto=validate
blueriq.hibernate.process-sql-store.dialect=org.hibernate.dialect.Oracle12cDialect

### Trace SQL Store ###
blueriq.datasource.trace-sql-store.tenants.google.url=jdbc:oracle:thin:@localhost:1521:orcl
blueriq.datasource.trace-sql-store.tenants.google.username=google
blueriq.datasource.trace-sql-store.tenants.google.password=welcome
blueriq.datasource.trace-sql-store.tenants.apple.url=jdbc:oracle:thin:@localhost:1521:orcl
blueriq.datasource.trace-sql-store.tenants.apple.username=apple
blueriq.datasource.trace-sql-store.tenants.apple.password=welcome
blueriq.datasource.trace-sql-store.driverClassName=oracle.jdbc.driver.OracleDriver
blueriq.hibernate.trace-sql-store.hbm2ddl.auto=validate
blueriq.hibernate.trace-sql-store.dialect=org.hibernate.dialect.Oracle12cDialect

JNDI datasources

application-jndidatasources.properties
### Comments SQL Store ###
blueriq.datasource.comments-sql-store.tenants.google.jndiName=java:/comp/env/jdbc/google
blueriq.datasource.comments-sql-store.tenants.apple.jndiName=java:/comp/env/jdbc/apple

blueriq.hibernate.comments-sql-store.hbm2ddl.auto=validate
blueriq.hibernate.comments-sql-store.dialect=org.hibernate.dialect.Oracle12cDialect

### Process SQL Store ###
blueriq.datasource.process-sql-store.tenants.google.jndiName=java:/comp/env/jdbc/google
blueriq.datasource.process-sql-store.tenants.apple.jndiName=java:/comp/env/jdbc/apple

blueriq.hibernate.process-sql-store.hbm2ddl.auto=validate
blueriq.hibernate.process-sql-store.dialect=org.hibernate.dialect.Oracle12cDialect

### Trace SQL Store ###
blueriq.datasource.trace-sql-store.tenants.google.jndiName=java:/comp/env/jdbc/google
blueriq.datasource.trace-sql-store.tenants.apple.jndiName=java:/comp/env/jdbc/apple

blueriq.hibernate.trace-sql-store.hbm2ddl.auto=validate
blueriq.hibernate.trace-sql-store.dialect=org.hibernate.dialect.Oracle12cDialect

CMIS 

To configure CMIS in a multi-tenant environment, Blueriq supports setting the following properties per tenant:

  • user
  • password
  • servicesUrl
  • repositoryId

The rest of the CMIS properties are the same for all tenants. See How to setup a CMIS connection for the further configuration.

Note that it is not necessary to override the above properties for each tenant. If they are not defined for a tenant, the normal (not tenant-specific) properties are used.

Below is a sample configuration for two tenants, where the 'google' tenant uses the standard servicesUrl, while the 'apple' tenant overrides this.

# common
blueriq.cmis.services-url=http://host:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
blueriq.cmis.object-type-id=D:my:objectType
blueriq.cmis.binding-type=atompub

# multi-tenant google
blueriq.cmis.tenants.google.user=admin
blueriq.cmis.tenants.google.password=adminpass
blueriq.cmis.tenants.google.repository-id=google

# multi-tenant apple
blueriq.cmis.tenants.apple.services-url=http://apple.local:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
blueriq.cmis.tenants.apple.user=apple
blueriq.cmis.tenants.apple.password=applepassword
blueriq.cmis.tenants.apple.repository-id=apple


Connections

The file system connection requires a different connection to the file system for each tenant. This way of storing data allows the data of different tenants to be stored on the same file system. For long term storage, a better way to store files is to use a DMS (Document Management System) instead. This can be achieved using the CMIS connection.

application.properties
blueriq.connection.connectionName.filesystem.tenants.google.path=C:/google/files

blueriq.connection.connectionName.filesystem.tenants.apple.path=C:/apple/files

Rest & soap

The rest and soap filesystem connections can also be configured for each tenant. Most properties will be the same for each tenant, except for url, username and password. These can be configured for each tenant. In a multi-tenancy setup, two additional (optional) properties are added for soap and rest connections. It is possible to pass the tenant with your rest call, for example when you want to call a BAARS or an external application that is multi-tenant as well. To do this the tenant header should be enabled with the property tenantIdEnabled and the header can be set in the property tenantHeaderName. An example setup will look as follows:

application.properties
# rest
blueriq.connection.RestCall.http.tenantIdEnabled=true
blueriq.connection.RestCall.http.tenantHeaderName=Tenant-Id
blueriq.connection.RestCall.http.tenants.blueriq.url=http://something
blueriq.connection.RestCall.http.tenants.blueriq.username=username
blueriq.connection.RestCall.http.tenants.blueriq.password=password

# soap
blueriq.connection.SoapService.soap.tenantIdEnabled=true
blueriq.connection.SoapService.soap.tenantHeaderName=Tenant-Id
blueriq.connection.SoapService.soap.tenants.blueriq.url=http://something
blueriq.connection.SoapService.soap.tenants.blueriq.username=username
blueriq.connection.SoapService.soap.tenants.blueriq.password=password

DCM Lists Client

When multi-tenancy is enabled, the runtime will send the X-TENANT-ID HTTP header to the DCM lists service whenever an HTTP request is made. To use a separate RabbitMQ instance for each tenant, additional configuration is required in application-dcm-lists-client.properties

application-dcm-lists-client.properties
blueriq.dcm.lists-client.rabbitmq.tenants.google.host=localhost
blueriq.dcm.lists-client.rabbitmq.tenants.google.port=5672
blueriq.dcm.lists-client.rabbitmq.tenants.google.username=google
blueriq.dcm.lists-client.rabbitmq.tenants.google.password=welcome
blueriq.dcm.lists-client.rabbitmq.tenants.google.exchangeName=processEvents
blueriq.dcm.lists-client.rabbitmq.tenants.google.virtualHost=google
blueriq.dcm.lists-client.rabbitmq.tenants.google.queueNames=dcmListsService

blueriq.dcm.lists-client.rabbitmq.tenants.apple.host=localhost
blueriq.dcm.lists-client.rabbitmq.tenants.apple.port=5672
blueriq.dcm.lists-client.rabbitmq.tenants.apple.username=apple
blueriq.dcm.lists-client.rabbitmq.tenants.apple.password=welcome
blueriq.dcm.lists-client.rabbitmq.tenants.apple.exchangeName=processEvents
blueriq.dcm.lists-client.rabbitmq.tenants.apple.virtualHost=apple
blueriq.dcm.lists-client.rabbitmq.tenants.apple.queueNames=dcmListsService

DCM / Case Engine

The DCM module provides the Service call type: DCM_CaseCreate service call type that you can use to start a case by publishing data on a queue. The Case Engine will consume messages from the queue and start the case asynchronously. Below are examples on how to configure the RabbitMQ instance for each tenant.

application.properties
blueriq.dcm.rabbitmq.tenants.google.host=localhost
blueriq.dcm.rabbitmq.tenants.google.port=5672
blueriq.dcm.rabbitmq.tenants.google.username=google
blueriq.dcm.rabbitmq.tenants.google.password=welcome
blueriq.dcm.rabbitmq.tenants.google.exchangeName=processEvents
blueriq.dcm.rabbitmq.tenants.google.virtualHost=google

blueriq.dcm.rabbitmq.tenants.apple.host=localhost
blueriq.dcm.rabbitmq.tenants.apple.port=5672
blueriq.dcm.rabbitmq.tenants.apple.username=apple
blueriq.dcm.rabbitmq.tenants.apple.password=welcome
blueriq.dcm.rabbitmq.tenants.apple.exchangeName=processEvents
blueriq.dcm.rabbitmq.tenants.apple.virtualHost=apple
application-case-engine.properties
# DCM Events
blueriq.dcm.rabbitmq.tenants.google.host=localhost
blueriq.dcm.rabbitmq.tenants.google.port=5672
blueriq.dcm.rabbitmq.tenants.google.username=google
blueriq.dcm.rabbitmq.tenants.google.password=welcome
blueriq.dcm.rabbitmq.tenants.google.exchangeName=processEvents
blueriq.dcm.rabbitmq.tenants.google.virtualHost=google

blueriq.dcm.rabbitmq.tenants.apple.host=localhost
blueriq.dcm.rabbitmq.tenants.apple.port=5672
blueriq.dcm.rabbitmq.tenants.apple.username=apple
blueriq.dcm.rabbitmq.tenants.apple.password=welcome
blueriq.dcm.rabbitmq.tenants.apple.exchangeName=processEvents
blueriq.dcm.rabbitmq.tenants.apple.virtualHost=apple

#Trace Event Publisher
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.google.host=localhost
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.google.port=5672
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.google.username=google
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.google.password=welcome
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.google.virtualHost=google
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.google.exchangeName=traceEvents

blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.apple.host=localhost
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.apple.port=5672
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.apple.username=apple
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.apple.password=welcome
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.apple.virtualHost=apple
blueriq.trace.event.publisher.channel.amqp.rabbitmq.tenants.apple.exchangeName=traceEvents

# Trace Event Listener
blueriq.trace.event.listener.amqp.rabbitmq.tenants.google.host=localhost
blueriq.trace.event.listener.amqp.rabbitmq.tenants.google.port=5672
blueriq.trace.event.listener.amqp.rabbitmq.tenants.google.username=google
blueriq.trace.event.listener.amqp.rabbitmq.tenants.google.password=welcome
blueriq.trace.event.listener.amqp.rabbitmq.tenants.google.virtualHost=google
blueriq.trace.event.listener.amqp.rabbitmq.tenants.google.queueNames=traceQueue

blueriq.trace.event.listener.amqp.rabbitmq.tenants.apple.host=localhost
blueriq.trace.event.listener.amqp.rabbitmq.tenants.apple.port=5672
blueriq.trace.event.listener.amqp.rabbitmq.tenants.apple.username=apple
blueriq.trace.event.listener.amqp.rabbitmq.tenants.apple.password=welcome
blueriq.trace.event.listener.amqp.rabbitmq.tenants.apple.virtualHost=apple
blueriq.trace.event.listener.amqp.rabbitmq.tenants.apple.queueNames=traceQueue

# Timeline Event Publisher
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.google.host=localhost
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.google.port=5672
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.google.username=google
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.google.password=welcome
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.google.virtualHost=google
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.google.exchangeName=timelineEvents

blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.apple.host=localhost
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.apple.port=5672
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.apple.username=apple
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.apple.password=welcome
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.apple.virtualHost=apple
blueriq.timeline.event.publisher.channel.amqp.rabbitmq.tenants.apple.exchangeName=timelineEvents

# Timeline Event Listener
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.google.host=localhost
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.google.port=5672
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.google.username=google
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.google.password=welcome
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.google.virtualHost=google
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.google.queueNames=timelineQueue

blueriq.timeline.event.listener.amqp.rabbitmq.tenants.apple.host=localhost
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.apple.port=5672
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.apple.username=apple
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.apple.password=welcome
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.apple.virtualHost=apple
blueriq.timeline.event.listener.amqp.rabbitmq.tenants.apple.queueNames=timelineQueue

# Audit Event Publisher
blueriq.audit.rabbitmq.tenants.google.host=localhost
blueriq.audit.rabbitmq.tenants.google.port=5672
blueriq.audit.rabbitmq.tenants.google.username=google
blueriq.audit.rabbitmq.tenants.google.password=welcome
blueriq.audit.rabbitmq.tenants.google.virtualHost=google
blueriq.audit.rabbitmq.tenants.google.exchangeName=auditEvents

blueriq.audit.rabbitmq.tenants.apple.host=localhost
blueriq.audit.rabbitmq.tenants.apple.port=5672
blueriq.audit.rabbitmq.tenants.apple.username=apple
blueriq.audit.rabbitmq.tenants.apple.password=welcome
blueriq.audit.rabbitmq.tenants.apple.virtualHost=apple
blueriq.audit.rabbitmq.tenants.apple.exchangeName=auditEvents

Authentication - OAuth2 and Keycloak

In single-tenant mode as well as in multi-tenancy mode, OAuth2 and Keycloak can be used for the authentication mechanism. The difference with multi-tenancy is that the application now expects a claim to be present in the JWT token with the claim path name "tenant" and with the tenant name as value. This claim name is customizable if the tenant is present in the JWT token with a different claim name.

Customizing the tenant path

The tenant claim can be customized using a JsonPath expression in the same way the roles-path and username-path can be set.

application.properties
blueriq:
  jwt:
    tenant-path: $.custom_tenant_claim_path

Case Engine

Error rendering macro 'excerpt-include'

User 'null' does not have permission to view the page.

 Customer Data Service

Event publisher tenant configuration

Since CDS 4.4 the customerdata service supports a multi-tenant event publisher. Enabling multi-tenancy means that properties for publishing aggregate event messages to a queue can be configured for each tenant. To enable the event publisher the entity-event-publisher-amqp profile should be active.

Tenant configuration

blueriq-customerdata-odata-service-v1.yml or blueriq-customerdata-odata-service-v1.properties
blueriq:
  multi-tenancy:
    enabled: true
    allowed-tenants: <tenant-name-A>,<tenant-name-B> 
  customerdata:
 	datasource:
      <datasource-name>:
   	    driver-class-name: <driver> 
        tenants: 
          <tenant-name-A>: 
            url: <url>
            username: <username>
            password: <password>
          <tenant-name-B>: 
            url: <url>
            username: <username>
            password: <password>
	# publisher
    aggregate-event:
      channel:
        amqp:
          rabbitmq:
            tenants:
              google:
                host: <host>
                port: <port>
                virtualHost: <virtualHost>
                username: <username>
                password: <password>
                ssl:
                  enabled: <enabled>
                exchangeName: <exchangeName>
              apple:
                host: <host>
                port: <port>
                virtualHost: <virtualHost>
                username: <username>
                password: <password>
                ssl:
                  enabled: <enabled>
                exchangeName: <exchangeName> 


Example setup

Configuration

blueriq-customerdata-odata-service-v1.yml or blueriq-customerdata-odata-service-v1.properties
blueriq:
  multi-tenancy:
    enabled: true
    allowed-tenants: google,apple
  customerdata:
 	datasource:
      customer-data-sql-store:
   	    driver-class-name: oracle.jdbc.driver.OracleDriver
        tenants: 
          google: 
            url: jdbc:oracle:thin:@localhost:1521:orcl
            username: google
            password: welcome
          apple: 
            url: jdbc:oracle:thin:@localhost:1521:orcl
            username: apple
            password: welcome
	# publisher
    aggregate-event:
      channel:
        amqp:
          rabbitmq:
            tenants:
              google:
                host: localhost
                port: 5672
                virtualHost: Blueriq
                username: guest
                password: guest
                ssl:
                  enabled: false
                exchangeName: customerDataService
              apple:
                host: localhost
                port: 5672
                virtualHost: Everest
                username: guest
                password: guest
                ssl:
                  enabled: false
                exchangeName: customerDataService
hibernate:
  dialect: org.hibernate.dialect.Oracle12cDialect
  hbm2ddl:
    auto: validate
  id:
    new_generator_mappings: true
  show_sql: true
  use_nationalized_character_data: true

HTTP request

Example request
GET http://localhost:8080/api/v1/Aggregates HTTP/1.1
Content-Type: application/json
Authorization: Basic Ymx1ZXJpcTp3ZWxjb21l
X-TENANT-ID: google

DCM Lists Service

Example Multi-tenancy DCM Lists Service configuration

blueriq-dcm-lists.yml
blueriq:
  dcm:
    lists:
      multi-tenancy:
        enabled: true
        allowed-tenants:
          - google
          - apple
		mongodb:
		  tenants:
			google:
		      host: localhost
              port: 27017
              database: google
			apple:
		      host: localhost
              port: 27017
              database: apple
        rabbitmq:
		  tenants:
            google:
              host: localhost
              port: 5672
              virtualHost: google
              username: google
              password: welcome
              ssl:
                enabled: false
              queueNames: googleQueue
            apple:
              host: localhost
              port: 5672
              virtualHost: apple
              username: apple
              password: welcome
              ssl:
                enabled: false
              queueNames: appleQueue

DCM Maintenance App

Authentication

To be able to use the DCM Maintenance App, the user should be authenticated. This is done through Keycloak as explained in Blueriq Gateway and OAuth2 configuration. The difference with multi-tenancy is that the application now expects a claim to be present in the JWT token with the claim path name "tenant" and with the tenant name as value. This claim name is customizable if the tenant is present in the JWT token with a different claim name.

Customizing the tenant path

The tenant claim can be customized using a JsonPath expression in the same way the roles-path and username-path can be set.

blueriq-dcm-maintenance-app.yml
blueriq:
  jwt:
    tenant-path: $.custom_tenant_claim_path

RabbitMQ and MongoDB configuration

For RabbitMQ and MongoDB the properties need to be set per tenant as well.

Currently, it's required to supply the queue and exchange names if multi-tenancy is enabled. This is an example of this configuration:


blueriq-dcm-maintenance-app.yml
blueriq:
  multi-tenancy:
    enabled: true
    allowed-tenants:
      - A
      - B
  dcm:
    maintenance:
      app:        
        dlq:
          retry:
            delay: 2m
            max-retries: 3
          rabbitmq:
            tenants:
              A:
                host: localhost
                port: 5672
                username: guest
                password: guest
                virtualHost: A_vhost
                queueNames:
                  - dcmEventsDlq
                  - dcmTasksEventsDlq
                  - dcmScheduledEventsDlq
                  - traceDlq
                  - timelineDlq
                  - dcmMaintenanceEventsDlq
                  - auditEventsDlq
                  - dcmListsEventsDlq
              B:
                host: localhost
                port: 5672
                username: guest
                password: guest
                virtualHost: B_vhost
                queueNames:
                  - dcmEventsDlq
                  - dcmTasksEventsDlq
                  - dcmScheduledEventsDlq
                  - traceDlq
                  - timelineDlq
                  - dcmMaintenanceEventsDlq
                  - auditEventsDlq
                  - dcmListsEventsDlq
        case-engine:
          rabbitmq:
            tenants:
              A:
                host: localhost
                port: 5672
                username: guest
                password: guest
                queueNames:
                  - dcmMaintenanceEventsQueue
                virtualHost: A_vhost
              B:
                host: localhost
                port: 5672
                username: guest
                password: guest
                queueNames:
                  - dcmMaintenanceEventsQueue
                virtualHost: B_vhost

        mongodb:
          tenants:
            A:
              host: localhost
              port: 27017
              database: A_messages
            B:
              host: localhost
              port: 27017
              database: B_messages

Audit Consumer

Audit Event store tenant configuration

Since Audit Consumer 4.2 the audit consumer supports a multi-tenant datastore. Enabling multi-tenancy means that properties for listening to audit events messages and storing these audit event messages to a database can be configured for each tenant. For the audit event store only the properties url, username, password and JNDI are multi-tenant. JNDI is only required when a JNDI setup is used. Below are examples of how to configure a multi-tenant setup for the audit consumer. 

Tenant configuration

Configuration YAML
# Audit event store
blueriq:
  audit:
	consumer:
      datasource:
        audit-sql-store:
	      driver-class-name: <driver-class>
          validation-query: <validation-query>
          testWhileIdle: true
          timeBetweenEvictionRunsMillis: 5000
	      tenants:
		    Apple:
           	  url: <url>
        	  username: <username>
        	  password: <password>
		    Google:
        	  url: <url>
        	  username: <username>
        	  password: <password>
# RabbitMQ
blueriq:
  audit:
    consumer:
      rabbitmq:
		tenants:
          Apple
  	        host: ---
            port: ---
            virtualHost: ---
     	    username: ---
            password: ---
            ssl:
              enabled: ---
            queueNames: ---
            errorExchange: --- 
          Google:
  	        host: ---
            port: ---
            virtualHost: ---
     	    username: ---
            password: ---
            ssl:
              enabled: ---
            queueNames: ---
            errorExchange: --- 

JNDI

If you would like to use JNDI to configure your datasource, replace the blueriq.audit.consumer.datasource section in the application.yml described above with the following:

datasource
blueriq:
  audit:
    consumer:
      datasource:
        audit-sql-store:   
		  tenants:
			Apple:            
			  jndi-name: java:jboss/datasources/Apple
		    Google:            
			  jndi-name: java:jboss/datasources/Google

Be aware that if one tenant uses JNDI, all tenants should use JNDI.

  • No labels