@Override
  public String getDeployedURL(
      String tenantDomain, String applicationID, String applicationVersion, String stage)
      throws AppFactoryException {
    String url = (String) this.properties.getProperty(LAUNCH_URL_PATTERN);

    String artifactTrunkVersionName =
        AppFactoryUtil.getAppfactoryConfiguration()
            .getFirstProperty(AppFactoryConstants.TRUNK_WEBAPP_ARTIFACT_VERSION_NAME);
    String sourceTrunkVersionName =
        AppFactoryUtil.getAppfactoryConfiguration()
            .getFirstProperty(AppFactoryConstants.TRUNK_WEBAPP_SOURCE_VERSION_NAME);
    if (applicationVersion.equalsIgnoreCase(sourceTrunkVersionName)) {
      applicationVersion = artifactTrunkVersionName;
    }

    String stratosAppId =
        CommonUtil.getStratosApplicationId(applicationID, applicationVersion, stage, appType);
    url =
        url.replace(PARAM_TENANT_DOMAIN, tenantDomain)
            .replace(PARAM_APP_ID, applicationID)
            .replace(PARAM_APP_VERSION, applicationVersion)
            .replace(PARAM_STRATOS_APP_ID, stratosAppId);
    return url;
  }
  /**
   * Clear the role authorizations from database
   *
   * @param role
   * @param userName
   * @throws AppFactoryException
   */
  private void clearRoleAuthorization(String role, String userName) throws AppFactoryException {
    boolean errorOccurred = false;
    // get base access urls from appfactory.xml
    Map<String, String> baseAccessURLs = AppFactoryUtil.getBaseAccessURLs();
    if (baseAccessURLs.isEmpty()) {
      String msg = "Could not find any remote server URLs configured for cloud environments.";
      log.error(msg);
      throw new AppFactoryException(msg);
    }

    for (Map.Entry entry : baseAccessURLs.entrySet()) {
      String stage = (String) entry.getKey();
      try {
        // construct remote service url based on base access url
        String remoteServiceURL = (String) entry.getValue();
        if (!remoteServiceURL.endsWith("/")) {
          remoteServiceURL += "/services/";
        } else {
          remoteServiceURL += "services/";
        }

        // create remote authorization management client and authenticate with mutual auth.
        RemoteAuthorizationMgtClient authorizationMgtClient =
            new RemoteAuthorizationMgtClient(remoteServiceURL);
        AppFactoryUtil.setAuthHeaders(
            authorizationMgtClient.getStub()._getServiceClient(), userName);

        try {
          authorizationMgtClient.clearAllRoleAuthorization(role);
        } catch (Exception e) {
          String errorMsg = "Failed to clear authorization for role:" + role + " on stage:" + stage;
          log.error(errorMsg);
          if (log.isDebugEnabled()) {
            log.debug(errorMsg, e);
          }
          errorOccurred = true;
          // continue to other permissions and throw generic exception at the end of flow.
        }

      } catch (Exception e) {
        String errorMsg = "Failed to clear role:" + role + " on stage:" + stage;
        log.error(errorMsg);
        if (log.isDebugEnabled()) {
          log.debug(errorMsg, e);
        }
        errorOccurred = true;
        // continue to other stages and throw generic exception at the end of flow.
      }
    }

    if (errorOccurred) {
      throw new AppFactoryException("Failed to clear role:" + role);
    }
  }
  /**
   * Authorize given role with given set of permissions
   *
   * @param role - role name
   * @param userName - authorized user to authorize roles
   * @param permissions - set of permissions
   * @throws AppFactoryException if remote exceptions or user store exceptions occurred.
   */
  private void authorizeRole(String role, String userName, Permission[] permissions)
      throws AppFactoryException {
    boolean errorOccurred = false;
    // get base access urls from appfactory.xml
    Map<String, String> baseAccessURLs = AppFactoryUtil.getBaseAccessURLs();
    if (baseAccessURLs.isEmpty()) {
      String msg = "Could not find any remote server URLs configured for cloud environments.";
      log.error(msg);
      throw new AppFactoryException(msg);
    }

    for (Map.Entry entry : baseAccessURLs.entrySet()) {
      String stage = (String) entry.getKey();
      try {
        // construct remote service url based on base access url
        String remoteServiceURL = (String) entry.getValue();
        // create remote authorization management client and authenticate with mutual auth.
        RemoteAuthorizationMgtClient authorizationMgtClient =
            new RemoteAuthorizationMgtClient(remoteServiceURL);
        AppFactoryUtil.setAuthHeaders(
            authorizationMgtClient.getStub()._getServiceClient(), userName);

        for (Permission permission : permissions) {
          try {
            authorizationMgtClient.authorizeRole(
                role, permission.getResourceId(), permission.getAction());
          } catch (Exception e) {
            String errorMsg =
                "Failed to authorize role:"
                    + role
                    + " ,permission:"
                    + permission.getResourceId()
                    + " ,action:"
                    + permission.getAction()
                    + " on stage:"
                    + stage;
            log.error(errorMsg, e);
            errorOccurred = true;
            // continue to other permissions and throw generic exception at the end of flow.
          }
        }
      } catch (Exception e) {
        String errorMsg = "Failed to authorize role:" + role + " on stage:" + stage;
        log.error(errorMsg, e);
        errorOccurred = true;
        // continue to other stages and throw generic exception at the end of flow.
      }
    }

    if (errorOccurred) {
      throw new AppFactoryException("Failed to authorize role:" + role);
    }
  }
  @Override
  public void onCreation(
      Application application, String userName, String tenantDomain, boolean isUploadableAppType)
      throws AppFactoryException {
    // authorize application specific unique role in all cloud environments.
    log.info(
        "EnvironmentAuthorizationListener was called for application:"
            + application.getId()
            + " creation event.");
    String applicationRoleName = AppFactoryUtil.getRoleNameForApplication(application.getId());
    Permission perAppRolePermission =
        new Permission(
            AppFactoryConstants.PER_APP_ROLE_PERMISSION, CarbonConstants.UI_PERMISSION_ACTION);
    authorizeRole(applicationRoleName, userName, new Permission[] {perAppRolePermission});
    try {
      //
      String infoMessageTitle =
          "Application "
              + application.getName()
              + " is successfully authorized for all "
              + "Cloud environments";

      EventNotifier.getInstance()
          .notify(
              AppCreationEventBuilderUtil.buildApplicationCreationEvent(
                  infoMessageTitle, "", Event.Category.INFO));
      // EventNotifier.getInstance().notify(EventBuilderUtil.buildApplicationCreationEvent(application.getId(), infoMessage, infoMessage, Event.Category.INFO));
    } catch (AppFactoryEventException e) {
      log.error("Failed to notify Cloud environment authorization events", e);
      // do not throw again.
    }
  }
 @Override
 public boolean hasExecuted(Application application, String userName, String tenantDomain)
     throws AppFactoryException {
   String applicationRoleName = AppFactoryUtil.getRoleNameForApplication(application.getId());
   Permission perAppRolePermission =
       new Permission(
           AppFactoryConstants.PER_APP_ROLE_PERMISSION, CarbonConstants.UI_PERMISSION_ACTION);
   return isRoleAuthorized(applicationRoleName, userName, new Permission[] {perAppRolePermission});
 }
  private static String changeFileName(String name, String changedVersion)
      throws AppFactoryException {

    String applicationName = name;
    String artifactVersionXPath =
        "-" + AppFactoryUtil.getAppfactoryConfiguration().getFirstProperty(ARTIFACT_VERSION_XPATH);
    if (name.lastIndexOf(artifactVersionXPath) != -1) {
      applicationName = name.substring(0, name.lastIndexOf(artifactVersionXPath));
    } else if (name.lastIndexOf("-") != -1) {
      applicationName = name.substring(0, name.lastIndexOf("-"));
    }
    return applicationName + "-" + changedVersion;
  }
 @Override
 public void onDeletion(Application application, String userName, String tenantDomain)
     throws AppFactoryException {
   String applicationRoleName = AppFactoryUtil.getRoleNameForApplication(application.getId());
   clearRoleAuthorization(applicationRoleName, userName);
 }