IdentityNow - ConnectorRules - JDBCProvision

Hi,
why do I get this error when I trigger the JDBCProvision rule on a SQL Loader source? (I checked the permission on csv files for accounts and entitlements and they seem to be ok)

Error occurred:
java.sql.SQLException: Failed to upgrade the access mode of ExternalIdentities table from “r” to “rw”

Thanks in advance for your support

Code

	import java.sql.Connection;
	import java.sql.DriverManager;
	import java.sql.PreparedStatement;
	import java.sql.SQLException;
	import java.sql.Types;
	import java.util.List;
	import sailpoint.api.SailPointContext;
	import sailpoint.connector.JDBCConnector;
	import sailpoint.object.Application;
	import sailpoint.object.ProvisioningPlan;
	import sailpoint.object.ProvisioningPlan.AccountRequest;
	import sailpoint.object.ProvisioningPlan.AttributeRequest;
	import sailpoint.object.ProvisioningPlan.PermissionRequest;
	import sailpoint.object.ProvisioningResult;
	import sailpoint.object.Schema;
	
	
	public String getAttributeRequestValue(AccountRequest acctReq, String attribute) {
	
	  if (acctReq != null) {
	    AttributeRequest attrReq = acctReq.getAttributeRequest(attribute);
	    if (attrReq != null) {
	      return attrReq.getValue();
	    }
	  }
	  return null;
	}
	
	ProvisioningResult result = new ProvisioningResult();
	PreparedStatement statement;
	String csvExternalEmployeeHeader = "identificationNumber,employeeID,name,firstName,lastName,email,manager,company,company,countryCode,country,department,jobTitle,city,status";
	if (plan != null) {
	
	  List accounts = plan.getAccountRequests();
	  if ((accounts != null) && (accounts.size() > 0)) {
	    for (AccountRequest account: accounts) {
	      try {
	        if (AccountRequest.Operation.Create.equals(account.getOperation())) {
            statement = connection.prepareStatement("SELECT MAX(employeeID) FROM ExternalIdentities");
            resultSet = statement.executeQuery();
            int maxEmployeeID = 0;
            if (resultSet.next()) {
                maxEmployeeID = resultSet.getInt(1);
             }
             int newEmployeeID = maxEmployeeID + 1;
             String newIdentificationNumber = "RE" + newEmployeeID;
			

	          statement = connection.prepareStatement("insert into ExternalIdentities (identificationNumber,employeeID,name,firstName,lastName,email,manager,company,company,countryCode,country,department,jobTitle,city,status) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
			  statement.setString(1, getAttributeRequestValue(account, newIdentificationNumber));
			  statement.setInt(2, newEmployeeID);
			  statement.setString(3, getAttributeRequestValue(account, "name"));
			  statement.setString(4, getAttributeRequestValue(account, "firstName"));
			  statement.setString(5, getAttributeRequestValue(account, "lastName"));
			  statement.setString(6, getAttributeRequestValue(account, "email"));
			  statement.setString(7, getAttributeRequestValue(account, "manager"));
			  statement.setString(8, getAttributeRequestValue(account, "company"));
			  statement.setString(9, getAttributeRequestValue(account, "company"));
			  statement.setString(10, getAttributeRequestValue(account, "countryCode"));
			  statement.setString(11, getAttributeRequestValue(account, "country"));
			  statement.setString(12, getAttributeRequestValue(account, "department"));
			  statement.setString(13, getAttributeRequestValue(account, "jobTitle"));
			  statement.setString(14, getAttributeRequestValue(account, "city"));
			  statement.setString(15, getAttributeRequestValue(account, "status"));
	          statement.executeUpdate();
	
	          result.setStatus(ProvisioningResult.STATUS_COMMITTED);
	
	        } else if (AccountRequest.Operation.Modify.equals(account.getOperation())) {
	
	          // Modify account request -- change role
	
	          PreparedStatement statement = connection.prepareStatement("update ExternalIdentities set role = ? where name = ?");
	          statement.setString(2, (String) account.getNativeIdentity());
	          if (account != null) {
	            AttributeRequest attrReq = account.getAttributeRequest("role");
	            if (attrReq != null && ProvisioningPlan.Operation.Remove.equals(attrReq.getOperation())) {
	              statement.setNull(1, Types.NULL);
	              statement.executeUpdate();
	            } else {
	              statement.setString(1, attrReq.getValue());
	              statement.executeUpdate();
	            }
	          }
	          result.setStatus(ProvisioningResult.STATUS_COMMITTED);
	
	        } else if (AccountRequest.Operation.Delete.equals(account.getOperation())) {
	
	          PreparedStatement statement = connection.prepareStatement((String) application.getAttributeValue("account.deleteSQL"));
	
	          statement.setString(1, (String) account.getNativeIdentity());
	          statement.executeUpdate();
	
	          result.setStatus(ProvisioningResult.STATUS_COMMITTED);
	
	        } else if (AccountRequest.Operation.Disable.equals(account.getOperation())) {
	
	          // Disable, not supported.
	
	        } else if (AccountRequest.Operation.Enable.equals(account.getOperation())) {
	
	          // Enable, not supported.
	
	        } else if (AccountRequest.Operation.Lock.equals(account.getOperation())) {
	
	          // Lock, not supported.
	
	        } else if (AccountRequest.Operation.Unlock.equals(account.getOperation())) {
	
	          // Unlock, not supported.
	
	        } else {
	          // Unknown operation!
	        }
	      }
	      catch(SQLException e) {
	        result.setStatus(ProvisioningResult.STATUS_FAILED);
	        result.addError(e);
	      }
	      finally {
	        if (statement != null) {
	          statement.close();
	        }
	      }
	    }
	  }
	}
	
	return result;

Your code looks fine to me. This error typically occurs when there is an issue with changing the access mode of a database table from “read-only” to “read-write”.

Can you ensure that the file you have on the server has below:

  • Right-click the file > Properties > Security > Edit.
  • Ensure the user account under which your connection is established has: Read & Execute, Write, Modify
  • Also ensure to apply the same permissions to the folder containing the csv file.
1 Like

Hi @psalat8887100

I think it might be the permission issue.
Please check that the database user has the necessary permissions to modify the ExternalIdentities table.

Thank you

1 Like

Hi,
here the configuration, the file ExternalIdentities.csv resides on virtual appliance machine

the permissions seems to be right. Could the problem be the fact of having uploaded the file to the virtual appliance machine?

Thanks,
Paolo

@psalat8887100, The file must not reside on the virtual appliance for SQL loader. VA is just a gateway for SailPoint to communicate with the direct connector based applications in your network. It comes as a pre-defined image from SailPoint and has restrictions on inbound connections. It would not work in your case and it is behaving as expected.

Try to spin up a new linux instance/windows host and then replicate the steps as per documentation including the service account and permissions on the folder containing your CSV. It should work that way.

Keep us posted on how it goes.

Thanks,
Arshad.

1 Like

Hi,
thanks to your suggestion, the file now resides on a Windows Server machine elected as OpenSSH server reachable from the virtual appliances of our cluster in sftp and everything works correctly.
Thank you very much!
You were decisive :slight_smile:

1 Like

That’s great news! Glad it worked. :grin:

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.