Filtering data in account and entitlement aggregation

Hello All,

I have a webservice connector with HTTP operations setup for Account and Entitlement aggregation.

Now, I have 2 requirements.

1. I want to filter certain entitlement assignments from accounts and return in account aggregation result.

I created an afteroperation below to handle that, it is showing expected result in the logs for updatedMapInfo but not reflecting in the connector UI. I have the connection attached properly and did error handling test to confirm that.

Below is the code I have for AfterOperationRule

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Set;

log.trace(“Enter rule: WebServiceAfterOperationRule - Accounts”);

Map updatedMapInfo = new HashMap();

List filteredAccounts = new ArrayList();

try {

Set blockedGroupGuids = new HashSet();

blockedGroupGuids.add(“ABC-123”);

blockedGroupGuids.add(“498-781A”);

// If processed response is a list then iterate accounts.

if (processedResponseObject instanceof List) {

List inputList = (List) processedResponseObject;

// Loop Through aggregated accounts to strip blocked group GUIDs.

for (int accountIndex = 0; accountIndex < inputList.size(); accountIndex++) {

Object accountObject = inputList.get(accountIndex);

if (!(accountObject instanceof Map)) {

log.warn("Groups - Skipping non-map entry: " + accountObject);

continue;

}

Map accountMap = (Map) accountObject;

Map newAccountMap = new HashMap(accountMap);

Object groupGuidsObj = newAccountMap.get(“groupGuids”);

if (groupGuidsObj instanceof List) {

List originalGroupGuids = (List) groupGuidsObj;

List updatedGroupGuids = new ArrayList();

// Loop Through group GUIDs to drop blocked values.

for (int groupIndex = 0; groupIndex < originalGroupGuids.size(); groupIndex++) {

Object guidObj = originalGroupGuids.get(groupIndex);

if (guidObj == null) {

continue;

}

String candidateGuid = guidObj.toString().trim();

if (!blockedGroupGuids.contains(candidateGuid.toUpperCase())) {

updatedGroupGuids.add(candidateGuid);

} else {

log.debug("Groups - Filtered group GUID: " + candidateGuid);

}

} // End For - Loop Through group GUIDs to drop blocked values

newAccountMap.put(“groupGuids”, updatedGroupGuids);

}

filteredAccounts.add(newAccountMap);

} // End For - Loop Through aggregated accounts to strip blocked group GUIDs

} else {

log.warn("Groups - processedResponseObject was not a List: " + processedResponseObject);

}

updatedMapInfo.put(“content”, filteredAccounts);

} catch (Exception exception) {

log.error(“Failed to filter group GUIDs.”, exception);

throw new RuntimeException(“Failed to filter group GUIDs.”, exception);

} finally {

log.trace(“Exit rule: WebServiceAfterOperationRule - Groups”);

}

for (Object keyObj : updatedMapInfo.keySet()) {

Object valueObj = updatedMapInfo.get(keyObj);

log.debug("Groups - updatedMapInfo key: " + keyObj

+ " value: " + valueObj);

}

Object contentObj = updatedMapInfo.get(“content”);

