Java Code Examples for org.wso2.carbon.utils.multitenancy.MultitenantConstants#INVALID_TENANT_ID

The following examples show how to use org.wso2.carbon.utils.multitenancy.MultitenantConstants#INVALID_TENANT_ID . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AbstractAPIManager.java    From carbon-apimgt with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a list of pre-defined # {@link org.wso2.carbon.apimgt.api.model.Tier} in the system.
 *
 * @return Set<Tier>
 */
public Set<Tier> getTiers(String tenantDomain) throws APIManagementException {

    Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator());
    Map<String, Tier> tierMap;
    if (!APIUtil.isAdvanceThrottlingEnabled()) {
        startTenantFlow(tenantDomain);
        int requestedTenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
        if (requestedTenantId == MultitenantConstants.SUPER_TENANT_ID
                || requestedTenantId == MultitenantConstants.INVALID_TENANT_ID) {
            tierMap = APIUtil.getTiers();
        } else {
            tierMap = APIUtil.getTiers(requestedTenantId);
        }
        tiers.addAll(tierMap.values());
        endTenantFlow();
    } else {
        tierMap = APIUtil.getTiersFromPolicies(PolicyConstants.POLICY_LEVEL_SUB, tenantId);
        tiers.addAll(tierMap.values());
    }
    return tiers;
}
 
Example 2
Source File: AbstractAPIManager.java    From carbon-apimgt with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a list of pre-defined # {@link org.wso2.carbon.apimgt.api.model.Tier} in the system.
 *
 * @return Set<Tier>
 */
public Set<Tier> getTiers() throws APIManagementException {
    Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator());

    Map<String, Tier> tierMap;
    if (!APIUtil.isAdvanceThrottlingEnabled()) {
        if (tenantId == MultitenantConstants.INVALID_TENANT_ID) {
            tierMap = APIUtil.getTiers();
        } else {
            PrivilegedCarbonContext.startTenantFlow();
            PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
            tierMap = APIUtil.getTiers(tenantId);
            endTenantFlow();
        }
        tiers.addAll(tierMap.values());
    } else {
        tierMap = APIUtil.getTiersFromPolicies(PolicyConstants.POLICY_LEVEL_SUB, tenantId);
        tiers.addAll(tierMap.values());
    }

    return tiers;
}
 
Example 3
Source File: IdentityTenantUtil.java    From carbon-identity-framework with Apache License 2.0 6 votes vote down vote up
public static int getTenantId(String tenantDomain) throws IdentityRuntimeException {

        int tenantId = MultitenantConstants.INVALID_TENANT_ID;
        try {
            if (realmService != null) {
                tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
            }
        } catch (UserStoreException e) {
            // Ideally user.core should be throwing an unchecked exception, in which case no need to wrap at this
            // level once more without adding any valuable contextual information. Because we don't have exception
            // enrichment properly implemented, we are appending the error message from the UserStoreException to the
            // new message
            throw IdentityRuntimeException.error("Error occurred while retrieving tenantId for tenantDomain: " +
                    tenantDomain + e.getMessage(), e);
        }
        if(tenantId == MultitenantConstants.INVALID_TENANT_ID){
            throw IdentityRuntimeException.error("Invalid tenant domain " + tenantDomain);
        } else {
            return tenantId;
        }

    }
 
Example 4
Source File: IdentityTenantUtil.java    From carbon-identity-framework with Apache License 2.0 6 votes vote down vote up
/**
 * Get the tenant id of the given user.
 *
 * @param username Username
 * @return Tenant Id of domain user belongs to.
 * @throws IdentityRuntimeException Error when getting the tenant Id from tenant domain
 */
