Using the CarbonContext API
PrivilegedCarbonContext
PrivilegedCarbonContext
is a special subclass of CarbonContext
, which allows you to perform privileged operations such as, setting the tenant ID and domain, starting or ending tenant flows and more. This class can only be used by Carbon components that have the permission to get hold of an instance of the PrivilegedCarbonContext
. An instance of PrivilegedCarbonContext
can only be obtained using the static methods outlined below.
Obtaining the PrivilegedCarbonContext
The following method has to be statically invoked, and will return an instance of PrivilegedCarbonContext.
getThreadLocalCarbonContext()
Obtains the PrivilegedCarbonContext
by using data stored in the current thread: PrivilegedCarbonContext.getThreadLocalCarbonContext().
As a result, in cases like the deployers, where you can be sure that the deployment scheduler thread would set the ThreadLocal
data, you should directly call the getThreadLocalCarbonContext
method. You should have an idea, under which thread you are executing. It is better to resolve the CarbonContext
outside that util method, as opposed to resolving the CarbonContext within the method.
Setting information into PrivilegedCarbonContext
If the data backed by the PrivilegedCarbonContext
has been created for the first time, you have to populate information (such as, tenant ID, tenant domain etc.) needed by the downstream code, so that the code can simply get hold of an instance of CarbonContext
or PrivilegedCarbonContext
, and start using it. Populating this data can be done using the following setter methods.
- setTenantId(int tenantId)
- setTenantId(int tenantId, boolean resolveTenantDomain)
- setUsername(String username)
- setTenantDomain(String tenantDomain)
- setTenantDomain(String tenantDomain, boolean resolveTenantId)
- setApplicationName(String applicationName)
- setUserRealm(UserRealm userRealm)
- setRegistry(RegistryType type, Registry registry)
setTenantId(int tenantId)
This method sets the tenant ID in the CarbonContext
. The tenant domain corresponding to this tenant ID will not be resolved.
setTenantId(int tenantId, boolean resolveTenantDomain)
This method sets the tenant ID in the CarbonContext
. The tenant domain corresponding to this tenant ID will be resolved, if resolveTenantDomain
is set to true
.
setUsername(String username)
If there is a user logged in, this method sets that user's username in the PrivilegedCarbonContext
.
setTenantDomain(String tenantDomain)
This method sets the tenant domain on this CarbonContext
instance. This method will not automatically resolve the tenant ID based on the tenant domain.
setTenantDomain(String tenantDomain, boolean resolveTenantId)
This method sets the tenant domain on this CarbonContext
instance. If resolveTenantId
is set to true
, the tenant ID corresponding to the tenantDomain
will be resolved internally.
setApplicationName(String applicationName)
This method sets the name of the webapp or service to which the request was destined.
setUserRealm(UserRealm userRealm)
This method sets the tenant specific UserRealm.
setRegistry(RegistryType type, Registry registry)
This method sets the tenant specific registry.
RegistryTypes
- USER_CONFIGURATION - The configuration registry of the currently logged in user.
- USER_GOVERNANCE - The governance registry of the currently logged in user.
- SYSTEM_CONFIGURATION - The configuration registry of the system.
- LOCAL_REPOSITORY - The local repository of the system.
Switching tenant flows
During an execution flow, sometimes you will need to switch from super tenant mode to tenant mode, do some work as that tenant, and then get back to super tenant mode. In such a scenario, you will do the following:
Start the Tenant Flow.
Set the tenant ID and the tenant domain in the new CarbonContext data holder that gets created when you start the tenant flow.
Carryout the respective action.
End the tenant flow.
Always follow the following template when you carryout the latter mentioned steps:
try{ PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext privilegedCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext() privilegedCarbonContext.setTenantId(tenantId); privilegedCarbonContext.setTenantDomain(tenantDomain); // set other stuff like registry etc. if needed doSomething(); } finally { PrivilegedCarbonContext.endTenantFlow(); }
Inside the doSomething()
method, now if you call CarbonContext
or PrivilegedCarbonContext.getThreadLocalCarbonContext
, you will get the newly created data. The code that started the tenant flow is referred to as the upstream code, and all the code that gets called after starting the tenant flow are referred to as the downstream code. One example where you may start a tenant flow is when the super tenant runs tasks on behalf of a tenant. In the latter mentioned instance it may have a loop; and within that loop start a tenant flow for tenants, run the task as that tenant, get back to the super tenant mode (endTenantFlow
), switch back to another tenant(startTenantFlow
), run the task of the second tenant, get back to super tenant mode, and so on.
In most situations you will not need to start a tenant flow since you will not generally switch to tenant mode from super tenant mode.
PrivilegedCarbonContext.startTenantFlow()
This method starts a new tenant flow, and creates a new holder for tenant data. Thereafter, until endTenantFlow
is called, the getCarbonContext() and getThreadLocalCarbonContext()
methods will return the data related to the newly created tenant data holder. Once startTenantFlow
is called, set the tenant ID, tenant domain and other tenant specific data.
PrivilegedCarbonContext.endTenantFlow()
This methods will end the tenant flow and restore the previous CarbonContext
.
The following diagram depicts during an execution of a thread, how we can start as a super tenant, then switch to tenant 'x' and carryout some actions, and later switch to tenant 'y' and carryout some actions and continue.
Getting Information from PrivilegedCarbonContext
- getTenantDomain(boolean resolve)
- getTenantId(boolean resolve)
- getRegistry(RegistryType type)
- Object getOSGiService(Class clazz)
- List<Object> getOSGiServices(Class clazz)
getTenantDomain(boolean resolve)
This method retrieves the tenant domain, and if resolve
is set to true
, it will try to resolve the domain using the tenant ID.
getTenantId(boolean resolve)
This method retrieves the tenant ID, and if resolve
is set to true
, it will try to resolve the tenant ID using the tenant domain.
getRegistry(RegistryType type)
This method retrieves the Registry of the tenant of type RegistryType
.
RegistryTypes
- SYSTEM_CONFIGURATION - The system configuration registry of the tenant.
- SYSTEM_GOVERNANCE - The governance registry of the tenant.
Object getOSGiService(Class clazz)
This method obtains the first instance of the OSGi services found for the interface or class clazz
.
Note that this method is depreciated in Carbon 4.3.0. The new method is getOSGiService(Class clazz, Hashtable<String, String> props).
List<Object> getOSGiServices(Class clazz)
This method obtai ns all OSGi service instances found for interface or class clazz.
Note that this method is depreciated in Carbon 4.3.0. The new method is List<Object> getOSGiServices(Class clazz, Hashtable<String, String> props).
Miscellaneous Methods
public static void unloadTenant(int tenantId)
This method unloads the tenant.
public static void destroyCurrentContext()
This method destroys the current ThreadLocal CarbonContext.
CarbonContext
The CarbonContext
is designed for normal tenants to retrieve information from the Carbon runtime. In the super tenant mode, for this to work the relevant data has to be set so that tenants can retrieve information using the CarbonContext
.
Obtaining the CarbonContext
getThreadLocalCarbonContext()
This method obtains the CarbonContext
by using the data stored in the current thread: The CarbonContext.getThreadLocalCarbonContext().
Retrieving information
The following methods allow tenants to retrieve information relevant to those tenants from the Carbon runtime.
- public int getTenantId()
- String getUsername()
- String getTenantDomain()
- Registry getRegistry(RegistryType type)
- UserRealm getUserRealm()
- CarbonQueue<?> getQueue(String name)
- Context getJNDIContext(Hashtable properties) throws NamingException
- Context getJNDIContext() throws NamingException
- CarbonContext API String[] discover(URI[] scopes)
public int getTenantId()
This method retrieves the tenant ID.
String getUsername()
This method retrieves the tenant's username.
String getTenantDomain()
This method retrieves the tenant domain.
Registry getRegistry(RegistryType type)
This method retrieves the tenant specific registry.
Registry Types
- USER_CONFIGURATION - The configuration registry of the currently logged in user.
- USER_GOVERNANCE - The governance registry of the currently logged in user.
- SYSTEM_CONFIGURATION - The configuration registry of the system.
- SYSTEM_GOVERNANCE - The governance registry of the system.
- LOCAL_REPOSITORY - The local repository of the system.
UserRealm getUserRealm()
This method retrieves the user realm of the current tenant.
CarbonQueue<?> getQueue(String name)
This method obtains a named queue instance.
Context getJNDIContext(Hashtable properties) throws NamingException
This method obtains a JNDI-context with the given initialization properties.
Method description
properties
- the properties required to create the JNDI-context instance.
NamingException
- if the operation fails, the naming exception will be thrown.
Context getJNDIContext() throws NamingException
This method obtains a JNDI-context.
Method description
NamingException
- if the operation fails, the naming exception will be thrown.
String[] discover(URI[] scopes)
This method is used to discover a set of service endpoints belonging the defined scopes. Therefore, when this method is executed the list of service endpoints will be returned.
Method description
scopes -
the scopes in which to look-up for the service.