Search in sources :

Example 46 with ObjectReferenceType

use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType in project midpoint by Evolveum.

the class TestSanityLegacy method test303LiveSyncLink.

@Test
public void test303LiveSyncLink() throws Exception {
    final String TEST_NAME = "test303LiveSyncLink";
    TestUtil.displayTestTile(TEST_NAME);
    // GIVEN
    assertNoRepoCache();
    PrismObject<UserType> user = PrismTestUtil.parseObject(USER_E_LINK_ACTION_FILE);
    UserType userType = user.asObjectable();
    final String userOid = userType.getOid();
    // Encrypt e's password
    protector.encrypt(userType.getCredentials().getPassword().getValue());
    // create user in repository
    OperationResultType resultType = new OperationResultType();
    Holder<OperationResultType> resultHolder = new Holder<OperationResultType>(resultType);
    Holder<String> oidHolder = new Holder<String>();
    display("Adding user object", userType);
    addObjectViaModelWS(userType, null, oidHolder, resultHolder);
    //check results
    assertNoRepoCache();
    displayJaxb("addObject result:", resultHolder.value, SchemaConstants.C_RESULT);
    TestUtil.assertSuccess("addObject has failed", resultHolder.value);
    //        AssertJUnit.assertEquals(userOid, oidHolder.value);
    //WHEN
    //create account for e which should be correlated
    final OperationResult result = new OperationResult(TestSanityLegacy.class.getName() + "." + TEST_NAME);
    final Task syncCycle = taskManager.getTask(TASK_OPENDJ_SYNC_OID, result);
    AssertJUnit.assertNotNull(syncCycle);
    int tokenBefore = findSyncToken(syncCycle);
    display("Sync token before", tokenBefore);
    Entry entry = openDJController.addEntryFromLdifFile(LDIF_E_FILENAME_LINK);
    display("Entry from LDIF", entry);
    // THEN
    // Wait a bit to give the sync cycle time to detect the change
    basicWaitForSyncChangeDetection(syncCycle, tokenBefore, 4, result);
    //check user and account ref
    userType = searchUserByName("e");
    List<ObjectReferenceType> accountRefs = userType.getLinkRef();
    assertEquals("Account ref not found, or found too many", 1, accountRefs.size());
    //check account defined by account ref
    String accountOid = accountRefs.get(0).getOid();
    ShadowType account = searchAccountByOid(accountOid);
    assertEqualsPolyString("Name doesn't match", "uid=e,ou=People,dc=example,dc=com", account.getName());
    assertAndStoreSyncTokenIncrement(syncCycle, 4);
    checkAllShadows();
}
Also used : Task(com.evolveum.midpoint.task.api.Task) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) Holder(javax.xml.ws.Holder) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) PrismAsserts.assertEqualsPolyString(com.evolveum.midpoint.prism.util.PrismAsserts.assertEqualsPolyString) ChangeRecordEntry(org.opends.server.util.ChangeRecordEntry) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) OperationResultType(com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType) UserType(com.evolveum.midpoint.xml.ns._public.common.common_3.UserType) Test(org.testng.annotations.Test) AbstractModelIntegrationTest(com.evolveum.midpoint.model.test.AbstractModelIntegrationTest)

Example 47 with ObjectReferenceType

use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType in project midpoint by Evolveum.

the class TestSanityLegacy method test420RecomputeUsers.

