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

Reply via email to