com.healthmarketscience.rmiio.RemoteIteratorTest.java Source code

Java tutorial

Introduction

Here is the source code for com.healthmarketscience.rmiio.RemoteIteratorTest.java

Source

/*
Copyright (c) 2007 Health Market Science, Inc.
    
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 com.healthmarketscience.rmiio;

import java.io.IOException;
import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author James Ahlborn
 */
public class RemoteIteratorTest extends BaseRemoteStreamTest {

    private static final Log LOG = LogFactory.getLog(RemoteIteratorTest.class);

    public void testTransfer() throws Exception {
        List<List<TestObject>> testObjLists = mainTest(false, false, false, _clientExceptions, _monitors);

        checkClientExceptions(0);

        // should have 3 lists
        assertEquals(3, testObjLists.size());

        // compare all sent objects to originals
        for (List<TestObject> testObjList : testObjLists) {
            assertEquals(ObjectClient.SEND_OBJECTS, testObjList);
        }

        checkMonitors(5, true);
    }

    public void testEmptyTransfer() throws Exception {
        List<List<TestObject>> testObjLists = mainTest(true, false, false, _clientExceptions, _monitors);

        checkClientExceptions(0);

        // should have 3 lists
        assertEquals(3, testObjLists.size());

        // should have empty result lists
        for (List<TestObject> testObjList : testObjLists) {
            assertTrue(testObjList.isEmpty());
        }

        checkMonitors(5, true);
    }

    public void testAbortedTransfer() throws Exception {
        List<List<TestObject>> testObjLists = mainTest(false, true, false, _clientExceptions, _monitors);

        checkClientExceptions(3);

        checkMonitors(3, false);
    }

    public void testNoDelayTransfer() throws Exception {
        List<List<TestObject>> testObjLists = mainTest(false, false, true, _clientExceptions, _monitors);

        // should have one list with one element
        assertEquals(1, testObjLists.size());
        assertEquals(1, testObjLists.get(0).size());

        assertEquals(ObjectClient.SEND_OBJECTS.get(0), testObjLists.get(0).get(0));

        checkClientExceptions(1);

        checkMonitors(1, false);
    }

    public void testSimple() throws Exception {
        List<TestObject> srcList = new ArrayList<TestObject>();
        srcList.addAll(Arrays.asList(new TestObject("obj1", 1), new TestObject("obj2", 2), null,
                new TestObject("obj3", 3), new TestObject("obj4", 4)));

        RemoteIterator<TestObject> srcIter = new SimpleRemoteIterator<TestObject>(srcList);

        // serialize/deserialize
        RemoteIterator<TestObject> dstIter = RemoteStreamServerTest.simulateRemote(srcIter);

        assertNotSame(srcIter, dstIter);

        List<TestObject> dstList = new ArrayList<TestObject>();
        while (dstIter.hasNext()) {
            dstList.add(dstIter.next());
        }

        assertEquals(srcList, dstList);
    }

    public void testNullIterator() throws Exception {
        try {
            new SimpleRemoteIterator<TestObject>(null);
            fail("IllegalArgumentException should have been thrown");
        } catch (IllegalArgumentException e) {
            // success
        }
        try {
            new SerialRemoteIteratorServer<TestObject>((IOIterator<TestObject>) null);
            fail("IllegalArgumentException should have been thrown");
        } catch (IllegalArgumentException e) {
            // success
        }
    }

    public static List<List<TestObject>> mainTest(final boolean sendEmptyList, final boolean doAbort,
            final boolean noDelayAbort, final List<Throwable> clientExceptions,
            final List<AccumulateRemoteStreamMonitor<?>> monitors) throws Exception {

        ObjectServer server = new ObjectServer();
        final RemoteObjectServer stub = (RemoteObjectServer) RemoteStreamServerTest
                .simulateRemote(UnicastRemoteObject.exportObject(server, 0));
        LOG.debug("Server ready");

        LOG.debug("Sleeping 3000 ms...");
        Thread.sleep(3000);

        LOG.debug("Running tests");
        Thread clientThread = new Thread(new Runnable() {
            public void run() {
                clientExceptions.addAll(ObjectClient.main(stub, sendEmptyList, doAbort, noDelayAbort, monitors));
            }
        });
        clientThread.start();
        clientThread.join();

        LOG.debug("Unexporting server");
        UnicastRemoteObject.unexportObject(server, true);

        return server._recvdObjectLists;
    }

    public interface RemoteObjectServer extends Remote {

        public void sendObjects(RemoteIterator<TestObject> iterator, boolean doPartial) throws IOException;

    }

    public static class ObjectServer implements RemoteObjectServer {

        private List<List<TestObject>> _recvdObjectLists = new LinkedList<List<TestObject>>();

        public ObjectServer() {
        }

        public void sendObjects(RemoteIterator<TestObject> iterator, boolean doPartial) throws IOException {
            List<TestObject> recvdObjectList = new LinkedList<TestObject>();
            if (!doPartial) {
                _recvdObjectLists.add(recvdObjectList);
            }
            try {
                int numRecvd = 0;
                while (iterator.hasNext()) {
                    recvdObjectList.add(iterator.next());
                    ++numRecvd;
                    if (doPartial && (numRecvd > ObjectClient.PARTIAL_SIZE)) {
                        // just stop reading
                        break;
                    }
                }
            } finally {
                iterator.close();
            }
            LOG.debug("Server got " + recvdObjectList.size() + " objects");
        }

    }