@Test
public void test420RecomputeUsers() throws Exception {
    final String TEST_NAME = "test420RecomputeUsers";
    TestUtil.displayTestTile(TEST_NAME);
    // GIVEN
    final OperationResult result = new OperationResult(TestSanityLegacy.class.getName() + "." + TEST_NAME);
    // Assign role to a user, but we do this using a repository instead of model.
    // The role assignment will not be executed and this created an inconsistent state.
    ObjectDeltaType changeAddRoleCaptain = unmarshallValueFromFile(REQUEST_USER_MODIFY_ADD_ROLE_CAPTAIN_1_FILENAME, ObjectDeltaType.class);
    Collection<? extends ItemDelta> modifications = DeltaConvertor.toModifications(changeAddRoleCaptain.getItemDelta(), getUserDefinition());
    repositoryService.modifyObject(UserType.class, changeAddRoleCaptain.getOid(), modifications, result);
    // TODO: setup more "inconsistent" state
    // Add reconciliation task. This will trigger reconciliation
    importObjectFromFile(TASK_USER_RECOMPUTE_FILENAME, result);
    // We need to wait for a sync interval, so the task scanner has a chance
    // to pick up this
    // task
    waitFor("Waiting for task to finish", new Checker() {

        public boolean check() throws ObjectNotFoundException, SchemaException {
            Task task = taskManager.getTask(TASK_USER_RECOMPUTE_OID, result);
            // wait until the task is finished
            if (TaskExecutionStatus.CLOSED == task.getExecutionStatus()) {
                return true;
            }
            return false;
        }

        @Override
        public void timeout() {
        // No reaction, the test will fail right after return from this
        }
    }, 40000);
    // wait a second until the task will be definitely saved
    Thread.sleep(1000);
    // Check task status
    Task task = taskManager.getTask(TASK_USER_RECOMPUTE_OID, result);
    result.computeStatus();
    display("getTask result", result);
    TestUtil.assertSuccess("getTask has failed", result);
    AssertJUnit.assertNotNull(task);
    display("Task after finish", task);
    AssertJUnit.assertNotNull(task.getTaskIdentifier());
    assertFalse(task.getTaskIdentifier().isEmpty());
    PrismObject<TaskType> o = repositoryService.getObject(TaskType.class, TASK_USER_RECOMPUTE_OID, null, result);
    display("Task after pickup in the repository", o.asObjectable());
    AssertJUnit.assertEquals(TaskExecutionStatus.CLOSED, task.getExecutionStatus());
    // .. and last run should not be zero
    assertNotNull(task.getLastRunStartTimestamp());
    AssertJUnit.assertFalse(task.getLastRunStartTimestamp().longValue() == 0);
    assertNotNull(task.getLastRunFinishTimestamp());
    AssertJUnit.assertFalse(task.getLastRunFinishTimestamp().longValue() == 0);
    AssertJUnit.assertEquals(10, task.getProgress());
    // Test for presence of a result. It should be there and it should
    // indicate success
    OperationResult taskResult = task.getResult();
    display("Recompute task result", taskResult);
    AssertJUnit.assertNotNull(taskResult);
    TestUtil.assertSuccess("Recompute task result", taskResult);
    // STOP the task. We don't need it any more and we don't want to give it a chance to run more than once
    taskManager.deleteTask(TASK_USER_RECOMPUTE_OID, result);
    // CHECK RESULT: account created for user guybrush
    // Check if user object was modified in the repo
    OperationResult repoResult = new OperationResult("getObject");
    PrismObject<UserType> object = repositoryService.getObject(UserType.class, USER_GUYBRUSH_OID, null, repoResult);
    UserType repoUser = object.asObjectable();
    repoResult.computeStatus();
    displayJaxb("User (repository)", repoUser, new QName("user"));
    List<ObjectReferenceType> accountRefs = repoUser.getLinkRef();
    assertEquals("Wrong number of accountRefs after recompute for user " + repoUser.getName(), 1, accountRefs.size());
    ObjectReferenceType accountRef = accountRefs.get(0);
    accountShadowOidGuybrushOpendj = accountRef.getOid();
    assertFalse(accountShadowOidGuybrushOpendj.isEmpty());
    // Check if shadow was created in the repo
    repoResult = new OperationResult("getObject");
    PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, accountShadowOidGuybrushOpendj, null, repoResult);
    ShadowType repoShadowType = repoShadow.asObjectable();
    repoResult.computeStatus();
    TestUtil.assertSuccess("getObject has failed", repoResult);
    displayJaxb("Shadow (repository)", repoShadowType, new QName("shadow"));
    assertNotNull(repoShadowType);
    assertEquals(RESOURCE_OPENDJ_OID, repoShadowType.getResourceRef().getOid());
    accountGuybrushOpendjEntryUuuid = checkRepoShadow(repoShadow);
    // check if account was created in LDAP
    Entry entry = openDJController.searchAndAssertByEntryUuid(accountGuybrushOpendjEntryUuuid);
    display("LDAP account", entry);
    OpenDJController.assertAttribute(entry, "uid", "guybrush");
    OpenDJController.assertAttribute(entry, "givenName", "Guybrush");
    OpenDJController.assertAttribute(entry, "sn", "Threepwood");
    OpenDJController.assertAttribute(entry, "cn", "Guybrush Threepwood");
    OpenDJController.assertAttribute(entry, "displayName", "Guybrush Threepwood");
    // The "l" attribute is assigned indirectly through schemaHandling and
    // config object
    OpenDJController.assertAttribute(entry, "l", "Deep in the Caribbean");
    // Set by the role
    OpenDJController.assertAttribute(entry, "employeeType", "sailor");
    OpenDJController.assertAttribute(entry, "title", "Honorable Captain");
    OpenDJController.assertAttribute(entry, "carLicense", "C4PT41N");
    OpenDJController.assertAttribute(entry, "businessCategory", "cruise");
    String guybrushPassword = OpenDJController.getAttributeValue(entry, "userPassword");
    assertNotNull("Pasword was not set on create", guybrushPassword);
    checkAllShadows();
}
Also used : Checker(com.evolveum.midpoint.test.Checker) ObjectChecker(com.evolveum.midpoint.test.ObjectChecker) Task(com.evolveum.midpoint.task.api.Task) QName(javax.xml.namespace.QName) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) PrismAsserts.assertEqualsPolyString(com.evolveum.midpoint.prism.util.PrismAsserts.assertEqualsPolyString) ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) ChangeRecordEntry(org.opends.server.util.ChangeRecordEntry) TaskType(com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType) UserType(com.evolveum.midpoint.xml.ns._public.common.common_3.UserType) Test(org.testng.annotations.Test) AbstractModelIntegrationTest(com.evolveum.midpoint.model.test.AbstractModelIntegrationTest)

