use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.
the class ApacheLdapProviderImpl method init.
@Override
public void init(final ChaiConfiguration chaiConfig, final ChaiProviderFactory providerFactory) throws ChaiUnavailableException {
this.chaiConfig = chaiConfig;
super.init(chaiConfig, providerFactory);
// grab the first URL from the list.
currentLdapUrl = chaiConfig.bindURLsAsList().get(0);
final URI ldapURL = URI.create(currentLdapUrl);
final LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
ldapConnectionConfig.setLdapHost(ldapURL.getHost());
ldapConnectionConfig.setLdapPort(ldapURL.getPort());
if (ldapURL.getScheme().equalsIgnoreCase("ldaps")) {
ldapConnectionConfig.setUseSsl(true);
final boolean usePromiscuousSSL = Boolean.parseBoolean(chaiConfig.getSetting(ChaiSetting.PROMISCUOUS_SSL));
if (usePromiscuousSSL) {
try {
final PromiscuousTrustManager promiscuousTrustManager = new PromiscuousTrustManager();
ldapConnectionConfig.setTrustManagers(promiscuousTrustManager);
} catch (Exception e) {
LOGGER.error("error creating promiscuous ssl ldap socket factory: " + e.getMessage());
}
} else if (chaiConfig.getTrustManager() != null) {
try {
final X509TrustManager[] trustManager = chaiConfig.getTrustManager();
ldapConnectionConfig.setTrustManagers(trustManager);
} catch (Exception e) {
LOGGER.error("error creating configured ssl ldap socket factory: " + e.getMessage());
}
}
}
final LdapConnection newConnection;
try {
newConnection = new LdapNetworkConnection(ldapConnectionConfig);
newConnection.connect();
final String bindPassword = chaiConfig.getSetting(ChaiSetting.BIND_PASSWORD);
final String bindDN = chaiConfig.getSetting(ChaiSetting.BIND_DN);
newConnection.bind(bindDN, bindPassword);
} catch (LdapException e) {
final String message = e.getMessage();
if (message.contains("Cannot connect on the server")) {
throw new ChaiUnavailableException(message, ChaiError.COMMUNICATION, false, false);
}
throw ChaiUnavailableException.forErrorMessage(message);
} catch (Exception e) {
e.printStackTrace();
final String message = e.getMessage();
throw new ChaiUnavailableException(message, ChaiError.UNKNOWN, false, false);
}
connection = newConnection;
}
use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.
the class ChaiProviderFactory method newProviderImpl.
ChaiProviderImplementor newProviderImpl(final ChaiConfiguration chaiConfiguration, final boolean failOverWrapperChild) throws ChaiUnavailableException {
checkStatus();
ChaiProviderImplementor providerImpl;
try {
final boolean enableFailover = "true".equalsIgnoreCase(chaiConfiguration.getSetting(ChaiSetting.FAILOVER_ENABLE));
if (enableFailover && !failOverWrapperChild) {
providerImpl = FailOverWrapper.forConfiguration(this, chaiConfiguration);
} else {
if (LOGGER.isTraceEnabled()) {
final String debugMsg = "creating new jndi ldap connection to " + chaiConfiguration.getSetting(ChaiSetting.BIND_URLS) + " as " + chaiConfiguration.getSetting(ChaiSetting.BIND_DN);
LOGGER.trace(debugMsg);
}
providerImpl = createConcreteProvider(this, chaiConfiguration, true);
}
} catch (Exception e) {
final String errorMsg = "unable to create connection: " + e.getClass().getName() + ":" + e.getMessage();
if (e instanceof ChaiException || e instanceof IOException) {
LOGGER.debug(errorMsg);
} else {
LOGGER.debug(errorMsg, e);
}
throw new ChaiUnavailableException("unable to create connection: " + e.getMessage(), ChaiErrors.getErrorForMessage(e.getMessage()));
}
if (!failOverWrapperChild) {
providerImpl = addProviderWrappers(providerImpl);
getCentralService().registerProvider(providerImpl);
}
return providerImpl;
}
use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.
the class JNDIProviderImpl method compareStringAttribute.
@LdapOperation
public final boolean compareStringAttribute(final String entryDN, final String attributeName, final String value) throws ChaiUnavailableException, ChaiOperationException {
activityPreCheck();
getInputValidator().compareStringAttribute(entryDN, attributeName, value);
final byte[] ba;
try {
ba = value.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new UnsupportedOperationException(e);
}
// Set up the search controls
final SearchControls ctls = new SearchControls();
// Return no attrs
ctls.setReturningAttributes(new String[0]);
// Search object only
ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
final LdapContext ldapConnection = getLdapConnection();
NamingEnumeration<SearchResult> answer = null;
boolean result = false;
try {
answer = ldapConnection.search(addJndiEscape(entryDN), "(" + attributeName + "={0})", new Object[] { ba }, ctls);
result = answer.hasMore();
} catch (NamingException e) {
convertNamingException(e);
} finally {
if (answer != null) {
try {
answer.close();
} catch (Exception e) {
/* action not required */
}
}
}
return result;
}
use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.
the class JNDIProviderImpl method replaceBinaryAttribute.
@LdapOperation
@ModifyOperation
public final void replaceBinaryAttribute(final String entryDN, final String attributeName, final byte[] oldValue, final byte[] newValue) throws ChaiUnavailableException, ChaiOperationException {
activityPreCheck();
getInputValidator().replaceBinaryAttribute(entryDN, attributeName, oldValue, newValue);
final String jndiBinarySetting = "java.naming.ldap.attributes.binary";
// Create the ModificationItem
final ModificationItem[] modificationItem = new ModificationItem[2];
{
// Create a BasicAttribute for the old value.
final BasicAttribute oldValueOperation = new BasicAttribute(attributeName, oldValue);
// Populate the ModificationItem array with the removal of the old value.
modificationItem[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, oldValueOperation);
// Create a BasicAttribute for the new value.
final BasicAttribute newValueOperation = new BasicAttribute(attributeName, newValue);
// Populate the ModificationItem array with the removal of the old value.
modificationItem[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE, newValueOperation);
}
// get ldap connection
final LdapContext ldapConnection = getLdapConnection();
// Modify the Attributes.
try {
ldapConnection.modifyAttributes(addJndiEscape(entryDN), modificationItem);
// inform jndi the attribute is binary.
ldapConnection.addToEnvironment(jndiBinarySetting, attributeName);
} catch (NamingException e) {
convertNamingException(e);
} finally {
// clean up jndi environment
try {
ldapConnection.removeFromEnvironment(jndiBinarySetting);
} catch (Exception e) {
// doesnt matter
}
}
}
use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.
the class ChaiUtility method testAttributeReplication.
/**
* <p>Test the replication of an attribute. It is left to the implementation to determine the means and criteria for
* this operation. Typically this method would be used just after a write operation in some type of time delayed loop.
* This method does not write any data to the directory.</p>
*
* <p>Typical implementations will do the following:</p>
* <ul>
* <li>issue {@link com.novell.ldapchai.ChaiEntry#readStringAttribute(String)} to read a value</li>
* <li>establish an LDAP connection to all known replicas</li>
* <li>issue {@link com.novell.ldapchai.ChaiEntry#compareStringAttribute(String, String)} to to each server directly</li>
* <li>return true if each server contacted has the same value, false if not</li>
* </ul>
*
* <p>Target servers that are unreachable or return errors are ignored, and do not influence the results. It is entirely
* possible that no matter how many times this method is called, false will always be returned, so the caller should
* take care not to repeat a test indefinitely.</p>
*
* <p>This operation is potentially expensive, as it may establish new LDAP level connections to each target server each
* time it is invoked.</p>
*
* <p>The following sample shows how this method might be used. There are a few important attributes of the sample:</p>
* <ul>
* <li>Multiple ldap servers are specified</li>
* <li>There is a pause time between each replication check (the test can be expensive)</li>
* <li>There is a timeout period (the test may never successfully complete)</li>
* </ul>
* <p><b>Example Usage:</b></p>
* <pre>
* // write a timestamp value to an attribute
* theUser.writeStringAttributes("description","testValue" + Instant.now().toString());
*
* // maximum time to wait for replication
* final int maximumWaitTime = 120 * 1000;
*
* // time between iterations
* final int pauseTime = 3 * 1000;
*
* // timestamp of beginning of wait
* final long startTime = System.currentTimeMillis();
*
* boolean replicated = false;
*
* // loop until
* while (System.currentTimeMillis() - startTime < maximumWaitTime) {
*
* // sleep between iterations
* try { Thread.sleep(pauseTime); } catch (InterruptedException e) {}
*
* // check if data replicated yet
* replicated = ChaiUtility.testAttributeReplication(theUser,"description",null);
*
* // break if data has replicated
* if (replicated) {
* break;
* }
* }
*
* // report success
* System.out.println("Attribute replication successful: " + replicated);
* </pre>
*
* @param chaiEntry A valid entry
* @param attribute A valid attribute on the entry
* @param value The value to test for. If {@code null}, a value is read from the active server
* @return true if the attribute is the same on all servers
* @throws ChaiOperationException If an error is encountered during the operation
* @throws ChaiUnavailableException If no directory servers are reachable
* @throws IllegalStateException If the underlying connection is not in an available state
*/
public static boolean testAttributeReplication(final ChaiEntry chaiEntry, final String attribute, final String value) throws ChaiOperationException, ChaiUnavailableException {
final String effectiveValue = (value == null || value.length() < 1) ? chaiEntry.readStringAttribute(attribute) : value;
if (effectiveValue == null) {
throw ChaiOperationException.forErrorMessage("unreadable to read test attribute from primary ChaiProvider");
}
final ChaiConfiguration chaiConfiguration = chaiEntry.getChaiProvider().getChaiConfiguration();
final List<String> ldapURLs = chaiConfiguration.bindURLsAsList();
LOGGER.trace("testAttributeReplication, will test the following ldap urls: " + ldapURLs);
int testCount = 0;
int successCount = 0;
final Collection<ChaiConfiguration> perReplicaProviders = splitConfigurationPerReplica(chaiEntry.getChaiProvider().getChaiConfiguration(), Collections.singletonMap(ChaiSetting.FAILOVER_CONNECT_RETRIES, "1"));
for (final ChaiConfiguration loopConfiguration : perReplicaProviders) {
ChaiProvider loopProvider = null;
try {
loopProvider = chaiEntry.getChaiProvider().getProviderFactory().newProvider(loopConfiguration);
if (loopProvider.compareStringAttribute(chaiEntry.getEntryDN(), attribute, effectiveValue)) {
successCount++;
}
testCount++;
} catch (ChaiUnavailableException e) {
// disregard
} catch (ChaiOperationException e) {
// disregard
} finally {
try {
if (loopProvider != null) {
loopProvider.close();
}
} catch (Exception e) {
// already closed, whatever.
}
}
}
if (LOGGER.isDebugEnabled()) {
final StringBuilder debugMsg = new StringBuilder();
debugMsg.append("testAttributeReplication for ").append(chaiEntry).append(":").append(attribute);
debugMsg.append(" ").append(testCount).append(" up,");
debugMsg.append(" ").append(ldapURLs.size() - testCount).append(" down,");
debugMsg.append(" ").append(successCount).append(" in sync");
LOGGER.debug(debugMsg);
}
return testCount > 0 && testCount == successCount;
}
Aggregations