public static int getTenantIdOfUser(String username) throws IdentityRuntimeException {

    int tenantId = MultitenantConstants.INVALID_TENANT_ID;
    String domainName = MultitenantUtils.getTenantDomain(username);
    if (domainName != null) {
        try {
            TenantManager tenantManager = IdentityTenantUtil.getRealmService().getTenantManager();
            tenantId = tenantManager.getTenantId(domainName);
        } catch (UserStoreException e) {
            String errorMsg = "Error when getting the tenant id from the tenant domain : " + domainName;
            throw IdentityRuntimeException.error(errorMsg, e);
        }
    }
    if(tenantId == MultitenantConstants.INVALID_TENANT_ID){
        throw IdentityRuntimeException.error("Invalid tenant domain of user " + username);
    } else {
        return tenantId;
    }
}
 
Example 5
Source File: FederatedAssociationManagerImpl.java    From carbon-identity-framework with Apache License 2.0 6 votes vote down vote up
private int getValidatedTenantId(User user) throws FederatedAssociationManagerException {

        int tenantId;
        RealmService realmService;
        try {
            realmService = IdentityUserProfileServiceDataHolder.getInstance().getRealmService();
            tenantId = realmService.getTenantManager().getTenantId(user.getTenantDomain());
        } catch (UserStoreException e) {
            if (log.isDebugEnabled()) {
                log.debug("Error while getting the tenant Id for the tenant domain: "
                        + user.getTenantDomain());
            }
            throw handleFederatedAssociationManagerServerException(ERROR_WHILE_WORKING_WITH_FEDERATED_ASSOCIATIONS, e,
                    false);
        }
        if (MultitenantConstants.INVALID_TENANT_ID == tenantId) {
            if (log.isDebugEnabled()) {
                log.debug("Invalid tenant id is resolved for the tenant domain: " + user.getTenantDomain());
            }
            throw handleFederatedAssociationManagerClientException(INVALID_TENANT_DOMAIN_PROVIDED, null, true);
        }
        return tenantId;
    }
 
Example 6
Source File: FederatedAssociationManagerImpl.java    From carbon-identity-framework with Apache License 2.0 6 votes vote down vote up
private int getValidatedTenantIdFromDomain(String tenantDomain) throws FederatedAssociationManagerException {

        int tenantId;
        RealmService realmService;
        try {
            realmService = IdentityUserProfileServiceDataHolder.getInstance().getRealmService();
            tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
        } catch (UserStoreException e) {
            if (log.isDebugEnabled()) {
                log.debug("Error while getting the tenant Id for the tenant domain: " + tenantDomain);
            }
            throw handleFederatedAssociationManagerServerException(ERROR_WHILE_WORKING_WITH_FEDERATED_ASSOCIATIONS, e,
                    false);
        }
        if (MultitenantConstants.INVALID_TENANT_ID == tenantId) {
            if (log.isDebugEnabled()) {
                log.debug("Invalid tenant id is resolved for the tenant domain: " + tenantDomain);
            }
            throw handleFederatedAssociationManagerClientException(INVALID_TENANT_DOMAIN_PROVIDED, null, true);
        }
        return tenantId;
    }
 
Example 7
Source File: AbstractAPIManager.java    From carbon-apimgt with Apache License 2.0 6 votes vote down vote up
@Override
public Set<Tier> getAllTiers() throws APIManagementException {
    Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator());
    Map<String, Tier> tierMap;

    if (tenantId == MultitenantConstants.INVALID_TENANT_ID) {
        tierMap = APIUtil.getAllTiers();
    } else {
        boolean isTenantFlowStarted = false;
        try {
            if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
                startTenantFlow(tenantDomain);
                isTenantFlowStarted = true;
            }
            tierMap = APIUtil.getAllTiers(tenantId);
        } finally {
            if (isTenantFlowStarted) {
                endTenantFlow();
            }
        }
    }

    tiers.addAll(tierMap.values());
    return tiers;
}
 
