Search in sources :

Example 21 with ExecTO

use of org.apache.syncope.common.lib.to.ExecTO in project syncope by apache.

the class NotificationTaskITCase method notifyByMailWithRetry.

@Test
public void notifyByMailWithRetry() throws Exception {
    // 1. Set higher number of retries
    AttrTO origMaxRetries = configurationService.get("notification.maxRetries");
    configurationService.set(attrTO(origMaxRetries.getSchema(), "10"));
    // 2. Stop mail server to force errors while sending out e-mails
    stopGreenMail();
    try {
        // 3. create notification and user
        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
        String subject = "Test notification " + getUUIDString();
        Pair<String, String> created = createNotificationTask(true, true, TraceLevel.ALL, sender, subject);
        NotificationTaskTO taskTO = findNotificationTask(created.getLeft(), 50);
        assertNotNull(taskTO);
        assertNotNull(taskTO.getNotification());
        int preExecs = taskTO.getExecutions().size();
        // 4. verify notification could not be delivered
        execTask(taskService, TaskType.NOTIFICATION, taskTO.getKey(), NotificationJob.Status.NOT_SENT.name(), 5, false);
        taskTO = taskService.read(TaskType.NOTIFICATION, taskTO.getKey(), true);
        assertNotNull(taskTO);
        assertFalse(taskTO.isExecuted());
        assertTrue(preExecs <= taskTO.getExecutions().size());
        for (ExecTO exec : taskTO.getExecutions()) {
            assertEquals(NotificationJob.Status.NOT_SENT.name(), exec.getStatus());
        }
    } finally {
        // start mail server again
        startGreenMail();
        // reset number of retries
        configurationService.set(origMaxRetries);
    }
}
Also used : ExecTO(org.apache.syncope.common.lib.to.ExecTO) AttrTO(org.apache.syncope.common.lib.to.AttrTO) NotificationTaskTO(org.apache.syncope.common.lib.to.NotificationTaskTO) Test(org.junit.jupiter.api.Test)

Example 22 with ExecTO

use of org.apache.syncope.common.lib.to.ExecTO in project syncope by apache.

the class PullTaskITCase method filteredReconciliation.

@Test
public void filteredReconciliation() throws IOException {
    String user1OnTestPull = UUID.randomUUID().toString();
    String user2OnTestPull = UUID.randomUUID().toString();
    JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
    PullTaskTO task = null;
    UserTO userTO = null;
    try {
        // 1. create 2 users on testpull
        jdbcTemplate.execute("INSERT INTO testpull VALUES (" + "'" + user1OnTestPull + "', 'user1', 'Doe', false, 'mail1@apache.org', NULL)");
        jdbcTemplate.execute("INSERT INTO testpull VALUES (" + "'" + user2OnTestPull + "', 'user2', 'Rossi', false, 'mail2@apache.org', NULL)");
        // 2. create new pull task for test-db, with reconciliation filter (surname 'Rossi')
        ImplementationTO reconFilterBuilder = new ImplementationTO();
        reconFilterBuilder.setKey("TestReconFilterBuilder");
        reconFilterBuilder.setEngine(ImplementationEngine.GROOVY);
        reconFilterBuilder.setType(ImplementationType.RECON_FILTER_BUILDER);
        reconFilterBuilder.setBody(IOUtils.toString(getClass().getResourceAsStream("/TestReconFilterBuilder.groovy"), StandardCharsets.UTF_8));
        Response response = implementationService.create(reconFilterBuilder);
        reconFilterBuilder = implementationService.read(reconFilterBuilder.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
        assertNotNull(reconFilterBuilder);
        task = taskService.read(TaskType.PULL, "7c2242f4-14af-4ab5-af31-cdae23783655", true);
        task.setPullMode(PullMode.FILTERED_RECONCILIATION);
        task.setReconFilterBuilder(reconFilterBuilder.getKey());
        response = taskService.create(TaskType.PULL, task);
        task = getObject(response.getLocation(), TaskService.class, PullTaskTO.class);
        assertNotNull(task);
        assertEquals(reconFilterBuilder.getKey(), task.getReconFilterBuilder());
        // 3. exec task
        ExecTO execution = execProvisioningTask(taskService, TaskType.PULL, task.getKey(), 50, false);
        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
        // 4. verify that only enabled user was pulled
        userTO = userService.read("user2");
        assertNotNull(userTO);
        try {
            userService.read("user1");
            fail("This should not happen");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.NotFound, e.getType());
        }
    } finally {
        jdbcTemplate.execute("DELETE FROM testpull WHERE id = '" + user1OnTestPull + "'");
        jdbcTemplate.execute("DELETE FROM testpull WHERE id = '" + user2OnTestPull + "'");
        if (task != null && !"7c2242f4-14af-4ab5-af31-cdae23783655".equals(task.getKey())) {
            taskService.delete(TaskType.PULL, task.getKey());
        }
        if (userTO != null) {
            userService.delete(userTO.getKey());
        }
    }
}
Also used : ImplementationTO(org.apache.syncope.common.lib.to.ImplementationTO) Response(javax.ws.rs.core.Response) ExecTO(org.apache.syncope.common.lib.to.ExecTO) UserTO(org.apache.syncope.common.lib.to.UserTO) TaskService(org.apache.syncope.common.rest.api.service.TaskService) PullTaskTO(org.apache.syncope.common.lib.to.PullTaskTO) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) JdbcTemplate(org.springframework.jdbc.core.JdbcTemplate) Test(org.junit.jupiter.api.Test)

