/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.translator.ldap;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapContext;
import org.junit.Test;
import org.mockito.Mockito;
import org.teiid.cdk.api.TranslationUtility;
import org.teiid.language.Command;
import org.teiid.language.Literal;
import org.teiid.metadata.Column;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.query.unittest.RealMetadataFactory;
import org.teiid.translator.ExecutionContext;
@SuppressWarnings("nls")
public class TestQueryExecution {
private static final class SimpleNamingEnumeration<T> implements
NamingEnumeration<T> {
private final Iterator<T> iter;
private SimpleNamingEnumeration(Iterator<T> iter) {
this.iter = iter;
}
@Override
public boolean hasMoreElements() {
return iter.hasNext();
}
@Override
public T nextElement() {
return iter.next();
}
@Override
public void close() throws NamingException {
}
@Override
public boolean hasMore() throws NamingException {
return hasMoreElements();
}
@Override
public T next() throws NamingException {
return nextElement();
}
}
@Test public void testUnwrap() throws Exception {
TranslationUtility util = new TranslationUtility(RealMetadataFactory.fromDDL("CREATE FOREIGN TABLE GROUP_PEOPLE (objectClass string options (\"teiid_ldap:unwrap\" true)) OPTIONS(nameinsource 'ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU', updatable true);", "x", "y"));
Command command = util.parseCommand("select * from group_people");
ExecutionContext ec = Mockito.mock(ExecutionContext.class);
RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
LdapContext connection = Mockito.mock(LdapContext.class);
LdapContext ctx = Mockito.mock(LdapContext.class);
Mockito.stub(connection.lookup("ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU")).toReturn(ctx);
Attributes attribs = Mockito.mock(Attributes.class);
Attribute attrib = Mockito.mock(Attribute.class);
Mockito.stub(attrib.size()).toReturn(2);
NamingEnumeration attribValues = new SimpleNamingEnumeration(Arrays.asList("foo", "bar").iterator());
Mockito.stub(attrib.getAll()).toReturn(attribValues);
Mockito.stub(attribs.get("objectClass")).toReturn(attrib);
final SearchResult sr = new SearchResult("x", null, attribs);
NamingEnumeration<SearchResult> enumeration = new SimpleNamingEnumeration(Arrays.asList(sr).iterator());
Mockito.stub(ctx.search((String)Mockito.any(), (String)Mockito.any(), (SearchControls)Mockito.any())).toReturn(enumeration);
LDAPExecutionFactory lef = new LDAPExecutionFactory();
lef.start();
LDAPSyncQueryExecution execution = (LDAPSyncQueryExecution)lef.createExecution(command, ec, rm, connection);
execution.execute();
List<?> result = execution.next();
assertEquals(Arrays.asList("foo"), result);
result = execution.next();
assertEquals(Arrays.asList("bar"), result);
assertNull(execution.next());
//missing attribute handling
Mockito.stub(attribs.get("objectClass")).toReturn(null);
enumeration = new SimpleNamingEnumeration(Arrays.asList(sr).iterator());
Mockito.stub(ctx.search((String)Mockito.any(), (String)Mockito.any(), (SearchControls)Mockito.any())).toReturn(enumeration);
execution = (LDAPSyncQueryExecution)lef.createExecution(command, ec, rm, connection);
execution.execute();
result = execution.next();
assertEquals(Collections.singletonList(null), result);
assertNull(execution.next());
//empty attribute handling
attribValues = new SimpleNamingEnumeration(new ArrayList<Object>().iterator());
Mockito.stub(attrib.size()).toReturn(0);
Mockito.stub(attrib.getAll()).toReturn(attribValues);
Mockito.stub(attribs.get("objectClass")).toReturn(attrib);
enumeration = new SimpleNamingEnumeration(Arrays.asList(sr).iterator());
Mockito.stub(ctx.search((String)Mockito.any(), (String)Mockito.any(), (SearchControls)Mockito.any())).toReturn(enumeration);
execution = (LDAPSyncQueryExecution)lef.createExecution(command, ec, rm, connection);
execution.execute();
result = execution.next();
assertEquals(Collections.singletonList(null), result);
assertNull(execution.next());
}
@Test public void testUnwrapExtract() throws Exception {
TranslationUtility util = new TranslationUtility(RealMetadataFactory.fromDDL("CREATE FOREIGN TABLE GROUP_PEOPLE (\"member\" string options (\"teiid_ldap:unwrap\" true, \"teiid_ldap:rdn_type\" 'uid', \"teiid_ldap:dn_prefix\" 'ou=users')) OPTIONS(nameinsource 'ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU', updatable true);", "x", "y"));
Command command = util.parseCommand("select * from group_people");
ExecutionContext ec = Mockito.mock(ExecutionContext.class);
RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
LdapContext connection = Mockito.mock(LdapContext.class);
LdapContext ctx = Mockito.mock(LdapContext.class);
Mockito.stub(connection.lookup("ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU")).toReturn(ctx);
BasicAttributes attributes = new BasicAttributes(true);
BasicAttribute attrib = new BasicAttribute("member");
attributes.put(attrib);
attrib.add("uid=foo,ou=users");
attrib.add("user=bar,ou=users"); //does not match rdn type
attrib.add("uid=bar"); //does not dn prefix
final SearchResult sr = new SearchResult("x", null, attributes);
NamingEnumeration<SearchResult> enumeration = new SimpleNamingEnumeration(Arrays.asList(sr).iterator());
Mockito.stub(ctx.search((String)Mockito.any(), (String)Mockito.any(), (SearchControls)Mockito.any())).toReturn(enumeration);
LDAPExecutionFactory lef = new LDAPExecutionFactory();
lef.start();
LDAPSyncQueryExecution execution = (LDAPSyncQueryExecution)lef.createExecution(command, ec, rm, connection);
execution.execute();
List<?> result = execution.next();
assertEquals(Arrays.asList("foo"), result);
assertNull(execution.next());
}
@Test public void testMultiAttribute() throws NamingException {
Column c = new Column();
c.setDefaultValue(LDAPQueryExecution.MULTIVALUED_CONCAT);
Attribute a = LDAPUpdateExecution.createBasicAttribute("x", new Literal("a?b?c", String.class), c);
assertEquals(3, a.size());
assertEquals("b", Collections.list(a.getAll()).get(1));
}
}