Example 8
Source File: IdentityTenantUtil.java    From carbon-identity with Apache License 2.0 6 votes vote down vote up
public static int getTenantId(String tenantDomain) throws IdentityRuntimeException {

        int tenantId = MultitenantConstants.INVALID_TENANT_ID;
        try {
            tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
        } catch (UserStoreException e) {
            // Ideally user.core should be throwing an unchecked exception, in which case no need to wrap at this
            // level once more without adding any valuable contextual information. Because we don't have exception
            // enrichment properly implemented, we are appending the error message from the UserStoreException to the
            // new message
            throw IdentityRuntimeException.error("Error occurred while retrieving tenantId for tenantDomain: " +
                    tenantDomain + e.getMessage(), e);
        }
        if(tenantId == MultitenantConstants.INVALID_TENANT_ID){
            throw IdentityRuntimeException.error("Invalid tenant domain " + tenantDomain);
        } else {
            return tenantId;
        }

    }
 
Example 9
Source File: IdentityTenantUtil.java    From carbon-identity with Apache License 2.0 6 votes vote down vote up
/**
 * Get the tenant id of the given user.
 *
 * @param username Username
 * @return Tenant Id of domain user belongs to.
 * @throws IdentityRuntimeException Error when getting the tenant Id from tenant domain
 */
public static int getTenantIdOfUser(String username) throws IdentityRuntimeException {

    int tenantId = MultitenantConstants.INVALID_TENANT_ID;
    String domainName = MultitenantUtils.getTenantDomain(username);
    if (domainName != null) {
        try {
            TenantManager tenantManager = IdentityTenantUtil.getRealmService().getTenantManager();
            tenantId = tenantManager.getTenantId(domainName);
        } catch (UserStoreException e) {
            String errorMsg = "Error when getting the tenant id from the tenant domain : " + domainName;
            throw IdentityRuntimeException.error(errorMsg, e);
        }
    }
    if(tenantId == MultitenantConstants.INVALID_TENANT_ID){
        throw IdentityRuntimeException.error("Invalid tenant domain of user " + username);
    } else {
        return tenantId;
    }
}
 
Example 10
Source File: ApplicationTemplateDAOImpl.java    From carbon-identity-framework with Apache License 2.0 5 votes vote down vote up
private int getTenantID(String tenantDomain) {

        // get logged-in users tenant identifier.
        int tenantID = MultitenantConstants.INVALID_TENANT_ID;
        if (tenantDomain != null) {
            tenantID = IdentityTenantUtil.getTenantId(tenantDomain);
        }
        return tenantID;
    }
 
Example 11
Source File: AbstractAPIManager.java    From carbon-apimgt with Apache License 2.0 5 votes vote down vote up
@Override
public Set<Tier> getAllTiers(String tenantDomain) throws APIManagementException {
    Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator());
    Map<String, Tier> tierMap;
    boolean isTenantFlowStarted = false;

    try {
        if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
            startTenantFlow(tenantDomain);
            isTenantFlowStarted = true;
        }

        int requestedTenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
        if (requestedTenantId == MultitenantConstants.SUPER_TENANT_ID
                || requestedTenantId == MultitenantConstants.INVALID_TENANT_ID) {
            tierMap = APIUtil.getAllTiers();
        } else {
            tierMap = APIUtil.getAllTiers(requestedTenantId);
        }
    } finally {
        if (isTenantFlowStarted) {
            endTenantFlow();
        }
    }

    tiers.addAll(tierMap.values());
    return tiers;
}
 
Example 12
Source File: DefaultAuthSeqMgtDAOImpl.java    From carbon-identity-framework with Apache License 2.0 5 votes vote down vote up
private int getTenantID(String tenantDomain) {

        // get logged-in users tenant identifier.
        int tenantID = MultitenantConstants.INVALID_TENANT_ID;
        if (tenantDomain != null) {
            tenantID = IdentityTenantUtil.getTenantId(tenantDomain);
        }
        return tenantID;
    }
 
Example 13
Source File: CORSManagementServiceImpl.java    From carbon-identity-framework with Apache License 2.0 5 votes vote down vote up
/**
 * Validate the tenant domain.
 *
 * @param tenantDomain The tenant domain.
 * @throws CORSManagementServiceClientException
 */