Example 23 with ExecTO

use of org.apache.syncope.common.lib.to.ExecTO in project syncope by apache.

the class PullTaskITCase method remediation.

@Test
public void remediation() {
    // First of all, clear any potential conflict with existing user / group
    ldapCleanup();
    // 1. create ldap cloned resource, where 'userId' (mandatory on Syncope) is removed from mapping
    ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
    ldap.setKey("ldapForRemediation");
    ProvisionTO provision = ldap.getProvision(AnyTypeKind.USER.name()).get();
    provision.getVirSchemas().clear();
    provision.getMapping().getItems().removeIf(item -> "userId".equals(item.getIntAttrName()));
    ldap = createResource(ldap);
    // 2. create PullTask with remediation enabled, for the new resource
    PullTaskTO pullTask = (PullTaskTO) taskService.search(new TaskQuery.Builder(TaskType.PULL).resource(RESOURCE_NAME_LDAP).build()).getResult().get(0);
    assertNotNull(pullTask);
    pullTask.setResource(ldap.getKey());
    pullTask.setRemediation(true);
    pullTask.getActions().clear();
    Response response = taskService.create(TaskType.PULL, pullTask);
    if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
        throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
    }
    pullTask = getObject(response.getLocation(), TaskService.class, PullTaskTO.class);
    assertNotNull(pullTask);
    try {
        // 3. execute the pull task and verify that:
        ExecTO execution = execProvisioningTask(taskService, TaskType.PULL, pullTask.getKey(), 50, false);
        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
        // 3a. user was not pulled
        try {
            userService.read("pullFromLDAP");
            fail("This should never happen");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.NotFound, e.getType());
        }
        // 3b. remediation was created
        Optional<RemediationTO> remediation = remediationService.list().stream().filter(r -> "uid=pullFromLDAP,ou=People,o=isp".equalsIgnoreCase(r.getRemoteName())).findFirst();
        assertTrue(remediation.isPresent());
        assertEquals(AnyTypeKind.USER.name(), remediation.get().getAnyType());
        assertEquals(ResourceOperation.CREATE, remediation.get().getOperation());
        assertNotNull(remediation.get().getAnyTOPayload());
        assertNull(remediation.get().getAnyPatchPayload());
        assertNull(remediation.get().getKeyPayload());
        assertTrue(remediation.get().getError().contains("RequiredValuesMissing [userId]"));
        // 4. remedy by copying the email value to userId
        UserTO user = (UserTO) remediation.get().getAnyTOPayload();
        user.getResources().clear();
        String email = user.getPlainAttr("email").get().getValues().get(0);
        user.getPlainAttrs().add(new AttrTO.Builder().schema("userId").value(email).build());
        remediationService.remedy(remediation.get().getKey(), user);
        // 5. user is now found
        user = userService.read("pullFromLDAP");
        assertNotNull(user);
        assertEquals(email, user.getPlainAttr("userId").get().getValues().get(0));
        // 6. remediation was removed
        try {
            remediationService.read(remediation.get().getKey());
            fail("This should never happen");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.NotFound, e.getType());
        }
    } finally {
        resourceService.delete(ldap.getKey());
    }
}
Also used : ProvisionTO(org.apache.syncope.common.lib.to.ProvisionTO) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) TaskTO(org.apache.syncope.common.lib.to.TaskTO) Date(java.util.Date) Autowired(org.springframework.beans.factory.annotation.Autowired) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) ProvisioningResult(org.apache.syncope.common.lib.to.ProvisioningResult) ConnObjectTO(org.apache.syncope.common.lib.to.ConnObjectTO) ResourceOperation(org.apache.syncope.common.lib.types.ResourceOperation) ResourceDeassociationAction(org.apache.syncope.common.lib.types.ResourceDeassociationAction) AnyTypeKind(org.apache.syncope.common.lib.types.AnyTypeKind) SpringJUnitConfig(org.springframework.test.context.junit.jupiter.SpringJUnitConfig) LDAPPasswordPullActions(org.apache.syncope.core.provisioning.java.pushpull.LDAPPasswordPullActions) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Pair(org.apache.commons.lang3.tuple.Pair) BeforeAll(org.junit.jupiter.api.BeforeAll) Locale(java.util.Locale) Map(java.util.Map) RESTHeaders(org.apache.syncope.common.rest.api.RESTHeaders) PagedResult(org.apache.syncope.common.lib.to.PagedResult) FlowableDetector(org.apache.syncope.fit.FlowableDetector) ExecTO(org.apache.syncope.common.lib.to.ExecTO) PullMode(org.apache.syncope.common.lib.types.PullMode) DBPasswordPullActions(org.apache.syncope.core.provisioning.java.pushpull.DBPasswordPullActions) Set(java.util.Set) UUID(java.util.UUID) GroupTO(org.apache.syncope.common.lib.to.GroupTO) StandardCharsets(java.nio.charset.StandardCharsets) ImplementationTO(org.apache.syncope.common.lib.to.ImplementationTO) Test(org.junit.jupiter.api.Test) IOUtils(org.apache.commons.io.IOUtils) ImplementationEngine(org.apache.syncope.common.lib.types.ImplementationEngine) Response(javax.ws.rs.core.Response) DeassociationPatch(org.apache.syncope.common.lib.patch.DeassociationPatch) TestPullActions(org.apache.syncope.fit.core.reference.TestPullActions) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Optional(java.util.Optional) RemediationTO(org.apache.syncope.common.lib.to.RemediationTO) PullPolicyTO(org.apache.syncope.common.lib.policy.PullPolicyTO) Assertions.fail(org.junit.jupiter.api.Assertions.fail) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) TaskService(org.apache.syncope.common.rest.api.service.TaskService) PropagationTaskExecStatus(org.apache.syncope.common.lib.types.PropagationTaskExecStatus) AttrTO(org.apache.syncope.common.lib.to.AttrTO) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) SerializationUtils(org.apache.commons.lang3.SerializationUtils) JdbcTemplate(org.springframework.jdbc.core.JdbcTemplate) HashSet(java.util.HashSet) ConnConfProperty(org.apache.syncope.common.lib.types.ConnConfProperty) DataSource(javax.sql.DataSource) ItemTO(org.apache.syncope.common.lib.to.ItemTO) ImplementationType(org.apache.syncope.common.lib.types.ImplementationType) ClientExceptionType(org.apache.syncope.common.lib.types.ClientExceptionType) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) AnyQuery(org.apache.syncope.common.rest.api.beans.AnyQuery) MembershipTO(org.apache.syncope.common.lib.to.MembershipTO) CipherAlgorithm(org.apache.syncope.common.lib.types.CipherAlgorithm) OutputStream(java.io.OutputStream) SyncopeConstants(org.apache.syncope.common.lib.SyncopeConstants) Properties(java.util.Properties) TaskQuery(org.apache.syncope.common.rest.api.beans.TaskQuery) Encryptor(org.apache.syncope.core.spring.security.Encryptor) ResourceTO(org.apache.syncope.common.lib.to.ResourceTO) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) Name(org.identityconnectors.framework.common.objects.Name) PolicyType(org.apache.syncope.common.lib.types.PolicyType) PasswordPatch(org.apache.syncope.common.lib.patch.PasswordPatch) ConnectorCapability(org.apache.syncope.common.lib.types.ConnectorCapability) PullTaskTO(org.apache.syncope.common.lib.to.PullTaskTO) ConnectorService(org.apache.syncope.common.rest.api.service.ConnectorService) ConnInstanceTO(org.apache.syncope.common.lib.to.ConnInstanceTO) SyncopeClient(org.apache.syncope.client.lib.SyncopeClient) UserTO(org.apache.syncope.common.lib.to.UserTO) InputStream(java.io.InputStream) AnyObjectTO(org.apache.syncope.common.lib.to.AnyObjectTO) TaskType(org.apache.syncope.common.lib.types.TaskType) ExecTO(org.apache.syncope.common.lib.to.ExecTO) TaskService(org.apache.syncope.common.rest.api.service.TaskService) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) RemediationTO(org.apache.syncope.common.lib.to.RemediationTO) Response(javax.ws.rs.core.Response) ResourceTO(org.apache.syncope.common.lib.to.ResourceTO) UserTO(org.apache.syncope.common.lib.to.UserTO) PullTaskTO(org.apache.syncope.common.lib.to.PullTaskTO) ProvisionTO(org.apache.syncope.common.lib.to.ProvisionTO) Test(org.junit.jupiter.api.Test)

