/*
* ====================
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License("CDDL") (the "License"). You may not use this file
* except in compliance with the License.
*
* You can obtain a copy of the License at
* http://IdentityConnectors.dev.java.net/legal/license.txt
* See the License for the specific language governing permissions and limitations
* under the License.
*
* When distributing the Covered Code, include this CDDL Header Notice in each file
* and include the License file at identityconnectors/legal/license.txt.
* If applicable, add the following below this CDDL Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
*/
package org.identityconnectors.databasetable;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import org.testng.Assert;
import org.testng.AssertJUnit;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.logging.Log;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.dbcommon.SQLParam;
import org.identityconnectors.dbcommon.SQLUtil;
import org.identityconnectors.framework.api.operations.AuthenticationApiOp;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.identityconnectors.framework.common.exceptions.InvalidCredentialException;
import org.identityconnectors.framework.common.exceptions.UnknownUidException;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.AttributeInfo;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.ObjectClassInfo;
import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
import org.identityconnectors.framework.common.objects.Schema;
import org.identityconnectors.framework.common.objects.SyncDelta;
import org.identityconnectors.framework.common.objects.SyncDeltaType;
import org.identityconnectors.framework.common.objects.SyncResultsHandler;
import org.identityconnectors.framework.common.objects.SyncToken;
import org.identityconnectors.framework.common.objects.Uid;
import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
import org.identityconnectors.framework.common.objects.filter.FilterBuilder;
import org.identityconnectors.test.common.TestHelpers;
/**
* Attempts to test the Connector with the framework.
*/
public abstract class DatabaseTableTestBase {
// Constants..
static final String CHANGELOG = "changelog";
static final String ACCOUNTID = "accountId";
static final String PASSWORD = "password";
static final String MANAGER = "manager";
static final String MIDDLENAME = "middlename";
static final String FIRSTNAME = "firstname";
static final String LASTNAME = "lastname";
static final String EMAIL = "email";
static final String DEPARTMENT = "department";
static final String TITLE = "title";
static final String AGE = "age";
static final String SALARY = "salary";
static final String JPEGPHOTO = "jpegphoto";
static final String ENROLLED = "enrolled";
static final String ACTIVATE = "activate";
static final String ACCESSED = "accessed";
static final String OPENTIME = "opentime";
static final String CHANGED = "changed";
/**
* Setup logging for the {@link DatabaseTableConnector}.
*/
static final Log log = Log.getLog(DatabaseTableConnector.class);
// always seed that same for results..
static final Random r = new Random(17);
/**
* The connector
*/
DatabaseTableConnector con = null;
/**
* Create the test configuration
* @return the initialized configuration
* @throws Exception anything wrong
*/
protected abstract DatabaseTableConfiguration getConfiguration() throws Exception;
/**
* Create the test attribute sets
* @param cfg
* @return the initialized attribute set
* @throws Exception anything wrong
*/
protected abstract Set<Attribute> getCreateAttributeSet(DatabaseTableConfiguration cfg) throws Exception;
/**
* Create the test modify attribute set
* @param cfg the configuration
* @return the initialized attribute set
* @throws Exception anything wrong
*/
protected abstract Set<Attribute> getModifyAttributeSet(DatabaseTableConfiguration cfg) throws Exception;
/**
* The class load method
* @param conn
* @throws Exception
*/
protected void deleteAllFromAccounts(DatabaseTableConnection conn) throws Exception {
// update the last change
final String SQL_TEMPLATE = "DELETE FROM ACCOUNTS";
log.ok(SQL_TEMPLATE);
PreparedStatement ps = null;
try {
ps = conn.getConnection().prepareStatement(SQL_TEMPLATE);
ps.execute();
} finally {
SQLUtil.closeQuietly(ps);
}
conn.commit();
}
/**
* The close connector after test method
*/
@AfterMethod
public void disposeConnector() {
log.ok("disposeConnector");
if (con != null) {
con.dispose();
con = null;
}
}
/**
* test method
* @throws Exception
*/
@Test
public void testConfiguration() throws Exception {
// attempt to test driver info..
log.ok("testConfiguration");
DatabaseTableConfiguration config = getConfiguration();
config.validate();
}
/**
* test method
* @throws Exception
*/
@Test
public void testTestMethod() throws Exception {
log.ok("testTestMethod");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
con.test();
}
/**
* For testing purposes we creating connection an not the framework.
* @throws Exception
*/
@Test(expectedExceptions = ConnectorException.class)
public void testInvalidConnectionQuery() throws Exception {
log.ok("testInvalidConnectionQuery");
final DatabaseTableConfiguration cfg = getConfiguration();
cfg.setValidConnectionQuery("INVALID");
con = getConnector(cfg);
con.test();
}
/**
* Make sure the Create call works..
* @throws Exception
*/
@Test
public void testCreateCall() throws Exception {
log.ok("testCreateCall");
DatabaseTableConfiguration cfg = getConfiguration();
DatabaseTableConnector con = getConnector(cfg);
deleteAllFromAccounts(con.getConn());
Set<Attribute> expected = getCreateAttributeSet(cfg);
Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
// attempt to get the record back..
List<ConnectorObject> results = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, FilterBuilder.equalTo(uid));
AssertJUnit.assertTrue("expect 1 connector object", results.size() == 1);
final ConnectorObject co = results.get(0);
AssertJUnit.assertNotNull(co);
final Set<Attribute> actual = co.getAttributes();
AssertJUnit.assertNotNull(actual);
attributeSetsEquals(con.schema(), expected, actual);
}
/**
* Make sure the Create call works..
* @throws Exception
*/
@Test(expectedExceptions = ConnectorException.class)
public void testCreateCallNotNull() throws Exception {
log.ok("testCreateCallNotNull");
DatabaseTableConfiguration cfg = getConfiguration();
DatabaseTableConnector con = getConnector(cfg);
Set<Attribute> expected = getCreateAttributeSet(cfg);
// create modified attribute set
Map<String, Attribute> chMap = new HashMap<String, Attribute>(AttributeUtil.toMap(expected));
chMap.put("firstname", AttributeBuilder.build(FIRSTNAME, (String) null));
final Set<Attribute> changeSet = CollectionUtil.newSet(chMap.values());
con.create(ObjectClass.ACCOUNT, changeSet, null);
}
/**
* Make sure the Create call works..
* @throws Exception
*/
@Test
public void testCreateCallNotNullEnableEmptyString() throws Exception {
log.ok("testCreateCallNotNullEnableEmptyString");
DatabaseTableConfiguration cfg = getConfiguration();
cfg.setEnableEmptyString(true);
DatabaseTableConnector c = getConnector(cfg);
Set<Attribute> expected = getCreateAttributeSet(cfg);
// create modified attribute set
Map<String, Attribute> chMap = new HashMap<String, Attribute>(AttributeUtil.toMap(expected));
chMap.put(FIRSTNAME, AttributeBuilder.build(FIRSTNAME, (String) null));
chMap.put(LASTNAME, AttributeBuilder.build(LASTNAME, (String) null));
final Set<Attribute> changeSet = CollectionUtil.newSet(chMap.values());
Uid uid = c.create(ObjectClass.ACCOUNT, changeSet, null);
// attempt to get the record back..
List<ConnectorObject> results = TestHelpers.searchToList(c, ObjectClass.ACCOUNT, FilterBuilder.equalTo(uid));
AssertJUnit.assertTrue("expect 1 connector object", results.size() == 1);
final ConnectorObject co = results.get(0);
AssertJUnit.assertNotNull(co);
final Set<Attribute> actual = co.getAttributes();
AssertJUnit.assertNotNull(actual);
attributeSetsEquals(c.schema(), changeSet, actual, FIRSTNAME, LASTNAME);
}
/**
* Make sure the Create call works..
* @throws Exception
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testCreateUnsuported() throws Exception {
log.ok("testCreateUnsuported");
DatabaseTableConfiguration cfg = getConfiguration();
DatabaseTableConnector con = getConnector(cfg);
ObjectClass objClass = new ObjectClass("NOTSUPPORTED");
con.create(objClass, getCreateAttributeSet(cfg), null);
}
/**
* test method
* @throws Exception
*/
@Test
public void testCreateWithName() throws Exception {
log.ok("testCreateWithName");
DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> attributes = getCreateAttributeSet(cfg);
Name name = AttributeUtil.getNameFromAttributes(attributes);
final Uid uid = con.create(ObjectClass.ACCOUNT, attributes, null);
AssertJUnit.assertNotNull(uid);
AssertJUnit.assertEquals(name.getNameValue(), uid.getUidValue());
}
/**
* Test creating of the connector object, searching using UID and delete
* @throws Exception
*/
@Test
public void testCreateAndDelete() throws Exception {
log.ok("testCreateAndDelete");
final String ERR1 = "Could not find new object.";
final String ERR2 = "Found object that should not be there.";
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
try {
System.out.println("Uid: " + uid);
// attempt to find the newly created object..
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(ERR1, list.size() == 1);
//Test the created attributes are equal the searched
final ConnectorObject co = list.get(0);
AssertJUnit.assertNotNull(co);
final Set<Attribute> actual = co.getAttributes();
AssertJUnit.assertNotNull(actual);
attributeSetsEquals(con.schema(), expected, actual);
} finally {
// attempt to delete the object..
con.delete(ObjectClass.ACCOUNT, uid, null);
// attempt to find it again to make sure
// it actually deleted the object..
// attempt to find the newly created object..
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(ERR2, list.size() == 0);
try {
// now attempt to delete an object that is not there..
con.delete(ObjectClass.ACCOUNT, uid, null);
Assert.fail("Should have thrown an execption.");
} catch (UnknownUidException exp) {
// should get here..
}
}
}
/**
* Test creating of the connector object, searching using UID and delete
* @throws Exception
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testDeleteUnsupported() throws Exception {
log.ok("testDeleteUnsupported");
final String ERR1 = "Could not find new object.";
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
try {
System.out.println("Uid: " + uid);
// attempt to find the newly created object..
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(ERR1, list.size() == 1);
} finally {
// attempt to delete the object..
ObjectClass objc = new ObjectClass("UNSUPPORTED");
con.delete(objc, uid, null);
}
}
/**
* Test creating of the connector object, searching using UID and update
* @throws Exception
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testUpdateUnsupported() throws Exception {
log.ok("testUpdateUnsupported");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// retrieve the object
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(list.size() == 1);
// create updated connector object
Set<Attribute> changeSet = getModifyAttributeSet(cfg);
ObjectClass objClass = new ObjectClass("NOTSUPPORTED");
con.update(objClass, uid, changeSet, null);
}
/**
* Test creating of the connector object, searching using UID and update
* @throws Exception
*/
@Test
public void testUpdateNull() throws Exception {
log.ok("testUpdateNull");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// retrieve the object
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(list.size() == 1);
// create updated connector object
Map<String, Attribute> chMap = new HashMap<String, Attribute>(AttributeUtil.toMap(expected));
chMap.put(SALARY, AttributeBuilder.build(SALARY, (Integer) null));
// do the update
final Set<Attribute> changeSet = CollectionUtil.newSet(chMap.values());
con.update(ObjectClass.ACCOUNT, uid, changeSet, null);
// retrieve the object
List<ConnectorObject> list2 = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertNotNull(list2);
AssertJUnit.assertTrue(list2.size() == 1);
final Set<Attribute> actual = list2.get(0).getAttributes();
attributeSetsEquals(con.schema(), changeSet, actual, SALARY);
}
/**
* Test creating of the connector object, searching using UID and update
*
* @throws Exception
*/
@Test
public void testCreateAndUpdate() throws Exception {
log.ok("testCreateAndUpdate");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// retrieve the object
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(list.size() == 1);
// create updated connector object
final Set<Attribute> changeSet = getModifyAttributeSet(cfg);
uid = con.update(ObjectClass.ACCOUNT, uid, changeSet, null);
// retrieve the object
List<ConnectorObject> list2 = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertNotNull(list2);
AssertJUnit.assertTrue(list2.size() == 1);
final Set<Attribute> actual = list2.get(0).getAttributes();
attributeSetsEquals(con.schema(), changeSet, actual);
}
/**
* Test method for
* Test creating of the connector object, searching using UID and update
* @throws Exception
*/
@Test
public void testAuthenticateOriginal() throws Exception {
log.ok("testAuthenticateOriginal");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// retrieve the object
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(list.size() == 1);
// check if authenticate operation is present (it should)
Schema schema = con.schema();
Set<ObjectClassInfo> oci = schema.getSupportedObjectClassesByOperation(AuthenticationApiOp.class);
AssertJUnit.assertTrue(oci.size() >= 1);
// this should not throw any RuntimeException, on invalid authentication
final Name name = AttributeUtil.getNameFromAttributes(expected);
final GuardedString passwordValue = AttributeUtil.getPasswordValue(expected);
final Uid auid = con.authenticate(ObjectClass.ACCOUNT, name.getNameValue(), passwordValue, null);
AssertJUnit.assertEquals(uid, auid);
// cleanup (should not throw any exception.)
con.delete(ObjectClass.ACCOUNT, uid, null);
}
/**
* Test method for
* Test creating of the connector object, searching using UID and update
* @throws Exception
*/
@Test
public void testResolveUsernameOriginal() throws Exception {
log.ok("testAuthenticateOriginal");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// retrieve the object
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(list.size() == 1);
// check if authenticate operation is present (it should)
Schema schema = con.schema();
Set<ObjectClassInfo> oci = schema.getSupportedObjectClassesByOperation(AuthenticationApiOp.class);
AssertJUnit.assertTrue(oci.size() >= 1);
// this should not throw any RuntimeException, on invalid authentication
final Name name = AttributeUtil.getNameFromAttributes(expected);
final Uid auid = con.resolveUsername(ObjectClass.ACCOUNT, name.getNameValue(), null);
AssertJUnit.assertEquals(uid, auid);
// cleanup (should not throw any exception.)
con.delete(ObjectClass.ACCOUNT, uid, null);
}
/**
* Test method for
* @throws Exception
*/
@Test(expectedExceptions = InvalidCredentialException.class)
public void testAuthenticateWrongOriginal() throws Exception {
log.ok("testAuthenticateOriginal");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
// this should throw InvalidCredentials exception, as we query a
// non-existing user
con.authenticate(ObjectClass.ACCOUNT, "NON", new GuardedString("MOM".toCharArray()), null);
}
/**
* Test method for
* @throws Exception
*/
@Test(expectedExceptions = InvalidCredentialException.class)
public void testResolveUsernameWrongOriginal() throws Exception {
log.ok("testAuthenticateOriginal");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
// this should throw InvalidCredentials exception, as we query a
// non-existing user
con.resolveUsername(ObjectClass.ACCOUNT, "WRONG", null);
}
/**
* Test method for
* @throws Exception
*/
@Test(expectedExceptions = UnsupportedOperationException.class)
public void testNoPassColumnAutenticate() throws Exception {
log.ok("testNoPassColumnAutenticate");
final DatabaseTableConfiguration cfg = getConfiguration();
// Erasing password column from the configuration (it will be no longer treated as special attribute).
cfg.setPasswordColumn(null);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
con = getConnector(cfg);
// note: toAttributeSet(false), where false means, password will not be
// treated as special attribute.
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// check if authenticate operation is present (it should NOT!)
Schema schema = con.schema();
Set<ObjectClassInfo> oci = schema.getSupportedObjectClassesByOperation(AuthenticationApiOp.class);
AssertJUnit.assertTrue(oci.size() == 0);
// authentication should not be allowed -- will throw an
// IllegalArgumentException
// this should not throw any RuntimeException, on invalid authentication
final Name name = AttributeUtil.getNameFromAttributes(expected);
final GuardedString passwordValue = AttributeUtil.getPasswordValue(expected);
con.authenticate(ObjectClass.ACCOUNT, name.getNameValue(), passwordValue, null);
// cleanup (should not throw any exception.)
con.delete(ObjectClass.ACCOUNT, uid, null);
}
/**
* Test method
* @throws Exception
*/
@Test
public void testSearchByName() throws Exception {
log.ok("testSearchByName");
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// retrieve the object
List<ConnectorObject> list = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, new EqualsFilter(uid));
AssertJUnit.assertTrue(list.size() == 1);
ConnectorObject actual = list.get(0);
AssertJUnit.assertNotNull(actual);
attributeSetsEquals(con.schema(), expected, actual.getAttributes());
}
/**
* Test method to issue #238
* @throws Exception
*/
@Test
public void testSearchWithNullPassword() throws Exception {
log.ok("testSearchWithNullPassword");
final String SQL_TEMPLATE = "UPDATE {0} SET password = null WHERE {1} = ?";
final DatabaseTableConfiguration cfg = getConfiguration();
final String sql = MessageFormat.format(SQL_TEMPLATE, cfg.getTable(), cfg.getKeyColumn());
con = getConnector(cfg);
PreparedStatement ps = null;
DatabaseTableConnection conn = DatabaseTableConnection.createDBTableConnection(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
//set password to null
//expected.setPassword((String) null);
try {
List<SQLParam> values = new ArrayList<SQLParam>();
values.add(new SQLParam("user", uid.getUidValue(), Types.VARCHAR));
ps = conn.prepareStatement(sql, values);
ps.execute();
conn.commit();
} finally {
SQLUtil.closeQuietly(ps);
}
// attempt to get the record back..
List<ConnectorObject> results = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, FilterBuilder.equalTo(uid));
AssertJUnit.assertTrue("expect 1 connector object", results.size() == 1);
final Set<Attribute> attributes = results.get(0).getAttributes();
attributeSetsEquals(con.schema(), expected, attributes);
}
/**
* Test method, issue #186
* @throws Exception
*/
@Test
public void testSearchByNameAttributesToGet() throws Exception {
log.ok("testSearchByNameAttributesToGet");
// create connector
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// attempt to get the record back..
OperationOptionsBuilder opOption = new OperationOptionsBuilder();
opOption.setAttributesToGet(FIRSTNAME, LASTNAME, MANAGER);
List<ConnectorObject> results = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, FilterBuilder.equalTo(uid),
opOption.build());
AssertJUnit.assertTrue("expect 1 connector object", results.size() == 1);
final ConnectorObject co = results.get(0);
AssertJUnit.assertEquals(uid.getUidValue(), co.getUid().getUidValue());
AssertJUnit.assertEquals(uid.getUidValue(), co.getName().getNameValue());
Set<Attribute> actual = co.getAttributes();
AssertJUnit.assertNotNull(actual);
AssertJUnit.assertNull(AttributeUtil.find(AGE, actual));
AssertJUnit.assertNull(AttributeUtil.find(DEPARTMENT, actual));
AssertJUnit.assertNull(AttributeUtil.find(EMAIL, actual));
AssertJUnit.assertNotNull(AttributeUtil.find(FIRSTNAME, actual));
AssertJUnit.assertNotNull(AttributeUtil.find(LASTNAME, actual));
AssertJUnit.assertNotNull(AttributeUtil.find(MANAGER, actual));
AssertJUnit.assertNull(AttributeUtil.find(MIDDLENAME, actual));
AssertJUnit.assertNull(AttributeUtil.find(SALARY, actual));
AssertJUnit.assertNull(AttributeUtil.find(TITLE, actual));
AssertJUnit.assertNull(AttributeUtil.find(JPEGPHOTO, actual));
AssertJUnit.assertNull(AttributeUtil.find(CHANGED, actual));
}
/**
* Test method, issue #186
*
* @throws Exception
*/
@Test
public void testSearchByNameAttributesToGetExtended() throws Exception {
log.ok("testSearchByNameAttributesToGetExtended");
// create connector
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
deleteAllFromAccounts(con.getConn());
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
// attempt to get the record back..
OperationOptionsBuilder opOption = new OperationOptionsBuilder();
opOption.setAttributesToGet(FIRSTNAME, LASTNAME, MANAGER, JPEGPHOTO);
List<ConnectorObject> results = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, FilterBuilder.equalTo(uid),
opOption.build());
AssertJUnit.assertTrue("expect 1 connector object", results.size() == 1);
final ConnectorObject co = results.get(0);
AssertJUnit.assertEquals(uid.getUidValue(), co.getUid().getUidValue());
AssertJUnit.assertEquals(uid.getUidValue(), co.getName().getNameValue());
Set<Attribute> actual = co.getAttributes();
AssertJUnit.assertNotNull(actual);
AssertJUnit.assertNull(AttributeUtil.find(AGE, actual));
AssertJUnit.assertNull(AttributeUtil.find(DEPARTMENT, actual));
AssertJUnit.assertNull(AttributeUtil.find(EMAIL, actual));
AssertJUnit.assertNotNull(AttributeUtil.find(FIRSTNAME, actual));
AssertJUnit.assertNotNull(AttributeUtil.find(LASTNAME, actual));
AssertJUnit.assertNotNull(AttributeUtil.find(MANAGER, actual));
AssertJUnit.assertNull(AttributeUtil.find(MIDDLENAME, actual));
AssertJUnit.assertNull(AttributeUtil.find(SALARY, actual));
AssertJUnit.assertNull(AttributeUtil.find(TITLE, actual));
AssertJUnit.assertNotNull(AttributeUtil.find(JPEGPHOTO, actual));
AssertJUnit.assertEquals(AttributeUtil.find(JPEGPHOTO, expected), AttributeUtil.find(JPEGPHOTO, actual));
}
// TEest SYNCmethod
/**
* Test creating of the connector object, searching using UID and delete
* @throws Exception
*/
@Test
public void testSyncFull() throws Exception {
final String ERR1 = "Could not find new object.";
// create connector
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
try {
System.out.println("Uid: " + uid);
FindUidSyncHandler handler = new FindUidSyncHandler(uid);
// attempt to find the newly created object..
con.sync(ObjectClass.ACCOUNT, null, handler, null);
AssertJUnit.assertTrue(ERR1, handler.found);
AssertJUnit.assertEquals(0L, handler.token.getValue());
// assertEquals(expected, handler.deltaType); // not definned till now
//Test the created attributes are equal the searched
AssertJUnit.assertNotNull(handler.attributes);
attributeSetsEquals(con.schema(), expected, handler.attributes);
} finally {
// attempt to delete the object..
con.delete(ObjectClass.ACCOUNT, uid, null);
// attempt to find it again to make sure
// attempt to find the newly created object..
List<ConnectorObject> results = TestHelpers.searchToList(con, ObjectClass.ACCOUNT, FilterBuilder
.equalTo(uid));
AssertJUnit.assertFalse("expect 1 connector object", results.size() == 1);
try {
// now attempt to delete an object that is not there..
con.delete(ObjectClass.ACCOUNT, uid, null);
Assert.fail("Should have thrown an execption.");
} catch (UnknownUidException exp) {
// should get here..
}
}
}
/**
* Test creating of the connector object, searching using UID and delete
* @throws Exception
* @throws SQLException
*/
@Test
public void testSyncIncemental() throws Exception {
final String ERR1 = "Could not find new object.";
final String SQL_TEMPLATE = "UPDATE Accounts SET changelog = ? WHERE accountId = ?";
// create connector
final DatabaseTableConfiguration cfg = getConfiguration();
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
// create the object
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
AssertJUnit.assertNotNull(uid);
final Long changelog = 10L;
// update the last change
PreparedStatement ps = null;
DatabaseTableConnection conn = DatabaseTableConnection.createDBTableConnection(cfg);
try {
List<SQLParam> values = new ArrayList<SQLParam>();
values.add(new SQLParam("changelog", changelog, Types.INTEGER));
values.add(new SQLParam("accountId", uid.getUidValue(), Types.VARCHAR));
ps = conn.prepareStatement(SQL_TEMPLATE, values);
ps.execute();
conn.commit();
} finally {
SQLUtil.closeQuietly(ps);
}
System.out.println("Uid: " + uid);
FindUidSyncHandler ok = new FindUidSyncHandler(uid);
// attempt to find the newly created object..
con.sync(ObjectClass.ACCOUNT, new SyncToken(changelog - 1), ok, null);
AssertJUnit.assertTrue(ERR1, ok.found);
// Test the created attributes are equal the searched
AssertJUnit.assertNotNull(ok.attributes);
attributeSetsEquals(con.schema(), expected, ok.attributes);
//Not in the next result
FindUidSyncHandler empt = new FindUidSyncHandler(uid);
// attempt to find the newly created object..
con.sync(ObjectClass.ACCOUNT, ok.token, empt, null);
AssertJUnit.assertFalse(ERR1, empt.found);
}
/**
* Test creating of the connector object, searching using UID and delete
* @throws Exception
* @throws SQLException
*/
@Test
public void testSyncUsingIntegerColumn() throws Exception {
final String ERR1 = "Could not find new object.";
final String SQL_TEMPLATE = "UPDATE Accounts SET age = ? WHERE accountId = ?";
final DatabaseTableConfiguration cfg = getConfiguration();
cfg.setChangeLogColumn(AGE);
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
// update the last change
PreparedStatement ps = null;
DatabaseTableConnection conn = DatabaseTableConnection.createDBTableConnection(cfg);
Integer changed = new Long(System.currentTimeMillis()).intValue();
try {
List<SQLParam> values = new ArrayList<SQLParam>();
values.add(new SQLParam("age", changed, Types.INTEGER));
values.add(new SQLParam("accountId", uid.getUidValue(), Types.VARCHAR));
ps = conn.prepareStatement(SQL_TEMPLATE, values);
ps.execute();
conn.commit();
} finally {
SQLUtil.closeQuietly(ps);
}
System.out.println("Uid: " + uid);
FindUidSyncHandler ok = new FindUidSyncHandler(uid);
// attempt to find the newly created object..
con.sync(ObjectClass.ACCOUNT, new SyncToken(changed - 1000), ok, null);
AssertJUnit.assertTrue(ERR1, ok.found);
// Test the created attributes are equal the searched
AssertJUnit.assertNotNull(ok.attributes);
attributeSetsEquals(con.schema(), expected, ok.attributes, AGE);
System.out.println("Uid: " + uid);
FindUidSyncHandler empt = new FindUidSyncHandler(uid);
// attempt to find the newly created object..
con.sync(ObjectClass.ACCOUNT, ok.token, empt, null);
AssertJUnit.assertFalse(ERR1, empt.found);
}
/**
* Test creating of the connector object, searching using UID and delete
* @throws Exception
* @throws SQLException
*/
@Test
public void testSyncUsingLongColumn() throws Exception {
final String ERR1 = "Could not find new object.";
final String SQL_TEMPLATE = "UPDATE Accounts SET accessed = ? WHERE accountId = ?";
final DatabaseTableConfiguration cfg = getConfiguration();
cfg.setChangeLogColumn(ACCESSED);
con = getConnector(cfg);
final Set<Attribute> expected = getCreateAttributeSet(cfg);
final Uid uid = con.create(ObjectClass.ACCOUNT, expected, null);
// update the last change
PreparedStatement ps = null;
DatabaseTableConnection conn = DatabaseTableConnection.createDBTableConnection(cfg);
Integer changed = new Long(System.currentTimeMillis()).intValue();
try {
List<SQLParam> values = new ArrayList<SQLParam>();
values.add(new SQLParam("accessed", changed, Types.INTEGER));
values.add(new SQLParam("accountId", uid.getUidValue(), Types.VARCHAR));
ps = conn.prepareStatement(SQL_TEMPLATE, values);
ps.execute();
conn.commit();
} finally {
SQLUtil.closeQuietly(ps);
}
System.out.println("Uid: " + uid);
FindUidSyncHandler ok = new FindUidSyncHandler(uid);
// attempt to find the newly created object..
con.sync(ObjectClass.ACCOUNT, new SyncToken(changed - 1000), ok, null);
AssertJUnit.assertTrue(ERR1, ok.found);
// Test the created attributes are equal the searched
AssertJUnit.assertNotNull(ok.attributes);
attributeSetsEquals(con.schema(), expected, ok.attributes, ACCESSED);
System.out.println("Uid: " + uid);
FindUidSyncHandler empt = new FindUidSyncHandler(uid);
// attempt to find the newly created object..
con.sync(ObjectClass.ACCOUNT, ok.token, empt, null);
AssertJUnit.assertFalse(ERR1, empt.found);
}
// Helper Methods/Classes
/**
* @param cfg
* @return the connector
*/
protected DatabaseTableConnector getConnector(DatabaseTableConfiguration cfg) {
con = new DatabaseTableConnector();
con.init(cfg);
return con;
}
/**
* @param schema a schema
* @param expected an expected value
* @param actual an actual value
* @param ignore ignore list
*/
protected void attributeSetsEquals(final Schema schema, Set<Attribute> expected, Set<Attribute> actual, String ... ignore) {
attributeSetsEquals(schema, AttributeUtil.toMap(expected), AttributeUtil.toMap(actual), ignore);
}
/**
* @param schema a schema
* @param expMap an expected value map
* @param actMap an actual value map
* @param ignore ignore list
*/
protected void attributeSetsEquals(final Schema schema, final Map<String, Attribute> expMap, final Map<String, Attribute> actMap, String ... ignore) {
log.ok("attributeSetsEquals");
final Set<String> ignoreSet = new HashSet<String>(Arrays.asList(ignore));
if(schema != null ) {
final ObjectClassInfo oci = schema.findObjectClassInfo(ObjectClass.ACCOUNT_NAME);
final Set<AttributeInfo> ais = oci.getAttributeInfo();
for (AttributeInfo ai : ais) {
//ignore not returned by default
if (!ai.isReturnedByDefault()) {
ignoreSet.add(ai.getName());
}
//ignore not readable attributes
if (!ai.isReadable()) {
ignoreSet.add(ai.getName());
}
}
}
Set<String> names = CollectionUtil.newCaseInsensitiveSet();
names.addAll(expMap.keySet());
names.addAll(actMap.keySet());
names.removeAll(ignoreSet);
names.remove(Uid.NAME);
int missing = 0;
List<String> mis = new ArrayList<String>();
List<String> extra = new ArrayList<String>();
for (String attrName : names) {
final Attribute expAttr = expMap.get(attrName);
final Attribute actAttr = actMap.get(attrName);
if(expAttr != null && actAttr != null ) {
AssertJUnit.assertEquals(attrName, expAttr, actAttr);
} else {
missing = missing + 1;
if(expAttr != null) {
mis.add(expAttr.getName());
}
if(actAttr != null) {
extra.add(actAttr.getName());
}
}
}
AssertJUnit.assertEquals("missing attriburtes extra "+extra+" , missing "+mis, 0, missing);
log.ok("attributeSets are equal!");
}
protected static class FindUidSyncHandler implements SyncResultsHandler {
/**
* Determines if found..
*/
public boolean found = false;
/**
* Uid to find.
*/
public final Uid uid;
/**
*
*/
public SyncDeltaType deltaType;
/**
* Sync token to find
*/
public SyncToken token;
/**
* Attribute set to find
*/
public Set<Attribute> attributes = null;
/**
* @param uid
*/
public FindUidSyncHandler(Uid uid) {
this.uid = uid;
}
/* (non-Javadoc)
* @see org.identityconnectors.framework.common.objects.SyncResultsHandler#handle(org.identityconnectors.framework.common.objects.SyncDelta)
*/
public boolean handle(SyncDelta delta) {
System.out.println("SyncDeltat: " + delta);
if (delta.getUid().equals(uid)) {
found = true;
this.attributes = delta.getObject().getAttributes();
this.deltaType = delta.getDeltaType();
this.token = delta.getToken();
return false;
}
return true;
}
}
}