use of com.novell.ldapchai.exception.ChaiOperationException 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;
}
use of com.novell.ldapchai.exception.ChaiOperationException in project ldapchai by ldapchai.
the class ChaiProviderTester method testDeleteAttribute.
public void testDeleteAttribute() throws Exception {
final ChaiProvider[] providers = this.getProviders();
for (final ChaiProvider provider : providers) {
final ChaiEntry testContainer = TestHelper.createTestContainer();
final String testUserDN = TestHelper.createNewTestUser(testContainer).getEntryDN();
System.out.println("Testing provider " + provider.toString());
{
// test single value writes.
provider.writeStringAttribute(testUserDN, testAttribute, new HashSet<String>(Arrays.asList("value1", "value2")), false);
final Set<String> results = provider.readMultiStringAttribute(testUserDN, testAttribute);
Assert.assertTrue("setup values failed", results.size() == 2 && results.contains("value1") && results.contains("value2"));
}
{
// delete existing value
provider.deleteStringAttributeValue(testUserDN, testAttribute, "value2");
final Set<String> results = provider.readMultiStringAttribute(testUserDN, testAttribute);
Assert.assertTrue("delete existing value failed", results.size() == 1 && results.contains("value1"));
}
{
// delete non existing value
try {
provider.deleteStringAttributeValue(testUserDN, testAttribute, "value2");
Assert.fail("missing exception during delete of non-existant value");
} catch (ChaiOperationException e) {
Assert.assertEquals("missing NO_SUCH_VALUE error", e.getErrorCode(), ChaiError.NO_SUCH_VALUE);
}
}
}
}
use of com.novell.ldapchai.exception.ChaiOperationException in project ldapchai by ldapchai.
the class TestHelper method implCleanUp.
private static void implCleanUp(final ChaiEntry object) throws ChaiUnavailableException, ChaiOperationException {
try {
final Set<ChaiEntry> results = object.getChildObjects();
for (final ChaiEntry loopEntry : results) {
if (!loopEntry.equals(object)) {
implCleanUp(loopEntry);
}
}
if (!object.getEntryDN().equals("")) {
System.out.print(".");
object.getChaiProvider().deleteEntry(object.getEntryDN());
}
} catch (ChaiOperationException e) {
if (e.getErrorCode() != ChaiError.NO_SUCH_ENTRY) {
throw e;
}
}
}
use of com.novell.ldapchai.exception.ChaiOperationException in project ldapchai by ldapchai.
the class AdvancedConnection method main.
public static void main(final String[] args) {
// connection parameters
String ldapURL = "ldap://ldaphost:389";
String ldapBindDN = "cn=admin,ou=ou,o=o";
String ldapBindPW = "password";
// allocate a new ChaiConfiguration
ChaiConfiguration chaiConfig = ChaiConfiguration.builder(ldapURL, ldapBindDN, ldapBindPW).setSetting(ChaiSetting.CR_CHAI_STORAGE_ATTRIBUTE, "title").setSetting(ChaiSetting.WATCHDOG_ENABLE, "false").setSetting(ChaiSetting.PROMISCUOUS_SSL, "true").setSetting(ChaiSetting.EDIRECTORY_ENABLE_NMAS, "true").build();
try {
// create a ChaiProviderFactory;
ChaiProviderFactory chaiProviderFactory = ChaiProviderFactory.newProviderFactory();
// create a ChaiProvider
ChaiProvider provider = chaiProviderFactory.newProvider(chaiConfig);
// create a ChaiProvider
ChaiUser bindUser = provider.getEntryFactory().newChaiUser(ldapBindDN);
// read the user's last name.
String surname = bindUser.readStringAttribute(ChaiUser.ATTR_SURNAME);
// read the bind user's surname
System.out.println("surname = " + surname);
} catch (ChaiUnavailableException e) {
System.out.println("LDAP unreachable: " + e.getMessage());
} catch (ChaiOperationException e) {
System.out.println("LDAP error: " + e.getMessage());
}
}
use of com.novell.ldapchai.exception.ChaiOperationException in project pwm by pwm-project.
the class LdapProfile method readCanonicalDN.
public String readCanonicalDN(final PwmApplication pwmApplication, final String dnValue) throws PwmUnrecoverableException {
{
final boolean doCanonicalDnResolve = Boolean.parseBoolean(pwmApplication.getConfig().readAppProperty(AppProperty.LDAP_RESOLVE_CANONICAL_DN));
if (!doCanonicalDnResolve) {
return dnValue;
}
}
final boolean enableCanonicalCache = Boolean.parseBoolean(pwmApplication.getConfig().readAppProperty(AppProperty.LDAP_CACHE_CANONICAL_ENABLE));
String canonicalValue = null;
final CacheKey cacheKey = CacheKey.makeCacheKey(LdapPermissionTester.class, null, "canonicalDN-" + this.getIdentifier() + "-" + dnValue);
if (enableCanonicalCache) {
final String cachedDN = pwmApplication.getCacheService().get(cacheKey);
if (cachedDN != null) {
canonicalValue = cachedDN;
}
}
if (canonicalValue == null) {
try {
final ChaiProvider chaiProvider = this.getProxyChaiProvider(pwmApplication);
final ChaiEntry chaiEntry = chaiProvider.getEntryFactory().newChaiEntry(dnValue);
canonicalValue = chaiEntry.readCanonicalDN();
if (enableCanonicalCache) {
final long cacheSeconds = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.LDAP_CACHE_CANONICAL_SECONDS));
final CachePolicy cachePolicy = CachePolicy.makePolicyWithExpiration(new TimeDuration(cacheSeconds, TimeUnit.SECONDS));
pwmApplication.getCacheService().put(cacheKey, cachePolicy, canonicalValue);
}
LOGGER.trace("read and cached canonical ldap DN value for input '" + dnValue + "' as '" + canonicalValue + "'");
} catch (ChaiUnavailableException | ChaiOperationException e) {
LOGGER.error("error while reading canonicalDN for dn value '" + dnValue + "', error: " + e.getMessage());
return dnValue;
}
}
return canonicalValue;
}
Aggregations