Example 24 with ExecTO

use of org.apache.syncope.common.lib.to.ExecTO in project syncope by apache.

the class PullTaskITCase method issueSYNCOPE272.

@Test
public void issueSYNCOPE272() {
    removeTestUsers();
    // create user with testdb resource
    UserTO userTO = UserITCase.getUniqueSampleTO("syncope272@syncope.apache.org");
    userTO.getResources().add(RESOURCE_NAME_TESTDB);
    ProvisioningResult<UserTO> result = createUser(userTO);
    userTO = result.getEntity();
    try {
        assertNotNull(userTO);
        assertEquals(1, result.getPropagationStatuses().size());
        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
        ExecTO taskExecTO = execProvisioningTask(taskService, TaskType.PULL, "986867e2-993b-430e-8feb-aa9abb4c1dcd", 50, false);
        assertNotNull(taskExecTO.getStatus());
        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()));
        userTO = userService.read(userTO.getKey());
        assertNotNull(userTO);
        assertNotNull(userTO.getPlainAttr("firstname").get().getValues().get(0));
    } finally {
        removeTestUsers();
    }
}
Also used : ExecTO(org.apache.syncope.common.lib.to.ExecTO) UserTO(org.apache.syncope.common.lib.to.UserTO) Test(org.junit.jupiter.api.Test)