private void validateTenantDomain(String tenantDomain) throws CORSManagementServiceClientException {

    if (IdentityTenantUtil.getTenantId(tenantDomain) == MultitenantConstants.INVALID_TENANT_ID) {
        throw handleClientException(ErrorMessages.ERROR_CODE_INVALID_TENANT_DOMAIN, tenantDomain);
    }
}
 
Example 14
Source File: SingleLogoutMessageBuilder.java    From carbon-identity with Apache License 2.0 4 votes vote down vote up
public LogoutRequest buildLogoutRequest(String subject, String sessionId, String reason, String destination,
                                        String nameIDFormat, String tenantDomain, String
                                                requestsigningAlgorithmUri, String requestDigestAlgoUri) throws
        IdentityException {

    LogoutRequest logoutReq = new LogoutRequestBuilder().buildObject();

    logoutReq.setID(SAMLSSOUtil.createID());

    DateTime issueInstant = new DateTime();
    logoutReq.setIssueInstant(issueInstant);
    logoutReq.setIssuer(SAMLSSOUtil.getIssuerFromTenantDomain(tenantDomain));
    logoutReq.setNotOnOrAfter(new DateTime(issueInstant.getMillis() + 5 * 60 * 1000));

    NameID nameId = new NameIDBuilder().buildObject();
    nameId.setFormat(nameIDFormat);
    nameId.setValue(subject);
    logoutReq.setNameID(nameId);

    SessionIndex sessionIndex = new SessionIndexBuilder().buildObject();
    sessionIndex.setSessionIndex(sessionId);
    logoutReq.getSessionIndexes().add(sessionIndex);

    if (destination != null) {
        logoutReq.setDestination(destination);
    }

    logoutReq.setReason(reason);

    int tenantId;
    if (StringUtils.isEmpty(tenantDomain) || "null".equals(tenantDomain)) {
        tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
        tenantId = MultitenantConstants.SUPER_TENANT_ID;
    } else {
        try {
            tenantId = SAMLSSOUtil.getRealmService().getTenantManager().getTenantId(tenantDomain);
        } catch (UserStoreException e) {
            throw IdentityException.error("Error occurred while retrieving tenant id from tenant domain", e);
        }

        if(MultitenantConstants.INVALID_TENANT_ID == tenantId) {
            throw IdentityException.error("Invalid tenant domain - '" + tenantDomain + "'" );
        }
    }

    try {
        PrivilegedCarbonContext.startTenantFlow();
        PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
        PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
        SAMLSSOUtil.setSignature(logoutReq, requestsigningAlgorithmUri, requestDigestAlgoUri, new
                SignKeyDataHolder(null));
    } finally {
        PrivilegedCarbonContext.endTenantFlow();
    }

    return logoutReq;
}
 
Example 15
Source File: SingleLogoutMessageBuilder.java    From carbon-identity with Apache License 2.0 4 votes vote down vote up
public LogoutResponse buildLogoutResponse(String id, String status, String statMsg, String destination, boolean
        isSignResponse, String tenantDomain, String responseSigningAlgorithmUri, String responseDigestAlgoUri)
        throws IdentityException {

    LogoutResponse logoutResp = new LogoutResponseBuilder().buildObject();
    logoutResp.setID(SAMLSSOUtil.createID());
    logoutResp.setInResponseTo(id);
    logoutResp.setIssuer(SAMLSSOUtil.getIssuer());
    logoutResp.setStatus(buildStatus(status, statMsg));
    logoutResp.setIssueInstant(new DateTime());
    logoutResp.setDestination(destination);

    // Currently, does not sign the error response since this message pass through a url to the error page
    if (isSignResponse && SAMLSSOConstants.StatusCodes.SUCCESS_CODE.equals(status)) {
        int tenantId;
        if (StringUtils.isEmpty(tenantDomain)) {
            tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
            tenantId = MultitenantConstants.SUPER_TENANT_ID;
        } else {
            try {
                tenantId = SAMLSSOUtil.getRealmService().getTenantManager().getTenantId(tenantDomain);
            } catch (UserStoreException e) {
                throw IdentityException.error("Error occurred while retrieving tenant id from tenant domain", e);
            }

            if(MultitenantConstants.INVALID_TENANT_ID == tenantId) {
                throw IdentityException.error("Invalid tenant domain - '" + tenantDomain + "'" );
            }
        }

        try {
            PrivilegedCarbonContext.startTenantFlow();
            PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
            PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
            SAMLSSOUtil.setSignature(logoutResp, responseSigningAlgorithmUri, responseDigestAlgoUri, new
                    SignKeyDataHolder(null));
        } finally {
            PrivilegedCarbonContext.endTenantFlow();
        }
    }

    return logoutResp;
}
 
