[teiid-commits] teiid SVN: r3357 - in branches/7.4.x: connectors/translator-ldap/src/main/java/org/teiid/translator/ldap and 1 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Wed Aug 3 11:13:06 EDT 2011


Author: shawkins
Date: 2011-08-03 11:13:06 -0400 (Wed, 03 Aug 2011)
New Revision: 3357

Modified:
   branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html
   branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java
   branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java
   branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml
Log:
TEIID-1659 adding pagination support for ldap

Modified: branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html	2011-08-01 18:58:02 UTC (rev 3356)
+++ branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html	2011-08-03 15:13:06 UTC (rev 3357)
@@ -69,6 +69,7 @@
 			<LI><B>Sync at Start</B> - When a node is restarted in a cluster, at end of start cycle Teiid will asynchronously fetch the cached internal materialized view contents from other nodes.
 		</UL>
 	</LI>
+	<LI><B>LDAP Pagination</B> - the ldap translator now supports pagination for retrieving large results from directory servers like Active Directory and OpenLDAP.
 </UL>
 
 <h2><a name="Compatibility">Compatibility Issues</a></h2>

Modified: branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java
===================================================================
--- branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java	2011-08-01 18:58:02 UTC (rev 3356)
+++ branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java	2011-08-03 15:13:06 UTC (rev 3357)
@@ -53,6 +53,7 @@
 	private String searchDefaultBaseDN;
 	private boolean restrictToObjectClass;
 	private SearchDefaultScope searchDefaultScope = SearchDefaultScope.ONELEVEL_SCOPE;
+	private boolean usePagination;
 	
 	public LDAPExecutionFactory() {
 		this.setMaxInCriteriaSize(1000);
@@ -89,7 +90,7 @@
 	@Override
 	public ResultSetExecution createResultSetExecution(QueryExpression command,ExecutionContext executionContext, RuntimeMetadata metadata, LdapContext context)
 			throws TranslatorException {
-		return new LDAPSyncQueryExecution((Select)command, this, context);
+		return new LDAPSyncQueryExecution((Select)command, this, executionContext, context);
 	}
 	
 	@Override
@@ -142,5 +143,15 @@
 	@Override
 	public boolean supportsNotCriteria() {
 		return true;
+	}
+
+	@TranslatorProperty(display="Use Pagination", description="Use a PagedResultsControl to page through large results.  This is not supported by all directory servers.")
+	public boolean usePagination() {
+		return usePagination;
 	}	
+	
+	public void setUsePagination(boolean usePagination) {
+		this.usePagination = usePagination;
+	}
+	
 }

Modified: branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java
===================================================================
--- branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java	2011-08-01 18:58:02 UTC (rev 3356)
+++ branches/7.4.x/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java	2011-08-03 15:13:06 UTC (rev 3357)
@@ -91,6 +91,8 @@
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.Control;
 import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.PagedResultsControl;
+import javax.naming.ldap.PagedResultsResponseControl;
 import javax.naming.ldap.SortControl;
 import javax.naming.ldap.SortKey;
 
@@ -98,6 +100,7 @@
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
 import org.teiid.metadata.Column;
+import org.teiid.translator.ExecutionContext;
 import org.teiid.translator.ResultSetExecution;
 import org.teiid.translator.TranslatorException;
 import org.teiid.translator.TypeFacility;
@@ -119,6 +122,8 @@
 	private IQueryToLdapSearchParser parser;
 	private Select query;
 	private LDAPExecutionFactory executionFactory;
+	private ExecutionContext executionContext;
+	private SearchControls ctrls;
 
 	/** 
 	 * Constructor
@@ -127,10 +132,11 @@
 	 * @param logger the ConnectorLogger
 	 * @param ldapCtx the LDAP Context
 	 */
