You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2006/05/15 08:48:39 UTC

svn commit: r406557 - /directory/branches/elecharny/apacheds/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java

Author: elecharny
Date: Sun May 14 23:48:36 2006
New Revision: 406557

URL: http://svn.apache.org/viewcvs?rev=406557&view=rev
Log:
Added the Import command (to import ldif files)

Added:
    directory/branches/elecharny/apacheds/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java

Added: directory/branches/elecharny/apacheds/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java
URL: http://svn.apache.org/viewcvs/directory/branches/elecharny/apacheds/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java?rev=406557&view=auto
==============================================================================
--- directory/branches/elecharny/apacheds/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java (added)
+++ directory/branches/elecharny/apacheds/server-tools/src/main/java/org/apache/directory/server/tools/ImportCommand.java Sun May 14 23:48:36 2006
@@ -0,0 +1,561 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.BufferedOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+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 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.ldif.Entry;
+import org.apache.directory.shared.ldap.ldif.LdifReader;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.util.StringTools;
+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.extended.ExtendedResponse;
+import org.apache.directory.shared.ldap.codec.util.LdapResultEnum;
+
+/**
+ * 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;
+
+	/**
+	 * Socket used to connect to the server
+	 */
+	private SocketChannel channel;
+    private SocketAddress serverAddress;
+	private OutputStream 	serverOut;
+	private InputStream 	serverIn;
+	private IAsn1Container ldapMessageContainer = new LdapMessageContainer();
+	private Asn1Decoder ldapDecoder = new LdapDecoder();
+
+	/**
+	 * Stream used to talk to the server
+	 */
+	private InputStream in = null;
+
+	/**
+	 * Stream used to read from the server
+	 */
+	private OutputStream out = null;
+
+	/**
+	 * 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
+	 */
+	public 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 {
+		
+		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() != 0 )
+			        	{
+			        		System.out.println( "Error : " + resp.getLdapResult().getErrorMessage() );
+			        	}
+		        	}
+		        	else if (messageResp instanceof ExtendedResponse )
+		        	{
+			        	ExtendedResponse resp = ((LdapMessageContainer)ldapMessageContainer).getLdapMessage().getExtendedResponse();
+			        	
+			        	if (resp.getLdapResult().getResultCode() != 0 )
+			        	{
+			        		System.out.println( "Error : " + resp.getLdapResult().getErrorMessage() );
+			        	}
+		        	}
+		        	
+		        	System.out.println( messageResp.toString() );
+		        	
+		        	//System.out.println( ((LdapMessageContainer)ldapMessageContainer).getLdapMessage() );
+		        	((LdapMessageContainer)ldapMessageContainer).clean();
+		        	break;
+		        }
+		        else
+		        {
+		        	bb.flip();
+		        }
+			}
+		}
+
+		return messageResp;
+		
+	}
+
+	private LdapMessage decode(ByteBuffer buffer) throws DecoderException {
+		Asn1Decoder ldapDecoder = new LdapDecoder();
+
+		// Allocate a LdapMessageContainer Container
+		IAsn1Container ldapMessageContainer = new LdapMessageContainer();
+
+		// Decode the PDU
+		ldapDecoder.decode(buffer, ldapMessageContainer);
+
+		// Check that everything is OK
+		LdapMessage ldapMessage = ((LdapMessageContainer) ldapMessageContainer)
+				.getLdapMessage();
+
+		return ldapMessage;
+	}
+
+	/**
+	 * Prepare the LDIF entry and send it to the encoder, then wait for a
+	 * reponse from the LDAP server on the results of the operation.
+	 * 
+	 * @param a_buf
+	 *            The string buffer that contain the LDIF entry
+	 * @param msgId
+	 *            message id number
+	 */
+	private void add(Entry entry, int messageId) throws IOException,
+			DecoderException, InvalidNameException, NamingException,
+			EncoderException {
+		AddRequest addRequest = new AddRequest();
+
+		String dn = entry.getDn();
+		Attributes attributes = entry.getAttributes();
+
+		addRequest.setEntry(new LdapDN(dn));
+
+		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);
+		ByteBuffer bb = message.encode(null);
+
+		sendMessage(bb);
+		
+		bb.clear();
+		
+		LdapMessage response = readResponse( bb );
+
+		LdapResult result = response.getAddResponse().getLdapResult();
+
+		if (result.getResultCode() == LdapResultEnum.SUCCESS) {
+			if (isDebugEnabled()) {
+				System.out.println("Add of Entry " + entry.getDn()
+						+ " was successful");
+			}
+		} else {
+			System.err
+					.println("Add of entry "
+							+ entry.getDn()
+							+ " failed for the following reasons provided by the server:\n"
+							+ result.getErrorMessage());
+		}
+	}
+
+	private void bind(int messageId) throws InvalidNameException, 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 );
+		ByteBuffer bb = message.encode(null);
+		bb.flip();
+
+		connect();
+		sendMessage(bb);
+		
+		bb.clear();
+		
+		LdapMessage response = readResponse( bb );
+
+		LdapResult result = response.getAddResponse().getLdapResult();
+
+		if (result.getResultCode() == LdapResultEnum.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());
+		}
+	}
+
+	/**
+	 * 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);
+
+		// Parse the file and inject every entri or every modification
+		Iterator entries = ldifReader.iterator();
+
+		while (entries.hasNext()) {
+
+		}
+
+	}
+
+	/**
+	 * 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 (getConfiguration() != null) {
+			port = getConfiguration().getLdapPort();
+
+			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('i')) {
+			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( "i", "ignore", true,
+				"continue to process the file even if errors are encountered " );
+		op.setRequired(false);
+		opts.addOption(op);
+
+		return opts;
+	}
+}