Multi-tenancy is a pattern wherein a single instance of software—in this case a Smart API—can serve multiple tenants. A tenant represents a group of users who share access with specific privileges to a set of data. All multi-tenant Smart APIs follow the same rules/protocol as outlined here.
Because the SampleService Smart API comprises a data set loosely based on the Smart P&ID application produced by Hexagon PPM, and the fact that this application provides a good example of the multi-tenant pattern, it is used as an example.
To demonstrate multi-tenancy, there is a V3 version of the SampleService API implemented:
https://sam.spclouddave.com/SampleService/Sppid/V3/
This version is also secured by an authorization server included with the following, public-facing instance of Smart API Manager:
https://sam.spclouddave.com/sam/
Be aware of the URLs referenced in this topic, as they refer to the V3 version of the API exclusively.
Terminology
Smart P&ID users go through a site database to access plants. Plant data is stored in its own database. Therefore, a user must navigate to a particular site and/or plant before accessing actual engineering data, such as vessels, pipes, and nozzles. Here, terms are defined in relation to this design.
-
Partitioning - To logically or physically separate data into distinct, independent parts. Data is partitioned for isolation, management, and/or performance reasons. For this example, a plant (database) represents a data partition.
-
Partition Entity - An entity that participates in defining a path to a data partition. A partition entity is identified via the IsPartitionEntity annotation. For this example, there are two partition entities: Site and Plant.
-
Tenant - Group of users sharing access to a data partition. For this example, the set of users with privileges to access a particular plant defines a tenant.
-
Partition Path - The path a client must take in order to reach data in the partition of a single tenant. The partition path comprises a set of partition entities associated via contained relationships, that is, navigation properties.
Thus, a partition path is formed by an instance of the first (root) partition entity, followed by an instance of a related descendant entity (also annotated as IsPartitionEntity), and so forth, until the last (leaf) partition entity is reached.
For this example, Sites is the top-level entity set accessible from the service root, and Site is a partition entity. Site has a navigation property to Plants, with Plant also being a partition entity. So, a partition path starts with an instance of a Site, and it ends with an instance of a Plant. There are two partition paths for this example:
-
https://sam.spclouddave.com/SampleService/Sppid/V3/Sites('Site A')/Plants('Plant A')
-
https://sam.spclouddave.com/SampleService/Sppid/V3/Sites('Site A')/Plants('Plant B')
-
-
Multi-tenant - As stated previously, multi-tenancy is a software design pattern wherein a single instance of software can serve multiple tenants. To determine if the Smart API you are using is multi-tenant, look for the IsMultiTenant annotation in the annotations $metadata:
https://sam.spclouddave.com/SampleService/Sppid/V3/Annotations/$metadata
<Annotations Target="Com.Ingr.Sppid.V3.Container">
<Annotation Term="Com.Ingr.Vocabularies.Core.V1.IsMultitenant" Bool="true"/>
</Annotations>
Discoverability
If you navigate to the service root of a multi-tenant Smart API, you will notice only one EntitySet, in this case Sites:
{
@odata.context: "https://sam.spclouddave.com/SampleService/V3/$metadata",
value: [
{
name: "Sites",
kind: "EntitySet",
url: "Sites"
},
.
]
}
Reviewing the https://sam.spclouddave.com/SampleService/Sppid/V3/$metadata for the service reveals the following hierarchy, essentially a plant breakdown structure:
Site\Plant\Area\Unit
From Unit, you can navigate to the following types:
-
PlantItems (base type for equipment)
-
Equipments (base type for Vessel, Nozzle, Pipe)
-
Vessels
-
Pipes
-
Nozzles
You can navigate the hierarchy of a multi-tenant Smart API, discovering what is available at each partition.