Example 48 with ObjectReferenceType

use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType in project midpoint by Evolveum.

the class TestSanityLegacy method test104AssignRoleJudge.

/**
     * Judge role excludes pirate role. This assignment should fail. 
     */
@Test
public void test104AssignRoleJudge() throws Exception {
    final String TEST_NAME = "test104AssignRoleJudge";
    TestUtil.displayTestTile(TEST_NAME);
    // GIVEN
    OperationResultType result = new OperationResultType();
    Holder<OperationResultType> resultHolder = new Holder<OperationResultType>(result);
    Holder<String> oidHolder = new Holder<String>();
    assertNoRepoCache();
    ObjectDeltaType objectChange = unmarshallValueFromFile(REQUEST_USER_MODIFY_ADD_ROLE_JUDGE_FILENAME, ObjectDeltaType.class);
    try {
        // WHEN ObjectTypes.USER.getTypeQName(), 
        result = modifyObjectViaModelWS(objectChange);
        // THEN
        AssertJUnit.fail("Expected a failure after assigning conflicting roles but nothing happened and life goes on");
    } catch (FaultMessage f) {
    // This is expected
    // TODO: check if the fault is the right one
    }
    assertNoRepoCache();
    displayJaxb("modifyObject result", result, SchemaConstants.C_RESULT);
    TestUtil.assertSuccess("modifyObject has failed", result);
    // Check if user object remain unmodified in the repo
    OperationResult repoResult = new OperationResult("getObject");
    PrismObject<UserType> uObject = repositoryService.getObject(UserType.class, USER_GUYBRUSH_OID, null, repoResult);
    UserType repoUser = uObject.asObjectable();
    repoResult.computeStatus();
    display("User (repository)", repoUser);
    List<ObjectReferenceType> accountRefs = repoUser.getLinkRef();
    assertEquals("Unexpected number or accountRefs", 1, accountRefs.size());
}
Also used : ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) FaultMessage(com.evolveum.midpoint.xml.ns._public.common.fault_3.FaultMessage) OperationResultType(com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType) Holder(javax.xml.ws.Holder) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) PrismAsserts.assertEqualsPolyString(com.evolveum.midpoint.prism.util.PrismAsserts.assertEqualsPolyString) UserType(com.evolveum.midpoint.xml.ns._public.common.common_3.UserType) Test(org.testng.annotations.Test) AbstractModelIntegrationTest(com.evolveum.midpoint.model.test.AbstractModelIntegrationTest)

Example 49 with ObjectReferenceType

use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType in project midpoint by Evolveum.

the class TestSanity method test103AssignRoleCaptainAgain.

/**
     * Assign the same "captain" role again, this time with a slightly different assignment parameters.
     */
