Even after attaching jdbc provision rule still cant write into csv file through SQL LOADER connector

Hi Guys,

Even after attaching jdbc rule i am not able to provision into csv file through sql loader. below rule i used . But i am only trying to provision few given in rule but still no luck may i know what should i do to do provisoning

these are the headers of csv

racerId (1st part) emploeeNumber racerId (2nd part) employeeNrOld sn givenName foreName surnamePrefix surnameAppendix title birthName birthDate birthPlace gender preferredLanguage costCenter companyCode l subDepartment subDepartmentLong department departmentLong homePostalCode homeCity homeStreet homeAddressAdd homeCountry homeCountryCode snReal givenNameReal lReal homeCityReal homeStreetReal homeAddressAdd titleNational retireDate retireReason hireDate employeeType employeeState accountingArea personnelArea personnelSubArea personnelStructKey telephoneNumber facsimileTelephoneNumber roomNumber EmployeeTypeInternal Member Flag HireReason formerContractEmployeeNumber formerContractCompanyCode formerContractEmail ReactivationDate partnerDUNSnumber LastValidationDate mgmtLevel VPNInternal mobile CompanyVehicleGroup GID
import sailpoint.object.*;
import java.sql.*;
import java.util.*;

Map result = new HashMap();

try {
    if (plan != null && connection != null) {
        List accountRequests = plan.getAccountRequests();

        if (accountRequests != null && accountRequests.size() > 0) {
            for (int i = 0; i < accountRequests.size(); i++) {
                Object acctReqObj = accountRequests.get(i);

                String operation = acctReqObj.getOperation().toString();

                if ("Create".equals(operation)) {

                    String emploeeNumber = (String) acctReqObj.getAttributeValue("emploeeNumber");
                    String givenName = (String) acctReqObj.getAttributeValue("givenName");
                    String sn = (String) acctReqObj.getAttributeValue("sn");
                    String mgmtLevel = (String) acctReqObj.getAttributeValue("mgmtLevel");
                    String department = (String) acctReqObj.getAttributeValue("department");

                    log.debug("Creating account: " + emploeeNumber);

                    String sql = "INSERT INTO vcd (emploeeNumber, givenName, sn, mgmtLevel, department) VALUES (?, ?, ?, ?, ?)";

                    PreparedStatement stmt = connection.prepareStatement(sql);
                    stmt.setString(1, emploeeNumber);
                    stmt.setString(2, givenName);
                    stmt.setString(3, sn);
                    stmt.setString(4, mgmtLevel);
                    stmt.setString(5, department);

                    int rowsAffected = stmt.executeUpdate();
                    log.debug("Rows affected: " + rowsAffected);

                    String packSQL = "pack table vcd";
                    Statement packStmt = connection.createStatement();
                    packStmt.execute(packSQL);
                    packStmt.close();

                    stmt.close();

                    log.info("Account created successfully: " + emploeeNumber);

                    result.put("result", "success");
                    result.put("accountId", emploeeNumber);

                } else if ("Delete".equals(operation)) {

                    log.info("Delete operation received");
                    result.put("result", "Delete not supported");

                } else {

                    log.debug("Unsupported operation: " + operation);
                    result.put("result", "Operation not supported");
                }
            }
        }
    }

} catch (Exception e) {

    log.error("Failed to create account: " + e.getMessage(), e);
    result.put("error", "Failed to create account: " + e.getMessage());
    result.put("result", "failed");
}

return result;

Hi @Rakesh_Singh_1234

As mentionned by Sailpoint documentation Supported Features

For some features : Provision accounts, Password Management, … you should contact first Sailpoint to activate those feaures in your tenant.

@Rakesh_Singh_1234 Your rule need some changes. Please refer the below article and correct your script.

https://community.sailpoint.com/t5/Identity-Security-Cloud-Wiki/IdentityNow-Rule-Guide-JDBC-Provision-Rule/ta-p/77339

