You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pa...@apache.org on 2008/04/02 13:03:08 UTC
svn commit: r643845 [2/2] - in
/directory/apacheds/branches/bigbang/server-tools/src:
main/java/org/apache/directory/server/tools/
main/java/org/apache/directory/server/tools/commands/
main/java/org/apache/directory/server/tools/execution/ main/java/or...
Added: directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java?rev=643845&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java (added)
+++ directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java Wed Apr 2 04:02:57 2008
@@ -0,0 +1,976 @@
+/*
+ * 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.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+
+import javax.naming.InvalidNameException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.directory.daemon.AvailablePortFinder;
+import org.apache.directory.shared.asn1.ber.Asn1Decoder;
+import org.apache.directory.shared.asn1.ber.IAsn1Container;
+import org.apache.directory.shared.asn1.ber.tlv.TLVStateEnum;
+import org.apache.directory.shared.asn1.codec.DecoderException;
+import org.apache.directory.shared.asn1.codec.EncoderException;
+import org.apache.directory.shared.ldap.codec.LdapConstants;
+import org.apache.directory.shared.ldap.codec.LdapDecoder;
+import org.apache.directory.shared.ldap.codec.LdapMessage;
+import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
+import org.apache.directory.shared.ldap.codec.LdapResult;
+import org.apache.directory.shared.ldap.codec.add.AddRequest;
+import org.apache.directory.shared.ldap.codec.bind.BindRequest;
+import org.apache.directory.shared.ldap.codec.bind.BindResponse;
+import org.apache.directory.shared.ldap.codec.bind.LdapAuthentication;
+import org.apache.directory.shared.ldap.codec.bind.SimpleAuthentication;
+import org.apache.directory.shared.ldap.codec.del.DelRequest;
+import org.apache.directory.shared.ldap.codec.extended.ExtendedResponse;
+import org.apache.directory.shared.ldap.codec.modify.ModifyRequest;
+import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNRequest;
+import org.apache.directory.shared.ldap.codec.unbind.UnBindRequest;
+import org.apache.directory.shared.ldap.ldif.ChangeType;
+import org.apache.directory.shared.ldap.ldif.LdifEntry;
+import org.apache.directory.shared.ldap.ldif.LdifReader;
+import org.apache.directory.shared.ldap.message.ModificationItemImpl;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.name.Rdn;
+import org.apache.directory.shared.ldap.util.StringTools;
+
+/**
+ * A command to import data into a server. The data to be imported must be
+ * stored in a Ldif File, and they could be added entries or modified entries.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 406112 $
+ */
+public class ImportCommand 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 user = "uid=admin,ou=system";
+
+ private String auth = "simple";
+
+ private File ldifFile;
+
+ private String logs;
+
+ private boolean ignoreErrors = false;
+
+ private static final int IMPORT_ERROR = -1;
+ private static final int IMPORT_SUCCESS= 0;
+
+ /**
+ * Socket used to connect to the server
+ */
+ private SocketChannel channel;
+
+ private SocketAddress serverAddress;
+
+ private IAsn1Container ldapMessageContainer = new LdapMessageContainer();
+
+ private Asn1Decoder ldapDecoder = new LdapDecoder();
+
+ /**
+ * The constructor save the command's name into it's super class
+ *
+ */
+ protected ImportCommand()
+ {
+ super( "import" );
+ }
+
+ /**
+ * Connect to the LDAP server through a socket and establish the Input and
+ * Output Streams. All the required information for the connection should be
+ * in the options from the command line, or the default values.
+ *
+ * @throws UnknownHostException
+ * The hostname or the Address of server could not be found
+ * @throws IOException
+ * There was a error opening or establishing the socket
+ */
+ private void connect() throws UnknownHostException, IOException
+ {
+ serverAddress = new InetSocketAddress( host, port );
+ channel = SocketChannel.open( serverAddress );
+ channel.configureBlocking( true );
+ }
+
+ private void sendMessage( ByteBuffer bb ) throws IOException
+ {
+ channel.write( bb );
+ bb.clear();
+ }
+
+ private LdapMessage readResponse( ByteBuffer bb ) throws IOException, DecoderException, NamingException
+ {
+
+ LdapMessage messageResp = null;
+
+ while ( true )
+ {
+ int nbRead = channel.read( bb );
+
+ if ( nbRead == -1 )
+ {
+ break;
+ }
+ else
+ {
+ bb.flip();
+
+ // Decode the PDU
+ ldapDecoder.decode( bb, ldapMessageContainer );
+
+ if ( ldapMessageContainer.getState() == TLVStateEnum.PDU_DECODED )
+ {
+ messageResp = ( (LdapMessageContainer) ldapMessageContainer ).getLdapMessage();
+
+ if ( messageResp instanceof BindResponse )
+ {
+ BindResponse resp = ( (LdapMessageContainer) ldapMessageContainer ).getLdapMessage().getBindResponse();
+
+ if ( resp.getLdapResult().getResultCode() != ResultCodeEnum.SUCCESS )
+ {
+ System.out.println( "Error : " + resp.getLdapResult().getErrorMessage() );
+ }
+ }
+ else if ( messageResp instanceof ExtendedResponse )
+ {
+ ExtendedResponse resp = ( (LdapMessageContainer) ldapMessageContainer ).getLdapMessage()
+ .getExtendedResponse();
+
+ if ( resp.getLdapResult().getResultCode() != ResultCodeEnum.SUCCESS )
+ {
+ System.out.println( "Error : " + resp.getLdapResult().getErrorMessage() );
+ }
+ }
+
+ ( (LdapMessageContainer) ldapMessageContainer ).clean();
+ break;
+ }
+ else
+ {
+ bb.flip();
+ }
+ }
+ }
+
+ return messageResp;
+
+ }
+
+ /**
+ * Send the entry to the encoder, then wait for a
+ * reponse from the LDAP server on the results of the operation.
+ *
+ * @param entry
+ * The entry to add
+ * @param msgId
+ * message id number
+ */
+ private int addEntry( LdifEntry entry, int messageId ) throws IOException, DecoderException, InvalidNameException,
+ NamingException, EncoderException
+ {
+ AddRequest addRequest = new AddRequest();
+
+ String dn = entry.getDn();
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Adding entry " + dn );
+ }
+
+ Attributes attributes = entry.getAttributes();
+
+ addRequest.setEntry( new LdapDN( dn ) );
+
+ // Copy the attributes
+ addRequest.initAttributes();
+
+ for ( NamingEnumeration attrs = attributes.getAll(); attrs.hasMoreElements(); )
+ {
+ Attribute attribute = (Attribute) attrs.nextElement();
+
+ addRequest.addAttributeType( attribute.getID() );
+
+ for ( NamingEnumeration values = attribute.getAll(); values.hasMoreElements(); )
+ {
+ Object value = values.nextElement();
+ addRequest.addAttributeValue( value );
+ }
+ }
+
+ LdapMessage message = new LdapMessage();
+
+ message.setProtocolOP( addRequest );
+ message.setMessageId( messageId );
+
+ // Encode and send the addRequest message
+ ByteBuffer bb = message.encode( null );
+ bb.flip();
+
+ sendMessage( bb );
+
+ bb.clear();
+
+ // Get the response
+ LdapMessage response = readResponse( bb );
+
+ LdapResult result = response.getAddResponse().getLdapResult();
+
+ if ( result.getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Add of Entry " + entry.getDn() + " was successful" );
+ }
+
+ return IMPORT_SUCCESS;
+ }
+ else
+ {
+ System.err.println( "Add of entry " + entry.getDn() + " failed for the following reasons provided by the server:\n"
+ + result.getErrorMessage() );
+
+ return IMPORT_ERROR;
+ }
+ }
+
+ /**
+ * Send the entry to the encoder, then wait for a
+ * reponse from the LDAP server on the results of the operation.
+ *
+ * @param entry
+ * The entry to delete
+ * @param msgId
+ * message id number
+ */
+ private int deleteEntry( LdifEntry entry, int messageId ) throws IOException, DecoderException, InvalidNameException,
+ NamingException, EncoderException
+ {
+ DelRequest delRequest = new DelRequest();
+
+ String dn = entry.getDn();
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Deleting entry " + dn );
+ }
+
+ delRequest.setEntry( new LdapDN( dn ) );
+
+ LdapMessage message = new LdapMessage();
+
+ message.setProtocolOP( delRequest );
+ message.setMessageId( messageId );
+
+ // Encode and send the delete request
+ ByteBuffer bb = message.encode( null );
+ bb.flip();
+
+ sendMessage( bb );
+
+ bb.clear();
+
+ // Get the response
+ LdapMessage response = readResponse( bb );
+
+ LdapResult result = response.getDelResponse().getLdapResult();
+
+ if ( result.getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Delete of Entry " + entry.getDn() + " was successful" );
+ }
+
+ return IMPORT_SUCCESS;
+ }
+ else
+ {
+ System.err.println( "Delete of entry " + entry.getDn() + " failed for the following reasons provided by the server:\n"
+ + result.getErrorMessage() );
+ return IMPORT_ERROR;
+ }
+ }
+
+ /**
+ * Send the entry to the encoder, then wait for a
+ * reponse from the LDAP server on the results of the operation.
+ *
+ * @param entry
+ * The entry to modify
+ * @param msgId
+ * message id number
+ */
+ private int changeModRDNEntry( LdifEntry entry, int messageId ) throws IOException, DecoderException, InvalidNameException,
+ NamingException, EncoderException
+ {
+ ModifyDNRequest modifyDNRequest = new ModifyDNRequest();
+
+ String dn = entry.getDn();
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Modify DN of entry " + dn );
+ }
+
+ modifyDNRequest.setEntry( new LdapDN( dn ) );
+ modifyDNRequest.setDeleteOldRDN( entry.isDeleteOldRdn() );
+ modifyDNRequest.setNewRDN( new Rdn( entry.getNewRdn() ) );
+
+ if ( StringTools.isEmpty( entry.getNewSuperior() ) == false )
+ {
+ modifyDNRequest.setNewSuperior( new LdapDN( entry.getNewSuperior() ) );
+ }
+
+ LdapMessage message = new LdapMessage();
+
+ message.setProtocolOP( modifyDNRequest );
+ message.setMessageId( messageId );
+
+ // Encode and send the delete request
+ ByteBuffer bb = message.encode( null );
+ bb.flip();
+
+ sendMessage( bb );
+
+ bb.clear();
+
+ // Get the response
+ LdapMessage response = readResponse( bb );
+
+ LdapResult result = response.getModifyDNResponse().getLdapResult();
+
+ if ( result.getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "ModifyDn of Entry " + entry.getDn() + " was successful" );
+ }
+
+ return IMPORT_SUCCESS;
+ }
+ else
+ {
+ System.err.println( "ModifyDn of entry " + entry.getDn() + " failed for the following reasons provided by the server:\n"
+ + result.getErrorMessage() );
+ return IMPORT_ERROR;
+ }
+ }
+
+ /**
+ * Send the entry to the encoder, then wait for a
+ * reponse from the LDAP server on the results of the operation.
+ *
+ * @param entry
+ * The entry to modify
+ * @param msgId
+ * message id number
+ */
+ private int changeModifyEntry( LdifEntry entry, int messageId ) throws IOException, DecoderException, InvalidNameException,
+ NamingException, EncoderException
+ {
+ ModifyRequest modifyRequest = new ModifyRequest();
+
+ String dn = entry.getDn();
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Modify of entry " + dn );
+ }
+
+ modifyRequest.setObject( new LdapDN( dn ) );
+ modifyRequest.initModifications();
+
+ Iterator modifications = entry.getModificationItems().iterator();
+
+ while ( modifications.hasNext() )
+ {
+ ModificationItemImpl modification = (ModificationItemImpl)modifications.next();
+
+ switch ( modification.getModificationOp() )
+ {
+ case DirContext.ADD_ATTRIBUTE :
+ modifyRequest.setCurrentOperation( LdapConstants.OPERATION_ADD );
+ break;
+
+ case DirContext.REMOVE_ATTRIBUTE :
+ modifyRequest.setCurrentOperation( LdapConstants.OPERATION_DELETE );
+ break;
+
+ case DirContext.REPLACE_ATTRIBUTE :
+ modifyRequest.setCurrentOperation( LdapConstants.OPERATION_REPLACE );
+ break;
+
+ default :
+ System.err.println( "Unknown modify operation for DN " + dn );
+ }
+
+ modifyRequest.addAttributeTypeAndValues( modification.getAttribute().getID() );
+
+ for ( NamingEnumeration values = modification.getAttribute().getAll(); values.hasMoreElements(); )
+ {
+ Object value = values.nextElement();
+ modifyRequest.addAttributeValue( value );
+ }
+ }
+
+ LdapMessage message = new LdapMessage();
+
+ message.setProtocolOP( modifyRequest );
+ message.setMessageId( messageId );
+
+ // Encode and send the delete request
+ ByteBuffer bb = message.encode( null );
+ bb.flip();
+
+ sendMessage( bb );
+
+ bb.clear();
+
+ // Get the response
+ LdapMessage response = readResponse( bb );
+
+ LdapResult result = response.getModifyResponse().getLdapResult();
+
+ if ( result.getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Modify of Entry " + entry.getDn() + " was successful" );
+ }
+
+ return IMPORT_SUCCESS;
+ }
+ else
+ {
+ System.err.println( "Modify of entry " + entry.getDn() + " failed for the following reasons provided by the server:\n"
+ + result.getErrorMessage() );
+ return IMPORT_ERROR;
+ }
+ }
+
+ /**
+ * Send the change operation to the encoder, then wait for a
+ * reponse from the LDAP server on the results of the operation.
+ *
+ * @param entry
+ * The entry to add
+ * @param msgId
+ * message id number
+ */
+ private int changeEntry( LdifEntry entry, int messageId ) throws IOException, DecoderException, InvalidNameException,
+ NamingException, EncoderException
+ {
+ switch ( entry.getChangeType().getChangeType() )
+ {
+ case ChangeType.ADD_ORDINAL:
+ // No difference with the injection of new entries
+ return addEntry( entry, messageId );
+
+ case ChangeType.DELETE_ORDINAL:
+ return deleteEntry( entry, messageId );
+
+ case ChangeType.MODIFY_ORDINAL:
+ return changeModifyEntry( entry, messageId );
+
+ case ChangeType.MODDN_ORDINAL:
+ case ChangeType.MODRDN_ORDINAL:
+ return changeModRDNEntry( entry, messageId );
+
+ default:
+ return IMPORT_ERROR;
+ }
+ }
+
+ /**
+ * Bind to the ldap server
+ *
+ * @param messageId The message Id
+ */
+ private void bind( int messageId ) throws NamingException, EncoderException, DecoderException, IOException
+ {
+ BindRequest bindRequest = new BindRequest();
+ LdapMessage message = new LdapMessage();
+ LdapAuthentication authentication = null;
+
+ if ( "simple".equals( auth ) )
+ {
+ authentication = new SimpleAuthentication();
+ ( (SimpleAuthentication) authentication ).setSimple( StringTools.getBytesUtf8( password ) );
+ }
+
+ bindRequest.setAuthentication( authentication );
+ bindRequest.setName( new LdapDN( user ) );
+ bindRequest.setVersion( 3 );
+
+ message.setProtocolOP( bindRequest );
+ message.setMessageId( messageId );
+
+ // Encode and send the bind request
+ ByteBuffer bb = message.encode( null );
+ bb.flip();
+
+ connect();
+ sendMessage( bb );
+
+ bb.clear();
+
+ // Get the bind response
+ LdapMessage response = readResponse( bb );
+
+ LdapResult result = response.getBindResponse().getLdapResult();
+
+ if ( result.getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Binding of user " + user + " was successful" );
+ }
+ }
+ else
+ {
+ System.err.println( "Binding of user " + user + " failed for the following reasons provided by the server:\n"
+ + result.getErrorMessage() );
+ System.exit( 1 );
+ }
+ }
+
+ /**
+ * Unbind from the server
+ *
+ * @param messageId
+ * The message Id
+ * @throws InvalidNameException
+ * @throws EncoderException
+ * @throws DecoderException
+ * @throws IOException
+ */
+ private void unbind( int messageId ) throws InvalidNameException, EncoderException, DecoderException, IOException
+ {
+ UnBindRequest unbindRequest = new UnBindRequest();
+ LdapMessage message = new LdapMessage();
+
+ message.setProtocolOP( unbindRequest );
+ message.setMessageId( messageId );
+ ByteBuffer bb = message.encode( null );
+ bb.flip();
+
+ sendMessage( bb );
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Unbinding of user " + user + " was successful" );
+ }
+ }
+
+ /**
+ * Execute the command
+ *
+ * @param cmd
+ * The command to be executed
+ */
+ public void execute( CommandLine cmd ) throws Exception
+ {
+ processOptions( cmd );
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Parameters for Ldif import request:" );
+ System.out.println( "port = " + port );
+ System.out.println( "host = " + host );
+ System.out.println( "user = " + user );
+ System.out.println( "auth type = " + auth );
+ System.out.println( "file = " + ldifFile );
+ System.out.println( "logs = " + logs );
+ }
+
+ int messageId = 0;
+
+ // Login to the server
+ bind( messageId++ );
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Connection to the server established.\n" + "Importing data ... " );
+ }
+
+ LdifReader ldifReader = new LdifReader( ldifFile );
+
+ if ( ldifReader.containsEntries() )
+ {
+ // Parse the file and inject every entry
+ Iterator<LdifEntry> entries = ldifReader.iterator();
+ long t0 = System.currentTimeMillis();
+ int nbAdd = 0;
+
+ while ( entries.hasNext() )
+ {
+ LdifEntry entry = entries.next();
+
+ // Check if we have had some error, has next() does not throw any exception
+ if ( ldifReader.hasError() )
+ {
+ System.err.println( "Found an error while persing an entry : " + ldifReader.getError().getMessage() );
+
+ if ( ignoreErrors == false )
+ {
+ unbind( messageId );
+
+ System.err.println( "Import failed..." );
+ System.exit( 1 );
+ }
+ }
+
+ if ( ( addEntry( entry, messageId++ ) == IMPORT_ERROR ) &&
+ ( ignoreErrors == false ) )
+ {
+ unbind( messageId );
+
+ System.err.println( "Import failed..." );
+ System.exit( 1 );
+ }
+
+ nbAdd++;
+
+ if ( nbAdd % 10 == 0 )
+ {
+ System.out.print( '.' );
+ }
+
+ if ( nbAdd % 500 == 0 )
+ {
+ System.out.println( nbAdd );
+ }
+ }
+
+ long t1 = System.currentTimeMillis();
+
+ System.out.println( "Done!" );
+ System.out.println( nbAdd + " users added in " + ( ( t1 - t0 ) / 1000 ) + " seconds" );
+ }
+ else
+ {
+ // Parse the file and inject every modification
+ Iterator<LdifEntry> entries = ldifReader.iterator();
+ long t0 = System.currentTimeMillis();
+ int nbMod = 0;
+
+ while ( entries.hasNext() )
+ {
+ LdifEntry entry = entries.next();
+
+ // Check if we have had some error, has next() does not throw any exception
+ if ( ldifReader.hasError() )
+ {
+ System.err.println( "Found an error while persing an entry : " + ldifReader.getError().getMessage() );
+
+ if ( ignoreErrors == false )
+ {
+ unbind( messageId );
+
+ System.err.println( "Import failed..." );
+ System.exit( 1 );
+ }
+ }
+
+ if ( ( changeEntry( entry, messageId++ ) == IMPORT_ERROR ) &&
+ ( ignoreErrors == false ) )
+ {
+ unbind( messageId );
+
+ System.err.println( "Import failed..." );
+ System.exit( 1 );
+ }
+
+ nbMod++;
+
+ if ( nbMod % 10 == 0 )
+ {
+ System.out.print( '.' );
+ }
+
+ if ( nbMod % 500 == 0 )
+ {
+ System.out.println( nbMod );
+ }
+ }
+
+ long t1 = System.currentTimeMillis();
+
+ System.out.println( "Done!" );
+ System.out.println( nbMod + " users changed in " + ( ( t1 - t0 ) / 1000 ) + " seconds" );
+ }
+
+ // Logout to the server
+ unbind( messageId++ );
+
+ }
+
+ /**
+ * Read the command line and get the options : 'h' : host 'p' : port 'u' :
+ * user 'w' : password 'a' : authentication type 'i' : ignore errors 'f' :
+ * ldif file to import
+ *
+ * @param cmd
+ * The command line
+ */
+ private void processOptions( CommandLine cmd )
+ {
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "Processing options for launching diagnostic UI ..." );
+ }
+
+ // -------------------------------------------------------------------
+ // figure out the host value
+ // -------------------------------------------------------------------
+
+ if ( cmd.hasOption( 'h' ) )
+ {
+ host = cmd.getOptionValue( 'h' );
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "ignore-errors overriden by -i option: true" );
+ }
+ }
+ else if ( isDebugEnabled() )
+ {
+ System.out.println( "ignore-errors set to default: false" );
+ }
+
+ // -------------------------------------------------------------------
+ // 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 user value
+ // -------------------------------------------------------------------
+
+ if ( cmd.hasOption( 'u' ) )
+ {
+ user = cmd.getOptionValue( 'u' );
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "user overriden by -u option: " + user );
+ }
+ }
+ else if ( isDebugEnabled() )
+ {
+ System.out.println( "user set to default: " + user );
+ }
+
+ // -------------------------------------------------------------------
+ // 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 );
+ }
+
+ // -------------------------------------------------------------------
+ // figure out the authentication type
+ // -------------------------------------------------------------------
+
+ if ( cmd.hasOption( 'a' ) )
+ {
+ auth = cmd.getOptionValue( 'a' );
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "authentication type overriden by -a option: " + auth );
+ }
+ }
+ else if ( isDebugEnabled() )
+ {
+ System.out.println( "authentication type set to default: " + auth );
+ }
+
+ // -------------------------------------------------------------------
+ // figure out the 'ignore-errors' flag
+ // -------------------------------------------------------------------
+
+ if ( cmd.hasOption( 'e' ) )
+ {
+ ignoreErrors = true;
+
+ if ( isDebugEnabled() )
+ {
+ System.out.println( "authentication type overriden by -a option: " + auth );
+ }
+ }
+ else if ( isDebugEnabled() )
+ {
+ System.out.println( "authentication type set to default: " + auth );
+ }
+
+ // -------------------------------------------------------------------
+ // figure out the ldif file to import
+ // -------------------------------------------------------------------
+
+ if ( cmd.hasOption( 'f' ) )
+ {
+ String ldifFileName = cmd.getOptionValue( 'f' );
+
+ ldifFile = new File( ldifFileName );
+
+ if ( ldifFile.exists() == false )
+ {
+ System.err.println( "ldif file '" + ldifFileName + "' does not exist" );
+ System.exit( 1 );
+ }
+
+ if ( ldifFile.canRead() == false )
+ {
+ System.err.println( "ldif file '" + ldifFileName + "' can't be read" );
+ System.exit( 1 );
+ }
+
+ if ( isDebugEnabled() )
+ {
+ try
+ {
+ System.out.println( "ldif file to import: " + ldifFile.getCanonicalPath() );
+ }
+ catch (IOException ioe)
+ {
+ System.out.println( "ldif file to import: " + ldifFileName );
+ }
+ }
+ }
+ else
+ {
+ System.err.println( "ldif file name must be provided" );
+ System.exit( 1 );
+ }
+ }
+
+ public Options getOptions()
+ {
+ Options opts = new Options();
+ Option 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( "u", "user", true, "the user: default to uid=admin, ou=system" );
+ 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( "a", "auth", true, "the authentication mode: defaults to 'simple'" );
+ op.setRequired( false );
+ opts.addOption( op );
+ op = new Option( "f", "file", true, "the ldif file to import" );
+ op.setRequired( true );
+ opts.addOption( op );
+ op = new Option( "e", "ignore", false, "continue to process the file even if errors are encountered " );
+ op.setRequired( false );
+ opts.addOption( op );
+
+ return opts;
+ }
+}
Added: directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/IndexCommand.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/IndexCommand.java?rev=643845&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/IndexCommand.java (added)
+++ directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/IndexCommand.java Wed Apr 2 04:02:57 2008
@@ -0,0 +1,257 @@
+/*
+ * 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.File;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+
+import jdbm.helper.MRU;
+import jdbm.recman.BaseRecordManager;
+import jdbm.recman.CacheRecordManager;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.DefaultDirectoryService;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.partition.impl.btree.Index;
+import org.apache.directory.server.core.partition.impl.btree.Tuple;
+import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
+import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmMasterTable;
+import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
+import org.apache.directory.server.core.schema.PartitionSchemaLoader;
+import org.apache.directory.server.schema.SerializableComparator;
+import org.apache.directory.server.schema.bootstrap.ApacheSchema;
+import org.apache.directory.server.schema.bootstrap.ApachemetaSchema;
+import org.apache.directory.server.schema.bootstrap.BootstrapSchemaLoader;
+import org.apache.directory.server.schema.bootstrap.CoreSchema;
+import org.apache.directory.server.schema.bootstrap.Schema;
+import org.apache.directory.server.schema.bootstrap.SystemSchema;
+import org.apache.directory.server.schema.bootstrap.partition.DbFileListing;
+import org.apache.directory.server.schema.registries.DefaultOidRegistry;
+import org.apache.directory.server.schema.registries.DefaultRegistries;
+import org.apache.directory.server.schema.registries.OidRegistry;
+import org.apache.directory.server.schema.registries.Registries;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.exception.LdapConfigurationException;
+import org.apache.directory.shared.ldap.exception.LdapNamingException;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.util.AttributeUtils;
+
+
+/**
+ * Simple tool used to dump the contents of a jdbm based partition.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 442600 $
+ */
+public class IndexCommand extends ToolCommand
+{
+ private Registries bootstrapRegistries = new DefaultRegistries( "bootstrap",
+ new BootstrapSchemaLoader(), new DefaultOidRegistry() );
+
+
+ public IndexCommand()
+ {
+ super( "index" );
+ }
+
+ private Registries loadRegistries() throws Exception
+ {
+ // --------------------------------------------------------------------
+ // Load the bootstrap schemas to start up the schema partition
+ // --------------------------------------------------------------------
+
+ // setup temporary loader and temp registry
+ BootstrapSchemaLoader loader = new BootstrapSchemaLoader();
+ OidRegistry oidRegistry = new DefaultOidRegistry();
+ final Registries registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
+
+ // load essential bootstrap schemas
+ Set<Schema> bootstrapSchemas = new HashSet<Schema>();
+ bootstrapSchemas.add( new ApachemetaSchema() );
+ bootstrapSchemas.add( new ApacheSchema() );
+ bootstrapSchemas.add( new CoreSchema() );
+ bootstrapSchemas.add( new SystemSchema() );
+ loader.loadWithDependencies( bootstrapSchemas, registries );
+
+ // run referential integrity tests
+ List<Throwable> errors = registries.checkRefInteg();
+
+ if ( !errors.isEmpty() )
+ {
+ NamingException e = new NamingException();
+ e.setRootCause( ( Throwable ) errors.get( 0 ) );
+ throw e;
+ }
+
+ SerializableComparator.setRegistry( registries.getComparatorRegistry() );
+
+ // --------------------------------------------------------------------
+ // Initialize schema partition or bomb out if we cannot find it on disk
+ // --------------------------------------------------------------------
+
+ // If not present then we need to abort
+ File schemaDirectory = new File( getLayout().getPartitionsDirectory(), "schema" );
+ if ( ! schemaDirectory.exists() )
+ {
+ throw new LdapConfigurationException( "The following schema directory from " +
+ "the installation layout could not be found:\n\t" + schemaDirectory );
+ }
+
+ JdbmPartition schemaPartition = new JdbmPartition();
+ schemaPartition.setId( "schema" );
+ schemaPartition.setCacheSize( 1000 );
+
+ DbFileListing listing;
+ try
+ {
+ listing = new DbFileListing();
+ }
+ catch( IOException e )
+ {
+ throw new LdapNamingException( "Got IOException while trying to read DBFileListing: " + e.getMessage(),
+ ResultCodeEnum.OTHER );
+ }
+
+ Set<Index> indexedAttributes = new HashSet<Index>();
+
+ for ( String attributeId : listing.getIndexedAttributes() )
+ {
+ indexedAttributes.add( new JdbmIndex( attributeId ) );
+ }
+
+ schemaPartition.setIndexedAttributes( indexedAttributes );
+ schemaPartition.setSuffix( ServerDNConstants.OU_SCHEMA_DN );
+
+ ServerEntry systemEntry = new DefaultServerEntry( registries, new LdapDN( "ou=schema" ) );
+ systemEntry.put( SchemaConstants.OBJECT_CLASS_AT,
+ SchemaConstants.TOP_OC,
+ SchemaConstants.ORGANIZATIONAL_UNIT_OC );
+ systemEntry.put( SchemaConstants.OU_AT, "schema" );
+ schemaPartition.setContextEntry( systemEntry );
+
+ DirectoryService directoryService = new DefaultDirectoryService();
+ schemaPartition.init( directoryService );
+
+ // --------------------------------------------------------------------
+ // Initialize schema subsystem and reset registries
+ // --------------------------------------------------------------------
+
+ PartitionSchemaLoader schemaLoader = new PartitionSchemaLoader( schemaPartition, registries );
+ Registries globalRegistries = new DefaultRegistries( "global", schemaLoader, oidRegistry );
+ schemaLoader.loadEnabled( globalRegistries );
+ SerializableComparator.setRegistry( globalRegistries.getComparatorRegistry() );
+ return globalRegistries;
+ }
+
+ public void execute( CommandLine cmdline ) throws Exception
+ {
+ getLayout().verifyInstallation();
+ bootstrapRegistries = loadRegistries();
+
+ String[] partitions = cmdline.getOptionValues( 'p' );
+ String attribute = cmdline.getOptionValue( 'a' );
+
+ for ( int ii = 0; ii < partitions.length; ii++ )
+ {
+ File partitionDirectory = new File( getLayout().getPartitionsDirectory(), partitions[ii] );
+ buildIndex( partitionDirectory, bootstrapRegistries.getAttributeTypeRegistry().lookup( attribute ) );
+ }
+ }
+
+
+ private void buildIndex( File partitionDirectory, AttributeType attributeType ) throws Exception
+ {
+ if ( !partitionDirectory.exists() )
+ {
+ System.err.println( "Partition directory " + partitionDirectory + " does not exist!" );
+ System.exit( 1 );
+ }
+
+ String path = partitionDirectory.getPath() + File.separator + "master";
+ BaseRecordManager base = new BaseRecordManager( path );
+ base.disableTransactions();
+ CacheRecordManager recMan = new CacheRecordManager( base, new MRU( 1000 ) );
+
+ JdbmMasterTable master = new JdbmMasterTable( recMan );
+ JdbmIndex index = new JdbmIndex();
+ index.setAttributeId( attributeType.getName() );
+ index.setWkDirPath( partitionDirectory );
+ index.setCacheSize( 1000 );
+ index.setNumDupLimit( 1000 );
+ index.init( attributeType, partitionDirectory );
+
+ NamingEnumeration list = master.listTuples();
+ while ( list.hasMore() )
+ {
+ Tuple tuple = ( Tuple ) list.next();
+ BigInteger id = ( BigInteger ) tuple.getKey();
+ Attributes entry = ( Attributes ) tuple.getValue();
+
+ Attribute attr = AttributeUtils.getAttribute( entry, attributeType );
+ if ( attr == null )
+ {
+ continue;
+ }
+
+ for ( int ii = 0; ii < attr.size(); ii++ )
+ {
+ index.add( attr.get( ii ), id );
+ }
+ }
+
+ index.sync();
+ }
+
+
+ public Options getOptions()
+ {
+ Options opts = new Options();
+ Option op = null;
+ op = new Option( "p", "partitions", true, "the partitions to add the attribute indices to" );
+ op.setRequired( true );
+ op.setValueSeparator( File.pathSeparatorChar );
+ opts.addOption( op );
+ op = new Option( "a", "attributes", true, "the attribute to index" );
+ op.setRequired( true );
+ op.setValueSeparator( File.pathSeparatorChar );
+ opts.addOption( op );
+ op = new Option( "i", "install-path", true, "path to apacheds installation directory" );
+ op.setRequired( true );
+ opts.addOption( op );
+ return opts;
+ }
+}
Modified: directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/ToolCommand.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/ToolCommand.java?rev=643845&r1=643844&r2=643845&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/ToolCommand.java (original)
+++ directory/apacheds/branches/bigbang/server-tools/src/main/java/org/apache/directory/server/tools/ToolCommand.java Wed Apr 2 04:02:57 2008
@@ -19,18 +19,136 @@
*/
package org.apache.directory.server.tools;
-import org.apache.directory.server.constants.ServerDNConstants;
+
+import java.io.File;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.directory.daemon.InstallationLayout;
+import org.apache.directory.server.configuration.ApacheDS;
/**
- * Interface that must be extended by every type of command.
+ * Simple base class for tool commands.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
*/
-public interface ToolCommand
+public abstract class ToolCommand
{
- // Default values
- public final static int DEFAULT_PORT = 10389;
- public final static String DEFAULT_HOST = "localhost";
- public final static String DEFAULT_PASSWORD = "secret";
- public final static String DEFAULT_USER = ServerDNConstants.ADMIN_SYSTEM_DN;
- public final static String DEFAULT_AUTH = "simple";
+ private final String name;
+ private boolean debugEnabled = false;
+ private boolean verboseEnabled = false;
+ private boolean quietEnabled = false;
+ private String version;
+ private InstallationLayout layout;
+ private ApacheDS apacheDS;
+
+
+ protected ToolCommand(String name)
+ {
+ this.name = name;
+ }
+
+
+ public abstract void execute( CommandLine cmd ) throws Exception;
+
+
+ public abstract Options getOptions();
+
+
+ public String getName()
+ {
+ return this.name;
+ }
+
+
+ public void setLayout( File installationDirectory )
+ {
+ this.layout = new InstallationLayout( installationDirectory );
+ }
+
+
+ public void setLayout( String installationPath )
+ {
+ this.layout = new InstallationLayout( installationPath );
+ }
+
+
+ public void setLayout( InstallationLayout layout )
+ {
+ this.layout = layout;
+ }
+
+
+ public InstallationLayout getLayout()
+ {
+ return layout;
+ }
+
+
+ public void setApacheDS( ApacheDS apacheDS )
+ {
+ this.apacheDS = apacheDS;
+ }
+
+
+ public ApacheDS getApacheDS()
+ {
+ return apacheDS;
+ }
+
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+
+ public String toString()
+ {
+ return getName();
+ }
+
+
+ public void setDebugEnabled( boolean debugEnabled )
+ {
+ this.debugEnabled = debugEnabled;
+ }
+
+
+ public boolean isDebugEnabled()
+ {
+ return debugEnabled;
+ }
+
+
+ public void setVerboseEnabled( boolean verboseEnabled )
+ {
+ this.verboseEnabled = verboseEnabled;
+ }
+
+
+ public boolean isVerboseEnabled()
+ {
+ return verboseEnabled;
+ }
+
+
+ public void setQuietEnabled( boolean quietEnabled )
+ {
+ this.quietEnabled = quietEnabled;
+ }
+
+
+ public boolean isQuietEnabled()
+ {
+ return quietEnabled;
+ }
}