One of the key objectives of our R&D on the BlueMind solution is to design a modern architecture capable of meeting the demands of all client types. Specifically, this means:
- Designing a scalable architecture that meets the needs of organisations of all sizes – from just a few users to thousands of them,
- Ensuring optimum performance through architecture improvements aimed at providing efficient use while keeping resource consumption controlled,
- Offering extension points to make enhancing the BlueMind solution easier through plugins without the need for complex developments,
- Exposing all BlueMind features through an API so that all BlueMind applications’ actions pass through the specified API endpoints
This article describes the architecture of BlueMind Core with an overview of available APIs (please refer to BlueMind’s documentation about APIs and BlueMind Docs).
DESCRIPTION of CORE V2’s architecture
BlueMind’s 2nd generation Core is a Java program. It exposes web services representing BlueMind’s API. It runs scheduled tasks (back-ups, re-indexing, directory synching, reporting).
Core is the only component that handles the data from PostgreSQL databases. All other components pass through it to read and edit information. It receives http requests on the 8090 port and returns responses in json format.
Http methods are used to indicate the type of operations to be performed:
- GET (retrieve),
- POST (update),
- PUT (create),
These web services are commonly called RESTful.
The Core relies on several technologies:
License: open source, Apache software 2.0 license
Vert.x is a reactive application framework that transforms network requests into events that can be subscribed to and therefore reacted to.
Based on the netty network library, it relies on non-blocking I/O for increased scalability and more efficiency on multi-core CPUs. This type of architecture means that just a few threads (typically twice the number of server cores) are capable of supporting a large number of network connections.
License: Apache 2.0 License
The core, databind and annotation modules are used to transform Java objects into json objects and vice versa.
Having annotations on interfaces or objects avoids having to implement clients method by method: everything is managed automatically on-the-go using java.lang.reflect.Proxy objects (see HttpClientFactory). Interfaces are available in synchronous and asynchronous versions.
- OSGi / Eclipse Runtime
License: open source, eclipse
Eclipse IDE technologies are used for dependency injection and plugin creation. Components declare extension points using a schema (.exds files) referenced in a plugin.xml file. Components connect and implement extensions using a plugin.xml file. One component may simultaneously declare extension points and become extensible while extending other extension points.
CONTAINERS AND ITEMS
To understand core APIs, we need to explain the notions of Containers and Items.
Core is built around a set of containers with a UID (unique identifier) and a type. Containers contain items. Items also have a unique identifier within their container.
UID: abcd-1234-5678-afef Type: installation
This installation type container whose UID is generated on the BlueMind installation contains server type items.
UID: bluemind.net Type: domain
A domain type container is created when a domain is added to a BlueMind installation.
UID: users_bluemind.net Type: users
A users type container is created when a domain is created and contains the users of the domain bluemind.net.
UID: addressbook_bluemind.net Type: addressbook
This container contains vCard type items representing users’ and groups’ contact information.
Using these generic containers enables reusable cross-application features, the three main ones being:
- Rights management and ACLs which will be positioned on the containers
- Automatic maintenance of change history, of a version number on the container and of a version on the item
- Subscription management (you subscribe to the container “richard_calendar” so that it is always shown in your UI)
Generic items will carry the values all objects would usually carry:
- Last edit date, creation date
- The user’s UID used for the last edit, UID used on creation
- External ID (especially useful during a migration process to save the object’s ID in the source folder and know that this object is imported)
Synchronisation au niveau des containers
Most BlueMind APIs are used specifying the container to be acted on. When a container is created, a database sequence is created to maintain version numbers within the container.
A ChangeLog table is automatically populated each time an item is created, updated or deleted.
This makes generic synching mechanisms particularly efficient as communication with the server is limited to exchanging version number and modification types. Depending on the version number gap between the client and the server, the client is able to request changes and data (section by section or all at once depending on the amount of data).
The synching code is therefore implemented once and not repeated: the process is exactly the same for events, contacts or any type of data whose changes are tracked.
It is located in ContainerStoreService, via the changelog() and changeset() methods.
SecurityContext and rights management
During authentication, a SecurityContext is created and a session ID is allocated. This object registers the session ID, users’ UIDs as well as the groups users are a member of.
The Session ID is included with every API request as an X-Bm-ApiKey header.
This complete architecture overhaul has kept our R&D team busy for months, which is why our version 3.5 was such a long time coming. But thanks to this work, we’ve achieved a robust, scalable architecture that meets three crucial goals:
- Elastic infrastructures that can accommodate load increases — from tens of users to hundreds of thousands of them
- Load balancing and service redundancy capability
- The ability to replace relational databases by noSQL databases and file structures better adapted to Cloud solutions.