/** {@inheritDoc} */
  public InvocationResponse invoke(MessageContext messageContext) throws AxisFault {
    if (log.isDebugEnabled()) {
      log.debug(
          "Starting Activation Handler invocation. Incoming Message: "
              + messageContext.getEnvelope().toString());
    }

    AxisService service = messageContext.getAxisService();
    int tenantId = getTenantId(messageContext);
    if (service != null && "ActivationService".equals(service.getName())) {
      log.debug("Granted access to the Activation Service");
      if (tenantId > 0) {
        TenantAxisUtils.getTenantAxisConfiguration(
            getTenantDomain(), messageContext.getConfigurationContext());
        log.debug("Loaded Tenant Configuration");
      }
      return InvocationResponse.CONTINUE;
    }
    if (tenantId == MultitenantConstants.SUPER_TENANT_ID) {
      log.debug("Granted access for super tenant");
      return InvocationResponse.CONTINUE;
    }
    if (ActivationManager.activationRecorded(tenantId)) {
      if (ActivationManager.getActivation(tenantId)) {
        TenantAxisUtils.getTenantAxisConfiguration(
            getTenantDomain(), messageContext.getConfigurationContext());
        log.debug("Loaded Tenant Configuration");
        return InvocationResponse.CONTINUE;
      } else {
        if (log.isWarnEnabled()) {
          String serviceName = Util.getServiceName();
          log.warn("Failed attempt to access " + serviceName + " by tenant " + tenantId);
        }
        return InvocationResponse.ABORT;
      }
    }
    String serviceName = Util.getServiceName();
    try {
      if (CloudServicesUtil.isCloudServiceActive(serviceName, tenantId)) {
        log.debug("Successful attempt to access " + serviceName + " by tenant " + tenantId);
        ActivationManager.setActivation(tenantId, true);
        TenantAxisUtils.getTenantAxisConfiguration(
            getTenantDomain(), messageContext.getConfigurationContext());
        log.debug("Loaded Tenant Configuration");
        return InvocationResponse.CONTINUE;
      }
    } catch (Exception e) {
      throw new AxisFault("Failed to determine Activation status.", e);
    }
    log.warn("Failed attempt to access " + serviceName + " by tenant " + tenantId);
    ActivationManager.setActivation(tenantId, false);
    return InvocationResponse.ABORT;
  }
 public void run() {
   try {
     TenantAxisUtils.cleanupTenants(tenantIdleTimeMillis);
   } catch (Throwable e) {
     log.error("Error occurred while executing tenant cleanup", e);
   }
 }
  /**
   * Search the service artifacts stored in the registry and find the set of services that satisfy
   * the conditions stated in the given WS-D probe. If the probe does not impose any restrictions on
   * the result set, all the services in the registry will be returned.
   *
   * @param probe a WS-D probe describing the search criteria
   * @return an array of TargetService instances matching the probe or null
   * @throws Exception if an error occurs while accessing the registry
   */
  public static TargetService[] findServices(Probe probe) throws Exception {
    ServiceManager serviceManager = new ServiceManager(getRegistry());
    DiscoveryServiceFilter filter = new DiscoveryServiceFilter(probe);

    // Check whether the inactive services should be skipped when searching
    AxisConfiguration axisConfig;
    String tenantDomain =
        PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true);
    ConfigurationContext mainCfgCtx = ConfigHolder.getInstance().getServerConfigurationContext();
    if (tenantDomain != MultitenantConstants.SUPER_TENANT_DOMAIN_NAME) {
      axisConfig = TenantAxisUtils.getTenantAxisConfiguration(tenantDomain, mainCfgCtx);
    } else {
      axisConfig = mainCfgCtx.getAxisConfiguration();
    }

    Parameter parameter = axisConfig.getParameter(DiscoveryConstants.SKIP_INACTIVE_SERVICES);
    filter.setSkipInactiveServices(parameter == null || "true".equals(parameter.getValue()));

    Service[] services = serviceManager.findServices(filter);
    if (services != null && services.length > 0) {
      TargetService[] targetServices = new TargetService[services.length];
      for (int i = 0; i < services.length; i++) {
        targetServices[i] = getTargetService(services[i]);
      }
      return targetServices;
    }
    return null;
  }
  /**
   * First create a Deployment engine, use that to create an AxisConfiguration
   *
   * @return Axis Configuration
   * @throws AxisFault
   */
  public AxisConfiguration getAxisConfiguration() throws AxisFault {
    // ClassLoader origTccl = Thread.currentThread().getContextClassLoader();
    // Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    log.info(
        "Creating tenant AxisConfiguration for tenant: " + getTenantString(tenantDomain, tenantId));
    PrivilegedCarbonContext.startTenantFlow();
    try {
      PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getCurrentContext();
      carbonContext.setTenantId(tenantId);
      carbonContext.setTenantDomain(tenantDomain);
      if (log.isDebugEnabled()) {
        log.debug("Axis2 repo: " + repoLocation);
      }
      populateAxisConfig();
      addDeployer(new ModuleDeployer(), repoLocation + File.separator + "axis2modules", "mar");
      axisConfig.setConfigurator(this);

      // TODO: May need to set certain parameters into the AxisConfig

      // Hot deployment & update should be turned on for tenants
      axisConfig.addParameter(new Parameter(DeploymentConstants.TAG_HOT_DEPLOYMENT, "true"));
      axisConfig.addParameter(new Parameter(DeploymentConstants.TAG_HOT_UPDATE, "true"));

      globallyEngagedModules = axisConfig.getEngagedModules();
      loadRepository(repoLocation);

      // set the service class loader in the axisConfig, this is needed due to ghost deployer
      // as the service deployer is no longer treated as a special case, we have to do this
      File axis2ServicesDir = new File(repoLocation, CarbonUtils.getAxis2ServicesDir(axisConfig));
      if (axis2ServicesDir.exists()) {
        axisConfig.setServiceClassLoader(
            Utils.getClassLoader(
                axisConfig.getSystemClassLoader(),
                axis2ServicesDir,
                axisConfig.isChildFirstClassLoading()));
      }

      for (Object globallyEngagedModule : globallyEngagedModules) {
        AxisModule module = (AxisModule) globallyEngagedModule;
        if (log.isDebugEnabled()) {
          log.debug("Globally engaging module: " + module.getName());
        }
      }

      // Remove all the transports made available in the tenant's axis2.xml
      axisConfig.getTransportsOut().clear();

      // Remove all in-transports made available in the tenant's axis2.xml
      axisConfig.getTransportsIn().clear();

      // Add the transports that are made available in the main axis2.xml file
      TenantAxisUtils.setTenantTransports(mainAxisConfig, tenantDomain, axisConfig);

    } finally {
      PrivilegedCarbonContext.endTenantFlow();
      // Thread.currentThread().setContextClassLoader(origTccl);
    }
    return axisConfig;
  }
  private static Registry getRegistry() throws DiscoveryException {
    String domain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
    if (domain != MultitenantConstants.SUPER_TENANT_DOMAIN_NAME) {
      AxisConfiguration axisConfig =
          TenantAxisUtils.getTenantAxisConfiguration(
              domain, ConfigHolder.getInstance().getServerConfigurationContext());
      return (Registry)
          PrivilegedCarbonContext.getCurrentContext(axisConfig)
              .getRegistry(RegistryType.SYSTEM_GOVERNANCE);
    }

    return (Registry)
        PrivilegedCarbonContext.getCurrentContext().getRegistry(RegistryType.SYSTEM_GOVERNANCE);
  }
  public void process(
      HttpRequest request,
      HttpResponse response,
      MessageContext messageContext,
      NHttpServerConnection conn,
      OutputStream outputStream,
      boolean b) {

    boolean isRequestHandled = false;

    String uri = request.getRequestLine().getUri();

    String servicePath = cfgCtx.getServiceContextPath();
    if (!servicePath.startsWith("/")) {
      servicePath = "/" + servicePath;
    }
    String serviceName = getServiceName(request);

    boolean loadBalancer = Boolean.parseBoolean(System.getProperty("wso2.loadbalancer", "false"));
    if (uri.equals("/favicon.ico")) {
      response.setStatusCode(HttpStatus.SC_MOVED_PERMANENTLY);
      response.addHeader("Location", "http://wso2.org/favicon.ico");
      serverHandler.commitResponseHideExceptions(conn, response);
      isRequestHandled = true;
    } else if (uri.startsWith(servicePath) && (serviceName == null || serviceName.length() == 0)) {
      // check if service listing request is blocked
      if (isServiceListBlocked(uri)) {
        response.setStatusCode(HttpStatus.SC_FORBIDDEN);
        serverHandler.commitResponseHideExceptions(conn, response);
      } else {
        generateServicesList(response, conn, outputStream, servicePath);
      }
      try {
        outputStream.flush();
        outputStream.close();
      } catch (IOException ignore) {
      }
      isRequestHandled = true;
    } else {
      int pos = uri.indexOf('?');
      if (pos != -1) {
        String queryString = uri.substring(pos + 1);
        String requestUri = uri.substring(0, pos);
        String requestUrl = uri;
        if (requestUri.indexOf("://") == -1) {
          HttpInetConnection inetConn = (HttpInetConnection) conn;

          String hostName = "localhost";
          ServerConfiguration serverConfig = ServerConfiguration.getInstance();
          if (serverConfig.getFirstProperty("HostName") != null) {
            hostName = serverConfig.getFirstProperty("HostName");
          }

          requestUrl = "http://" + hostName + ":" + inetConn.getLocalPort() + requestUri;
        }

        String contextPath = cfgCtx.getServiceContextPath();
        int beginIndex = -1;
        if (requestUri.indexOf(contextPath) != -1) {
          beginIndex = requestUri.indexOf(contextPath) + contextPath.length() + 1;
        }

        /**
         * This reverseProxyMode was introduce to avoid LB exposing it's own services when invoked
         * through rest call. For a soap call this works well. But for a rest call this does not
         * work as intended. in LB it has to set system property "reverseProxyMode"
         */
        boolean reverseProxyMode = Boolean.parseBoolean(System.getProperty("reverseProxyMode"));
        AxisService axisService = null;
        if (!reverseProxyMode) {
          if (!(beginIndex < 0 || beginIndex > requestUri.length())) {
            serviceName = requestUri.substring(beginIndex);
            axisService = cfgCtx.getAxisConfiguration().getServiceForActivation(serviceName);
          }

          if (axisService == null && !loadBalancer && serviceName != null) {
            // Try to see whether the service is available in a tenant
            try {
              axisService = TenantAxisUtils.getAxisService(serviceName, cfgCtx);
            } catch (AxisFault axisFault) {
              axisFault.printStackTrace();
            }
          }
        }

        if (queryString != null) {
          for (String item : getRequestProcessors.keySet()) {
            if (queryString.indexOf(item) == 0
                && (queryString.equals(item)
                    || queryString.indexOf("&") == item.length()
                    || queryString.indexOf("=") == item.length())) {
              if (axisService == null) {
                continue;
              }

              try {
                processWithGetProcessor(
                    request,
                    response,
                    requestUri,
                    requestUrl,
                    queryString,
                    item,
                    outputStream,
                    conn);
              } catch (Exception e) {
                handleBrowserException(response, conn, outputStream, "Error processing request", e);
              }
              isRequestHandled = true;
              break;
            }
          }
        }
      }
    }

    if (!isRequestHandled) {
      processGetAndDelete(request, response, messageContext, conn, outputStream, "GET", b);
    }
  }