@Test
public void test103AssignRoleCaptainAgain() throws Exception {
    final String TEST_NAME = "test103AssignRoleCaptainAgain";
    TestUtil.displayTestTile(TEST_NAME);
    // GIVEN
    ObjectDeltaType objectChange = unmarshallValueFromFile(REQUEST_USER_MODIFY_ADD_ROLE_CAPTAIN_2_FILENAME, ObjectDeltaType.class);
    // WHEN ObjectTypes.USER.getTypeQName(), 
    OperationResultType result = modifyObjectViaModelWS(objectChange);
    // THEN
    assertNoRepoCache();
    displayJaxb("modifyObject result", result, SchemaConstants.C_RESULT);
    TestUtil.assertSuccess("modifyObject has failed", result);
    // Check if user object was modified in the repo
    OperationResult repoResult = new OperationResult("getObject");
    PrismObject<UserType> uObject = repositoryService.getObject(UserType.class, USER_GUYBRUSH_OID, null, repoResult);
    UserType repoUser = uObject.asObjectable();
    repoResult.computeStatus();
    display("User (repository)", repoUser);
    List<ObjectReferenceType> accountRefs = repoUser.getLinkRef();
    assertEquals(1, accountRefs.size());
    ObjectReferenceType accountRef = accountRefs.get(0);
    assertEquals(accountShadowOidGuybrushOpendj, accountRef.getOid());
    // Check if shadow is still in the repo
    repoResult = new OperationResult("getObject");
    PrismObject<ShadowType> aObject = repositoryService.getObject(ShadowType.class, accountShadowOidGuybrushOpendj, null, repoResult);
    ShadowType repoShadow = aObject.asObjectable();
    repoResult.computeStatus();
    TestUtil.assertSuccess("getObject has failed", repoResult);
    display("Shadow (repository)", repoShadow);
    assertNotNull(repoShadow);
    assertEquals(RESOURCE_OPENDJ_OID, repoShadow.getResourceRef().getOid());
    // check if account is still in LDAP
    Entry entry = openDJController.searchAndAssertByEntryUuid(accountGuybrushOpendjEntryUuuid);
    display("LDAP account", entry);
    OpenDJController.assertAttribute(entry, "uid", "guybrush");
    OpenDJController.assertAttribute(entry, "givenName", "Guybrush");
    OpenDJController.assertAttribute(entry, "sn", "Threepwood");
    OpenDJController.assertAttribute(entry, "cn", "Guybrush Threepwood");
    OpenDJController.assertAttribute(entry, "displayName", "Guybrush Threepwood");
    // The "l" attribute is assigned indirectly through schemaHandling and
    // config object
    OpenDJController.assertAttribute(entry, "l", "Deep in the Caribbean");
    // Set by the role
    OpenDJController.assertAttribute(entry, "employeeType", "sailor");
    OpenDJController.assertAttribute(entry, "title", "Bloody Pirate", "Honorable Captain");
    OpenDJController.assertAttribute(entry, "carLicense", "C4PT41N");
    OpenDJController.assertAttribute(entry, "businessCategory", "loot", "murder", "cruise");
    // Expression in the role taking that from the user
    OpenDJController.assertAttribute(entry, "destinationIndicator", "Guybrush Threepwood");
    OpenDJController.assertAttribute(entry, "departmentNumber", "Department of Guybrush");
    // Expression in the role taking that from the assignments (both of them)
    OpenDJController.assertAttribute(entry, "physicalDeliveryOfficeName", "The Sea Monkey", "The Dainty Lady");
    String guybrushPassword = OpenDJController.getAttributeValue(entry, "userPassword");
    assertNotNull("Pasword disappeared", guybrushPassword);
// TODO: Derby
}
Also used : ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) ChangeRecordEntry(org.opends.server.util.ChangeRecordEntry) OperationResultType(com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) PrismAsserts.assertEqualsPolyString(com.evolveum.midpoint.prism.util.PrismAsserts.assertEqualsPolyString) UserType(com.evolveum.midpoint.xml.ns._public.common.common_3.UserType) Test(org.testng.annotations.Test) AbstractModelIntegrationTest(com.evolveum.midpoint.model.test.AbstractModelIntegrationTest)

Example 50 with ObjectReferenceType

use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType in project midpoint by Evolveum.

the class TestSanity method test108UnassignRoleCaptain.