Example 16
Source File: ApplicationDAOImpl.java    From carbon-identity with Apache License 2.0 4 votes vote down vote up
@Override
public void updateApplication(ServiceProvider serviceProvider, String tenantDomain)
        throws IdentityApplicationManagementException {

    Connection connection = IdentityDatabaseUtil.getDBConnection();
    int applicationId = serviceProvider.getApplicationID();

    int tenantID = MultitenantConstants.INVALID_TENANT_ID;
    if (tenantDomain != null) {
        tenantID = IdentityTenantUtil.getTenantId(tenantDomain);
    }

    try {
        if (ApplicationManagementServiceComponent.getFileBasedSPs().containsKey(
                serviceProvider.getApplicationName())) {
            throw new IdentityApplicationManagementException(
                    "Application with the same name laoded from the file system.");
        }

        // update basic information of the application.
        // you can change application name, description, isSasApp...
        updateBasicApplicationData(serviceProvider, connection);
        updateInboundProvisioningConfiguration(applicationId,
                serviceProvider.getInboundProvisioningConfig(), connection);

        // delete all in-bound authentication requests.
        deleteInboundAuthRequestConfiguration(serviceProvider.getApplicationID(), connection);

        // update all in-bound authentication requests.
        updateInboundAuthRequestConfiguration(serviceProvider.getApplicationID(),
                serviceProvider.getInboundAuthenticationConfig(), connection);

        // delete local and out-bound authentication configuration.
        deleteLocalAndOutboundAuthenticationConfiguration(applicationId, connection);

        // update local and out-bound authentication configuration.
        updateLocalAndOutboundAuthenticationConfiguration(serviceProvider.getApplicationID(),
                serviceProvider.getLocalAndOutBoundAuthenticationConfig(), connection);

        deleteRequestPathAuthenticators(applicationId, connection);
        updateRequestPathAuthenticators(applicationId,
                serviceProvider.getRequestPathAuthenticatorConfigs(), connection);

        deteClaimConfiguration(applicationId, connection);
        updateClaimConfiguration(serviceProvider.getApplicationID(),
                serviceProvider.getClaimConfig(), applicationId, connection);

        deleteOutboundProvisioningConfiguration(applicationId, connection);
        updateOutboundProvisioningConfiguration(applicationId,
                serviceProvider.getOutboundProvisioningConfig(), connection);

        deletePermissionAndRoleConfiguration(applicationId, connection);
        updatePermissionAndRoleConfiguration(serviceProvider.getApplicationID(),
                serviceProvider.getPermissionAndRoleConfig(), connection);
        deleteAssignedPermissions(connection, serviceProvider.getApplicationName(),
                serviceProvider.getPermissionAndRoleConfig().getPermissions());

        if (serviceProvider.getSpProperties() != null) {
            updateServiceProviderProperties(connection, applicationId,
                    Arrays.asList(serviceProvider.getSpProperties()), tenantID);
        }

        if (!connection.getAutoCommit()) {
            connection.commit();
        }
    } catch (SQLException | UserStoreException e) {
        try {
            if (connection != null) {
                connection.rollback();
            }
        } catch (SQLException e1) {
            throw new IdentityApplicationManagementException(
                    "Failed to update service provider " + applicationId, e);
        }
        throw new IdentityApplicationManagementException("Failed to update service provider "
                + applicationId, e);
    } finally {
        IdentityApplicationManagementUtil.closeConnection(connection);
    }
}
 
