BlueMind Core, an innovative architecture that adapts to all uses

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),
  • DELETE.

These web services are commonly called RESTful.

TECHNOLOGIES USED

The Core relies on several technologies:

  • Vert.x

License: open source, Apache software 2.0 license

Website: http://vertx.io

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. 

A distributed message bus facilitates communication between application components while keeping components with different roles separate within the application. Application components declare addresses on the bus they know how to respond to. As the bus is distributed, the response to a message may come from another vert.x instance on another server. This enables high availability as well as load balancing as cores are dynamically added to the network when needed. The javascript code in the browser starts a websocket connection with the core. The server is then able to start a dialog. This capability is for instance used to notify users’ browsers immediately when a new email arrives and therefore avoids costly periodic checks.

  • Jackson

License: Apache 2.0 License

Websitehttps://github.com/FasterXML/jackson

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.

Examples

Container:

UID: abcd-1234-5678-afef Type: installation

This installation type container whose UID is generated on the BlueMind installation contains server type items.

Container:

UID: bluemind.net Type: domain

A domain type container is created when a domain is added to a BlueMind installation.

Container:

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.

Container:

UID: addressbook_bluemind.net Type: addressbook

This container contains vCard type items representing users’ and groups’ contact information.

Generic Features

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
  • Version
  • 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.

What next?

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.

To find out more, read our article on continuous integration at BlueMind. You can also watch our Quality Manager’s talk about BlueMind’s production process.

And, you’re welcome to join us at Libday for DevOps D-day in Marseille on 14th November 2019 and listen to our talk entitled: “DevOps and agility: diving into BlueMind’s production works”.

Thomas Fricker

Thomas Fricker

Share this article

Leave a Reply

Your email address will not be published. Required fields are marked *

74 − = 66

Subscription to the newsletter

One e-mail per month to keep up to date with all BlueMind news