/* * Copyright 2008-2010 UnboundID Corp. * All Rights Reserved. */ /* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2008-2010. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.jobs; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.slamd.parameter.Parameter; import com.slamd.parameter.ParameterList; import com.slamd.parameter.PlaceholderParameter; import com.slamd.parameter.StringParameter; import com.slamd.stat.StatTracker; import com.unboundid.ldap.sdk.Filter; import com.unboundid.ldap.sdk.LDAPConnection; import com.unboundid.ldap.sdk.LDAPException; import com.unboundid.ldap.sdk.ResultCode; import com.unboundid.ldap.sdk.RoundRobinServerSet; import com.unboundid.ldap.sdk.SearchRequest; import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchResultEntry; import com.unboundid.ldap.sdk.SearchScope; /** * This class provides a simple SLAMD job class that may be used to wait until * one or more Directory Server instances are available and respond to LDAP * requests. */ public class LDAPWaitForDirectoryJobClass extends LDAPJobClass { // The DN of the entry to retrieve. private static String entryDN; // The parameter to use to specify the target entry DN. private StringParameter entryDNParameter = new StringParameter("entryDN", "Entry to Retrieve", "The DN of the entry to retrieve from the server. If no value is " + "provided, then the root DSE will be retrieved.", false, ""); /** * Creates a new instance of this job class. */ public LDAPWaitForDirectoryJobClass() { super(); } /** * {@inheritDoc} */ @Override() public String getJobName() { return "LDAP Wait for Directory"; } /** * {@inheritDoc} */ @Override() public String getShortDescription() { return "Wait for an LDAP directory server to become available"; } /** * {@inheritDoc} */ @Override() public String[] getLongDescription() { return new String[] { "This job can be used to wait for an LDAP directory server to become " + "available and respond to requests. It will not end until it is able " + "to successfully connect to the directory server and retrieve the " + "specified entry. If multiple servers are specified, then it will not " + "complete until all servers are found to be available." }; } /** * {@inheritDoc} */ @Override() public int overrideNumClients() { return 1; } /** * {@inheritDoc} */ @Override() public int overrideThreadsPerClient() { return 1; } /** * {@inheritDoc} */ @Override() protected List<Parameter> getNonLDAPParameterStubs() { return Arrays.asList( new PlaceholderParameter(), entryDNParameter); } /** * {@inheritDoc} */ @Override() public StatTracker[] getStatTrackerStubs(final String clientID, final String threadID, final int collectionInterval) { return new StatTracker[0]; } /** * {@inheritDoc} */ @Override() public StatTracker[] getStatTrackers() { return new StatTracker[0]; } /** * {@inheritDoc} */ @Override() protected boolean testNonLDAPJobParameters(final ParameterList parameters, final LDAPConnection connection, final ArrayList<String> outputMessages) { boolean successful = true; // Ensure that the target entry DN exists. StringParameter entryDNParam = parameters.getStringParameter(entryDNParameter.getName()); if ((entryDNParam != null) && entryDNParam.hasValue()) { try { String dn = entryDNParam.getStringValue(); outputMessages.add("Ensuring that entry '" + dn + "' exists...."); SearchResultEntry e = connection.getEntry(dn); if (e == null) { outputMessages.add("ERROR: The base entry does not exist."); successful = false; } else { outputMessages.add("The base entry exists."); } } catch (Exception e) { successful = false; outputMessages.add("Unable to perform the search: " + stackTraceToString(e)); } outputMessages.add(""); } return successful; } /** * {@inheritDoc} */ @Override() protected void initializeClientNonLDAP(final String clientID, final ParameterList parameters) { entryDN = ""; entryDNParameter = parameters.getStringParameter(entryDNParameter.getName()); if ((entryDNParameter != null) && entryDNParameter.hasValue()) { entryDN = entryDNParameter.getStringValue(); } } /** * {@inheritDoc} */ @Override() public void initializeThread(final String clientID, final String threadID, final int collectionInterval, final ParameterList parameters) { // No implementation is required. } /** * {@inheritDoc} */ @Override() public void runJob() { SearchRequest searchRequest = new SearchRequest(entryDN, SearchScope.BASE, Filter.createPresenceFilter("objectClass"), "1.1"); searchRequest.setTimeLimitSeconds(5); searchRequest.setResponseTimeoutMillis(5000L); RoundRobinServerSet serverSet = getServerSet(); String[] addresses = serverSet.getAddresses(); int[] ports = serverSet.getPorts(); while (! shouldStop()) { boolean failed = false; for (int i=0; i < addresses.length; i++) { LDAPConnection c; try { c = createConnection(addresses[i], ports[i]); } catch (LDAPException le) { failed = true; break; } try { SearchResult searchResult = c.search(searchRequest); if ((! searchResult.getResultCode().equals(ResultCode.SUCCESS)) || (searchResult.getEntryCount() == 0)) { failed = true; break; } } catch (LDAPException le) { failed = true; break; } finally { c.close(); } } if (failed) { // The server doesn't look like it's ready yet, so wait for five seconds // before trying again. try { Thread.sleep(5000L); } catch (Exception e) {} } else { // There weren't any failures, so the server must be up and the entry // exists. return; } } } }