Provisioning Plan Request Not Including Attributes From Create Account

Hello,

I am debugging a new connector that I’m developing for userID generation. It is going to a SQL Server database to generate the userid based on first name, last name, and a sequence.

It is passing one of the attribute values; but the remaining are passed as null – even though there are attribute values. The attribute names match the Identity Profile mapping attribute names.

import java.sql.Types;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.Date;

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

import sailpoint.tools.Util;

// Get a string value from an attribute request object
public String getAttributeRequestValue(AccountRequest acctReq, String attribute) {
    String val = null;
    if ( acctReq != null ) {
      AttributeRequest attrReq = acctReq.getAttributeRequest(attribute);
      if ( attrReq != null && attrReq.getValue() instanceof String ) {
        val = attrReq.getValue();
      }
    }
    log.error(attribute + \" = \" + val);
    return val;
  }

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

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

// 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());
        log.error(\"getArguments: \" + account.getArguments());
        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, getAttributeRequestValue(account, \"empID\"));
            log.error(\"setting value for index 2\");
            cStatement.setString(2, getAttributeRequestValue(account, \"preferredgivenname\"));
            log.error(\"setting value for index 3\");
            cStatement.setString(3, getAttributeRequestValue(account, \"lastname\"));
            log.error(\"setting value for index 4\");
            cStatement.setString(4, getAttributeRequestValue(account, \"employmentStatusCode\"));
            log.error(\"setting value for index 5\");
            cStatement.setString(5, getAttributeRequestValue(account, \"startDate\"));
            log.error(\"setting value for index 6\");
            cStatement.setString(6, getAttributeRequestValue(account, \"endDate\"));
            log.error(\"setting value for index 7\");
            cStatement.setString(7, (String) plan.getNativeIdentity());
            log.error(\"setting value for index 8\");
            cStatement.setString(8, defaultRole);
            log.error(\"LoadUniqSAM payload: \" + cStatement.toString());

            cStatement.executeUpdate();

            // 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, getAttributeRequestValue(account, \"empID\"));
            log.error(\"setting value for index 2\");
            cStatement.setString(2, getAttributeRequestValue(account, \"preferredgivenname\"));
            log.error(\"setting value for index 3\");
            cStatement.setString(3, getAttributeRequestValue(account, \"LastName\"));
            log.error(\"setting value for index 4\");
            cStatement.setString(4, getAttributeRequestValue(account, \"employmentStatusCode\"));
            log.error(\"setting value for index 5\");
            cStatement.setString(5, getAttributeRequestValue(account, \"startDate\"));
            log.error(\"setting value for index 6\");
            cStatement.setString(6, getAttributeRequestValue(account, \"endDate\"));
            log.error(\"setting value for index 7\");
            cStatement.setString(7, (String) plan.getNativeIdentity());
            log.error(\"setting value for index 8\");
            cStatement.setString(8, defaultRole);
            log.error(\"LoadUniqSAM payload: \" + cStatement.toString());

            cStatement.executeUpdate();

            // 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(\"IdentityView2 UserID Provisioning SQL Error: \" + e.getMessage());
        } finally {
          if(cStatement != null) {
            cStatement.close();
          }
        }
      }
    }
}

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

return result;

@moss_snake_01 Please use a loop to go over all the attribute requests that you have in the provisioning plan.

You also need to get the name of the attribute validate if you want to get value of it or not for e.g. firstName

if (null != attributeRequest.getName() && "firstName".equalsIgnoreCase(attributeRequest.getName()))

if yes, then get the value of this attribute

Object attribute = attributeRequest.getValue();								
										
if (attribute instanceof String)
{
	String attributeValue = (String) attribute;
	return attributeValue;
}

Likewise you have to check for all the attributes that are required for you create account statement.

Hope this helps!

Great suggestions, @shekhardas1825! Let me work on them and I’ll report back.

1 Like

I decided to try and load a hashMap with the attributes, and it seems to work, but now getting a new error from the SQL Server DB and the sproc its calling to with:

[“com.microsoft.sqlserver.jdbc.SQLServerException: A result set was generated for update.”,“com.microsoft.sqlserver.jdbc.SQLServerException: A result set was generated for update.”]

Here is the latest code:

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;

// Get a string value from an attribute request object
// public String getAttributeRequestValue(AccountRequest acctReq, String attribute) {
//     String val = null;
//     if ( acctReq != null ) {
//       AttributeRequest attrReq = acctReq.getAttributeRequest(attribute);
//       if ( attrReq != null && attrReq.getValue() instanceof String ) {
//         val = attrReq.getValue();
//       }
//     }
//     log.error(attribute + \" = \" + val);
//     return val;
//   }

// Start of IdentityView JDBC UserID Provisioning rule
log.error(\"Enter IdentityViews2 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, attributeMap.get(\"Roles\"));
            log.error(\"map attr-Roles: \" + attributeMap.get(\"Roles\"));
            log.error(\"LoadUniqSAM payload: \" + cStatement.toString());

            cStatement.executeUpdate();

            // 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, attributeMap.get(\"Roles\"));
            log.error(\"map attr-Roles: \" + attributeMap.get(\"Roles\"));
            log.error(\"LoadUniqSAM payload: \" + cStatement.toString());

            cStatement.executeUpdate();

            // 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(\"IdentityView2 UserID Provisioning SQL Error: \" + e.getMessage());
        } finally {
          if(cStatement != null) {
            cStatement.close();
          }
        }
      }
    }
}

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

return result;

Ah, ha! I was using executeUpdate, rather than executeQuery. It’s now working as expected. I’ll working on some further validation / error raising where needed. Appreciate it!

1 Like

@moss_snake_01 Good to hear it is working.