Example 17
Source File: ApplicationDAOImpl.java    From carbon-identity with Apache License 2.0 4 votes vote down vote up
/**
 * Stores basic application information and meta-data such as the application name, creator and
 * tenant.
 *
 * @param serviceProvider
 * @throws IdentityApplicationManagementException
 */
@Override
public int createApplication(ServiceProvider serviceProvider, String tenantDomain)
        throws IdentityApplicationManagementException {

    // get logged-in users tenant identifier.
    int tenantID = MultitenantConstants.INVALID_TENANT_ID;

    if (tenantDomain != null) {
        tenantID = IdentityTenantUtil.getTenantId(tenantDomain);
    }

    String qualifiedUsername = CarbonContext.getThreadLocalCarbonContext().getUsername();
    if (ApplicationConstants.LOCAL_SP.equals(serviceProvider.getApplicationName())) {
        qualifiedUsername = CarbonConstants.REGISTRY_SYSTEM_USERNAME;
    }
    String username = UserCoreUtil.removeDomainFromName(qualifiedUsername);
    String userStoreDomain = IdentityUtil.extractDomainFromName(qualifiedUsername);
    String applicationName = serviceProvider.getApplicationName();
    String description = serviceProvider.getDescription();

    if (log.isDebugEnabled()) {
        log.debug("Creating Application " + applicationName + " for user " + qualifiedUsername);
    }

    Connection connection = IdentityDatabaseUtil.getDBConnection();
    PreparedStatement storeAppPrepStmt = null;
    ResultSet results = null;

    try {
        String dbProductName = connection.getMetaData().getDatabaseProductName();
        storeAppPrepStmt = connection.prepareStatement(
                ApplicationMgtDBQueries.STORE_BASIC_APPINFO, new String[]{
                        DBUtils.getConvertedAutoGeneratedColumnName(dbProductName, "ID")});

        // TENANT_ID, APP_NAME, USER_STORE, USERNAME, DESCRIPTION, AUTH_TYPE
        storeAppPrepStmt.setInt(1, tenantID);
        storeAppPrepStmt.setString(2, applicationName);
        storeAppPrepStmt.setString(3, userStoreDomain);
        storeAppPrepStmt.setString(4, username);
        storeAppPrepStmt.setString(5, description);
        // by default authentication type would be default.
        // default authenticator is defined system-wide - in the configuration file.
        storeAppPrepStmt.setString(6, ApplicationConstants.AUTH_TYPE_DEFAULT);
        storeAppPrepStmt.execute();

        results = storeAppPrepStmt.getGeneratedKeys();

        if (!connection.getAutoCommit()) {
            connection.commit();
        }

        int applicationId = 0;
        if (results.next()) {
            applicationId = results.getInt(1);
        }
        // some JDBC Drivers returns this in the result, some don't
        if (applicationId == 0) {
            if (log.isDebugEnabled()) {
                log.debug("JDBC Driver did not return the application id, executing Select operation");
            }
            applicationId = getApplicationIDByName(applicationName, tenantID, connection);
        }

        if (serviceProvider.getSpProperties() != null) {
            addServiceProviderProperties(connection, applicationId,
                    Arrays.asList(serviceProvider.getSpProperties()), tenantID);
        }

        if (log.isDebugEnabled()) {
            log.debug("Application Stored successfully with application id " + applicationId);
        }

        return applicationId;

    } catch (SQLException e) {
        try {
            if (connection != null) {
                connection.rollback();
            }
        } catch (SQLException sql) {
            throw new IdentityApplicationManagementException(
                    "Error while Creating Application", sql);
        }
        throw new IdentityApplicationManagementException("Error while Creating Application", e);
    } finally {
        IdentityApplicationManagementUtil.closeResultSet(results);
        IdentityApplicationManagementUtil.closeStatement(storeAppPrepStmt);
        IdentityApplicationManagementUtil.closeConnection(connection);
    }
}