ArchitectureTwo of the core concepts of Indicium’s architecture are extensibility and modularity. It is our goal to make it easy to extend Indicium by plugging in custom components that adhere to predefined interfaces. At the same time, we also want to make many of Indicium’s standard components modular. This makes both adding custom components and omitting standard components easy, allowing you to create a tailored version of Indicium that meets all your requirements without having any unnecessary features.
Another goal of Indicium’s architecture is maintaining cross-platform support for Indicium’s core services. The modularity of Indicium’s architecture makes this possible by allowing the inevitable platform-specific components to be added as plugins.
The image below shows an approximation of our architectural vision for the Indicium application tier.
The architecture of the Indicium application tier.
IntegrationDue to the increasing demand of interconnectivity between applications, one of the major goals of Indicium is the ability to integrate it in other application landscapes and vice versa. The previous article already illustrated Indicium’s role as an integration hub. This article will explain how this goal will be achieved.
RESTful API using ODataIndicium exposes a public Web API which can be used by clients to interact with the applications created with the Thinkwise Platform. Our own user interfaces communicate with Indicium through this same API. This means that all features available to our user interfaces are also available to other applications and services. Combine this public API with the fact that many features that currently reside in our user interfaces will be moved to Indicium, and the picture of a truly rich integration hub begins to form. Imagine that third party applications can play a role in our workflows, schedule actions for our applications, and are bound by the authorization and application logic that you will develop.
The API exposed by Indicium is based on several industry-leading standards, such as REST and OData. This will make the API as accessible to external developers as it can be, without the need for a large amount of documentation and support.
Custom ConnectorsNot only can external applications and services call Indicium, we also want to make it possible for Indicium to call external applications and services. This is where the extensibility of Indicium comes in. Should the standard connectors of Indicium fall short, then you can create your own custom connector.
PerformanceGreat performance is one of the cornerstones of the Indicium application tier. When comparing the performance of Indicium to its predecessor, the C# service tier, or comparing the new Universal user interface + Indicium to the current browser + Web user interface architecture, Indicium will greatly outperform both. This difference in performance can be explained by a few key improvements.
Less data transmitted between client and serverThe Mobile user interface and the old C# service tier communicated in XML, adhering to the SOAP protocol. XML by itself is quite verbose, requiring all column values for all records to be wrapped inside XML-elements with both a start-tag and a nearly identical end-tag. The SOAP protocol further aggravates this issue by wrapping entire responses in SOAP envelopes with various attributes.
The current Web user interface communicates with the browser in HTML. The Web user interface will process data sets by rendering the HTML for the user interface and transmit this HTML to the browser. The HTML produced by the Web user interface is even more verbose than the XML produced by the C# service tier, due to all the extra information regarding the structure and style of the user interface components.
The C# service tier’s XML response for one record.
Indicium’s JSON response for the same record
Faster web application frameworkThe Indicium application tier runs on ASP.NET Core MVC 6, Microsoft’s latest and most performant web application framework. ASP.NET Core is a redesign of the old ASP.NET framework with the intention of making the framework much leaner to increase request throughput. On top of that, it can run on .NET Core, which is not only much faster than the .NET Framework, but also capable of running on Linux and Mac OS servers.
These points make the ASP.NET Core framework significantly faster than the C# service tier’s WCF Framework and the Web user interface’s ASP.NET framework and allow Indicium’s core services to operate on non-Windows servers. Some features remain limited to Windows though, so please double-check if your application can run on a non-Windows platform.
The performance difference between ASP.NET Core and ASP.NET is illustrated by the image below. These results do not directly translate to Indicium due to the lack of complexity in this testing scenario, but it does give an indication that ASP.NET Core is quite a bit faster than ASP.NET.
A performance comparison using requests served per second of ASP.NET Core (blue) and ASP.NET 4.6 (red, in the bottom left).
Faster data access frameworkThe Indicium application tier uses the ADO.NET framework for all its data access needs. The Web user interface also uses ADO.NET, so there’s no significant difference in performance there. However, the old C# service tier uses the Entity Framework for data access, which is a lot slower than ADO.NET due to all the extra work it does to support features that we don’t use. The Entity Framework also restricted our ability to optimize the queries used to retrieve data due to the limited influence on the query generation process.
Performance comparison of ADO.NET versus various ways of using the Entity Framework
Memory usageThe Indicium application tier is quite lean when it comes to memory usage, especially when comparing it to the current Web user interface. The most important reason for this is the clear separation between the user interface on one side and the application logic and data access on the other. The Web user interface does a lot of things related to the user interface on the server, which causes it to require more information from the application model (e.g. themes and translations) and keep track of a lot of state to keep the client and the server in sync. Since Indicium does not concern itself with the user interface, it has a much smaller memory footprint than the Web user interface. The difference in memory usage between the Web user interface and Indicium is difficult to quantify because it depends on many variables. It is however possible to improve memory usage by a factor of 100 or more.
Moving away from two-tier architecturesSo far, the Windows user interface has not been mentioned yet in any of the performance comparisons above. The reason for this is that the introduction of Indicium will not make the Windows user interface faster. At the moment, the Windows user interface uses a two-tier architecture, which means that it accesses the database directly. When the Windows user interface starts making use of the Indicium Application Tier, it will have a three-tier architecture. Adding a layer between the Windows user interface and the database will obviously introduce some overhead, rather than remove it. However, the heavy focus on performance in Indicium, combined with the latest frameworks in the Universal user interface, should minimize the performance difference. Furthermore, as we continue to move features from the user interface to Indicium, some aspects, such as editing column values in a list or form, could become faster than they are now.
With that said, the benefits of a three-tier application far outweigh the minimal drop in performance that it might introduce. Because two-tier applications inherently require direct access to the database, they can only be used in the same network as the database server or with a VPN connection. By contrast, an application using a three-tier architecture can be used from anywhere. Furthermore, three-tier architectures also open many doors regarding data authorization. For instance, it’s much easier to use row-level, column-level and even cell-level authorization in a three-tier architecture, because users don’t require access to the database and the application tier can enforce these authorization rules.
SecurityAnother cornerstone of the Indicium application tier is security. Of course, security has always been a priority for our software, but the new architecture enables us to provide more authentication and authorization options. Furthermore, because Indicium will be a mandatory layer between the user interface and the database server, all existing and future authentication and authorization options will be immediately available to all user interface platforms.
Connection poolingAn important security aspect of Indicium is that it never connects to the database server with the credentials of the user that makes the request. All data access will be performed by the pool user after checking if the user making the request is allowed to perform the requested action. This approach has two advantages. Most importantly, this means that it’s not necessary to have an account for each user on the database server, allowing you to keep all your user and permission management contained within IAM. The second advantage is that only one connection will be opened per database due to the combination of connection pooling and having only one user accessing the database.
AuthorizationIndicium already enforces select, insert, update and delete permissions, including mandatory prefilters on select, update and delete actions. With this, row-level authorization is a possibility for all platforms with the new Universal user interface that connects to Indicium. We will expand on this in the upcoming months by integrating defaults and layouts in Indicium and only sending the visible columns to the clients. This would also make column-level and cell-level authorization a reality.
ScalabilityWith the Indicium Application tier, we aim to greatly improve our ability to scale applications. The reason for this is the increasing importance of cloud platforms, such as Microsoft Azure, and the fact that only scalable applications can utilize the power of these cloud platforms effectively.
When talking about the scalability of applications, it’s always important to distinguish between horizontal scaling and vertical scaling. Horizontal scaling means adding more servers which are running the same application and introducing a load balancer that will distribute incoming requests over these servers. Vertical scaling means adding more resources to a single server, such as processing power and memory, to increase that server’s capacity. If we look at the current Web user interface, both horizontal and vertical scaling can help to increase its capacity, but the effectiveness of each is limited.
Horizontal scalabilityIn the paragraph regarding Memory Usage, it was already explained that the Web user interface stores a lot of state in memory, which is needed to keep the client and the server in sync. This means that, once a user has started a session with an instance of the Web user interface, all subsequent requests for that session must arrive at the same instance of the Web user interface. This severely limits the effectiveness of balancing the load between servers, because most of the requests cannot be balanced. If the sessions which were initially assigned to server #1 end up causing large amounts of load later, then they cannot be redistributed, and server #1 may start to fail.
The Indicium application tier will not keep track of any application state. At some point, we will need to keep track of resource state, for instance for inserting and editing records, or keeping track of process flows. This resource state, however, will be shared between instances of Indicium, to ensure that there is no client-server affinity. This might sound as if all requests will converge at some kind of resource state server, effectively moving the bottleneck from the Indicium servers to that state server, but that’s not the case. Most of the requests won’t need to access the resource state at all, and the simplicity of such a state server enables it to handle large amounts of load.