if (contentObj instanceof List) {

List contentList = (List) contentObj;

for (int idx = 0; idx < contentList.size(); idx++) {

log.debug(“Groups - content[” + idx + "]: "

+ contentList.get(idx));

}

}

return updatedMapInfo;

Response Information - root path - $.content

Mapping

(SchemaAttribute)groupGuids → (AttributePath)groupGuids[*]

Actual Endpoint response format

{

“content”: [

{

“guid”: “2ABC-123”,

“accountReferenceGUID”: “1256sdfjk”,

“firstName”: “Test”,

“lastName”: “Testing”,

“emailAddresses”: [

“abc@gmail.com”

],

“phoneNumbers”: [],

“status”: “ACTIVE”,

“groupGuids”: [

“ABC-1234”,

“ABC-4567”

],

“userName”: “abcd”,

“connectionTimestamp”: “2022-12-02T03:24:57.251359Z”

}]

}

2. I want to filter same entitlement groups from the entitlement aggregation result as well.

I have created afteroperation here as well but facing same issue. Interestingly, if I make any change with any attribute that is getting reflected in the UI, but if I want to remove/filterout that group from the list that doesn’t reflect.

AfterOperation rule:

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.ArrayList;

log.trace(“Enter rule: - WebServiceAfterOperationRule - Groups”);

Map updatedMapInfo = new HashMap();

List finalList = new ArrayList();

// processedResponseObject should be a List from $.content[*]

if (processedResponseObject instanceof List) {

List inputList = (List) processedResponseObject;

log.debug(" Processing " + inputList.size() + " items");

for (Object item : inputList) {

Map cra = (Map) item; // each entitlement

String guid = (String) cra.get(“guid”);

if (guid != null && guid.trim().equalsIgnoreCase(“ABC-1234”)) {

log.debug("excluded: " + guid);

continue;

}

finalList.add(cra);

}

} else {

log.warn("processedResponseObject was null or not a List: " + processedResponseObject);

}

log.debug("finalList: " + finalList);

updatedMapInfo.put(“content”, finalList);

log.debug("updatedMapInfo: " + updatedMapInfo);

log.trace(“Exit rule:WebServiceAfterOperationRule - Groups”);

return updatedMapInfo;

Response Information ->Root path - $.content[*] , tried $.content as well both didn’t work.

Mapping -

(SchemaAttribute)guid → (AttributePath)guid

Actual Endpoint Result Json

{

“content”: [

{

“guid”: “ABC-1234”,

“name”: “Test”,

“description”: “Test’”,

“Count”: 1,

“TestGroup”: false

}]

}

Any help is much appreciated!

Thanks in advance!!

:bangbang: Please be sure you’ve read the docs and API specs before asking for help. Also, please be sure you’ve searched the forum for your answer before you create a new topic.

Please consider addressing the following when creating your topic:

  • What have you tried?
  • What errors did you face (share screenshots)?
  • Share the details of your efforts (code / search query, workflow json etc.)?
  • What is the result you are getting and what were you expecting?

@keerthiP7 have you tried to directly filter it at the API level ?

Hello @schattopadhy

we have filtered at API level as well, but there are some limitations and couldn’t filter out a few groups.

Thanks!

@keerthiP7 -

I suspect, the connector is ignoring your returned list because the return map key is wrong.
For WebServiceAfterOperationRule, the connector expects you to return:

data → the updated list of account/group resource objects

and connectorStateMap → values to persist in the source/app config

Not content
Could you try my below code -

I am modifying the processedResponseObject and returning it under data.

import connector.common.JsonUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

log.trace("Enter rule: WebServiceAfterOperationRule - Accounts");

Map updatedMapInfo = new HashMap();
List finalList = new ArrayList();

Set blockedGroupGuids = new HashSet(Arrays.asList(
  "ABC-123",     // blocked values
  "498-781A"
));

try {

  // Parse raw response into Map
  Map response = (Map) JsonUtil.toMap(rawResponseObject);
  if (response == null) {
    log.warn("Accounts - rawResponseObject parsed to null");
    updatedMapInfo.put("data", finalList);
    return updatedMapInfo;
  }


  Object contentObj = response.get("content");

  if (!(contentObj instanceof List)) {
    log.warn("Accounts - response content/data not a List. Found: " + contentObj);
    updatedMapInfo.put("data", finalList);
    return updatedMapInfo;
  }

  List inputList = (List) contentObj;
  log.debug("Accounts - Processing accounts: " + inputList.size());

  for (Object accountObject : inputList) {
    if (!(accountObject instanceof Map)) {
      log.warn("Accounts - Skipping non-map entry: " + accountObject);
      continue;
    }

    Map accountMap = (Map) accountObject;
    Map newAccountMap = new HashMap(accountMap); // copy all fields

    Object groupGuidsObj = newAccountMap.get("groupGuids");
    if (groupGuidsObj instanceof List) {

      List originalGroupGuids = (List) groupGuidsObj;
      List updatedGroupGuids = new ArrayList();

      for (Object guidObj : originalGroupGuids) {
        if (guidObj == null) continue;

        String candidateGuid = guidObj.toString().trim();
        String normalized = candidateGuid.toUpperCase();

        // NOTE: your blocked list values are like "ABC-123" but your actual groups are "ABC-1234".
        // So match EXACTLY on what you want blocked.
        if (!blockedGroupGuids.contains(normalized)) {
          updatedGroupGuids.add(candidateGuid);
        } else {
          log.debug("Accounts - Filtered group GUID: " + candidateGuid);
        }
      }

      newAccountMap.put("groupGuids", updatedGroupGuids);
    }

    finalList.add(newAccountMap);
  }

  updatedMapInfo.put("data", finalList);
  log.debug("Accounts - Returning filtered accounts count: " + finalList.size());
  return updatedMapInfo;

} catch (Exception e) {
  log.error("Accounts - Failed to filter group GUIDs.", e);
  throw new RuntimeException("Accounts - Failed to filter group GUIDs.", e);
} finally {
  log.trace("Exit rule: WebServiceAfterOperationRule - Accounts");
}

Let me know if this works.

Thanks

Thanks so much @amit_1140 It worked and filtered the list of groups and groups association for accounts as well.

@keerthiP7 - Kindly marked it as solved