Example 25 with ExecTO

use of org.apache.syncope.common.lib.to.ExecTO in project syncope by apache.

the class PullTaskITCase method fromCSV.

@Test
public void fromCSV() throws Exception {
    removeTestUsers();
    // Attemp to reset CSV content
    Properties props = new Properties();
    InputStream propStream = null;
    InputStream srcStream = null;
    OutputStream dstStream = null;
    try {
        propStream = getClass().getResourceAsStream("/core-test.properties");
        props.load(propStream);
        srcStream = new FileInputStream(props.getProperty("test.csv.src"));
        dstStream = new FileOutputStream(props.getProperty("test.csv.dst"));
        IOUtils.copy(srcStream, dstStream);
    } catch (IOException e) {
        fail(e.getMessage());
    } finally {
        if (propStream != null) {
            propStream.close();
        }
        if (srcStream != null) {
            srcStream.close();
        }
        if (dstStream != null) {
            dstStream.close();
        }
    }
    // -----------------------------
    // Create a new user ... it should be updated applying pull policy
    // -----------------------------
    UserTO inUserTO = new UserTO();
    inUserTO.setRealm(SyncopeConstants.ROOT_REALM);
    inUserTO.setPassword("password123");
    String userName = "test9";
    inUserTO.setUsername(userName);
    inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
    inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
    inUserTO.getPlainAttrs().add(attrTO("ctype", "a type"));
    inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
    inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
    inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
    inUserTO.getAuxClasses().add("csv");
    inUserTO = createUser(inUserTO).getEntity();
    assertNotNull(inUserTO);
    assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
    // -----------------------------
    try {
        int usersPre = userService.search(new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).page(1).size(1).build()).getTotalCount();
        assertNotNull(usersPre);
        ExecTO exec = execProvisioningTask(taskService, TaskType.PULL, PULL_TASK_KEY, 50, false);
        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(exec.getStatus()));
        LOG.debug("Execution of task {}:\n{}", PULL_TASK_KEY, exec);
        // check for pull results
        int usersPost = userService.search(new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).page(1).size(1).build()).getTotalCount();
        assertNotNull(usersPost);
        assertEquals(usersPre + 8, usersPost);
        // after execution of the pull task the user data should have been pulled from CSV
        // and processed by user template
        UserTO userTO = userService.read(inUserTO.getKey());
        assertNotNull(userTO);
        assertEquals(userName, userTO.getUsername());
        assertEquals(FlowableDetector.isFlowableEnabledForUsers(syncopeService) ? "active" : "created", userTO.getStatus());
        assertEquals("test9@syncope.apache.org", userTO.getPlainAttr("email").get().getValues().get(0));
        assertEquals("test9@syncope.apache.org", userTO.getPlainAttr("userId").get().getValues().get(0));
        assertTrue(Integer.valueOf(userTO.getPlainAttr("fullname").get().getValues().get(0)) <= 10);
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
        // Matching --> Update (no link)
        assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
        // check for user template
        userTO = userService.read("test7");
        assertNotNull(userTO);
        assertEquals("TYPE_OTHER", userTO.getPlainAttr("ctype").get().getValues().get(0));
        assertEquals(3, userTO.getResources().size());
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
        assertEquals(1, userTO.getMemberships().size());
        assertEquals("f779c0d4-633b-4be5-8f57-32eb478a3ca5", userTO.getMemberships().get(0).getGroupKey());
        // Unmatching --> Assign (link) - SYNCOPE-658
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
        assertEquals(1, userTO.getDerAttrs().stream().filter(attrTO -> "csvuserid".equals(attrTO.getSchema())).count());
        userTO = userService.read("test8");
        assertNotNull(userTO);
        assertEquals("TYPE_8", userTO.getPlainAttr("ctype").get().getValues().get(0));
        // Check for ignored user - SYNCOPE-663
        try {
            userService.read("test2");
            fail("This should not happen");
        } catch (SyncopeClientException e) {
            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
        }
        // Check for issue 215:
        // * expected disabled user test1
        // * expected enabled user test3
        userTO = userService.read("test1");
        assertNotNull(userTO);
        assertEquals("suspended", userTO.getStatus());
        userTO = userService.read("test3");
        assertNotNull(userTO);
        assertEquals("active", userTO.getStatus());
        Set<String> otherPullTaskKeys = new HashSet<>();
        otherPullTaskKeys.add("feae4e57-15ca-40d9-b973-8b9015efca49");
        otherPullTaskKeys.add("55d5e74b-497e-4bc0-9156-73abef4b9adc");
        execProvisioningTasks(taskService, TaskType.PULL, otherPullTaskKeys, 50, false);
        // Matching --> UNLINK
        assertFalse(userService.read("test9").getResources().contains(RESOURCE_NAME_CSV));
        assertFalse(userService.read("test7").getResources().contains(RESOURCE_NAME_CSV));
    } finally {
        removeTestUsers();
    }
}
Also used : ExecTO(org.apache.syncope.common.lib.to.ExecTO) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) SyncopeClientException(org.apache.syncope.common.lib.SyncopeClientException) IOException(java.io.IOException) Properties(java.util.Properties) FileInputStream(java.io.FileInputStream) UserTO(org.apache.syncope.common.lib.to.UserTO) FileOutputStream(java.io.FileOutputStream) HashSet(java.util.HashSet) Test(org.junit.jupiter.api.Test)

