private void doTestRequestTimeout(boolean isPersistentSearch) throws Exception { InetSocketAddress address = TestCaseUtils.findFreeSocketAddress(); /* * Use a mock server implementation which will ignore incoming requests * and leave the client waiting forever for a response. */ @SuppressWarnings("unchecked") LDAPListener listener = new LDAPListener( address, Connections.newServerConnectionFactory(mock(RequestHandler.class))); /* * Use a very long time out in order to prevent the timeout thread from * triggering the timeout. */ LDAPConnectionFactory factory = new LDAPConnectionFactory( address.getHostName(), address.getPort(), Options.defaultOptions() .set(TIMEOUT_IN_MILLISECONDS, TimeUnit.SECONDS.toMillis((long) 100))); GrizzlyLDAPConnection connection = (GrizzlyLDAPConnection) factory.getConnection(); try { SearchRequest request = Requests.newSearchRequest("dc=test", SearchScope.BASE_OBJECT, "(objectClass=*)"); if (isPersistentSearch) { request.addControl(PersistentSearchRequestControl.newControl(true, true, true)); } SearchResultHandler searchHandler = mock(SearchResultHandler.class); @SuppressWarnings("unchecked") ExceptionHandler<LdapException> exceptionHandler = mock(ExceptionHandler.class); connection.searchAsync(request, searchHandler).thenOnException(exceptionHandler); // Pass in a time which is guaranteed to trigger expiration. connection.handleTimeout(System.currentTimeMillis() + 1000000); if (isPersistentSearch) { verifyZeroInteractions(searchHandler); } else { ArgumentCaptor<LdapException> arg = ArgumentCaptor.forClass(LdapException.class); verify(exceptionHandler).handleException(arg.capture()); assertThat(arg.getValue()).isInstanceOf(TimeoutResultException.class); assertThat(arg.getValue().getResult().getResultCode()) .isEqualTo(ResultCode.CLIENT_SIDE_TIMEOUT); } } finally { connection.close(); listener.close(); factory.close(); } }
/** * Search the Database Server using the provided search request. * * @param request The search request. * @param handler A search result handler which can be used to asynchronously process the search * result entries and references as they are received, may be null. * @return The result of the operation. * @throws ErrorResultException If the result code indicates that the request failed for some * reason. * @throws SQLException If the SQL query has an invalid format. * @throws NullPointerException If {@code request} was {@code null}, or if a corresponding mapping * value could not be found in the mapping component. */ @Override public Result search(SearchRequest request, SearchResultHandler handler) throws ErrorResultException { Result r; try { // Split up the DN the of the request. final DN DN = request.getName(); final int DNSize = DN.size(); final String baseDN = DN.parent(DNSize - 2).toString(); RDN OU = null; RDN rDN = null; String OUName = ""; String rDNAttributeName = ""; String rDNAttributeValue = ""; if (DNSize > 3) { OU = DN.parent(1).rdn(); OUName = OU.getFirstAVA().getAttributeValue().toString(); rDN = DN.parent(0).rdn(); rDNAttributeName = rDN.getFirstAVA().getAttributeType().getNameOrOID(); rDNAttributeValue = rDN.getFirstAVA().getAttributeValue().toString(); } else if (DNSize > 2) { OU = DN.parent(0).rdn(); OUName = OU.getFirstAVA().getAttributeValue().toString(); } List<String> returnAttributeNames = request.getAttributes(); final List<String> removeAttributesList = new ArrayList<String>(); // Get all column names to be returned to return full records. if (returnAttributeNames == null) { if (OU != null) { returnAttributeNames = jdbcm.getOrganizationalUnitAttributes(baseDN, OUName); if (returnAttributeNames == null) throw new NullPointerException( "JDBC Error: Could not find any matching attributes in OU: '" + OUName + "'."); final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName); for (Iterator<String> iterAttributes = returnAttributeNames.iterator(); iterAttributes.hasNext(); ) { String returnAttributeName = iterAttributes.next(); final String returnColumnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, returnAttributeName); if (returnColumnName == null) removeAttributesList.add(returnAttributeName); } returnAttributeNames.removeAll(removeAttributesList); } else { final List<String> OUList = jdbcm.getOrganizationalUnits(baseDN); if (OUList == null) throw new NullPointerException( "JDBC Error: Could not find any matching organizational units in DN: '" + baseDN + "'."); for (Iterator<String> iterOU = OUList.iterator(); iterOU.hasNext(); ) { OUName = iterOU.next(); final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName); returnAttributeNames = jdbcm.getOrganizationalUnitAttributes(baseDN, OUName); for (Iterator<String> iterAttributes = returnAttributeNames.iterator(); iterAttributes.hasNext(); ) { String returnAttributeName = iterAttributes.next(); final String returnColumnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, returnAttributeName); if (returnColumnName == null) removeAttributesList.add(returnAttributeName); } returnAttributeNames.removeAll(removeAttributesList); } } } // Convert the search filter. final Filter searchFilter = request.getFilter(); final String convertedFilterString = convertSearchFilter(searchFilter, baseDN, OUName); if (convertedFilterString.startsWith("Err:")) { String[] errorStringSplitter = convertedFilterString.split("Err:"); throw new NullPointerException(errorStringSplitter[1]); } final List<String> returnColumnNames = new ArrayList<String>(); // Search mapping for the corresponding column name for each return attribute. for (Iterator<String> iter = returnAttributeNames.iterator(); iter.hasNext(); ) { if (OU == null) { final String returnAttributeName = iter.next(); final List<String> OUList = jdbcm.getOrganizationalUnits(baseDN); if (OUList == null) throw new NullPointerException( "JDBC Error: Could not find any matching organizational units in DN: '" + baseDN + "'."); for (Iterator<String> iterOU = OUList.iterator(); iterOU.hasNext(); ) { OUName = iterOU.next(); final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName); final String returnColumnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, returnAttributeName); if (returnColumnName == null) continue; else returnColumnNames.add(returnColumnName); break; } } else { final String returnAttributeName = iter.next(); final String tableName = jdbcm.getTableNameFromMapping(baseDN, OUName); if (tableName == null) throw new NullPointerException( "JDBC Error: Could not find matching table name for OU: '" + OUName + "' in DN: '" + baseDN + "'. Please check if mapping was succesful."); final String returnColumnName = jdbcm.getColumnNameFromMapping(tableName, baseDN, OUName, returnAttributeName); if (returnColumnName == null) throw new NullPointerException( "JDBC Error: Could not find matching column name for attribute: '" + returnAttributeName + "'. Please check if mapping was succesful."); returnColumnNames.add(returnColumnName); } } String selectString = ""; String fromString = ""; String whereString = convertedFilterString; if (returnAttributeNames.isEmpty()) selectString = "*"; // Build the SQL SELECT string. if (OU == null) { final List<String> OUList = jdbcm.getOrganizationalUnits(baseDN); if (OUList == null) throw new NullPointerException( "JDBC Error: Could not find any matching organizational units in DN: '" + baseDN + "'."); for (int i = 0; i < OUList.size(); i++) { final String currentOU = OUList.get(i); final String currentTable = jdbcm.getTableNameFromMapping(baseDN, currentOU); if (currentTable == null) continue; final List<String> currentTableColumnNames = jdbcm.getTableColumns(currentTable); if (!fromString.isEmpty()) fromString = fromString.concat(","); fromString = fromString.concat(currentTable); for (int j = 0; j < returnColumnNames.size(); j++) { final String returnColumnName = returnColumnNames.get(j); if (currentTableColumnNames.contains(returnColumnName)) { if (!selectString.isEmpty()) selectString = selectString.concat(","); selectString = selectString.concat(currentTable + "." + returnColumnName); } } } } else { final String selectTable = jdbcm.getTableNameFromMapping(baseDN, OUName); if (selectTable == null) throw new NullPointerException( "JDBC Error: Could not find matching table name for OU: '" + OUName + "' in DN: '" + baseDN + "'. Please check if mapping was succesful."); fromString = fromString.concat(selectTable); for (int j = 0; j < returnColumnNames.size(); j++) { final String returnColumnName = returnColumnNames.get(j); if (returnColumnName == null) continue; if (!selectString.isEmpty()) selectString = selectString.concat(","); selectString = selectString.concat(returnColumnName); } if (rDN != null) { final String columnName = jdbcm.getColumnNameFromMapping(selectTable, baseDN, OUName, rDNAttributeName); if (columnName == null) throw new NullPointerException( "JDBC Error: Could not find matching column name for attribute: '" + rDNAttributeName + "'. Please check if mapping was succesful."); whereString = columnName + "='" + rDNAttributeValue + "'"; } } // Build the SQL query. final Statement st = connection.createStatement(); String sql = "SELECT " + selectString + " FROM " + fromString; if (!whereString.isEmpty()) sql = sql.concat(" WHERE " + whereString); ResultSet rs = st.executeQuery(sql); ResultSetMetaData rsmd = rs.getMetaData(); // Fill the entries result for this query. searchEntries.clear(); while (rs.next()) { Entry e = new LinkedHashMapEntry(); for (int i = 1; i <= rsmd.getColumnCount(); i++) { e.addAttribute(rsmd.getTableName(i) + "_" + rsmd.getColumnName(i), rs.getObject(i)); } searchEntries.add(e); } r = Responses.newResult(ResultCode.SUCCESS); } catch (SQLException e) { System.out.println(e.toString()); r = Responses.newResult(ResultCode.OPERATIONS_ERROR); r.setCause(e); } catch (NullPointerException e) { System.out.println(e.toString()); r = Responses.newCompareResult(ResultCode.OPERATIONS_ERROR); r.setCause(e); } return r; }