    public static class ObjectClient {

        private static final List<TestObject> SEND_OBJECTS = new LinkedList<TestObject>();
        private static final int PARTIAL_SIZE = 100;

        static {
            SEND_OBJECTS.addAll(Arrays.asList(new TestObject("obj1", 1), new TestObject("obj2", 2), null,
                    new TestObject("obj3", 3), new TestObject("obj4", 4)));
            // make this list big!
            SEND_OBJECTS.addAll(Collections.nCopies(10000, new TestObject("objMany", 13)));
        }

        private ObjectClient() {
        }

        private static void sendObjects(RemoteObjectServer stub, boolean useCompression, boolean doPartial,
                boolean sendEmptyList, boolean doAbort, boolean noDelay, boolean noDelayAbort,
                List<AccumulateRemoteStreamMonitor<?>> monitors) throws Exception {
            LOG.debug("Getting iterator");
            List<TestObject> sendList = Collections.<TestObject>emptyList();
            if (!sendEmptyList) {
                sendList = SEND_OBJECTS;
            }
            AccumulateRemoteIteratorMonitor<RemoteInputStreamServer> monitor = new AccumulateRemoteIteratorMonitor<RemoteInputStreamServer>();
            if (monitors != null) {
                monitors.add(monitor);
            }

            SerialRemoteIteratorServer<TestObject> server = null;
            try {
                server = new SerialRemoteIteratorServer<TestObject>(useCompression, noDelay, monitor,
                        sendList.iterator());
                SerialRemoteIteratorClient<TestObject> client = RemoteStreamServerTest
                        .simulateRemote(new SerialRemoteIteratorClient<TestObject>(server));

                if (doAbort) {
                    monitor.setDoAbort(server, doAbort);
                }
                if (noDelayAbort) {
                    monitor.setNoDelayAbort(server, noDelayAbort);
                }

                stub.sendObjects(client, doPartial);
            } finally {
                if (server != null) {
                    server.close();
                }
            }

            LOG.debug("Sent objects");
        }

        public static List<Throwable> main(RemoteObjectServer stub, boolean sendEmptyList, boolean doAbort,
                boolean noDelayAbort, List<AccumulateRemoteStreamMonitor<?>> monitors) {
            List<Throwable> exceptions = new ArrayList<Throwable>();

            // try uncompressed, noDelay send
            try {
                sendObjects(stub, false, false, sendEmptyList, doAbort, true, noDelayAbort, monitors);
            } catch (Throwable t) {
                exceptions.add(t);
            }

            if (!noDelayAbort) {

                // try uncompressed send
                try {
                    sendObjects(stub, false, false, sendEmptyList, doAbort, false, false, monitors);
                } catch (Throwable t) {
                    exceptions.add(t);
                }

                // try compressed send
                try {
                    sendObjects(stub, true, false, sendEmptyList, doAbort, false, false, monitors);
                } catch (Throwable t) {
                    exceptions.add(t);
                }

                if (!doAbort) {

                    // try partial uncompressed send
                    try {
                        sendObjects(stub, false, true, sendEmptyList, false, false, false, monitors);
                    } catch (Throwable t) {
                        exceptions.add(t);
                    }

                    // try partial compressed send
                    try {
                        sendObjects(stub, true, true, sendEmptyList, false, false, false, monitors);
                    } catch (Throwable t) {
                        exceptions.add(t);
                    }
                }
            }

            return exceptions;
        }

    }

    private static class AccumulateRemoteIteratorMonitor<S extends RemoteStreamServer>
            extends AccumulateRemoteStreamMonitor<S> {
        private RemoteIteratorServer _server;
        private boolean _noDelayAbort;

        AccumulateRemoteIteratorMonitor() {
            super(false);
        }

        public void setDoAbort(RemoteIteratorServer server, boolean doAbort) {
            _server = server;
            _doAbort = doAbort;
        }

        public void setNoDelayAbort(RemoteIteratorServer server, boolean noDelayAbort) {
            _server = server;
            _noDelayAbort = noDelayAbort;
        }

        @Override
        public void localBytesMoved(S stream, int numBytes) {
            if (_noDelayAbort && (_numLocalBytes > 0)) {
                try {
                    _server.abort();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            _numLocalBytes += numBytes;
            if (_doAbort && (_numLocalBytes > 0)) {
                try {
                    _server.abort();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }

    public static class TestObject implements Serializable {
        private static final long serialVersionUID = 1;

        private String _strData;
        private int _intData;

        public TestObject(String strData, int intData) {
            _strData = strData;
            _intData = intData;
        }

        @Override
        public boolean equals(Object o) {
            return ((o instanceof TestObject) && (((TestObject) o)._strData.equals(_strData))
                    && (((TestObject) o)._intData == _intData));
        }

    }

}