private static void doPreConfigContextCreation(int tenantId) {
   BundleContext bundleContext = CarbonCoreDataHolder.getInstance().getBundleContext();
   if (bundleContext != null) {
     ServiceTracker tracker =
         new ServiceTracker(
             bundleContext, Axis2ConfigurationContextObserver.class.getName(), null);
     tracker.open();
     Object[] services = tracker.getServices();
     if (services != null) {
       for (Object service : services) {
         ((Axis2ConfigurationContextObserver) service).creatingConfigurationContext(tenantId);
       }
     }
     tracker.close();
   }
 }
  /**
   * Create Tenant Axis2 ConfigurationContexts & add them to the main Axis2 ConfigurationContext
   *
   * @param mainConfigCtx Super-tenant Axis2 ConfigurationContext
   * @param tenantDomain Tenant domain (e.g. foo.com)
   * @return The newly created Tenant ConfigurationContext
   * @throws Exception If an error occurs while creating tenant ConfigurationContext
   */
  private static ConfigurationContext createTenantConfigurationContext(
      ConfigurationContext mainConfigCtx, String tenantDomain) throws Exception {
    synchronized (tenantDomain.intern()) { // lock based on tenant domain
      Map<String, ConfigurationContext> tenantConfigContexts =
          getTenantConfigurationContexts(mainConfigCtx);
      ConfigurationContext tenantConfigCtx = tenantConfigContexts.get(tenantDomain);
      if (tenantConfigCtx != null) {
        return tenantConfigCtx;
      }
      long tenantLoadingStartTime = System.currentTimeMillis();
      int tenantId = getTenantId(tenantDomain);
      if (tenantId == MultitenantConstants.SUPER_TENANT_ID
          || tenantId == MultitenantConstants.INVALID_TENANT_ID) {
        throw new Exception("Tenant " + tenantDomain + " does not exist");
      }
      PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
      carbonContext.setTenantId(tenantId);
      carbonContext.setTenantDomain(tenantDomain);

      tenantConfigCtx = tenantConfigContexts.get(tenantDomain);
      if (tenantConfigCtx != null) {
        return tenantConfigCtx;
      }

      AxisConfiguration mainAxisConfig = mainConfigCtx.getAxisConfiguration();

      dataHolder.getTenantRegistryLoader().loadTenantRegistry(tenantId);

      try {
        UserRegistry tenantConfigRegistry =
            dataHolder.getRegistryService().getConfigSystemRegistry(tenantId);
        UserRegistry tenantLocalUserRegistry =
            dataHolder.getRegistryService().getLocalRepository(tenantId);
        TenantAxisConfigurator tenantAxisConfigurator =
            new TenantAxisConfigurator(
                mainAxisConfig,
                tenantDomain,
                tenantId,
                tenantConfigRegistry,
                tenantLocalUserRegistry);
        doPreConfigContextCreation(tenantId);
        tenantConfigCtx =
            ConfigurationContextFactory.createConfigurationContext(tenantAxisConfigurator);

        AxisConfiguration tenantAxisConfig = tenantConfigCtx.getAxisConfiguration();

        tenantConfigCtx.setServicePath(CarbonUtils.getAxis2ServicesDir(tenantAxisConfig));
        tenantConfigCtx.setContextRoot("local:/");

        TenantTransportSender transportSender = new TenantTransportSender(mainConfigCtx);
        // Adding transport senders
        HashMap<String, TransportOutDescription> transportSenders =
            mainAxisConfig.getTransportsOut();
        if (transportSenders != null && !transportSenders.isEmpty()) {
          for (String strTransport : transportSenders.keySet()) {
            TransportOutDescription outDescription = new TransportOutDescription(strTransport);
            outDescription.setSender(transportSender);
            tenantAxisConfig.addTransportOut(outDescription);
          }
        }

        // Set the work directory
        tenantConfigCtx.setProperty(
            ServerConstants.WORK_DIR, mainConfigCtx.getProperty(ServerConstants.WORK_DIR));
        PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
        new TransportPersistenceManager(tenantAxisConfig)
            .updateEnabledTransports(
                tenantAxisConfig.getTransportsIn().values(),
                tenantAxisConfig.getTransportsOut().values());

        // Notify all observers
        BundleContext bundleContext = dataHolder.getBundleContext();
        if (bundleContext != null) {
          ServiceTracker tracker =
              new ServiceTracker(
                  bundleContext, Axis2ConfigurationContextObserver.class.getName(), null);
          tracker.open();
          Object[] services = tracker.getServices();
          if (services != null) {
            for (Object service : services) {
              ((Axis2ConfigurationContextObserver) service)
                  .createdConfigurationContext(tenantConfigCtx);
            }
          }
          tracker.close();
        }
        tenantConfigCtx.setProperty(MultitenantConstants.LAST_ACCESSED, System.currentTimeMillis());

        // Register Capp deployer for this tenant
        Utils.addCAppDeployer(tenantAxisConfig);

        // deploy the services since all the deployers are initialized by now.
        tenantAxisConfigurator.deployServices();

        // tenant config context must only be made after the tenant is fully loaded, and all its
        // artifacts
        // are deployed.
        // -- THIS SHOULD BE THE LAST OPERATION OF THIS METHOD --
        tenantConfigContexts.put(tenantDomain, tenantConfigCtx);

        log.info(
            "Loaded tenant "
                + tenantDomain
                + " in "
                + (System.currentTimeMillis() - tenantLoadingStartTime)
                + " ms");

        return tenantConfigCtx;
      } catch (Exception e) {
        String msg = "Error occurred while running deployment for tenant ";
        log.error(msg + tenantDomain, e);
        throw new Exception(msg, e);
      }
    }
  }