-	public LDAPSyncQueryExecution(Select query, LDAPExecutionFactory factory, LdapContext ldapCtx) {
+	public LDAPSyncQueryExecution(Select query, LDAPExecutionFactory factory, ExecutionContext context, LdapContext ldapCtx) {
 		this.ldapConnection = ldapCtx;
 		this.query = query;
 		this.executionFactory = factory;
+		this.executionContext = context;
 	}
 
 	/** 
@@ -146,31 +152,40 @@
 
 		// Create and configure the new search context.
 		createSearchContext();
-		SearchControls ctrls = setSearchControls();
-		setStandardRequestControls();
+		ctrls = setSearchControls();
+		String ctxName = searchDetails.getContextName();
+		String filter = searchDetails.getContextFilter();
+		if (ctxName == null || filter == null || ctrls == null) {
+			throw new TranslatorException(LogConstants.CTX_CONNECTOR, "Search context, filter, or controls were null. Cannot execute search."); //$NON-NLS-1$
+		}
+		setRequestControls(null);
 		// Execute the search.
-		executeSearch(ctrls);
+		executeSearch();
 	}
 
 	/** 
 	 * Set the standard request controls
 	 */
-	private void setStandardRequestControls() throws TranslatorException {
-		Control[] sortCtrl = new Control[1];
+	private void setRequestControls(byte[] cookie) throws TranslatorException {
+		List<Control> ctrl = new ArrayList<Control>();
 		SortKey[] keys = searchDetails.getSortKeys();
-		if (keys != null) {
-			try {
-				sortCtrl[0] = new SortControl(keys, Control.NONCRITICAL);
-				this.ldapCtx.setRequestControls(sortCtrl);
-				LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Sort ordering was requested, and sort control was created successfully."); //$NON-NLS-1$
-			} catch (NamingException ne) {
-	            final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.setControlsError") +  //$NON-NLS-1$
-	            " : "+ne.getExplanation(); //$NON-NLS-1$
-				throw new TranslatorException(msg);
-			} catch(IOException e) {
-	            final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.setControlsError"); //$NON-NLS-1$
-				throw new TranslatorException(e,msg);
+		try {			
+			if (keys != null) {
+				ctrl.add(new SortControl(keys, Control.NONCRITICAL));
 			}
+			if (this.executionFactory.usePagination()) {
+				ctrl.add(new PagedResultsControl(this.executionContext.getBatchSize(), cookie, Control.CRITICAL));
+			}
+			if (!ctrl.isEmpty()) {
+				this.ldapCtx.setRequestControls(ctrl.toArray(new Control[ctrl.size()]));
+				LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Sort/pagination controls were created successfully."); //$NON-NLS-1$
+			}
+		} catch (NamingException ne) {
+            final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.setControlsError") +  //$NON-NLS-1$
+            " : "+ne.getExplanation(); //$NON-NLS-1$
+			throw new TranslatorException(ne, msg);
+		} catch(IOException e) {
+			throw new TranslatorException(e);
 		}
 	}
 
@@ -219,22 +234,14 @@
 	 * Perform the LDAP search against the subcontext, using the filter and 
 	 * search controls appropriate to the query and model metadata.
 	 */
-	private void executeSearch(SearchControls ctrls) throws TranslatorException {
-		String ctxName = searchDetails.getContextName();
+	private void executeSearch() throws TranslatorException {
 		String filter = searchDetails.getContextFilter();
-		if (ctxName == null || filter == null || ctrls == null) {
-			LogManager.logError(LogConstants.CTX_CONNECTOR, "Search context, filter, or controls were null. Cannot execute search."); //$NON-NLS-1$
-		}
 		try {
 			searchEnumeration = this.ldapCtx.search("", filter, ctrls); //$NON-NLS-1$
 		} catch (NamingException ne) {
-			LogManager.logError(LogConstants.CTX_CONNECTOR, "LDAP search failed. Attempted to search context " //$NON-NLS-1$
-					+ ctxName + " using filter " + filter); //$NON-NLS-1$
             final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.execSearchError"); //$NON-NLS-1$
-			throw new TranslatorException(msg + " : " + ne.getExplanation());  //$NON-NLS-1$ 
+			throw new TranslatorException(ne, msg + " : " + ne.getExplanation());  //$NON-NLS-1$ 
 		} catch(Exception e) {
-			LogManager.logError(LogConstants.CTX_CONNECTOR, "LDAP search failed. Attempted to search context " //$NON-NLS-1$
-					+ ctxName + " using filter " + filter); //$NON-NLS-1$
             final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.execSearchError"); //$NON-NLS-1$
 			throw new TranslatorException(e, msg); 
 		}
@@ -294,6 +301,27 @@
 				SearchResult searchResult = (SearchResult) searchEnumeration.next();
 				result = getRow(searchResult);
 			}
+			
+			if (result == null && this.executionFactory.usePagination()) {
+			    byte[] cookie = null;
+				Control[] controls = ldapCtx.getResponseControls();
+		        if (controls != null) {
+		        	for (int i = 0; i < controls.length; i++) {
+		        		if (controls[i] instanceof PagedResultsResponseControl) {
+		        			PagedResultsResponseControl prrc = (PagedResultsResponseControl)controls[i];
+		                    cookie = prrc.getCookie();
+		        		}
+		        	}
+		        }
+		        
+		        if (cookie == null) {
+		        	return null;
+		        }
+	
+		        setRequestControls(cookie);
+		        executeSearch();
+		        return next();
+			}
 
 			return result;
 		} catch (SizeLimitExceededException e) {
@@ -451,22 +479,4 @@
 		}
 	}
 	
-
-	/**
-	 * Active Directory and OpenLDAP supports PagedResultsControls, so I left
-	 * this method in here in case we decide to extend support for this control
-	 * in the future.
-	 */
-//	private void setADRequestControls(int maxBatchSize) {
-//		try {
-//			ldapCtx.setRequestControls(new Control[] { new PagedResultsControl(
-//					maxBatchSize, Control.CRITICAL) });
-//		} catch (NamingException ne) {
-//			logger.logError("Failed to set page size for LDAP results. Please ensure that paged results controls are supported by the LDAP server implementation."); //$NON-NLS-1$
-//			ne.printStackTrace();
-//		} catch (IOException ioe) {
-//			logger.logError("IO Exception while setting paged results control."); //$NON-NLS-1$
-//			ioe.printStackTrace();
-//		}
-//	}
 }

Modified: branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml
===================================================================
--- branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml	2011-08-01 18:58:02 UTC (rev 3356)
+++ branches/7.4.x/documentation/reference/src/main/docbook/en-US/content/translators.xml	2011-08-03 15:13:06 UTC (rev 3357)
@@ -545,6 +545,11 @@
                         <entry>Restrict Searches to objectClass named in the Name field for a table</entry>
                         <entry>false</entry>
                     </row>
+                    <row>
+                    	<entry>UsePagination</entry>
+                        <entry>Use a PagedResultsControl to page through large results.  This is not supported by all directory servers.</entry>
+                        <entry>false</entry>
+                    </row>
                 </tbody>
             </tgroup>
         </table>



More information about the teiid-commits mailing list