Updating Existing Connector

Hi everyone,

I recently tested a new JDBC connector in our sandbox tenant, and it works as expected; however, we’d like to update the existing JDBC connector that previously had a self contained jar file with further libraries it imported.

The new connector I tested used the MS SQL 12.8 JDBC driver. I removed self contained jar and attached this when I updated the existing connector.

I replicated all the other UI based configuration to mimic the new connector’s config and updated the provisioning rule to include the new BeanShell script. This script works in the net new connector, no errors. Though when I attempt to use the same script in the existing updated connector, I get the following:

[“BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: ``import java.sql.Types; import java.sql.CallableStatement; import java.sql.Prepar . . . \u0027\u0027 : Error in method invocation: Method setString(int, java.util.ArrayList) not found in class\u0027org.apache.commons.dbcp2.DelegatingCallableStatement\u0027 : at Line: 75 : in file: inline evaluation of: ``import java.sql.Types; import java.sql.CallableStatement; import java.sql.Prepar . . . \u0027\u0027 : cStatement .setString ( 8 , attributeMap .get ( "Roles" ) ) \n BSF info: IdentityViews JDBC Provisioning searchsam at line: 0 column: columnNo”,“BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: ``import java.sql.Types; import java.sql.CallableStatement; import java.sql.Prepar . . . \u0027\u0027 : Error in method invocation: Method setString(int, java.util.ArrayList) not found in class\u0027org.apache.commons.dbcp2.DelegatingCallableStatement\u0027 : at Line: 75 : in file: inline ev… 0 column: columnNo”]

Here is the provisioning rule script:

import java.sql.Types;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.Date;
import java.util.HashMap;
import java.util.Map;

import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.object.ProvisioningResult;

import sailpoint.tools.Util;

