db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From oyste...@apache.org
Subject svn commit: r577731 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/services/replication/net/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/
Date Thu, 20 Sep 2007 13:01:41 GMT
Author: oysteing
Date: Thu Sep 20 06:01:40 2007
New Revision: 577731

URL: http://svn.apache.org/viewvc?rev=577731&view=rev
Log:
Add a network service that connects the master and slave Derby instances
Contributed by Narayanan

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessage.java
  (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageReceive.java
  (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageTransmit.java
  (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SlaveAddress.java
  (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SocketConnection.java
  (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessage.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessage.java?rev=577731&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessage.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessage.java
Thu Sep 20 06:01:40 2007
@@ -0,0 +1,178 @@
+/*
+ 
+   Derby - Class org.apache.derby.impl.services.replication.net.ReplicationMessage
+ 
+   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.derby.impl.services.replication.net;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+/**
+ * This message is used for the communication between the master and the
+ * slave during Replication. The message is composed of a type flag
+ * and corresponding object. Each type flag indicating the type of the 
+ * content bundled inside the message.
+ *
+ * For now the following message types are defined
+ *
+ * TYPE_LOG - This flag will be used for all messages will carry LogRecords.
+ * TYPE_ACK - this flag is used to send a acknowledgment of successful
+ *            completion of a requested operation. It will however not
+ *            be used to signify reception for every message transmission
+ *            since tcp would automatically take care of this.
+ * TYPE_ERROR - Indicates that the requested operation was not able to be
+ *              completed successfully.
+ * TYPE_INITIATE - used during the intial handshake between the master and
+ *                 the slave. The initial handshake helps to negotiate the
+ *                 message UIDs and send a appropriate error or acknowledgment.
+ */
+public class ReplicationMessage implements Externalizable {
+    /**
+     * The version number is determined based on the database version
+     * of the current database. This would help to establish if the 
+     * master and the slave in replication are at compatible database
+     * versions.
+     */
+    public static final long serialVersionUID = 1L;
+    
+    /**
+     * This is the content of the replication message.
+     */
+    private Object message;
+    
+    /**
+     * The valid values for the type of the content of the message
+     * are listed below.
+     */
+    private int type;
+    
+    /**
+     * This flag will be used for all messages that carry log records.
+     * The Object this message type contains will be a <code>byte</code>
+     * array. The content of the byte array is the log records in the
+     * binary form.
+     */
+    public static final int TYPE_LOG = 0;
+    
+    /**
+     * This flag is used to send an acknowledgment of successful completion
+     * of a requested operation. It will however not be used to signify
+     * reception for every message transmission. The object this message
+     * type contains will be a <code>String</code>. The SQLState of the
+     * error message can be used here.
+     */
+    public static final int TYPE_ACK = 1;
+    
+    /**
+     * Indicates that the requested operation was not able to be
+     * completed successfully. The object this message type contains
+     * will be a <code>String</code>.
+     */
+    public static final int TYPE_ERROR = 2;
+    
+    /**
+     * used during the intial handshake between the master and
+     * the slave. The initial handshake helps to negotiate the
+     * message UIDs and send a appropriate error or acknowledgment.
+     * The object this message contains will be a <code>Long</code>.
+     */
+    public static final int TYPE_INITIATE = 3;
+    
+    /**
+     * public No args constructor required with Externalizable.
+     */
+    public ReplicationMessage() {}
+    
+    /**
+     * Constructor used to set the <code>type</code> and <code>message</code>.
+     * This is used while creating messages for sending while readExternal is
+     * used on the receiving end.
+     *
+     * @param type      The type of this message. Must be one of the message
+     *                  type constants of this class (TYPE_LOG, TYPE_ACK,
+     *                  TYPE_ERROR, TYPE_INITIATE).
+     *
+     * @param message   The message to be transmitted.
+     *
+     */
+    public ReplicationMessage(int type, Object message){
+        this.type = type;
+        this.message = message;
+    }
+    
+    /**
+     * Used to get the actual message that is wrapped inside the
+     * ReplicationMessage object.
+     *
+     * @return The object contained in the message
+     */
+    public Object getMessage(){
+        return message;
+    }
+    
+    /**
+     * Used to get the type of this <code>ReplicationMessage</code>.
+     *
+     * @return The type of the message.
+     */
+    public int getType(){
+        return type;
+    }
+    
+    /**
+     * Used to restore the contents of this object.
+     *
+     * @param in the stream to read data from in order to restore the object.
+     *
+     * @throws IOException If an exception occurs while reading from the
+     *                     <code>InputStream</code>.
+     *
+     * @throws ClassNotFoundException Class of a serialized object cannot
+     *                                be found.
+     *
+     */
+    public void readExternal(ObjectInput in) throws IOException,
+        ClassNotFoundException {
+        switch ((int)in.readLong()) {
+            case 1: {
+                type = in.readInt();
+                message = in.readObject();
+                break;
+            }
+        }
+    }
+    
+    /**
+     * Used to save the contents of this Object.
+     *
+     * @param out the stream to write the object to.
+     *
+     * @throws IOException if an exception occurs while writing to the
+     *                     <code>OutputStream</code>.
+     *
+     */
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeLong(serialVersionUID);
+        out.writeInt(type);
+        out.writeObject(message);
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageReceive.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageReceive.java?rev=577731&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageReceive.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageReceive.java
Thu Sep 20 06:01:40 2007
@@ -0,0 +1,215 @@
+/*
+ 
+   Derby - Class org.apache.derby.impl.services.replication.net.ReplicationMessageReceive
+ 
+   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.derby.impl.services.replication.net;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import javax.net.ServerSocketFactory;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.SQLState;
+
+/**
+ * This class is the Receiver (viz. Socket server or listener) part of the
+ * network communication. It receives the message from the master and
+ * performs appropriate action depending on the type of the message.
+ */
+public class ReplicationMessageReceive {
+    /**
+     * Contains the address (hostname and port number) of the slave
+     * to replicate to.
+     */
+    private final SlaveAddress slaveAddress;
+    
+    /**
+     * Contains the methods used to read and write to the Object streams
+     * obtained from a <code>Socket</code> connection.
+     */
+    private SocketConnection socketConn;
+    
+    /**
+     * Constructor initializes the slave address used in replication. Accepts
+     * the host name and port number that constitute the slave address as
+     * parameters.
+     *
+     * @param hostName a <code>String</code> that contains the host name of
+     *                 the slave to replicate to.
+     * @param portNumber an integer that contains the port number of the
+     *                   slave to replicate to.
+     *
+     * @throws UnknownHostException If an exception occurs while trying to
+     *                              resolve the host name.
+     */
+    public ReplicationMessageReceive(String hostName, int portNumber)
+    throws UnknownHostException {
+        slaveAddress = new SlaveAddress(hostName, portNumber);
+    }
+    
+    /**
+     * Used to create the server socket, listen on the socket
+     * for connections from the master and verify compatibility
+     * with the database version of the master.
+     *
+     * @throws PrivilegedActionException if an exception occurs while trying
+     *                                   to open a connection.
+     *
+     * @throws IOException if an exception occurs while trying to create the
+     *                     <code>SocketConnection</code> class.
+     *
+     * @throws ClassNotFoundException Class of a serialized object cannot
+     *                                be found.
+     * @throws StandardException if an incompatible database version is found.
+     *
+     */
+    public void initConnection() throws
+        PrivilegedActionException,
+        IOException,
+        StandardException,
+        ClassNotFoundException {
+        
+        //Contains the <code>ServerSocket</code> used to listen for
+        //connections from the replication master.
+        final ServerSocket serverSocket = createServerSocket();
+        
+        //Start listening on the socket and accepting the connection
+        Socket client =
+            (Socket)
+            AccessController.doPrivileged(new PrivilegedExceptionAction() {
+            public Object run() throws IOException {
+                return serverSocket.accept();
+            }
+        });
+        
+        //create the SocketConnection object using the client connection.
+        socketConn = new SocketConnection(client);
+        
+        //wait for the initiator message on the SocketConnection
+        ReplicationMessage initMesg = readMessage();
+        
+        //Check if this message is an initiator message, if not
+        //throw an exception
+        if (initMesg.getType() != ReplicationMessage.TYPE_INITIATE) {
+            //The message format was not recognized. Hence throw
+            //an unexpected exception.
+            throw StandardException.newException
+                (SQLState.REPLICATION_UNEXPECTED_EXCEPTION);
+        }
+        
+        //parse the initiator message and perform appropriate action
+        parseInitiatorMessage(initMesg);
+    }
+    
+    /**
+     * Used to create a <code>ServerSocket</code> for listening to connections
+     * from the master.
+     *
+     * @return an instance of the <code>ServerSocket</code> class.
+     *
+     * @throws PrivilegedActionException if an exception occurs while trying
+     *                                   to open a connection.
+     */
+    private ServerSocket createServerSocket() throws PrivilegedActionException {
+        //create a ServerSocket at the specified host name and the
+        //port number.
+        return   (ServerSocket) AccessController.doPrivileged
+            (new PrivilegedExceptionAction() {
+            public Object run() throws IOException, StandardException {
+                ServerSocketFactory sf = ServerSocketFactory.getDefault();
+                return sf.createServerSocket(slaveAddress.getPortNumber(),
+                    0, slaveAddress.getHostAddress());
+            }
+        });
+    }
+    
+    /**
+     * Used to parse the initiator message from the master and check if the
+     * slave is compatible with the master by comparing the UID of the 
+     * <code>ReplicationMessage</code> class of the master, that is wrapped
+     * in the initiator message, with the UID of the same class in the slave.
+     *
+     * @param initiatorMessage the object containing the UID.
+     *
+     * @throws IOException If an exception occurs while sending the
+     *                     acknowledgment.
+     *
+     * @throws StandardException If the UID's do not match.
+     */
+    private void parseInitiatorMessage(ReplicationMessage initiatorMessage)
+        throws IOException, StandardException {
+        //Holds the replication message that will be sent
+        //to the master.
+        ReplicationMessage ack = null;
+        //Get the UID of the master
+        long masterVersion = ((Long)initiatorMessage.getMessage()).longValue();
+        //If the UID's are equal send the acknowledgment message
+        if (masterVersion == ReplicationMessage.serialVersionUID) {
+            ack = new ReplicationMessage
+                (ReplicationMessage.TYPE_ACK, "UID OK");
+            socketConn.writeMessage(ack);
+        } else {
+            //If the UID's are not equal send an error message
+            ack = new ReplicationMessage
+                (ReplicationMessage.TYPE_ERROR,
+                SQLState.REPLICATION_MASTER_SLAVE_VERSION_MISMATCH);
+            
+            //The UID's do not match.
+            throw StandardException.newException
+                (SQLState.REPLICATION_MASTER_SLAVE_VERSION_MISMATCH);
+        }
+    }
+    
+    /**
+     * Used to send a replication message to the master.
+     *
+     * @param message a <code>ReplicationMessage</code> object that contains
+     *                the message to be transmitted.
+     *
+     * @throws IOException if an exception occurs while transmitting
+     *                     the message.
+     */
+    public void sendMessage(ReplicationMessage message) throws IOException {
+        socketConn.writeMessage(message);
+    }
+    
+    /**
+     * Used to read a replication message sent by the master. This method
+     * would wait on the connection from the master until a message is received
+     * or a connection failure occurs.
+     *
+     * @return a <code>ReplicationMessage</code> object that contains
+     *         the reply that is sent.
+     *
+     * @throws ClassNotFoundException Class of a serialized object cannot
+     *                                be found.
+     *
+     * @throws IOException if an exception occurs while reading from the
+     *                     stream.
+     */
+    public ReplicationMessage readMessage() throws
+        ClassNotFoundException, IOException {
+        return (ReplicationMessage)socketConn.readMessage();
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageReceive.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageTransmit.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageTransmit.java?rev=577731&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageTransmit.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageTransmit.java
Thu Sep 20 06:01:40 2007
@@ -0,0 +1,190 @@
+/*
+ 
+   Derby - Class org.apache.derby.impl.services.replication.net.ReplicationMessageTransmit
+ 
+   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.derby.impl.services.replication.net;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import javax.net.SocketFactory;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.SQLState;
+
+/**
+ * Used to send replication messages to the slave. Called by the
+ * Master controller to transmit replication messages wrapped in
+ * a <code>ReplicationMessage</code> object to a receiver. The
+ * receiver is implemented by the <code>ReplicationMessageReceive</code>
+ * class.
+ */
+public class ReplicationMessageTransmit {
+    
+    /**
+     * Contains the address (hostname and port number) of the slave
+     * to replicate to.
+     */
+    private final SlaveAddress slaveAddress;
+    
+    /**
+     * Used to write/read message objects to/from a connection.
+     */
+    private SocketConnection socketConn;
+    
+    /**
+     * Constructor initializes the slave address used in replication.
+     *
+     * @param hostName a <code>String</code> that contains the host name of
+     *                 the slave to replicate to.
+     * @param portNumber an integer that contains the port number of the
+     *                   slave to replicate to.
+     *
+     * @throws UnknownHostException If an exception occurs while trying to
+     *                              resolve the host name.
+     */
+    public ReplicationMessageTransmit(String hostName, int portNumber) 
+    throws UnknownHostException {
+        slaveAddress = new SlaveAddress(hostName, portNumber);
+    }
+    
+    /**
+     * Used to create a <code>Socket</code> connection to the slave and
+     * establish compatibility with the database version of the slave by
+     * comparing the UID's of the <code>ReplicationMessage</code> classes
+     * of the master and the slave.
+     *
+     * @throws PrivilegedActionException if an exception occurs while trying
+     *                                   to open a connection.
+     *
+     * @throws IOException if an exception occurs while trying to create the
+     *         <code>SocketConnection</code> class.
+     *
+     * @throws StandardException If an error message is received from the
+     *         server indicating incompatible software versions of master
+     *         and slave.
+     *
+     * @throws ClassNotFoundException Class of a serialized object cannot
+     *         be found.
+     */
+    public void initConnection() throws
+        PrivilegedActionException,
+        IOException,
+        StandardException,
+        ClassNotFoundException {
+        
+        Socket s = null;
+        
+        //create a connection to the slave.
+        s = (Socket)
+        AccessController.doPrivileged(new PrivilegedExceptionAction() {
+            public Object run() throws IOException {
+                SocketFactory sf = SocketFactory.getDefault();
+                return sf.createSocket(slaveAddress.getHostAddress(),
+                    slaveAddress.getPortNumber());
+            }
+        });
+        
+        socketConn = new SocketConnection(s);
+        
+        //send the initiate message and receive acknowledgment
+        sendInitiatorAndReceiveAck();
+    }
+    
+    /**
+     * Used to send a replication message to the slave.
+     *
+     * @param message a <code>ReplicationMessage</code> object that contains
+     *                the message to be transmitted.
+     *
+     * @throws IOException if an exception occurs while transmitting
+     *                     the message.
+     */
+    public void sendMessage(ReplicationMessage message) throws IOException {
+        socketConn.writeMessage(message);
+    }
+    
+    /**
+     * Used to read a replication message sent by the slave. This method
+     * would wait on the connection from the slave until a message is received
+     * or a connection failure occurs.
+     *
+     * @return the reply message.
+     *
+     * @throws ClassNotFoundException Class of a serialized object cannot
+     *                                be found.
+     *
+     * @throws IOException if an exception occurs while reading from the
+     *                     stream.
+     */
+    public ReplicationMessage readMessage() throws
+        ClassNotFoundException, IOException {
+        return (ReplicationMessage)socketConn.readMessage();
+    }
+    
+    /**
+     * Used to send a initiator message to the slave and receive information
+     * about the compatibility of the slave with the master. The slave 
+     * determines if the software versions are compatible by comparing the
+     * UID's of the <code>ReplicationMessage</code> of the master and the
+     * slave.
+     *
+     * @throws IOException if an exception occurs during the sending or
+     *                     reading of the message.
+     *
+     * @throws StandardException If an error message is received from the
+     *                           server indicating a mis-match in
+     *                           serialVersionUID.
+     *
+     * @throws ClassNotFoundException Class of a serialized object cannot
+     *                                be found.
+     */
+    private void sendInitiatorAndReceiveAck() 
+        throws IOException, StandardException, ClassNotFoundException {
+        //Build the initiator message with the serialVersionUID of the
+        //ReplicationMessage.
+        ReplicationMessage initiatorMsg = new ReplicationMessage
+            (ReplicationMessage.TYPE_INITIATE, new Long(
+            ReplicationMessage.serialVersionUID));
+        
+        //send the initiator message to the slave.
+        sendMessage(initiatorMsg);
+        
+        //read the acknowledgment from the slave.
+        ReplicationMessage ack = readMessage();
+        
+        
+        //If the message is a TYPE_ACK the slave is capable
+        //of handling the messages and is at a compatible database version.
+        if (ack.getType() == ReplicationMessage.TYPE_ACK) {
+            return;
+        } else if (ack.getType() == ReplicationMessage.TYPE_ERROR) {
+            //The UID's do not match.
+            throw StandardException.newException
+                ((String)ack.getMessage());
+        } else {
+            //The message format was not recognized. Hence throw
+            //an unexpected exception.
+            throw StandardException.newException
+                (SQLState.REPLICATION_UNEXPECTED_EXCEPTION);
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/ReplicationMessageTransmit.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SlaveAddress.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SlaveAddress.java?rev=577731&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SlaveAddress.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SlaveAddress.java
Thu Sep 20 06:01:40 2007
@@ -0,0 +1,94 @@
+/*
+ 
+   Derby - Class org.apache.derby.impl.services.replication.net.SlaveAddress
+ 
+   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.derby.impl.services.replication.net;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Encapsulates the host name and the port number of the slave machine.
+ */
+public class SlaveAddress {
+    /**
+     * Contains the IP Address of the slave to replicate to.
+     */
+    private final InetAddress hostAddress;
+    
+    /**
+     * Contains the port number at which the slave is listening for
+     * connections from the master.
+     */
+    private final int portNumber;
+    
+    /**
+     * Used as the default port number if the port number
+     * is not mentioned.
+     */
+    private final int DEFAULT_PORT_NO = 8001;
+    
+    /**
+     *
+     * Constructor initializes the host name and the port number with
+     * valid values. If a valid host name or port number is not provided 
+     * then these are initialized to default values.
+     *
+     * @param hostName a <code>String</code> that contains the host name of
+     *                 the slave.
+     * @param portNumber an <code>int</code> that contains the port number
+     *                   of the slave.
+     *
+     * @throws UnknownHostException If an exception occurs while trying to
+     *                              resolve the host name.
+     */
+    public SlaveAddress(String hostName, int portNumber) 
+    throws UnknownHostException {
+        //InetAddress#getByName will return the default (localhost) 
+        //if no host name is given.  Hence, no explicit handling of 
+        //default is necessary for the host address.
+        hostAddress = InetAddress.getByName(hostName);
+        //Check if a valid port number has been supplied
+        if (portNumber > 0) { //If yes assign the value to port number
+            this.portNumber = portNumber;
+        } else { //If no assign the default value of the port number
+            this.portNumber = DEFAULT_PORT_NO;
+        }
+    }
+    
+    /**
+     * Used to get the IP Address corresponding to the host name of the
+     * slave.
+     *
+     * @return an IP Address corresponding to the slave host name.
+     */
+    public InetAddress getHostAddress() {
+        return hostAddress;
+    }
+    
+    /**
+     * Used to get the port number of the slave.
+     *
+     * @return an int representing the value of the port number of the slave.
+     */
+    public int getPortNumber() {
+        return portNumber;
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SlaveAddress.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SocketConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SocketConnection.java?rev=577731&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SocketConnection.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SocketConnection.java
Thu Sep 20 06:01:40 2007
@@ -0,0 +1,102 @@
+/*
+ 
+   Derby - Class org.apache.derby.impl.services.replication.net.SocketConnection
+ 
+   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.derby.impl.services.replication.net;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+
+/**
+ * This class encapsulates a <code>Socket</code> connection and has
+ * methods that allow to read and write into the Object streams
+ * created from this connection.
+ */
+public class SocketConnection {
+    /**
+     * Contains the Socket connection between the Replication master and the
+     * slave.
+     */
+    private final Socket socket;
+    
+    /**
+     * used to write message objects into the socket connection.
+     */
+    private final ObjectOutputStream objOutputStream;
+    
+    /**
+     * used to read message objects sent in the socket connection.
+     */
+    private final ObjectInputStream objInputStream;
+    
+    /**
+     * Constructor creates the streams from the socket object passed as
+     * parameter.
+     *
+     * @param socket the <code>Socket</code> object that this class
+     *               encapsulates.
+     *
+     * @throws IOException If an exception occurs while creating the
+     *                     streams from the socket object.
+     */
+    public SocketConnection(Socket socket) throws IOException {
+        this.socket = socket;
+        
+        //Get the OutputStream from the socket
+        objOutputStream = new ObjectOutputStream(socket.getOutputStream());
+        //Get the InputStream from the socket
+        objInputStream = new ObjectInputStream(socket.getInputStream());
+    }
+    
+    /**
+     * Used to read the object messages that are sent.
+     * waits on the input stream until a data is present that
+     * can be read and returns this data.
+     *
+     * @return the data read from the connection.
+     *
+     * @throws ClassNotFoundException Class of a serialized object cannot 
+     *                                be found.
+     * @throws IOException if an exception occurs while reading from the
+     *                     stream.
+     */
+    public Object readMessage()
+    throws ClassNotFoundException, IOException {
+        return objInputStream.readObject();
+    }
+    
+    /**
+     * Used to send the object messages across the socket conection. 
+     *
+     * @param message the data to be written into the connection.
+     *
+     * @throws IOException if an exception occurs while writing into the
+     *                     stream.
+     */
+    public void writeMessage(Object message) throws IOException {
+        objOutputStream.writeObject(message);
+        //flush the stream to ensure that all the data that is part
+        //of the message object is written and no data remains
+        //in this stream.
+        objOutputStream.flush();
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/net/SocketConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=577731&r1=577730&r2=577731&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Thu Sep 20 06:01:40
2007
@@ -4720,6 +4720,14 @@
                 <name>XRE01</name>
                 <text>The log received from the master is corrupted.</text>
             </msg>
+            <msg>
+                <name>XRE02</name>
+                <text>Master and Slave at different versions. Unable to proceed with
Replication.</text>
+            </msg>
+            <msg>
+                <name>XRE03</name>
+                <text>Unexpected error during replication network communication initiation.</text>
+            </msg>
 
         </family>
 

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=577731&r1=577730&r2=577731&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
(original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
Thu Sep 20 06:01:40 2007
@@ -1763,6 +1763,7 @@
     */
     String CANNOT_REPLICATE_READONLY_DATABASE                      = "XRE00";
     String REPLICATION_LOG_CORRUPTED                               = "XRE01";
-
+    String REPLICATION_MASTER_SLAVE_VERSION_MISMATCH               = "XRE02";
+    String REPLICATION_UNEXPECTED_EXCEPTION                        = "XRE03";
 }
 



Mime
View raw message