@Test
public void test108UnassignRoleCaptain() throws Exception {
    final String TEST_NAME = "test108UnassignRoleCaptain";
    TestUtil.displayTestTile(TEST_NAME);
    // GIVEN
    OperationResultType result = new OperationResultType();
    assertNoRepoCache();
    ObjectDeltaType objectChange = unmarshallValueFromFile(REQUEST_USER_MODIFY_DELETE_ROLE_CAPTAIN_1_FILENAME, ObjectDeltaType.class);
    // WHEN ObjectTypes.USER.getTypeQName(), 
    result = modifyObjectViaModelWS(objectChange);
    // THEN
    assertNoRepoCache();
    displayJaxb("modifyObject result", result, SchemaConstants.C_RESULT);
    TestUtil.assertSuccess("modifyObject has failed", result);
    // Check if user object was modified in the repo
    // Check if user object was modified in the repo
    OperationResult repoResult = new OperationResult("getObject");
    PrismObject<UserType> repoUser = repositoryService.getObject(UserType.class, USER_GUYBRUSH_OID, null, repoResult);
    UserType repoUserType = repoUser.asObjectable();
    repoResult.computeStatus();
    display("User (repository)", repoUser);
    List<ObjectReferenceType> accountRefs = repoUserType.getLinkRef();
    assertEquals(1, accountRefs.size());
    ObjectReferenceType accountRef = accountRefs.get(0);
    assertEquals(accountShadowOidGuybrushOpendj, accountRef.getOid());
    // Check if shadow is still in the repo
    repoResult = new OperationResult("getObject");
    PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, accountShadowOidGuybrushOpendj, null, repoResult);
    ShadowType repoShadowType = repoShadow.asObjectable();
    repoResult.computeStatus();
    TestUtil.assertSuccess("getObject has failed", repoResult);
    display("Shadow (repository)", repoShadow);
    assertNotNull(repoShadowType);
    assertEquals(RESOURCE_OPENDJ_OID, repoShadowType.getResourceRef().getOid());
    // check if account is still in LDAP
    Entry entry = openDJController.searchAndAssertByEntryUuid(accountGuybrushOpendjEntryUuuid);
    display("LDAP account", entry);
    OpenDJController.assertAttribute(entry, "uid", "guybrush");
    OpenDJController.assertAttribute(entry, "givenName", "Guybrush");
    OpenDJController.assertAttribute(entry, "sn", "Threepwood");
    OpenDJController.assertAttribute(entry, "cn", "Guybrush Threepwood");
    OpenDJController.assertAttribute(entry, "displayName", "Guybrush Threepwood");
    // The "l" attribute is assigned indirectly through schemaHandling and
    // config object
    OpenDJController.assertAttribute(entry, "l", "Deep in the Caribbean");
    // Set by the role
    OpenDJController.assertAttribute(entry, "employeeType", "sailor");
    OpenDJController.assertAttribute(entry, "title", "Honorable Captain");
    OpenDJController.assertAttribute(entry, "carLicense", "C4PT41N");
    OpenDJController.assertAttribute(entry, "businessCategory", "cruise", "fighting", "capsize");
    // Expression in the role taking that from the user
    OpenDJController.assertAttribute(entry, "destinationIndicator", "Guybrush Threepwood");
    OpenDJController.assertAttribute(entry, "departmentNumber", "Department of Guybrush");
    // Expression in the role taking that from the assignments (both of them)
    OpenDJController.assertAttribute(entry, "physicalDeliveryOfficeName", "The Dainty Lady");
    String guybrushPassword = OpenDJController.getAttributeValue(entry, "userPassword");
    assertNotNull("Pasword disappeared", guybrushPassword);
// TODO: Derby        
}
Also used : ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) ChangeRecordEntry(org.opends.server.util.ChangeRecordEntry) OperationResultType(com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) PrismAsserts.assertEqualsPolyString(com.evolveum.midpoint.prism.util.PrismAsserts.assertEqualsPolyString) UserType(com.evolveum.midpoint.xml.ns._public.common.common_3.UserType) Test(org.testng.annotations.Test) AbstractModelIntegrationTest(com.evolveum.midpoint.model.test.AbstractModelIntegrationTest)

Aggregations

ObjectReferenceType (com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType)278 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)104 UserType (com.evolveum.midpoint.xml.ns._public.common.common_3.UserType)61 Test (org.testng.annotations.Test)61 ShadowType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType)56 Task (com.evolveum.midpoint.task.api.Task)53 QName (javax.xml.namespace.QName)46 ArrayList (java.util.ArrayList)44 AbstractModelIntegrationTest (com.evolveum.midpoint.model.test.AbstractModelIntegrationTest)42 PrismAsserts.assertEqualsPolyString (com.evolveum.midpoint.prism.util.PrismAsserts.assertEqualsPolyString)37 OperationResultType (com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType)33 AssignmentType (com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType)32 ObjectType (com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType)32 ObjectDeltaType (com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType)31 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)30 ChangeRecordEntry (org.opends.server.util.ChangeRecordEntry)30 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)26 PolyString (com.evolveum.midpoint.prism.polystring.PolyString)26 ObjectQuery (com.evolveum.midpoint.prism.query.ObjectQuery)23 List (java.util.List)23