use of com.unboundid.util.OutputFormat in project ldapsdk by pingidentity.
the class SearchAndModRate method doToolProcessing.
/**
* Performs the actual processing for this tool. In this case, it gets a
* connection to the directory server and uses it to perform the requested
* searches.
*
* @return The result code for the processing that was performed.
*/
@Override()
@NotNull()
public ResultCode doToolProcessing() {
// variable rate data file and return.
if (sampleRateFile.isPresent()) {
try {
RateAdjustor.writeSampleVariableRateFile(sampleRateFile.getValue());
return ResultCode.SUCCESS;
} catch (final Exception e) {
Debug.debugException(e);
err("An error occurred while trying to write sample variable data " + "rate file '", sampleRateFile.getValue().getAbsolutePath(), "': ", StaticUtils.getExceptionMessage(e));
return ResultCode.LOCAL_ERROR;
}
}
// Determine the random seed to use.
final Long seed;
if (randomSeed.isPresent()) {
seed = Long.valueOf(randomSeed.getValue());
} else {
seed = null;
}
// Create value patterns for the base DN, filter, and proxied authorization
// DN.
final ValuePattern dnPattern;
try {
dnPattern = new ValuePattern(baseDN.getValue(), seed);
} catch (final ParseException pe) {
Debug.debugException(pe);
err("Unable to parse the base DN value pattern: ", pe.getMessage());
return ResultCode.PARAM_ERROR;
}
final ValuePattern filterPattern;
try {
filterPattern = new ValuePattern(filter.getValue(), seed);
} catch (final ParseException pe) {
Debug.debugException(pe);
err("Unable to parse the filter pattern: ", pe.getMessage());
return ResultCode.PARAM_ERROR;
}
final ValuePattern authzIDPattern;
if (proxyAs.isPresent()) {
try {
authzIDPattern = new ValuePattern(proxyAs.getValue(), seed);
} catch (final ParseException pe) {
Debug.debugException(pe);
err("Unable to parse the proxied authorization pattern: ", pe.getMessage());
return ResultCode.PARAM_ERROR;
}
} else {
authzIDPattern = null;
}
// Get the set of controls to include in search requests.
final ArrayList<Control> searchControls = new ArrayList<>(5);
if (searchAssertionFilter.isPresent()) {
searchControls.add(new AssertionRequestControl(searchAssertionFilter.getValue()));
}
if (searchControl.isPresent()) {
searchControls.addAll(searchControl.getValues());
}
// Get the set of controls to include in modify requests.
final ArrayList<Control> modifyControls = new ArrayList<>(5);
if (modifyAssertionFilter.isPresent()) {
modifyControls.add(new AssertionRequestControl(modifyAssertionFilter.getValue()));
}
if (permissiveModify.isPresent()) {
modifyControls.add(new PermissiveModifyRequestControl());
}
if (preReadAttribute.isPresent()) {
final List<String> attrList = preReadAttribute.getValues();
final String[] attrArray = new String[attrList.size()];
attrList.toArray(attrArray);
modifyControls.add(new PreReadRequestControl(attrArray));
}
if (postReadAttribute.isPresent()) {
final List<String> attrList = postReadAttribute.getValues();
final String[] attrArray = new String[attrList.size()];
attrList.toArray(attrArray);
modifyControls.add(new PostReadRequestControl(attrArray));
}
if (modifyControl.isPresent()) {
modifyControls.addAll(modifyControl.getValues());
}
// Get the attributes to return.
final String[] returnAttrs;
if (returnAttributes.isPresent()) {
final List<String> attrList = returnAttributes.getValues();
returnAttrs = new String[attrList.size()];
attrList.toArray(returnAttrs);
} else {
returnAttrs = StaticUtils.NO_STRINGS;
}
// Get the names of the attributes to modify.
final String[] modAttrs = new String[modifyAttributes.getValues().size()];
modifyAttributes.getValues().toArray(modAttrs);
// Get the character set as a byte array.
final byte[] charSet = StaticUtils.getBytes(characterSet.getValue());
// If the --ratePerSecond option was specified, then limit the rate
// accordingly.
FixedRateBarrier fixedRateBarrier = null;
if (ratePerSecond.isPresent() || variableRateData.isPresent()) {
// We might not have a rate per second if --variableRateData is specified.
// The rate typically doesn't matter except when we have warm-up
// intervals. In this case, we'll run at the max rate.
final int intervalSeconds = collectionInterval.getValue();
final int ratePerInterval = (ratePerSecond.getValue() == null) ? Integer.MAX_VALUE : ratePerSecond.getValue() * intervalSeconds;
fixedRateBarrier = new FixedRateBarrier(1000L * intervalSeconds, ratePerInterval);
}
// If --variableRateData was specified, then initialize a RateAdjustor.
RateAdjustor rateAdjustor = null;
if (variableRateData.isPresent()) {
try {
rateAdjustor = RateAdjustor.newInstance(fixedRateBarrier, ratePerSecond.getValue(), variableRateData.getValue());
} catch (final IOException | IllegalArgumentException e) {
Debug.debugException(e);
err("Initializing the variable rates failed: " + e.getMessage());
return ResultCode.PARAM_ERROR;
}
}
// Determine whether to include timestamps in the output and if so what
// format should be used for them.
final boolean includeTimestamp;
final String timeFormat;
if (timestampFormat.getValue().equalsIgnoreCase("with-date")) {
includeTimestamp = true;
timeFormat = "dd/MM/yyyy HH:mm:ss";
} else if (timestampFormat.getValue().equalsIgnoreCase("without-date")) {
includeTimestamp = true;
timeFormat = "HH:mm:ss";
} else {
includeTimestamp = false;
timeFormat = null;
}
// Determine whether any warm-up intervals should be run.
final long totalIntervals;
final boolean warmUp;
int remainingWarmUpIntervals = warmUpIntervals.getValue();
if (remainingWarmUpIntervals > 0) {
warmUp = true;
totalIntervals = 0L + numIntervals.getValue() + remainingWarmUpIntervals;
} else {
warmUp = true;
totalIntervals = 0L + numIntervals.getValue();
}
// Create the table that will be used to format the output.
final OutputFormat outputFormat;
if (csvFormat.isPresent()) {
outputFormat = OutputFormat.CSV;
} else {
outputFormat = OutputFormat.COLUMNS;
}
final ColumnFormatter formatter = new ColumnFormatter(includeTimestamp, timeFormat, outputFormat, " ", new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Searches/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Srch Dur ms"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Mods/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Mod Dur ms"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Errors/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Overall", "Searches/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Overall", "Srch Dur ms"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Overall", "Mods/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Overall", "Mod Dur ms"));
// Create values to use for statistics collection.
final AtomicLong searchCounter = new AtomicLong(0L);
final AtomicLong errorCounter = new AtomicLong(0L);
final AtomicLong modCounter = new AtomicLong(0L);
final AtomicLong modDurations = new AtomicLong(0L);
final AtomicLong searchDurations = new AtomicLong(0L);
final ResultCodeCounter rcCounter = new ResultCodeCounter();
// Determine the length of each interval in milliseconds.
final long intervalMillis = 1000L * collectionInterval.getValue();
// Create the threads to use for the searches.
final Random random = new Random();
final CyclicBarrier barrier = new CyclicBarrier(numThreads.getValue() + 1);
final SearchAndModRateThread[] threads = new SearchAndModRateThread[numThreads.getValue()];
for (int i = 0; i < threads.length; i++) {
final LDAPConnection connection;
try {
connection = getConnection();
} catch (final LDAPException le) {
Debug.debugException(le);
err("Unable to connect to the directory server: ", StaticUtils.getExceptionMessage(le));
return le.getResultCode();
}
threads[i] = new SearchAndModRateThread(this, i, connection, dnPattern, scopeArg.getValue(), filterPattern, returnAttrs, modAttrs, valueLength.getValue(), charSet, authzIDPattern, simplePageSize.getValue(), searchControls, modifyControls, iterationsBeforeReconnect.getValue(), random.nextLong(), runningThreads, barrier, searchCounter, modCounter, searchDurations, modDurations, errorCounter, rcCounter, fixedRateBarrier);
threads[i].start();
}
// Display the table header.
for (final String headerLine : formatter.getHeaderLines(true)) {
out(headerLine);
}
// which case, we'll start it after the warm-up is complete.
if ((rateAdjustor != null) && (remainingWarmUpIntervals <= 0)) {
rateAdjustor.start();
}
// Indicate that the threads can start running.
try {
barrier.await();
} catch (final Exception e) {
Debug.debugException(e);
}
long overallStartTime = System.nanoTime();
long nextIntervalStartTime = System.currentTimeMillis() + intervalMillis;
boolean setOverallStartTime = false;
long lastSearchDuration = 0L;
long lastModDuration = 0L;
long lastNumErrors = 0L;
long lastNumSearches = 0L;
long lastNumMods = 0L;
long lastEndTime = System.nanoTime();
for (long i = 0; i < totalIntervals; i++) {
if (rateAdjustor != null) {
if (!rateAdjustor.isAlive()) {
out("All of the rates in " + variableRateData.getValue().getName() + " have been completed.");
break;
}
}
final long startTimeMillis = System.currentTimeMillis();
final long sleepTimeMillis = nextIntervalStartTime - startTimeMillis;
nextIntervalStartTime += intervalMillis;
if (sleepTimeMillis > 0) {
sleeper.sleep(sleepTimeMillis);
}
if (stopRequested.get()) {
break;
}
final long endTime = System.nanoTime();
final long intervalDuration = endTime - lastEndTime;
final long numSearches;
final long numMods;
final long numErrors;
final long totalSearchDuration;
final long totalModDuration;
if (warmUp && (remainingWarmUpIntervals > 0)) {
numSearches = searchCounter.getAndSet(0L);
numMods = modCounter.getAndSet(0L);
numErrors = errorCounter.getAndSet(0L);
totalSearchDuration = searchDurations.getAndSet(0L);
totalModDuration = modDurations.getAndSet(0L);
} else {
numSearches = searchCounter.get();
numMods = modCounter.get();
numErrors = errorCounter.get();
totalSearchDuration = searchDurations.get();
totalModDuration = modDurations.get();
}
final long recentNumSearches = numSearches - lastNumSearches;
final long recentNumMods = numMods - lastNumMods;
final long recentNumErrors = numErrors - lastNumErrors;
final long recentSearchDuration = totalSearchDuration - lastSearchDuration;
final long recentModDuration = totalModDuration - lastModDuration;
final double numSeconds = intervalDuration / 1_000_000_000.0d;
final double recentSearchRate = recentNumSearches / numSeconds;
final double recentModRate = recentNumMods / numSeconds;
final double recentErrorRate = recentNumErrors / numSeconds;
final double recentAvgSearchDuration;
if (recentNumSearches > 0L) {
recentAvgSearchDuration = 1.0d * recentSearchDuration / recentNumSearches / 1_000_000;
} else {
recentAvgSearchDuration = 0.0d;
}
final double recentAvgModDuration;
if (recentNumMods > 0L) {
recentAvgModDuration = 1.0d * recentModDuration / recentNumMods / 1_000_000;
} else {
recentAvgModDuration = 0.0d;
}
if (warmUp && (remainingWarmUpIntervals > 0)) {
out(formatter.formatRow(recentSearchRate, recentAvgSearchDuration, recentModRate, recentAvgModDuration, recentErrorRate, "warming up", "warming up", "warming up", "warming up"));
remainingWarmUpIntervals--;
if (remainingWarmUpIntervals == 0) {
out("Warm-up completed. Beginning overall statistics collection.");
setOverallStartTime = true;
if (rateAdjustor != null) {
rateAdjustor.start();
}
}
} else {
if (setOverallStartTime) {
overallStartTime = lastEndTime;
setOverallStartTime = false;
}
final double numOverallSeconds = (endTime - overallStartTime) / 1_000_000_000.0d;
final double overallSearchRate = numSearches / numOverallSeconds;
final double overallModRate = numMods / numOverallSeconds;
final double overallAvgSearchDuration;
if (numSearches > 0L) {
overallAvgSearchDuration = 1.0d * totalSearchDuration / numSearches / 1_000_000;
} else {
overallAvgSearchDuration = 0.0d;
}
final double overallAvgModDuration;
if (numMods > 0L) {
overallAvgModDuration = 1.0d * totalModDuration / numMods / 1_000_000;
} else {
overallAvgModDuration = 0.0d;
}
out(formatter.formatRow(recentSearchRate, recentAvgSearchDuration, recentModRate, recentAvgModDuration, recentErrorRate, overallSearchRate, overallAvgSearchDuration, overallModRate, overallAvgModDuration));
lastNumSearches = numSearches;
lastNumMods = numMods;
lastNumErrors = numErrors;
lastSearchDuration = totalSearchDuration;
lastModDuration = totalModDuration;
}
final List<ObjectPair<ResultCode, Long>> rcCounts = rcCounter.getCounts(true);
if ((!suppressErrors.isPresent()) && (!rcCounts.isEmpty())) {
err("\tError Results:");
for (final ObjectPair<ResultCode, Long> p : rcCounts) {
err("\t", p.getFirst().getName(), ": ", p.getSecond());
}
}
lastEndTime = endTime;
}
// Shut down the RateAdjustor if we have one.
if (rateAdjustor != null) {
rateAdjustor.shutDown();
}
// Stop all of the threads.
ResultCode resultCode = ResultCode.SUCCESS;
for (final SearchAndModRateThread t : threads) {
final ResultCode r = t.stopRunning();
if (resultCode == ResultCode.SUCCESS) {
resultCode = r;
}
}
return resultCode;
}
use of com.unboundid.util.OutputFormat in project ldapsdk by pingidentity.
the class LDAPSearch method doExtendedNonLDAPArgumentValidation.
/**
* {@inheritDoc}
*/
@Override()
public void doExtendedNonLDAPArgumentValidation() throws ArgumentException {
// was provided, then use that.
if (wrapColumn.isPresent()) {
final int wc = wrapColumn.getValue();
if (wc <= 0) {
WRAP_COLUMN = Integer.MAX_VALUE;
} else {
WRAP_COLUMN = wc;
}
} else if (dontWrap.isPresent()) {
WRAP_COLUMN = Integer.MAX_VALUE;
}
// If the ldapURLFile argument was provided, then there must not be any
// trailing arguments.
final List<String> trailingArgs = parser.getTrailingArguments();
if (ldapURLFile.isPresent()) {
if (!trailingArgs.isEmpty()) {
throw new ArgumentException(ERR_LDAPSEARCH_TRAILING_ARGS_WITH_URL_FILE.get(ldapURLFile.getIdentifierString()));
}
}
// not be a filter.
if (filter.isPresent() || filterFile.isPresent()) {
if (!trailingArgs.isEmpty()) {
try {
Filter.create(trailingArgs.get(0));
throw new ArgumentException(ERR_LDAPSEARCH_TRAILING_FILTER_WITH_FILTER_FILE.get(filterFile.getIdentifierString()));
} catch (final LDAPException le) {
// This is the normal condition. Not even worth debugging the
// exception.
}
}
}
// argument must be a valid search filter.
if (!(ldapURLFile.isPresent() || filter.isPresent() || filterFile.isPresent())) {
if (trailingArgs.isEmpty()) {
throw new ArgumentException(ERR_LDAPSEARCH_NO_TRAILING_ARGS.get(filterFile.getIdentifierString(), ldapURLFile.getIdentifierString()));
}
try {
Filter.create(trailingArgs.get(0));
} catch (final Exception e) {
Debug.debugException(e);
throw new ArgumentException(ERR_LDAPSEARCH_FIRST_TRAILING_ARG_NOT_FILTER.get(trailingArgs.get(0)), e);
}
}
// fail.
for (final String s : trailingArgs) {
if (s.startsWith("-")) {
commentToErr(WARN_LDAPSEARCH_TRAILING_ARG_STARTS_WITH_DASH.get(s));
break;
}
}
// pre-create the matched values request control.
if (matchedValuesFilter.isPresent()) {
final List<Filter> filterList = matchedValuesFilter.getValues();
final MatchedValuesFilter[] matchedValuesFilters = new MatchedValuesFilter[filterList.size()];
for (int i = 0; i < matchedValuesFilters.length; i++) {
try {
matchedValuesFilters[i] = MatchedValuesFilter.create(filterList.get(i));
} catch (final Exception e) {
Debug.debugException(e);
throw new ArgumentException(ERR_LDAPSEARCH_INVALID_MATCHED_VALUES_FILTER.get(filterList.get(i).toString()), e);
}
}
matchedValuesRequestControl = new MatchedValuesRequestControl(true, matchedValuesFilters);
}
// the argument value and pre-create the control.
if (matchingEntryCountControl.isPresent()) {
final MatchingEntryCountRequestControlProperties properties = new MatchingEntryCountRequestControlProperties();
Integer examineCount = null;
try {
for (final String element : matchingEntryCountControl.getValue().toLowerCase().split(":")) {
if (element.startsWith("examinecount=")) {
examineCount = Integer.parseInt(element.substring(13));
} else if (element.equals("allowunindexed")) {
properties.setProcessSearchIfUnindexed(true);
} else if (element.equals("alwaysexamine")) {
properties.setAlwaysExamineCandidates(true);
} else if (element.equals("skipresolvingexplodedindexes")) {
properties.setSkipResolvingExplodedIndexes(true);
} else if (element.startsWith("fastshortcircuitthreshold=")) {
properties.setFastShortCircuitThreshold(Long.parseLong(element.substring(26)));
} else if (element.startsWith("slowshortcircuitthreshold=")) {
properties.setSlowShortCircuitThreshold(Long.parseLong(element.substring(26)));
} else if (element.equals("extendedresponsedata")) {
properties.setIncludeExtendedResponseData(true);
} else if (element.equals("debug")) {
properties.setIncludeDebugInfo(true);
} else {
throw new ArgumentException(ERR_LDAPSEARCH_MATCHING_ENTRY_COUNT_INVALID_VALUE.get(matchingEntryCountControl.getIdentifierString()));
}
}
} catch (final ArgumentException ae) {
Debug.debugException(ae);
throw ae;
} catch (final Exception e) {
Debug.debugException(e);
throw new ArgumentException(ERR_LDAPSEARCH_MATCHING_ENTRY_COUNT_INVALID_VALUE.get(matchingEntryCountControl.getIdentifierString()), e);
}
if (examineCount == null) {
throw new ArgumentException(ERR_LDAPSEARCH_MATCHING_ENTRY_COUNT_INVALID_VALUE.get(matchingEntryCountControl.getIdentifierString()));
} else {
properties.setMaxCandidatesToExamine(examineCount);
}
matchingEntryCountRequestControl = new MatchingEntryCountRequestControl(true, properties);
}
// validate the provided values.
if (overrideSearchLimit.isPresent()) {
final LinkedHashMap<String, String> properties = new LinkedHashMap<>(StaticUtils.computeMapCapacity(10));
for (final String value : overrideSearchLimit.getValues()) {
final int equalPos = value.indexOf('=');
if (equalPos < 0) {
throw new ArgumentException(ERR_LDAPSEARCH_OVERRIDE_LIMIT_NO_EQUAL.get(overrideSearchLimit.getIdentifierString()));
} else if (equalPos == 0) {
throw new ArgumentException(ERR_LDAPSEARCH_OVERRIDE_LIMIT_EMPTY_PROPERTY_NAME.get(overrideSearchLimit.getIdentifierString()));
}
final String propertyName = value.substring(0, equalPos);
if (properties.containsKey(propertyName)) {
throw new ArgumentException(ERR_LDAPSEARCH_OVERRIDE_LIMIT_DUPLICATE_PROPERTY_NAME.get(overrideSearchLimit.getIdentifierString(), propertyName));
}
if (equalPos == (value.length() - 1)) {
throw new ArgumentException(ERR_LDAPSEARCH_OVERRIDE_LIMIT_EMPTY_PROPERTY_VALUE.get(overrideSearchLimit.getIdentifierString(), propertyName));
}
properties.put(propertyName, value.substring(equalPos + 1));
}
overrideSearchLimitsRequestControl = new OverrideSearchLimitsRequestControl(properties, false);
}
// the argument value and pre-create the control.
if (persistentSearch.isPresent()) {
boolean changesOnly = true;
boolean returnECs = true;
EnumSet<PersistentSearchChangeType> changeTypes = EnumSet.allOf(PersistentSearchChangeType.class);
try {
final String[] elements = persistentSearch.getValue().toLowerCase().split(":");
if (elements.length == 0) {
throw new ArgumentException(ERR_LDAPSEARCH_PERSISTENT_SEARCH_INVALID_VALUE.get(persistentSearch.getIdentifierString()));
}
final String header = StaticUtils.toLowerCase(elements[0]);
if (!(header.equals("ps") || header.equals("persist") || header.equals("persistent") || header.equals("psearch") || header.equals("persistentsearch"))) {
throw new ArgumentException(ERR_LDAPSEARCH_PERSISTENT_SEARCH_INVALID_VALUE.get(persistentSearch.getIdentifierString()));
}
if (elements.length > 1) {
final String ctString = StaticUtils.toLowerCase(elements[1]);
if (ctString.equals("any")) {
changeTypes = EnumSet.allOf(PersistentSearchChangeType.class);
} else {
changeTypes.clear();
for (final String t : ctString.split(",")) {
if (t.equals("add")) {
changeTypes.add(PersistentSearchChangeType.ADD);
} else if (t.equals("del") || t.equals("delete")) {
changeTypes.add(PersistentSearchChangeType.DELETE);
} else if (t.equals("mod") || t.equals("modify")) {
changeTypes.add(PersistentSearchChangeType.MODIFY);
} else if (t.equals("moddn") || t.equals("modrdn") || t.equals("modifydn") || t.equals("modifyrdn")) {
changeTypes.add(PersistentSearchChangeType.MODIFY_DN);
} else {
throw new ArgumentException(ERR_LDAPSEARCH_PERSISTENT_SEARCH_INVALID_VALUE.get(persistentSearch.getIdentifierString()));
}
}
}
}
if (elements.length > 2) {
if (elements[2].equalsIgnoreCase("true") || elements[2].equals("1")) {
changesOnly = true;
} else if (elements[2].equalsIgnoreCase("false") || elements[2].equals("0")) {
changesOnly = false;
} else {
throw new ArgumentException(ERR_LDAPSEARCH_PERSISTENT_SEARCH_INVALID_VALUE.get(persistentSearch.getIdentifierString()));
}
}
if (elements.length > 3) {
if (elements[3].equalsIgnoreCase("true") || elements[3].equals("1")) {
returnECs = true;
} else if (elements[3].equalsIgnoreCase("false") || elements[3].equals("0")) {
returnECs = false;
} else {
throw new ArgumentException(ERR_LDAPSEARCH_PERSISTENT_SEARCH_INVALID_VALUE.get(persistentSearch.getIdentifierString()));
}
}
} catch (final ArgumentException ae) {
Debug.debugException(ae);
throw ae;
} catch (final Exception e) {
Debug.debugException(e);
throw new ArgumentException(ERR_LDAPSEARCH_PERSISTENT_SEARCH_INVALID_VALUE.get(persistentSearch.getIdentifierString()), e);
}
persistentSearchRequestControl = new PersistentSearchRequestControl(changeTypes, changesOnly, returnECs, true);
}
// sort order and pre-create the control.
if (sortOrder.isPresent()) {
final ArrayList<SortKey> sortKeyList = new ArrayList<>(5);
final StringTokenizer tokenizer = new StringTokenizer(sortOrder.getValue(), ", ");
while (tokenizer.hasMoreTokens()) {
final String token = tokenizer.nextToken();
final boolean ascending;
String attributeName;
if (token.startsWith("-")) {
ascending = false;
attributeName = token.substring(1);
} else if (token.startsWith("+")) {
ascending = true;
attributeName = token.substring(1);
} else {
ascending = true;
attributeName = token;
}
final String matchingRuleID;
final int colonPos = attributeName.indexOf(':');
if (colonPos >= 0) {
matchingRuleID = attributeName.substring(colonPos + 1);
attributeName = attributeName.substring(0, colonPos);
} else {
matchingRuleID = null;
}
final StringBuilder invalidReason = new StringBuilder();
if (!PersistUtils.isValidLDAPName(attributeName, false, invalidReason)) {
throw new ArgumentException(ERR_LDAPSEARCH_SORT_ORDER_INVALID_VALUE.get(sortOrder.getIdentifierString()));
}
sortKeyList.add(new SortKey(attributeName, matchingRuleID, (!ascending)));
}
if (sortKeyList.isEmpty()) {
throw new ArgumentException(ERR_LDAPSEARCH_SORT_ORDER_INVALID_VALUE.get(sortOrder.getIdentifierString()));
}
final SortKey[] sortKeyArray = new SortKey[sortKeyList.size()];
sortKeyList.toArray(sortKeyArray);
sortRequestControl = new ServerSideSortRequestControl(sortKeyArray);
}
// argument value and pre-create the control.
if (virtualListView.isPresent()) {
try {
final String[] elements = virtualListView.getValue().split(":");
if (elements.length == 4) {
vlvRequestControl = new VirtualListViewRequestControl(Integer.parseInt(elements[2]), Integer.parseInt(elements[0]), Integer.parseInt(elements[1]), Integer.parseInt(elements[3]), null);
} else if (elements.length == 3) {
vlvRequestControl = new VirtualListViewRequestControl(elements[2], Integer.parseInt(elements[0]), Integer.parseInt(elements[1]), null);
} else {
throw new ArgumentException(ERR_LDAPSEARCH_VLV_INVALID_VALUE.get(virtualListView.getIdentifierString()));
}
} catch (final ArgumentException ae) {
Debug.debugException(ae);
throw ae;
} catch (final Exception e) {
Debug.debugException(e);
throw new ArgumentException(ERR_LDAPSEARCH_VLV_INVALID_VALUE.get(virtualListView.getIdentifierString()), e);
}
}
// pre-create that control.
if (joinRule.isPresent()) {
final JoinRule rule;
try {
final String[] elements = joinRule.getValue().toLowerCase().split(":");
final String ruleName = StaticUtils.toLowerCase(elements[0]);
if (ruleName.equals("dn")) {
rule = JoinRule.createDNJoin(elements[1]);
} else if (ruleName.equals("reverse-dn") || ruleName.equals("reversedn")) {
rule = JoinRule.createReverseDNJoin(elements[1]);
} else if (ruleName.equals("equals") || ruleName.equals("equality")) {
rule = JoinRule.createEqualityJoin(elements[1], elements[2], false);
} else if (ruleName.equals("contains") || ruleName.equals("substring")) {
rule = JoinRule.createContainsJoin(elements[1], elements[2], false);
} else {
throw new ArgumentException(ERR_LDAPSEARCH_JOIN_RULE_INVALID_VALUE.get(joinRule.getIdentifierString()));
}
} catch (final ArgumentException ae) {
Debug.debugException(ae);
throw ae;
} catch (final Exception e) {
Debug.debugException(e);
throw new ArgumentException(ERR_LDAPSEARCH_JOIN_RULE_INVALID_VALUE.get(joinRule.getIdentifierString()), e);
}
final JoinBaseDN joinBase;
if (joinBaseDN.isPresent()) {
final String s = StaticUtils.toLowerCase(joinBaseDN.getValue());
if (s.equals("search-base") || s.equals("search-base-dn")) {
joinBase = JoinBaseDN.createUseSearchBaseDN();
} else if (s.equals("source-entry-dn") || s.equals("source-dn")) {
joinBase = JoinBaseDN.createUseSourceEntryDN();
} else {
try {
final DN dn = new DN(joinBaseDN.getValue());
joinBase = JoinBaseDN.createUseCustomBaseDN(joinBaseDN.getValue());
} catch (final Exception e) {
Debug.debugException(e);
throw new ArgumentException(ERR_LDAPSEARCH_JOIN_BASE_DN_INVALID_VALUE.get(joinBaseDN.getIdentifierString()), e);
}
}
} else {
joinBase = JoinBaseDN.createUseSearchBaseDN();
}
final String[] joinAttrs;
if (joinRequestedAttribute.isPresent()) {
final List<String> valueList = joinRequestedAttribute.getValues();
joinAttrs = new String[valueList.size()];
valueList.toArray(joinAttrs);
} else {
joinAttrs = null;
}
joinRequestControl = new JoinRequestControl(new JoinRequestValue(rule, joinBase, joinScope.getValue(), DereferencePolicy.NEVER, joinSizeLimit.getValue(), joinFilter.getValue(), joinAttrs, joinRequireMatch.isPresent(), null));
}
// and pre-create those controls.
if (routeToBackendSet.isPresent()) {
final List<String> values = routeToBackendSet.getValues();
final Map<String, List<String>> idsByRP = new LinkedHashMap<>(StaticUtils.computeMapCapacity(values.size()));
for (final String value : values) {
final int colonPos = value.indexOf(':');
if (colonPos <= 0) {
throw new ArgumentException(ERR_LDAPSEARCH_ROUTE_TO_BACKEND_SET_INVALID_FORMAT.get(value, routeToBackendSet.getIdentifierString()));
}
final String rpID = value.substring(0, colonPos);
final String bsID = value.substring(colonPos + 1);
List<String> idsForRP = idsByRP.get(rpID);
if (idsForRP == null) {
idsForRP = new ArrayList<>(values.size());
idsByRP.put(rpID, idsForRP);
}
idsForRP.add(bsID);
}
for (final Map.Entry<String, List<String>> e : idsByRP.entrySet()) {
final String rpID = e.getKey();
final List<String> bsIDs = e.getValue();
routeToBackendSetRequestControls.add(RouteToBackendSetRequestControl.createAbsoluteRoutingRequest(true, rpID, bsIDs));
}
}
// Parse the dereference policy.
final String derefStr = StaticUtils.toLowerCase(dereferencePolicy.getValue());
if (derefStr.equals("always")) {
derefPolicy = DereferencePolicy.ALWAYS;
} else if (derefStr.equals("search")) {
derefPolicy = DereferencePolicy.SEARCHING;
} else if (derefStr.equals("find")) {
derefPolicy = DereferencePolicy.FINDING;
} else {
derefPolicy = DereferencePolicy.NEVER;
}
// See if any entry transformations need to be applied.
final ArrayList<EntryTransformation> transformations = new ArrayList<>(5);
if (excludeAttribute.isPresent()) {
transformations.add(new ExcludeAttributeTransformation(null, excludeAttribute.getValues()));
}
if (redactAttribute.isPresent()) {
transformations.add(new RedactAttributeTransformation(null, true, (!hideRedactedValueCount.isPresent()), redactAttribute.getValues()));
}
if (scrambleAttribute.isPresent()) {
final Long randomSeed;
if (scrambleRandomSeed.isPresent()) {
randomSeed = scrambleRandomSeed.getValue().longValue();
} else {
randomSeed = null;
}
transformations.add(new ScrambleAttributeTransformation(null, randomSeed, true, scrambleAttribute.getValues(), scrambleJSONField.getValues()));
}
if (renameAttributeFrom.isPresent()) {
if (renameAttributeFrom.getNumOccurrences() != renameAttributeTo.getNumOccurrences()) {
throw new ArgumentException(ERR_LDAPSEARCH_RENAME_ATTRIBUTE_MISMATCH.get());
}
final Iterator<String> sourceIterator = renameAttributeFrom.getValues().iterator();
final Iterator<String> targetIterator = renameAttributeTo.getValues().iterator();
while (sourceIterator.hasNext()) {
transformations.add(new RenameAttributeTransformation(null, sourceIterator.next(), targetIterator.next(), true));
}
}
if (moveSubtreeFrom.isPresent()) {
if (moveSubtreeFrom.getNumOccurrences() != moveSubtreeTo.getNumOccurrences()) {
throw new ArgumentException(ERR_LDAPSEARCH_MOVE_SUBTREE_MISMATCH.get());
}
final Iterator<DN> sourceIterator = moveSubtreeFrom.getValues().iterator();
final Iterator<DN> targetIterator = moveSubtreeTo.getValues().iterator();
while (sourceIterator.hasNext()) {
transformations.add(new MoveSubtreeTransformation(sourceIterator.next(), targetIterator.next()));
}
}
if (!transformations.isEmpty()) {
entryTransformations = transformations;
}
// Create the result writer.
final String outputFormatStr = StaticUtils.toLowerCase(outputFormat.getValue());
if (outputFormatStr.equals("json")) {
resultWriter = new JSONLDAPResultWriter(getOutStream());
} else if (outputFormatStr.equals("csv") || outputFormatStr.equals("multi-valued-csv") || outputFormatStr.equals("tab-delimited") || outputFormatStr.equals("multi-valued-tab-delimited")) {
// These output formats cannot be used with the --ldapURLFile argument.
if (ldapURLFile.isPresent()) {
throw new ArgumentException(ERR_LDAPSEARCH_OUTPUT_FORMAT_NOT_SUPPORTED_WITH_URLS.get(outputFormat.getValue(), ldapURLFile.getIdentifierString()));
}
// These output formats require the requested attributes to be specified
// via the --requestedAttribute argument rather than as unnamed trailing
// arguments.
final List<String> requestedAttributes = requestedAttribute.getValues();
if ((requestedAttributes == null) || requestedAttributes.isEmpty()) {
throw new ArgumentException(ERR_LDAPSEARCH_OUTPUT_FORMAT_REQUIRES_REQUESTED_ATTR_ARG.get(outputFormat.getValue(), requestedAttribute.getIdentifierString()));
}
switch(trailingArgs.size()) {
case 0:
// This is fine.
break;
case 1:
// filter nor filterFile argument was provided.
if (filter.isPresent() || filterFile.isPresent()) {
throw new ArgumentException(ERR_LDAPSEARCH_OUTPUT_FORMAT_REQUIRES_REQUESTED_ATTR_ARG.get(outputFormat.getValue(), requestedAttribute.getIdentifierString()));
}
break;
default:
throw new ArgumentException(ERR_LDAPSEARCH_OUTPUT_FORMAT_REQUIRES_REQUESTED_ATTR_ARG.get(outputFormat.getValue(), requestedAttribute.getIdentifierString()));
}
final OutputFormat format;
final boolean includeAllValues;
switch(outputFormatStr) {
case "multi-valued-csv":
format = OutputFormat.CSV;
includeAllValues = true;
break;
case "tab-delimited":
format = OutputFormat.TAB_DELIMITED_TEXT;
includeAllValues = false;
break;
case "multi-valued-tab-delimited":
format = OutputFormat.TAB_DELIMITED_TEXT;
includeAllValues = true;
break;
case "csv":
default:
format = OutputFormat.CSV;
includeAllValues = false;
break;
}
resultWriter = new ColumnBasedLDAPResultWriter(getOutStream(), format, requestedAttributes, WRAP_COLUMN, includeAllValues);
} else if (outputFormatStr.equals("dns-only")) {
resultWriter = new DNsOnlyLDAPResultWriter(getOutStream());
} else if (outputFormatStr.equals("values-only")) {
resultWriter = new ValuesOnlyLDAPResultWriter(getOutStream());
} else {
resultWriter = new LDIFLDAPResultWriter(getOutStream(), WRAP_COLUMN);
}
}
Aggregations