may i know what is wrong with my rule?

@Rakesh_Singh_1234 try with this code.

import sailpoint.object.*;
import java.sql.*;
import java.util.*;

// Initialize ProvisioningResult object instead of a Map
ProvisioningResult result = new ProvisioningResult();


public String getAttributeStringValue(AccountRequest acctReq, String attrName) {
    AttributeRequest attrReq = acctReq.getAttributeRequest(attrName);
    if (attrReq != null && attrReq.getValue() != null) {
        return attrReq.getValue().toString();
    }
    return null;
}

try {
    if (plan != null && connection != null) {
        List<AccountRequest> accountRequests = plan.getAccountRequests();

        if (accountRequests != null && !accountRequests.isEmpty()) {
            for (AccountRequest acctReq : accountRequests) {
                AccountRequest.Operation operation = acctReq.getOperation();

                if (AccountRequest.Operation.Create.equals(operation)) {
                    // FIX: AccountRequest does not have getAttributeValue(). 
                    // You must get the AttributeRequest first, check for null, and then get its value.
                    String emploeeNumber = getAttributeStringValue(acctReq, "emploeeNumber");
                    String givenName     = getAttributeStringValue(acctReq, "givenName");
                    String sn            = getAttributeStringValue(acctReq, "sn");
                    String mgmtLevel     = getAttributeStringValue(acctReq, "mgmtLevel");
                    String department    = getAttributeStringValue(acctReq, "department");

                    log.debug("Creating account: " + emploeeNumber);

                    String sql = "INSERT INTO vcd (emploeeNumber, givenName, sn, mgmtLevel, department) VALUES (?, ?, ?, ?, ?)";

                    PreparedStatement stmt = null;
                    Statement packStmt = null;

                    try {
                        stmt = connection.prepareStatement(sql);
                        stmt.setString(1, emploeeNumber);
                        stmt.setString(2, givenName);
                        stmt.setString(3, sn);
                        stmt.setString(4, mgmtLevel);
                        stmt.setString(5, department);

                        int rowsAffected = stmt.executeUpdate();
                        log.debug("Rows affected: " + rowsAffected);

                        String packSQL = "pack table vcd";
                        packStmt = connection.createStatement();
                        packStmt.execute(packSQL);

                        log.info("Account created successfully: " + emploeeNumber);

                        // Set result to COMMITTED
                        result.setStatus(ProvisioningResult.STATUS_COMMITTED);

                    } finally {
                        if (packStmt != null) packStmt.close();
                        if (stmt != null) extern stmt.close();
                    }

                } else if (AccountRequest.Operation.Delete.equals(operation)) {
                    log.info("Delete operation received but not supported");
                    
                    result.setStatus(ProvisioningResult.STATUS_FAILED);
                    result.addWarning("Delete operation is currently not supported.");
                    
                } else {
                    log.debug("Unsupported operation: " + operation);
                    
                    result.setStatus(ProvisioningResult.STATUS_FAILED);
                    result.addWarning("Unsupported operation: " + operation);
                }
            }
        }
    }
} catch (Exception e) {
    log.error("Failed to process account provisioning: " + e.getMessage(), e);
    
    // Set the result status to FAILED and attach the error details
    result.setStatus(ProvisioningResult.STATUS_FAILED);
    result.addError(e.getMessage());
}

return result;

Check the ccg.log or connector logs and add a few log.info() statements at the beginning of the rule to confirm execution.

For us it was working without connecting to Sailpoint support

how? are u able to write into csv files ?? waht have u done can you please guide?

@Rakesh_Singh_1234 Can you try bellow rule please. Check ccg.log on the VA to confirm the rule is triggered.

import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.SQLException;
import java.util.List;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.object.ProvisioningResult;

public String getAttributeStringValue(AccountRequest acctReq, String attrName) {
    if (acctReq != null) {
        AttributeRequest attrReq = acctReq.getAttributeRequest(attrName);
        if (attrReq != null && attrReq.getValue() != null) {
            return attrReq.getValue().toString();
        }
    }
    return null;
}