Aggregations

ExecTO (org.apache.syncope.common.lib.to.ExecTO)37 Test (org.junit.jupiter.api.Test)22 SyncopeClientException (org.apache.syncope.common.lib.SyncopeClientException)13 UserTO (org.apache.syncope.common.lib.to.UserTO)13 Response (javax.ws.rs.core.Response)11 PullTaskTO (org.apache.syncope.common.lib.to.PullTaskTO)10 Date (java.util.Date)9 TaskService (org.apache.syncope.common.rest.api.service.TaskService)8 NotFoundException (org.apache.syncope.core.persistence.api.dao.NotFoundException)7 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)7 Map (java.util.Map)6 GroupTO (org.apache.syncope.common.lib.to.GroupTO)6 ResourceTO (org.apache.syncope.common.lib.to.ResourceTO)6 IOException (java.io.IOException)5 TaskTO (org.apache.syncope.common.lib.to.TaskTO)5 JdbcTemplate (org.springframework.jdbc.core.JdbcTemplate)5 AttrTO (org.apache.syncope.common.lib.to.AttrTO)4 ConnInstanceTO (org.apache.syncope.common.lib.to.ConnInstanceTO)4 ImplementationTO (org.apache.syncope.common.lib.to.ImplementationTO)4 ItemTO (org.apache.syncope.common.lib.to.ItemTO)4