Performance Problem with a Quicklink Form

Which IIQ version are you inquiring about?

8.4p2

Share all details about your problem, including any error messages you may have received.

Hello Team,

I developed a custom form to show members of IT and BS roles members to role owners and System Administrators. I am creating html tables dynamically based on the selection from dropdown box. If the loggedInUser is a role owner of IT or/and BS roles, the user can see the details of only owned roles. There is no performance problem or issue in this case.

But if the loggedInUser has system administrator rights, I show all the roles in the 2 dropdown boxes and details of selected roles. In this case I am facing a performance issue since the code returns all the roles and details. When I click on quicklink it takes time to load the page. In the page when I click on arrows of dropdown boxes, it takes long time to show the roles’ names. When I select the role it takes time to create the html tables.

Could you please help or guide me to increase performance?

Related part from Form is below:


  <Section name="Business Roles with Members">
    <Field displayName="Select Business Roles to See Members" dynamic="true" multi="true" name="bsRoles" postBack="true" type="String">
      <AllowedValuesDefinition>
        <Script>
          <Source>


            import sailpoint.object.Filter;
            import sailpoint.object.QueryOptions;
            import sailpoint.object.Bundle;
            import sailpoint.object.Identity;
            import sailpoint.object.Capability;


            import sailpoint.api.IncrementalObjectIterator;

            import sailpoint.tools.Util;


            List bundleNames = new ArrayList();

            String userName= identityModel.get("identityName");
            Identity owner = context.getObjectByName(Identity.class,userName);
            QueryOptions ops=new QueryOptions();


            Identity user=context.getObject(Identity.class, userName);
            Capability capability = context.getObjectByName(Capability.class,"SystemAdministrator");
            Identity sysadmWG=context.getObject(Identity.class, "IIQ System Admin");
            if ((null != user.getCapabilities() &amp;&amp; user.getCapabilities().contains(capability)) || user.isInWorkGroup(sysadmWG) || user.getName().equals("spadmin")){
            ops.addFilter(Filter.eq("type", "rbr"));

            }else{

            ops.addFilter(Filter.and(Filter.eq("type", "rbr"),Filter.eq("owner", owner)));


            }


            IncrementalObjectIterator listBundles=new IncrementalObjectIterator(context, Bundle.class, ops);
            if(null!=listBundles){
            while(listBundles.hasNext()){

            Bundle b = listBundles.next();
            String name= b.getDisplayName();     

            bundleNames.add(name);

            }

            }

            Util.flushIterator(listBundles);

            return bundleNames;


          </Source>
        </Script>
      </AllowedValuesDefinition>
    </Field>
  </Section>
  <Section name="Role Details" type="datatable">
    <Field displayName="Selected Business Roles Details" displayType="radio" dynamic="true" hidden="true" name="bsRoleDetails" postBack="true" type="String">
      <Attributes>
        <Map>
          <entry key="contentIsEscaped" value="true"/>
        </Map>
      </Attributes>
      <Script>
        <Source>
          import sailpoint.object.Form;
          import sailpoint.object.Field;
          import java.util.List;
          import java.util.ArrayList;
          import java.util.Map;
          import sailpoint.object.Custom;
          import sailpoint.object.Attributes;

          import sailpoint.object.QueryOptions;
          import sailpoint.object.Filter;
          import sailpoint.object.Bundle;
          import sailpoint.object.Identity;
          import sailpoint.object.Capability;



          import sailpoint.api.IncrementalObjectIterator;

          import sailpoint.tools.Util;



          Identity user=context.getObject(Identity.class, identityModel.get("identityName"));
          Capability capability = context.getObjectByName(Capability.class,"SystemAdministrator");
          Identity sysadmWG=context.getObject(Identity.class, "IIQ System Admin");
          if (user.getCapabilities().contains(capability) || user.isInWorkGroup(sysadmWG) || user.getName().equals("spadmin")){


          String mainStr = """
          &lt;div style="max-width: 100%; word-break: break-word; white-space: normal;">

          &lt;table style='width:100%; border-collapse: collapse; font-family: Arial, sans-serif;'>
          &lt;thead>
          &lt;tr style='background-color: #f2f2f2;'>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Business Role Name&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Identity Count&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Role Owner&lt;/th>

          &lt;/tr>
          &lt;/thead>  &lt;tbody>
          """;


          List selectedValue = form.getField("bsRoles").getValue();
          log.error("selectedValue" + selectedValue);

          List options = new ArrayList();
          if (selectedValue != null) {

          for(String brRoleName : selectedValue){

          QueryOptions qo = new QueryOptions();
          Filter f = Filter.eq("assignedRoles.displayName", brRoleName);
          qo.addFilter(f);
          List identities = new ArrayList();
          identities = context.getObjects(Identity.class, qo);


          QueryOptions qo2 = new QueryOptions();
          Filter f2 = Filter.eq("displayName", brRoleName);
          qo2.addFilter(f2);
          IncrementalObjectIterator bundle = new IncrementalObjectIterator(context, Bundle.class, qo2);


          mainStr += """    &lt;tr>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+brRoleName+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+identities.size()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+bundle.next().getOwner().getDisplayName()+"""&lt;/td>

          &lt;/tr>
          """;




          Util.flushIterator(bundle);

          }


          mainStr += """  &lt;/tbody>
          &lt;/table>
          &lt;/div> """; 
          form.getField("bsRoleDetails").setHidden(false);
          log.error("mainStr" + mainStr);

          return mainStr;
          }
          log.error("mainStr" + mainStr);

          return mainStr;
          }
        </Source>
      </Script>
    </Field>
  </Section>
  <Section name="Selected Business Role Members Details" type="datatable">
    <Field displayName="Members Details" displayType="radio" dynamic="true" hidden="true" name="bsMembers" postBack="true" type="String">
      <Attributes>
        <Map>
          <entry key="contentIsEscaped" value="true"/>
        </Map>
      </Attributes>
      <Script>
        <Source>
          import sailpoint.object.Form;
          import sailpoint.object.Field;
          import java.util.List;
          import java.util.ArrayList;
          import java.util.Map;
          import sailpoint.object.Custom;
          import sailpoint.object.Attributes;

          import sailpoint.object.QueryOptions;
          import sailpoint.object.Filter;
          import sailpoint.object.Bundle;
          import sailpoint.object.Identity;


          import sailpoint.api.IncrementalObjectIterator;

          import sailpoint.tools.Util;



          String mainStr = """
          &lt;div style="max-width: 100%; word-break: break-word; white-space: normal;">

          &lt;table style='width:100%; border-collapse: collapse; font-family: Arial, sans-serif;'>
          &lt;thead>
          &lt;tr style='background-color: #f2f2f2;'>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>CorpID&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Display Name&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Email&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Manager&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Business Role Name&lt;/th>

          &lt;/tr>
          &lt;/thead>  &lt;tbody>
          """;

          String originalStr = mainStr;

          List selectedValue = form.getField("bsRoles").getValue();
          log.error("selectedValue" + selectedValue);

          List options = new ArrayList();
          if (selectedValue != null) {

          for(String brRoleName : selectedValue){

          QueryOptions qo = new QueryOptions();
          Filter f = Filter.eq("assignedRoles.displayName", brRoleName);
          qo.addFilter(f);
          IncrementalObjectIterator identities = new IncrementalObjectIterator(context, Identity.class, qo);

          if(null != identities){

          while(identities.hasNext()){
          Identity id = identities.next();
          Identity manager = id.getManager();
          mainStr += """    &lt;tr>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+id.getName()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+id.getDisplayName()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+id.getEmail()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+manager.getDisplayName()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+brRoleName+"""&lt;/td>

          &lt;/tr>
          """;

          }
          }

          Util.flushIterator(identities);

          }

          if(!originalStr.equals(mainStr)){

          form.getField("bsMembers").setHidden(false);

          }
          mainStr += """  &lt;/tbody>
          &lt;/table>
          &lt;/div> """; 


          log.error("mainStr" + mainStr);

          return mainStr;
          }
          log.error("mainStr" + mainStr);

          return mainStr;
        </Source>
      </Script>
    </Field>
  </Section>

  <Section name="IT Roles with Members">
    <Field displayName="Select IT Roles to See Members" dynamic="true" multi="true" name="itRolesNames" postBack="true" type="String">
      <AllowedValuesDefinition>
        <Script>
          <Source>


            import sailpoint.object.Filter;
            import sailpoint.object.QueryOptions;
            import sailpoint.object.Bundle;
            import sailpoint.object.Identity;
            import sailpoint.object.Capability;


            import sailpoint.api.IncrementalObjectIterator;

            import sailpoint.tools.Util;



            List bundleNames = new ArrayList();

            String userName= identityModel.get("identityName");
            Identity owner = context.getObjectByName(Identity.class,userName);
            QueryOptions ops=new QueryOptions();

            Identity user=context.getObject(Identity.class, userName);
            Capability capability = context.getObjectByName(Capability.class,"SystemAdministrator");
            Identity sysadmWG=context.getObject(Identity.class, "IIQ System Admin");
            if ((null != user.getCapabilities() &amp;&amp; user.getCapabilities().contains(capability)) || user.isInWorkGroup(sysadmWG) || user.getName().equals("spadmin")){
            ops.addFilter(Filter.eq("type", "it"));

            }else{

            ops.addFilter(Filter.and(Filter.eq("type", "it"),Filter.eq("owner", owner)));


            }


            IncrementalObjectIterator listBundles=new IncrementalObjectIterator(context,Bundle.class, ops );
            if(null!=listBundles){
            while(listBundles.hasNext()){
            Bundle b = listBundles.next();
            String name= b.getDisplayName();     

            bundleNames.add(name);

            }

            }
            Util.flushIterator(listBundles);

            return bundleNames;


          </Source>
        </Script>
      </AllowedValuesDefinition>
    </Field>
  </Section>
  <Section name="IT Role Details" type="datatable">
    <Field displayName="Selected IT Roles Details" displayType="radio" dynamic="true" hidden="true" name="itRoleDetails" postBack="true" type="String">
      <Attributes>
        <Map>
          <entry key="contentIsEscaped" value="true"/>
        </Map>
      </Attributes>
      <Script>
        <Source>
          import sailpoint.object.Form;
          import sailpoint.object.Field;
          import java.util.List;
          import java.util.ArrayList;
          import java.util.Map;
          import sailpoint.object.Custom;
          import sailpoint.object.Attributes;

          import sailpoint.object.QueryOptions;
          import sailpoint.object.Filter;
          import sailpoint.object.Bundle;
          import sailpoint.object.Identity;
          import sailpoint.object.Capability;


          import sailpoint.api.IncrementalObjectIterator;

          import sailpoint.tools.Util;



          Identity user=context.getObject(Identity.class, identityModel.get("identityName"));
          Capability capability = context.getObjectByName(Capability.class,"SystemAdministrator");
          Identity sysadmWG=context.getObject(Identity.class, "IIQ System Admin");
          if ((null != user.getCapabilities() &amp;&amp; user.getCapabilities().contains(capability)) || user.isInWorkGroup(sysadmWG) || user.getName().equals("spadmin")){
          String mainStr = """
          &lt;div style="max-width: 100%; word-break: break-word; white-space: normal;">

          &lt;table style='width:100%; border-collapse: collapse; font-family: Arial, sans-serif;'>
          &lt;thead>
          &lt;tr style='background-color: #f2f2f2;'>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>IT Role Name&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Identity Count&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Role Owner&lt;/th>

          &lt;/tr>
          &lt;/thead>  &lt;tbody>
          """;


          List selectedValue = form.getField("itRolesNames").getValue();
          log.error("selectedValue" + selectedValue);

          List options = new ArrayList();
          if (selectedValue != null) {

          for(String itRoleName : selectedValue){



          QueryOptions qo2 = new QueryOptions();
          Filter f2 = Filter.eq("displayName",itRoleName);
          qo2.addFilter(f2);
          IncrementalObjectIterator bundles = new IncrementalObjectIterator(context,Bundle.class,qo2);
          if(null != bundles){

          while(bundles.hasNext()){

          Bundle bundle = bundles.next();


          QueryOptions qo = new QueryOptions();
          Filter f = Filter.eq("bundles.name", bundle.getName());
          qo.addFilter(f);
          List identities = new ArrayList();
          identities = context.getObjects(Identity.class, qo);


          mainStr += """    &lt;tr>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+itRoleName+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+identities.size()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+bundle.getOwner().getDisplayName()+"""&lt;/td>

          &lt;/tr>
          """;


          }
          }


          Util.flushIterator(bundles);

          }


          mainStr += """  &lt;/tbody>
          &lt;/table>
          &lt;/div> """; 
          form.getField("itRoleDetails").setHidden(false);
          log.error("mainStr" + mainStr);

          return mainStr;
          }
          log.error("mainStr" + mainStr);

          return mainStr;
          }
        </Source>
      </Script>
    </Field>
  </Section>
  <Section name="Members Details" type="datatable">
    <Field displayName="Selected Roles Members Details" displayType="radio" dynamic="true" hidden="true" name="itMembers" postBack="true" type="String">
      <Attributes>
        <Map>
          <entry key="contentIsEscaped" value="true"/>
        </Map>
      </Attributes>
      <Script>
        <Source>
          import sailpoint.object.Form;
          import sailpoint.object.Field;
          import java.util.List;
          import java.util.ArrayList;
          import java.util.Map;
          import sailpoint.object.Custom;
          import sailpoint.object.Attributes;

          import sailpoint.object.QueryOptions;
          import sailpoint.object.Filter;
          import sailpoint.object.Bundle;
          import sailpoint.object.Identity;

          import sailpoint.api.IncrementalObjectIterator;

          import sailpoint.tools.Util;



          String mainStr = """

          &lt;div style="max-width: 100%; word-break: break-word; white-space: normal;">

          &lt;table id='myTable' style='width:100%; max-width: 100%; border-collapse: collapse; font-family: Arial, sans-serif; '>
          &lt;thead>
          &lt;tr style='background-color: #f2f2f2;'>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>CorpID&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Display Name&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Email&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>Manager&lt;/th>
          &lt;th style='border: 1px solid #ddd; padding: 8px;'>IT Role Name&lt;/th>

          &lt;/tr>
          &lt;/thead>  &lt;tbody>
          """;


          String originalStr = mainStr;

          List selectedValue = form.getField("itRolesNames").getValue();
          log.error("selectedValue" + selectedValue);

          List options = new ArrayList();
          if (selectedValue != null) {

          for(String itRoleName : selectedValue){

          QueryOptions qo2 = new QueryOptions();
          Filter f2 = Filter.eq("displayName",itRoleName);
          qo2.addFilter(f2);
          IncrementalObjectIterator bundles = new IncrementalObjectIterator(context,Bundle.class,qo2);
          if(null != bundles){

          while(bundles.hasNext()){

          Bundle bundle = bundles.next();

          QueryOptions qo = new QueryOptions();
          Filter f = Filter.eq("bundles.name", bundle.getName());
          qo.addFilter(f);
          IncrementalObjectIterator identities = new IncrementalObjectIterator(context, Identity.class, qo);

          if(null != identities){

          while(identities.hasNext()){

          Identity id = identities.next();
          Identity manager = id.getManager();
          String managerDisplayName = "";

          if(null != manager){
          managerDisplayName = manager.getDisplayName();
          }

          mainStr += """    &lt;tr>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+id.getName()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+id.getDisplayName()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+id.getEmail()+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+managerDisplayName+"""&lt;/td>
          &lt;td style='border: 1px solid #ddd; padding: 8px;'>"""+itRoleName+"""&lt;/td>


          &lt;/tr>
          """;

          }


          }
          Util.flushIterator(identities);


          }



          }
          Util.flushIterator(bundles);


          }

          if(!originalStr.equals(mainStr)){

          form.getField("itMembers").setHidden(false);

          }

          mainStr += """  &lt;/tbody>
          &lt;/table>

          &lt;/div>



          """; 



          log.error("mainStr" + mainStr);

          return mainStr;
          }
          log.error("mainStr" + mainStr);

          return mainStr;
        </Source>
      </Script>
    </Field>
  </Section>


Hi @burakhalitoglu ,

Can you try using context.search() instead of IncrementalObjectIterator , as search operation increases the performance.

yes try doing context.search , link to examples :

Try to use the SQL Queries to load the data faster. Check the below for your reference.

<AllowedValuesDefinition>
    <Script>
        <Source>
			import sailpoint.tools.Util;
			import sailpoint.tools.GeneralException;
			import org.apache.log4j.Logger;
			
			Logger logger= Logger.getLogger("something");
			
			List itemList = new ArrayList();
						
			try{
			
			String  columnSearch = "columnName";
			String  tableName = "tableName";
			String  sqlStatement ="select "+columnSearch+" from "+tableName;
			Iterator it = context.search("sql:"+sqlStatement, null,null);
			
			while ((null != it) &amp;&amp; it.hasNext()) {
				String i= it.next();
				if(!itemList.contains(i)) {
					itemList.add(i);
				}
			}
			Util.flushIterator(it);
			}
			catch(GeneralException ex){
				logger.error("Error in form : " +ex.getMessage());
			}
			return itemList;
		</Source>
    </Script>
</AllowedValuesDefinition>

@sarvanmarri It is working fine now! Thanks a lot!

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