Creating Dynamically Generated Tasks for Account Aggregation

Having difficulties managing the aggregation of every application in IIQ?

Many organizations have numerous applications in SailPoint that will need to be aggregated, but how can you manage aggregations for hundreds of applications? When new applications are on-boarded, how can you effectively add them to the aggregation tasks? Can you prevent an application aggregation failure from stopping the rest of the applications from aggregating?

Below you will find a rule that will help you manage aggregations by dynamically populating the applications list in the aggregation task and creating multiple tasks to perform the aggregation.

Steps

  1. Import the rule into SailPoint IIQ
  2. Go to Setup -> Tasks -> New Task -> create a new Run Rule task
  3. Assign Rule to Task -> Save and Execute

Rule

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule created="" id="" language="beanshell" modified="" name="Dynamic Linux Account Aggregation">
  <Source>
import sailpoint.object.Application;
import sailpoint.object.Attributes;
import sailpoint.object.Filter;
import sailpoint.connector.Connector;
import sailpoint.object.Identity;
import sailpoint.object.QueryOptions;
import sailpoint.object.TaskDefinition;
import sailpoint.object.TaskItemDefinition;
import sailpoint.object.tools.Util;
import sailpoint.api.TaskManager;
import java.util.*;
//***********************************************************************
//Set Task enablePartitioning flag to use multiple task servers
boolean setPartition = true;
//Set application type.
String appType = "Linux - Direct";
//Set partition size for number of applications per aggregation task
int partitionSize = 500;
//Run Test Connection
boolean testConnect = true;
//***********************************************************************

//Query options for applications
QueryOptions query = new QueryOptions();
Filter filter = Filter.ignoreCase(Filter.eq("type", appType));
query.addFilter(filter);

List apps = context.getObjects(Application.class, query);

if (testConnect) {
  Iterator It = context.getObjects(Application.class, query).iterator();
  while (It.hasNext()) {
    Application app = It.next();
  	try {
			Connector connector = sailpoint.connector.ConnectorFactory.getConnector(app, null);
			connector.testConfiguration();
		}
		catch (Exception e) {
			apps.remove(app);
		}
  }
}

//Set partition to split applications list
List partitions = new ArrayList();

for (int i=0; i @lt apps.size(); i += partitionSize) {
	partitions.add(apps.subList(i, Math.min(i + partitionSize, apps.size())));
}

int n=0;

for (List list : partitions) {
	
	n++;
	
	// Build an Account Aggregation task for application type.  
	String allTaskName = "TVA Dynamic " + appType + " Account Aggregation" + " Partition " + Integer.toString(n);  
	TaskDefinition td = context.getObjectByName(TaskDefinition.class, allTaskName);    

	boolean newTd = false;
	if (td == null) {  
		// New TaskDefinition.
		newTd = true;
		td = new TaskDefinition();   
	}
	td.setName(allTaskName);      
	td.setDescription("Dynamic Account Aggregation task for application type.");      
	td.setType(TaskItemDefinition.Type.AccountAggregation);      
	td.setResultAction(TaskDefinition.ResultAction.Delete);          
	td.setFormPath("/monitor/tasks/accountAggregationTask.xhtml");  

	//Reload applications list
	List appsList = new ArrayList();

	for (int i = 0; i @lt list.size(); i++) {
		Application app = list.get(i);  
		if (!appsList.contains(app.getName())) { 
			appsList.add(app.getName()); 
			appListChange = true;
		}
	}

	td.setArgument("applications", sailpoint.tools.Util.listToCsv(appsList));      
	td.setArgument("checkDeleted", "true");  
	td.setArgument("correlateOnly", "false");
	td.setOwner(context.getObjectByName(Identity.class, "spadmin"));  
	td.setParent(context.getObject(TaskDefinition.class, "Account Aggregation")); 

	//enable partitioning if flag is set to true
	if (setPartition){
		td.setArgument("enablePartitioning", "true");
		td.setArgument("logAllowedActions", "");
	}
   	if (!setPartition){
		td.setArgument("enablePartitioning", "false");
		td.setArgument("logAllowedActions", "CorrelateManual, CorrelateNewAccount, CorrelateReassign, Create, Ignore, Remove");
	}

	// Sets "Disable Optimization" flag.
	td.setArgument("noOptimizeReaggregation", "true");  
      
	// If one of the DB server aggregations should fail the task ignores, log it, and keep processing the rest.   
	td.setArgument("exitOnError", "false");          
	td.setArgument("trace", "true");  

	context.saveObject(td);  

	// Save task to IdentityIQ database.  
	if (appListChange || newTd) { 
		context.commitTransaction();
	}

	//Run Dynamic Task.
	TaskManager manager = new TaskManager(context);
	Attributes attributes = new Attributes();

	manager.run(allTaskName, attributes);
}

String tskSuccess = "Success"; 
return tskSuccess;
</Source>
</Rule>

Looking for other insights into managing SailPoint IdentityIQ? Check out some of our other recent SailPoint IIQ posts:

HOW TO CLEAN UP OLD TASK RESULTS IN SAILPOINT IIQ

HOW TO SET UP ROLE PROVISIONING POLICIES IN SAILPOINT IDENTITYIQ