ProvisioningResult result = new ProvisioningResult();

try {
    if (plan != null && connection != null) {

        List accountRequests = plan.getAccountRequests();

        log.info("SQL Loader CSV provisioning rule started. Account request count: "
            + (accountRequests == null ? 0 : accountRequests.size()));

        if (accountRequests != null && !accountRequests.isEmpty()) {

            for (Object obj : accountRequests) {

                AccountRequest acctReq = (AccountRequest) obj;
                AccountRequest.Operation operation = acctReq.getOperation();

                log.debug("Processing SQL Loader account request. Operation received: " + operation);

                if (AccountRequest.Operation.Create.equals(operation)) {

                    String emploeeNumber = getAttributeStringValue(acctReq, "emploeeNumber");

                    if (emploeeNumber == null || emploeeNumber.trim().length() == 0) {
                        emploeeNumber = acctReq.getNativeIdentity();
                        log.debug("emploeeNumber was not found in AttributeRequest. Using nativeIdentity instead.");
                    }

                    String givenName  = getAttributeStringValue(acctReq, "givenName");
                    String sn         = getAttributeStringValue(acctReq, "sn");
                    String mgmtLevel  = getAttributeStringValue(acctReq, "mgmtLevel");
                    String department = getAttributeStringValue(acctReq, "department");

                    log.info("Preparing CSV insert for SQL Loader table vcd. Account key: " + emploeeNumber);

                    PreparedStatement stmt = null;
                    Statement packStmt = null;

                    try {
                        String sql = "insert into vcd (emploeeNumber, givenName, sn, mgmtLevel, department) values (?, ?, ?, ?, ?)";

                        stmt = connection.prepareStatement(sql);
                        stmt.setString(1, emploeeNumber);
                        stmt.setString(2, givenName);
                        stmt.setString(3, sn);
                        stmt.setString(4, mgmtLevel);
                        stmt.setString(5, department);

                        int rowsAffected = stmt.executeUpdate();

                        log.info("SQL Loader CSV insert completed for table vcd. Rows affected: " + rowsAffected);

                        packStmt = connection.createStatement();
                        packStmt.execute("pack table vcd");

                        log.info("SQL Loader pack table command completed for vcd.");

                        result.setStatus(ProvisioningResult.STATUS_COMMITTED);

                        log.info("SQL Loader CSV provisioning completed successfully for account key: " + emploeeNumber);

                    } finally {

                        if (packStmt != null) {
                            try {
                                packStmt.close();
                            } catch (SQLException e) {
                                log.error("Unable to close SQL Loader pack statement cleanly: " + e.getMessage(), e);
                            }
                        }

                        if (stmt != null) {
                            try {
                                stmt.close();
                            } catch (SQLException e) {
                                log.error("Unable to close SQL Loader insert statement cleanly: " + e.getMessage(), e);
                            }
                        }
                    }

                } else {
                    log.info("SQL Loader provisioning rule received an unsupported operation: " + operation);

                    result.setStatus(ProvisioningResult.STATUS_FAILED);
                    result.addError("Unsupported SQL Loader provisioning operation received: " + operation);
                }
            }

        } else {
            log.info("SQL Loader provisioning rule completed with no account requests to process.");
            result.setStatus(ProvisioningResult.STATUS_COMMITTED);
        }

    } else {
        log.error("SQL Loader provisioning rule did not run because plan or connection was null.");

        result.setStatus(ProvisioningResult.STATUS_FAILED);
        result.addError("Provisioning plan or JDBC connection was null.");
    }

} catch (Exception e) {

    log.error("SQL Loader JDBC provisioning failed while writing to CSV table vcd: " + e.getMessage(), e);

    result.setStatus(ProvisioningResult.STATUS_FAILED);
    result.addError(e.getMessage());
}

return result;