package org.jacorb.test.orb.connection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.jacorb.config.Configuration;
import org.jacorb.orb.giop.ClientConnection;
import org.jacorb.orb.giop.GIOPConnection;
import org.jacorb.orb.giop.GIOPConnectionManager;
import org.jacorb.orb.giop.LocateRequestOutputStream;
import org.jacorb.orb.giop.MessageOutputStream;
import org.jacorb.orb.giop.Messages;
import org.jacorb.orb.giop.ReplyInputStream;
import org.jacorb.orb.giop.ReplyListener;
import org.jacorb.orb.giop.RequestInputStream;
import org.jacorb.orb.giop.RequestListener;
import org.jacorb.orb.giop.RequestOutputStream;
import org.jacorb.orb.giop.ServerGIOPConnection;
import org.jacorb.orb.iiop.IIOPAddress;
import org.jacorb.orb.iiop.IIOPProfile;
import org.jacorb.test.harness.ORBTestCase;
import org.junit.Before;
import org.junit.Test;
import org.omg.ETF.BufferHolder;
import org.omg.ETF.Profile;
import org.omg.GIOP.MsgType_1_1;
/**
* GIOPConnectionTest.java
*
* @author Nicolas Noffke
*/
public class GIOPConnectionTest extends ORBTestCase
{
private Configuration config;
@Before
public void setUp()
throws Exception
{
config = this.getORB().getConfiguration();
}
class DummyTransport extends org.omg.ETF._ConnectionLocalBase
{
private boolean closed = false;
private byte[] data = null;
private int index = 0;
private ByteArrayOutputStream b_out = new ByteArrayOutputStream();
private org.omg.ETF.Profile profile = new IIOPProfile
(
new IIOPAddress ("127.0.0.1", 4711),
null,
getORB().getGIOPMinorVersion()
);
public DummyTransport( List<byte[]> messages )
{
// convert the message list into a plain byte array
int size = 0;
for (Iterator<byte[]> i = messages.iterator(); i.hasNext();)
{
size += i.next().length;
}
data = new byte[size];
int index = 0;
for (Iterator<byte[]> i = messages.iterator(); i.hasNext();)
{
byte[] msg = i.next();
System.arraycopy(msg, 0, data, index, msg.length);
index += msg.length;
}
}
public byte[] getWrittenMessage()
{
return b_out.toByteArray();
}
@Override
public void connect (org.omg.ETF.Profile profile, long time_out)
{
// nothing
}
public boolean hasBeenClosed()
{
return closed;
}
@Override
public boolean is_connected()
{
return !closed;
}
@Override
public void write( boolean is_first, boolean is_last,
byte[] message, int start, int size,
long timeout )
{
b_out.write( message, start, size );
}
@Override
public void flush()
{
}
@Override
public void close()
{
closed = true;
}
public boolean isSSL()
{
return false;
}
public void turnOnFinalTimeout()
{
}
@Override
public Profile get_server_profile()
{
return profile;
}
@Override
public int read (BufferHolder data, int offset,
int min_length, int max_length, long time_out)
{
if (this.index + min_length > this.data.length)
{
throw new org.omg.CORBA.COMM_FAILURE ("end of stream");
}
System.arraycopy(this.data, this.index, data.value, offset, min_length);
this.index += min_length;
return min_length;
}
@Override
public boolean is_data_available()
{
return true;
}
@Override
public boolean supports_callback()
{
return false;
}
@Override
public boolean use_handle_time_out()
{
return false;
}
@Override
public boolean wait_next_data(long time_out)
{
return false;
}
}
private class DummyRequestListener
implements RequestListener
{
private byte[] request = null;
public DummyRequestListener()
{
}
public byte[] getRequest()
{
return request;
}
@Override
public void requestReceived( byte[] request,
GIOPConnection connection )
{
this.request = request;
}
@Override
public void locateRequestReceived( byte[] request,
GIOPConnection connection )
{
this.request = request;
}
@Override
public void cancelRequestReceived( byte[] request,
GIOPConnection connection )
{
this.request = request;
}
}
private class DummyReplyListener
implements ReplyListener
{
private byte[] reply = null;
public DummyReplyListener()
{
}
public byte[] getReply()
{
return reply;
}
@Override
public void replyReceived( byte[] reply,
GIOPConnection connection )
{
this.reply = reply;
}
@Override
public void locateReplyReceived( byte[] reply,
GIOPConnection connection )
{
this.reply = reply;
}
@Override
public void closeConnectionReceived( byte[] close_conn,
GIOPConnection connection )
{
this.reply = close_conn;
}
}
@Test
public void testGIOP_1_2_CorrectFragmentedRequest()
{
List<byte[]> messages = new Vector<byte[]>();
RequestOutputStream r_out =
new RequestOutputStream( getORB(), //ClientConnection
(ClientConnection) null, //request id
0, //operation
"foo", // response expected
true, // SYNC_SCOPE (irrelevant)
(short)-1, //request start time
null, //request end time
null, //reply start time
null, //object key
new byte[1], 2 // giop minor
);
//manually write the first half of the string "barbaz"
r_out.write_ulong( 7 ); //string length
r_out.write_octet( (byte) 'b' );
r_out.write_octet( (byte) 'a' );
r_out.write_octet( (byte) 'r' );
r_out.insertMsgSize();
byte[] b = r_out.getBufferCopy();
b[6] |= 0x02; //set "more fragments follow"
messages.add( b );
MessageOutputStream m_out =
new MessageOutputStream(orb);
m_out.writeGIOPMsgHeader( MsgType_1_1._Fragment,
2 // giop minor
);
m_out.write_ulong( 0 ); // Fragment Header (request id)
m_out.write_octet( (byte) 'b' );
m_out.write_octet( (byte) 'a' );
m_out.write_octet( (byte) 'z' );
m_out.write_octet( (byte) 0);
m_out.insertMsgSize();
messages.add( m_out.getBufferCopy() );
DummyTransport transport =
new DummyTransport( messages );
DummyRequestListener request_listener =
new DummyRequestListener();
DummyReplyListener reply_listener =
new DummyReplyListener();
GIOPConnectionManager giopconn_mg =
new GIOPConnectionManager();
try
{
giopconn_mg.configure (config);
}
catch (Exception e)
{
}
ServerGIOPConnection conn =
giopconn_mg.createServerGIOPConnection( null,
transport,
request_listener,
reply_listener );
try
{
//will not return until an IOException is thrown (by the
//DummyTransport)
conn.receiveMessages();
}
catch( IOException e )
{
//o.k., thrown by DummyTransport
}
//did the GIOPConnection hand the complete request over to the
//listener?
assertTrue( request_listener.getRequest() != null );
RequestInputStream r_in = new RequestInputStream
( getORB(), null, request_listener.getRequest() );
//is the body correct?
assertEquals( "barbaz", r_in.read_string() );
r_out.close();
r_in.close();
m_out.close();
}
@Test
public void testGIOP_1_0_CorrectRefusing()
{
List<byte[]> messages = new Vector<byte[]>();
RequestOutputStream r_out =
new RequestOutputStream( getORB(), //ClientConnection
null, //request id
0, //operation
"foo", //response expected
true, //SYNC_SCOPE (irrelevant)
(short)-1, //request start time
null, //request end time
null, //reply end time
null, //object key
new byte[1], 0 // giop minor
);
r_out.write_string( "bar" );
r_out.insertMsgSize();
byte[] b = r_out.getBufferCopy();
b[6] |= 0x02; //set "more fragments follow"
messages.add( b );
DummyTransport transport =
new DummyTransport( messages );
DummyRequestListener request_listener =
new DummyRequestListener();
DummyReplyListener reply_listener =
new DummyReplyListener();
GIOPConnectionManager giopconn_mg =
new GIOPConnectionManager();
try
{
giopconn_mg.configure (config);
}
catch (Exception e)
{
}
GIOPConnection conn =
giopconn_mg.createServerGIOPConnection( null,
transport,
request_listener,
reply_listener );
try
{
//will not return until an IOException is thrown (by the
//DummyTransport)
conn.receiveMessages();
}
catch( IOException e )
{
//o.k., thrown by DummyTransport
}
//no request or reply must have been handed over
assertTrue( request_listener.getRequest() == null );
assertTrue( reply_listener.getReply() == null );
//instead, an error message have must been sent via the
//transport
assertTrue( transport.getWrittenMessage() != null );
byte[] result = transport.getWrittenMessage();
assertTrue( Messages.getMsgType( result ) == MsgType_1_1._MessageError );
MessageOutputStream m_out =
new MessageOutputStream(orb);
m_out.writeGIOPMsgHeader( MsgType_1_1._Fragment,
0 // giop minor
);
m_out.write_ulong( 0 ); // Fragment Header (request id)
m_out.write_octet( (byte) 'b' );
m_out.write_octet( (byte) 'a' );
m_out.write_octet( (byte) 'z' );
m_out.insertMsgSize();
messages.add( m_out.getBufferCopy() );
try
{
//will not return until an IOException is thrown (by the
//DummyTransport)
conn.receiveMessages();
}
catch( IOException e )
{
//o.k., thrown by DummyTransport
}
//no request or reply must have been handed over
assertTrue( request_listener.getRequest() == null );
assertTrue( reply_listener.getReply() == null );
//instead, an error message have must been sent via the
//transport
assertTrue( transport.getWrittenMessage() != null );
//must be a new one
assertTrue( transport.getWrittenMessage() != result );
result = transport.getWrittenMessage();
assertTrue( Messages.getMsgType( result ) == MsgType_1_1._MessageError );
r_out.close();
m_out.close();
}
@Test
public void testGIOP_1_1_IllegalMessageType()
{
List<byte[]> messages = new Vector<byte[]>();
LocateRequestOutputStream r_out =
new LocateRequestOutputStream(
getORB(),
new byte[1], //object key
0, //request id
1 // giop minor
);
r_out.insertMsgSize();
byte[] b = r_out.getBufferCopy();
b[6] |= 0x02; //set "more fragments follow"
messages.add( b );
// MessageOutputStream m_out =
// new MessageOutputStream();
DummyTransport transport =
new DummyTransport( messages );
DummyRequestListener request_listener =
new DummyRequestListener();
DummyReplyListener reply_listener =
new DummyReplyListener();
GIOPConnectionManager giopconn_mg =
new GIOPConnectionManager();
try
{
giopconn_mg.configure (config);
}
catch (Exception e)
{
}
GIOPConnection conn =
giopconn_mg.createServerGIOPConnection( null,
transport,
request_listener,
reply_listener );
try
{
//will not return until an IOException is thrown (by the
//DummyTransport)
conn.receiveMessages();
}
catch( IOException e )
{
//o.k., thrown by DummyTransport
}
//no request or reply must have been handed over
assertTrue( request_listener.getRequest() == null );
assertTrue( reply_listener.getReply() == null );
//instead, an error message have must been sent via the
//transport
assertTrue( transport.getWrittenMessage() != null );
byte[] result = transport.getWrittenMessage();
assertTrue( Messages.getMsgType( result ) == MsgType_1_1._MessageError );
r_out.close();
}
@Test
public void testGIOP_1_1_NoImplement()
{
List<byte[]> messages = new Vector<byte[]>();
RequestOutputStream r_out =
new RequestOutputStream( getORB(), //ClientConnection
null, //request id
0, //operation
"foo", //response expected
true, //SYNC_SCOPE (irrelevant)
(short)-1, //request start time
null, //request end time
null, //reply end time
null, //object key
new byte[1], 1 // giop minor
);
r_out.write_string( "bar" );
r_out.insertMsgSize();
byte[] b = r_out.getBufferCopy();
b[6] |= 0x02; //set "more fragments follow"
messages.add( b );
DummyTransport transport =
new DummyTransport( messages );
DummyRequestListener request_listener =
new DummyRequestListener();
DummyReplyListener reply_listener =
new DummyReplyListener();
GIOPConnectionManager giopconn_mg =
new GIOPConnectionManager();
try
{
giopconn_mg.configure (config);
}
catch (Exception e)
{
}
GIOPConnection conn =
giopconn_mg.createServerGIOPConnection( null,
transport,
request_listener,
reply_listener );
try
{
//will not return until an IOException is thrown (by the
//DummyTransport)
conn.receiveMessages();
}
catch( IOException e )
{
//o.k., thrown by DummyTransport
}
//no request or reply must have been handed over
assertTrue( request_listener.getRequest() == null );
assertTrue( reply_listener.getReply() == null );
//instead, an error message have must been sent via the
//transport
assertTrue( transport.getWrittenMessage() != null );
byte[] result = transport.getWrittenMessage();
ReplyInputStream r_in = new ReplyInputStream( getORB(), result );
Exception ex = r_in.getException();
if ( ex != null && ex.getClass() == org.omg.CORBA.NO_IMPLEMENT.class )
{
// o.k.
}
else
{
fail();
}
MessageOutputStream m_out =
new MessageOutputStream(orb);
m_out.writeGIOPMsgHeader( MsgType_1_1._Fragment,
1 // giop minor
);
m_out.write_ulong( 0 ); // Fragment Header (request id)
m_out.write_octet( (byte) 'b' );
m_out.write_octet( (byte) 'a' );
m_out.write_octet( (byte) 'z' );
m_out.insertMsgSize();
messages.add( m_out.getBufferCopy() );
try
{
//will not return until an IOException is thrown (by the
//DummyTransport)
conn.receiveMessages();
}
catch( IOException e )
{
//o.k., thrown by DummyTransport
}
//no request or reply must have been handed over
assertTrue( request_listener.getRequest() == null );
assertTrue( reply_listener.getReply() == null );
//can't check more, message is discarded
m_out.close();
r_out.close();
r_in.close();
}
@Test
public void testGIOP_1_2_CorrectCloseOnGarbage()
{
List<byte[]> messages = new Vector<byte[]>();
String garbage = "This is a garbage message";
byte[] b = garbage.getBytes();
messages.add( b );
DummyTransport transport =
new DummyTransport( messages );
DummyRequestListener request_listener =
new DummyRequestListener();
DummyReplyListener reply_listener =
new DummyReplyListener();
GIOPConnectionManager giopconn_mg =
new GIOPConnectionManager();
try
{
giopconn_mg.configure (config);
}
catch (Exception e)
{
}
GIOPConnection conn =
giopconn_mg.createServerGIOPConnection( null,
transport,
request_listener,
reply_listener );
try
{
//will not return until an IOException is thrown (by the
//DummyTransport)
conn.receiveMessages();
}
catch( IOException e )
{
//o.k., thrown by DummyTransport
}
//no request or reply must have been handed over
assertTrue( request_listener.getRequest() == null );
assertTrue( reply_listener.getReply() == null );
//instead, connection should be closed
assertTrue( transport.hasBeenClosed() );
//no message is written (makes no real sense)
assertTrue( transport.getWrittenMessage() != null );
assertTrue( transport.getWrittenMessage().length == 0 );
}
@Test
public void testGIOP_1_1_CorrectRequest()
{
List<byte[]> messages = new Vector<byte[]>();
RequestOutputStream r_out =
new RequestOutputStream( getORB(), //ClientConnection
(ClientConnection) null, //request id
0, //operation
"foo", // response expected
true, // SYNC_SCOPE (irrelevant)
(short)-1, //request start time
null, //request end time
null, //reply start time
null, //object key
new byte[1], 1 // giop minor
);
String message = "Request";
r_out.write_string(message);
r_out.insertMsgSize();
messages.add( r_out.getBufferCopy() );
DummyTransport transport =
new DummyTransport( messages );
DummyRequestListener request_listener =
new DummyRequestListener();
DummyReplyListener reply_listener =
new DummyReplyListener();
GIOPConnectionManager giopconn_mg =
new GIOPConnectionManager();
try
{
giopconn_mg.configure (config);
}
catch (Exception e)
{
}
ServerGIOPConnection conn =
giopconn_mg.createServerGIOPConnection( null,
transport,
request_listener,
reply_listener );
try
{
//will not return until an IOException is thrown (by the
//DummyTransport)
conn.receiveMessages();
}
catch( IOException e )
{
//o.k., thrown by DummyTransport
}
//did the GIOPConnection hand the complete request over to the
//listener?
assertTrue( request_listener.getRequest() != null );
RequestInputStream r_in =
new RequestInputStream( getORB(), null, request_listener.getRequest() );
//is the body correct?
assertEquals( message, r_in.read_string() );
r_out.close();
r_in.close();
}
}// GIOPConnectionTest