blob: e7930f2234a423d5efabfba3facac568b08c1c60 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.server.tools;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Hashtable;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.directory.daemon.AvailablePortFinder;
import org.apache.directory.shared.ldap.message.AttributesImpl;
/**
* A capacity testing tool. This command will generate bogus user
* entries and add them under a base DN. It will output a table
* of values mapping the capacity of the partition to the time it
* took to add an entry to it.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
public class CapacityTestCommand extends ToolCommand
{
public static final String PORT_RANGE = "(" + AvailablePortFinder.MIN_PORT_NUMBER + ", "
+ AvailablePortFinder.MAX_PORT_NUMBER + ")";
private int port = 10389;
private String host = "localhost";
private String password = "secret";
private String baseDn = "ou=users,dc=example,dc=com";
public CapacityTestCommand()
{
super( "capacity" );
}
public void execute( CommandLine cmdline ) throws Exception
{
processOptions( cmdline );
getLayout().verifyInstallation();
String outputFile = cmdline.getOptionValue( 'f' );
PrintWriter out = null;
if ( outputFile == null )
{
out = new PrintWriter( System.out );
}
else
{
out = new PrintWriter( new FileWriter( outputFile ) );
}
if ( isDebugEnabled() )
{
out.println( "Parameters for capacity extended request:" );
out.println( "port = " + port );
out.println( "host = " + host );
out.println( "password = " + password );
}
Hashtable env = new Hashtable();
env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
env.put( "java.naming.provider.url", "ldap://" + host + ":" + port );
env.put( "java.naming.security.principal", "uid=admin,ou=system" );
env.put( "java.naming.security.credentials", password );
env.put( "java.naming.security.authentication", "simple" );
LdapContext ctx = new InitialLdapContext( env, null );
// create the base dn if it does not exist
createBase( ctx );
StringBuffer dnBuf = new StringBuffer();
StringBuffer outBuf = new StringBuffer();
int counter = 0;
if ( cmdline.hasOption( "s" ) )
{
counter = Integer.parseInt( cmdline.getOptionValue( 's' ) ) - 1;
}
int end = Integer.MAX_VALUE;
if ( cmdline.hasOption( "e" ) )
{
end = Integer.parseInt( cmdline.getOptionValue( 'e' ) );
}
while ( counter < end )
{
counter++;
Attributes attrs = generateLdif( counter );
dnBuf.setLength( 0 );
dnBuf.append( "uid=user." ).append( counter ).append( "," ).append( baseDn );
long startTime = System.currentTimeMillis();
ctx.createSubcontext( dnBuf.toString(), attrs );
outBuf.setLength( 0 );
outBuf.append( counter ).append( " " ).append( System.currentTimeMillis() - startTime );
out.println( outBuf.toString() );
out.flush();
}
}
private boolean createBase( LdapContext ctx ) throws NamingException
{
Attributes attrs = new AttributesImpl( "objectClass", "organizationalUnit", true );
attrs.put( "ou", "users" );
try
{
ctx.createSubcontext( "ou=users,dc=example,dc=com", attrs );
return true;
}
catch ( NameAlreadyBoundException e )
{
return false;
}
}
private Attributes generateLdif( int counter )
{
Attributes attrs = new AttributesImpl( "objectClass", "top", true );
Attribute oc = attrs.get( "objectClass" );
oc.add( "person" );
oc.add( "organizationalPerson" );
oc.add( "inetOrgPerson" );
attrs.put( "givenName", RandomStringUtils.randomAlphabetic( 6 ) );
attrs.put( "sn", RandomStringUtils.randomAlphabetic( 9 ) );
attrs.put( "cn", RandomStringUtils.randomAlphabetic( 15 ) );
attrs.put( "initials", RandomStringUtils.randomAlphabetic( 2 ) );
attrs.put( "mail", RandomStringUtils.randomAlphabetic( 15 ) );
attrs.put( "userPassword", "password" );
attrs.put( "telephoneNumber", RandomStringUtils.randomNumeric( 10 ) );
attrs.put( "homePhone", RandomStringUtils.randomNumeric( 10 ) );
attrs.put( "pager", RandomStringUtils.randomNumeric( 10 ) );
attrs.put( "mobile", RandomStringUtils.randomNumeric( 10 ) );
attrs.put( "employeeNumber", String.valueOf( counter ) );
attrs.put( "street", RandomStringUtils.randomAlphabetic( 20 ) );
attrs.put( "l", RandomStringUtils.randomAlphabetic( 10 ) );
attrs.put( "st", RandomStringUtils.randomAlphabetic( 2 ) );
attrs.put( "postalCode", RandomStringUtils.randomAlphabetic( 5 ) );
attrs.put( "postalAddress", RandomStringUtils.randomAlphabetic( 20 ) );
attrs.put( "description", RandomStringUtils.randomAlphabetic( 20 ) );
return attrs;
}
private void processOptions( CommandLine cmd )
{
if ( isDebugEnabled() )
{
System.out.println( "Processing options for capacity test ..." );
}
// -------------------------------------------------------------------
// figure out and error check the port value
// -------------------------------------------------------------------
if ( cmd.hasOption( 'p' ) ) // - user provided port w/ -p takes precedence
{
String val = cmd.getOptionValue( 'p' );
try
{
port = Integer.parseInt( val );
}
catch ( NumberFormatException e )
{
System.err.println( "port value of '" + val + "' is not a number" );
System.exit( 1 );
}
if ( port > AvailablePortFinder.MAX_PORT_NUMBER )
{
System.err.println( "port value of '" + val + "' is larger than max port number: "
+ AvailablePortFinder.MAX_PORT_NUMBER );
System.exit( 1 );
}
else if ( port < AvailablePortFinder.MIN_PORT_NUMBER )
{
System.err.println( "port value of '" + val + "' is smaller than the minimum port number: "
+ AvailablePortFinder.MIN_PORT_NUMBER );
System.exit( 1 );
}
if ( isDebugEnabled() )
{
System.out.println( "port overriden by -p option: " + port );
}
}
else if ( getApacheDS() != null )
{
port = getApacheDS().getLdapServer().getIpPort();
if ( isDebugEnabled() )
{
System.out.println( "port overriden by server.xml configuration: " + port );
}
}
else if ( isDebugEnabled() )
{
System.out.println( "port set to default: " + port );
}
// -------------------------------------------------------------------
// figure out the host value
// -------------------------------------------------------------------
if ( cmd.hasOption( 'h' ) )
{
host = cmd.getOptionValue( 'h' );
if ( isDebugEnabled() )
{
System.out.println( "host overriden by -h option: " + host );
}
}
else if ( isDebugEnabled() )
{
System.out.println( "host set to default: " + host );
}
// -------------------------------------------------------------------
// figure out the password value
// -------------------------------------------------------------------
if ( cmd.hasOption( 'w' ) )
{
password = cmd.getOptionValue( 'w' );
if ( isDebugEnabled() )
{
System.out.println( "password overriden by -w option: " + password );
}
}
else if ( isDebugEnabled() )
{
System.out.println( "password set to default: " + password );
}
}
public Options getOptions()
{
Options opts = new Options();
Option op = new Option( "f", "file", true, "file to output the stats to" );
op.setRequired( false );
opts.addOption( op );
op = new Option( "i", "install-path", true, "path to apacheds installation directory" );
op.setRequired( true );
opts.addOption( op );
op = new Option( "h", "host", true, "server host: defaults to localhost" );
op.setRequired( false );
opts.addOption( op );
op = new Option( "p", "port", true, "server port: defaults to 10389 or server.xml specified port" );
op.setRequired( false );
opts.addOption( op );
op = new Option( "w", "password", true, "the apacheds administrator's password: defaults to secret" );
op.setRequired( false );
opts.addOption( op );
op = new Option( "s", "start", true, "start on id: number to start on (user.start)" );
op.setRequired( false );
opts.addOption( op );
op = new Option( "e", "end", true, "end on id: number to end on (user.end)" );
op.setRequired( false );
opts.addOption( op );
return opts;
}
}