Hi Devs,
We need to start an ESB in a docker container, with a capp deployed in
tenant space. So in order to have the tenant space already created and to
get the tenant initialized when the container is serving requests, we have
tried out the following approach manually which works.
1.
Have the capp copied to [ESB_HOME]/repository/tenants/[tenantId]/ when
building the docker image. This tenantId may not be incremental and could
be any number
2.
Run the docker and wait for ESB to start
3.
Invoke the TenantMgtAdminService’s addTenant method specifying the
‘tenantId’ and other tenant details (username, password, etc)
4.
Invoke an API that is available in the copied capp (1) to initialize the
tenant
Basically, we need to have the tenant space created during ESB server
startup. Tenant could be initialized later for the first request. Therefore
we started writing an OSGI declarative component which waits for
TenantMgtServiceComponent and calls the TenantMgtAdminService to create the
tenant. The capps will be already copied to the tenant space when building
the docker image. Following is what we have tried so far.
1.
When trying to write a new OSGI component, say
TenantInitializerComponent, we wanted to add a TenantMgtServiceComponent
registered OSGI service as dependency. But there were no OSGI services
available in either of any tenant management components. Due to this we
were not able to get the TenantInitializerComponent activated.
2.
Since there were no OSGI services of TenantMgtServiceComponent
available, we tried by adding the dependencies of TenantMgtServiceComponent
to TenantInitializerComponent as below.
* @scr.reference name="org.wso2.carbon.tenant.mgt.listener.service"
*
interface="org.wso2.carbon.stratos.common.listeners.TenantMgtListener"
* cardinality="1..n" policy="dynamic"
* bind="setTenantMgtListenerService"
* unbind="unsetTenantMgtListenerService"
* @scr.reference name="default.tenant.billing.service"
*
interface="org.wso2.carbon.stratos.common.TenantBillingService"
* cardinality="0..1" policy="dynamic"
* bind="setTenantBillingService"
* unbind="unsetTenantBillingService"
TenantMgtListener is available in ESB and therefore set the cardinality to
1..n. TenantBillingService is not available in ESB and hence cardinality is
0..1.
Following is the implementation in the TenantInitializerComponent’s
activate method.
TenantMgtAdminService tenantMgtAdminService = new TenantMgtAdminService();
TenantInfoBean tenantInfoBean = new TenantInfoBean();
tenantInfoBean.setActive(true);
tenantInfoBean.setAdmin("admin");
tenantInfoBean.setAdminPassword("admin123");
tenantInfoBean.setFirstname("Maheeka");
tenantInfoBean.setLastname("Maheeka");
tenantInfoBean.setEmail("[email protected]");
tenantInfoBean.setTenantDomain("maheeka.com");
tenantInfoBean.setSuccessKey("");
tenantInfoBean.setTenantId(250);
tenantInfoBean.setUsagePlan("Demo");
try {
tenantMgtAdminService.addTenant(tenantInfoBean);
log.info("Tenant added successfully");
} catch (Exception e) {
log.error(“Error adding tenant", e);
}
However, “tenantMgtAdminService.addTenant(tenantInfoBean)” will invoke
TenantMgtServiceComponent
which is not activated by this time and thus throws a NPE.
1.
Next thing we tried was using the ServerStartupObserver as dependency to
TenantInitializerComponent. However even this time
TenantMgtServiceComponent is not activated by the time
TenantInitializerComponent tries to activate. According to [1], seems like
ServerStartupObserver only waits till the transports are started.
2.
If we write a BundleListener [3], we could wait for the
TenantMgtServiceComponent to be active and perform addTenant. Since this
captures all bundle statuses this might not be an effective approach.
3.
Finally, took a look at StartupFinalizerServiceComponent. This seems to
register a service after all the components are initialized as
org.apache.axis2.engine.ListenerManager. I was able to successfully create
the tenant by adding a reference to this service as below.
* @scr.reference name="listener.manager"
*
interface="org.apache.axis2.engine.ListenerManager"
* cardinality="1..1" policy="dynamic"
* bind="setListenerManager"
* unbind="unsetListenerManager"
Adding reference to org.apache.axis2.engine.ListenerManager seems to solve
the problem. However, need to verify whether there are any other better
ways to solve this problem. Or shall we proceed with this approach?
Appreciate your feedback on this.
Thanks Kalpa and Jayanga for helping out on the details.
[1] https://docs.wso2.com/display/Carbon447/Server+Startup+Observer
[2]
https://github.com/wso2/carbon-kernel/blob/4.4.x/core/org.wso2.carbon.core/src/main/java/org/wso2/carbon/core/internal/StartupFinalizerServiceComponent.java#L199
[3]
http://eclipsesource.com/blogs/2013/01/23/how-to-track-lifecycle-changes-of-osgi-bundles/
Thanks,
Maheeka Jayasuriya
Senior Software Engineer
Mobile : +94777750661
_______________________________________________
Dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/dev