// Start of IdentityView JDBC UserID Provisioning rule
log.error(\"Enter IdentityViews UserID Provisioning\");

ProvisioningResult result = new ProvisioningResult();
CallableStatement cStatement = null;
String defaultRole = \"RolesAllUsers\";
Map attributeMap = new HashMap();

// Check if plan is null
if ( plan instanceof ProvisioningPlan ) {
    // Get all account requests from plan
    List accounts = plan.getAccountRequests();
    // If the plan contains one or more account requests, we'll iterate through them
    if ((accounts != null) && (accounts.size() > 0)) {
      for (AccountRequest account : accounts) {
        String nativeId = (String) account.getNativeIdentity();
        log.error(\"native identity: \" + nativeId);
        log.error(\"application: \" + account.getApplicationName());
        log.error(\"operation: \" + account.getOperation());

        List attributeRequests = account.getAttributeRequests();

        if (attributeRequests != null) {
          log.error(\"Num of AttributeRequests: \" + attributeRequests.size());
          // iterate through each attribute request
          for (AttributeRequest attributeRequest : attributeRequests) {
            String attributeName = attributeRequest.getName();
            Object attributeValue = attributeRequest.getValue();
            attributeMap.put(attributeName,attributeValue);
          }
        log.error(\"map: \" + attributeMap.toString());
        }

        try {
          // CREATE procedure
          if ( AccountRequest.Operation.Create == account.getOperation()) {
            log.error(\"Entering Create Operation\");
            cStatement = connection.prepareCall(\"EXEC dbo.LoadUniqSAM ?, ?, ?, ?, ?, ?, ?, ?\");
            // Add attributes from account create profile
            log.error(\"setting value for index 1\");
            cStatement.setString(1, attributeMap.get(\"empID\"));
            log.error(\"map attr-empID: \" + attributeMap.get(\"empID\"));
            log.error(\"setting value for index 2\");
            cStatement.setString(2, attributeMap.get(\"firstname\"));
            log.error(\"map attr-firstname: \" + attributeMap.get(\"firstname\"));
            log.error(\"setting value for index 3\");
            cStatement.setString(3, attributeMap.get(\"lastname\"));
            log.error(\"map attr-lastname: \" + attributeMap.get(\"lastname\"));
            log.error(\"setting value for index 4\");
            cStatement.setString(4, attributeMap.get(\"empStatusCode\"));
            log.error(\"map attr-empStatusCode: \" + attributeMap.get(\"empStatusCode\"));
            log.error(\"setting value for index 5\");
            cStatement.setString(5, attributeMap.get(\"empLastHireDate\"));
            log.error(\"map attr-empLastHireDate: \" + attributeMap.get(\"empLastHireDate\"));
            log.error(\"setting value for index 6\");
            cStatement.setString(6, attributeMap.get(\"empEndDate\"));
            log.error(\"map attr-empEndDate: \" + attributeMap.get(\"empEndDate\"));
            log.error(\"setting value for index 7\");
            cStatement.setString(7, (String) account.getNativeIdentity());
            log.error(\"account attr-EEID: \" + account.getNativeIdentity());
            cStatement.setString(8, defaultRole);
            log.error(\"map attr-Roles: \" + defaultRole);
            log.error(\"LoadUniqSAM payload: \" + cStatement.toString());

            cStatement.executeQuery();

            // Successful Create, so mark result as COMMITTED
            log.error(\"Create Account Execution successfully completed\");
            result.setStatus(ProvisioningResult.STATUS_COMMITTED);
            log.error(\"Exiting Create Operation\");
          } else if (AccountRequest.Operation.Modify == account.getOperation()) {
            log.error(\"Entering Modify Operation\");

            cStatement = connection.prepareCall(\"EXEC dbo.LoadUniqSAM ?, ?, ?, ?, ?, ?, ?, ?\");

            // Add attributes from account modify profile
            log.error(\"setting value for index 1\");
            cStatement.setString(1, attributeMap.get(\"empID\"));
            log.error(\"map attr-empID: \" + attributeMap.get(\"empID\"));
            log.error(\"setting value for index 2\");
            cStatement.setString(2, attributeMap.get(\"firstname\"));
            log.error(\"map attr-firstname: \" + attributeMap.get(\"firstname\"));
            log.error(\"setting value for index 3\");
            cStatement.setString(3, attributeMap.get(\"lastname\"));
            log.error(\"map attr-lastname: \" + attributeMap.get(\"lastname\"));
            log.error(\"setting value for index 4\");
            cStatement.setString(4, attributeMap.get(\"empStatusCode\"));
            log.error(\"map attr-empStatusCode: \" + attributeMap.get(\"empStatusCode\"));
            log.error(\"setting value for index 5\");
            cStatement.setString(5, attributeMap.get(\"empLastHireDate\"));
            log.error(\"map attr-empLastHireDate: \" + attributeMap.get(\"empLastHireDate\"));
            log.error(\"setting value for index 6\");
            cStatement.setString(6, attributeMap.get(\"empEndDate\"));
            log.error(\"map attr-empEndDate: \" + attributeMap.get(\"empEndDate\"));
            log.error(\"setting value for index 7\");
            cStatement.setString(7, (String) account.getNativeIdentity());
            log.error(\"account attr-EEID: \" + account.getNativeIdentity());
            cStatement.setString(8, defaultRole);
            log.error(\"map attr-Roles: \" + defaultRole);
            log.error(\"LoadUniqSAM payload: \" + cStatement.toString());

            cStatement.executeQuery();

            // Successful Modify, so mark result as COMMITTED
            log.error(\"Modify Account Execution successfully completed\");
            result.setStatus(ProvisioningResult.STATUS_COMMITTED);

            log.error(\"Exiting Modify Operation\");
          }

        } catch(Exception e) {
          result.setStatus(ProvisioningResult.STATUS_FAILED);
          result.addError(e);
          log.error(\"IdentityViews UserID Provisioning SQL Error: \" + e.getMessage());
        } finally {
          if(cStatement != null) {
            cStatement.close();
          }
        }
      }
    }
}

log.error(\"Exit IdentityViews UserID Provisioning\");

return result;

I am not sure why it only complains on setString for Roles attribute after all the other setStrings have ran – you’ll notice in the code I set the errored line on Roles to a static value. This now leads to:

[“com.microsoft.sqlserver.jdbc.SQLServerException: Could not find stored procedure \u0027dbo.LoadUniqSAM\u0027.”,“com.microsoft.sqlserver.jdbc.SQLServerException: Could not find stored procedure \u0027dbo.LoadUniqSAM\u0027.”]

I suspect there is some config that I missed to remove. I’m not 100% how to check cloud rules, but I’m curious if there may be something there…any ideas? Thanks!

Hey Tim,

Two things here. I think the reason it failed the first time around was because the second parameter “attributeMap.get(“Roles”)” returns an ArrayList and the setString function is looking for a String value as a parameter. If there are multiple roles in the attributeMap, you may need to loop through them and create the appropriate string value.

With your static value test, I would think the rule would run fine. The error looks like it couldn’t find the stored procedure you have configured on one of your queries. Could you validate ‘dbo.LoadUniqSAM’ exists in your database?

Thanks,

Liam

Thanks, Liam!

Oops, good catch – I’ve updated this to pass the static role “defaultRole” we set for the new user creation in this connector.

I’m not sure why it was throwing the other could not find stored procedure, as it was there and the user had access.

It turns out the root of my problem was an identity attribute that didn’t get properly migrated in the identity mappings on a recent change for firstname. Glad you highlighted the other potential issue though too!