/*
 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 4915825 4921009 4934965 4977469
 * @summary Tests behavior when client or server gets object of unknown class
 * @author Eamonn McManus
 * @run clean MissingClassTest SingleClassLoader
 * @run build MissingClassTest SingleClassLoader
 * @run main MissingClassTest
 */

/*
  Tests that clients and servers react correctly when they receive
  objects of unknown classes.  This can happen easily due to version
  skew or missing jar files on one end or the other.  The default
  behaviour of causing a connection to die because of the resultant
  IOException is not acceptable!  We try sending attributes and invoke
  parameters to the server of classes it doesn't know, and we try
  sending attributes, exceptions and notifications to the client of
  classes it doesn't know.

  We also test objects that are of known class but not serializable.
  The test cases are similar.
 */

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectOutputStream;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.management.Attribute;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerFactory;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectionNotification;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnectorServer;
import org.omg.CORBA.MARSHAL;

public class MissingClassTest {
    private static final int NNOTIFS = 50;

    private static ClassLoader clientLoader, serverLoader;
    private static Object serverUnknown;
    private static Exception clientUnknown;
    private static ObjectName on;
    private static final Object[] NO_OBJECTS = new Object[0];
    private static final String[] NO_STRINGS = new String[0];

    private static final Object unserializableObject = Thread.currentThread();

    public static void main(String[] args) throws Exception {
        System.out.println("Test that the client or server end of a " +
                           "connection does not fail if sent an object " +
                           "it cannot deserialize");

        on = new ObjectName("test:type=Test");

        ClassLoader testLoader = MissingClassTest.class.getClassLoader();
        clientLoader =
            new SingleClassLoader("$ServerUnknown$", HashMap.class,
                                  testLoader);
        serverLoader =
            new SingleClassLoader("$ClientUnknown$", Exception.class,
                                  testLoader);
        serverUnknown =
            clientLoader.loadClass("$ServerUnknown$").newInstance();
        clientUnknown = (Exception)
            serverLoader.loadClass("$ClientUnknown$").newInstance();

        final String[] protos = {"rmi", /*"iiop",*/ "jmxmp"};
        boolean ok = true;
        for (int i = 0; i < protos.length; i++) {
            try {
                ok &= test(protos[i]);
            } catch (Exception e) {
                System.out.println("TEST FAILED WITH EXCEPTION:");
                e.printStackTrace(System.out);
                ok = false;
            }
        }

        if (ok)
            System.out.println("Test passed");
        else {
            System.out.println("TEST FAILED");
            System.exit(1);
        }
    }

    private static boolean test(String proto) throws Exception {
        System.out.println("Testing for proto " + proto);

        boolean ok = true;

        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
        mbs.createMBean(Test.class.getName(), on);

        JMXConnectorServer cs;
        JMXServiceURL url = new JMXServiceURL(proto, null, 0);
        Map serverMap = new HashMap();
        serverMap.put(JMXConnectorServerFactory.DEFAULT_CLASS_LOADER,
                      serverLoader);

        // make sure no auto-close at server side
        serverMap.put("jmx.remote.x.server.connection.timeout", "888888888");

        try {
            cs = JMXConnectorServerFactory.newJMXConnectorServer(url,
                                                                 serverMap,
                                                                 mbs);
        } catch (MalformedURLException e) {
            System.out.println("System does not recognize URL: " + url +
                               "; ignoring");
            return true;
        }
        cs.start();
        JMXServiceURL addr = cs.getAddress();
        Map clientMap = new HashMap();
        clientMap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER,
                      clientLoader);

        System.out.println("Connecting for client-unknown test");

        JMXConnector client = JMXConnectorFactory.connect(addr, clientMap);

        // add a listener to verify no failed notif
        CNListener cnListener = new CNListener();
        client.addConnectionNotificationListener(cnListener, null, null);

        MBeanServerConnection mbsc = client.getMBeanServerConnection();

        System.out.println("Getting attribute with class unknown to client");
        try {
            Object result = mbsc.getAttribute(on, "ClientUnknown");
            System.out.println("TEST FAILS: getAttribute for class " +
                               "unknown to client should fail, returned: " +
                               result);
            ok = false;
        } catch (IOException e) {
            Throwable cause = e.getCause();
            if (cause instanceof MARSHAL)  // see CR 4935098
                cause = cause.getCause();
            if (cause instanceof ClassNotFoundException) {
                System.out.println("Success: got an IOException wrapping " +
                                   "a ClassNotFoundException");
            } else {
                System.out.println("TEST FAILS: Caught IOException (" + e +
                                   ") but cause should be " +
                                   "ClassNotFoundException: " + cause);
                ok = false;
            }
        }

        System.out.println("Doing queryNames to ensure connection alive");
        Set names = mbsc.queryNames(null, null);
        System.out.println("queryNames returned " + names);

        System.out.println("Provoke exception of unknown class");
        try {
            mbsc.invoke(on, "throwClientUnknown", NO_OBJECTS, NO_STRINGS);
            System.out.println("TEST FAILS: did not get exception");
            ok = false;
        } catch (IOException e) {
            Throwable wrapped = e.getCause();
            if (wrapped instanceof MARSHAL)  // see CR 4935098
                wrapped = wrapped.getCause();
            if (wrapped instanceof ClassNotFoundException) {
                System.out.println("Success: got an IOException wrapping " +
                                   "a ClassNotFoundException: " +
                                   wrapped);
            } else {
                System.out.println("TEST FAILS: Got IOException but cause " +
                                   "should be ClassNotFoundException: ");
                if (wrapped == null)
                    System.out.println("(null)");
                else
                    wrapped.printStackTrace(System.out);
                ok = false;
            }
        } catch (Exception e) {
            System.out.println("TEST FAILS: Got wrong exception: " +
                               "should be IOException with cause " +
                               "ClassNotFoundException:");
            e.printStackTrace(System.out);
            ok = false;
        }

        System.out.println("Doing queryNames to ensure connection alive");
        names = mbsc.queryNames(null, null);
        System.out.println("queryNames returned " + names);

        ok &= notifyTest(client, mbsc);

        System.out.println("Doing queryNames to ensure connection alive");
        names = mbsc.queryNames(null, null);
        System.out.println("queryNames returned " + names);

        for (int i = 0; i < 2; i++) {
            boolean setAttribute = (i == 0); // else invoke
            String what = setAttribute ? "setAttribute" : "invoke";
            System.out.println("Trying " + what +
                               " with class unknown to server");
            try {
                if (setAttribute) {
                    mbsc.setAttribute(on, new Attribute("ServerUnknown",
                                                        serverUnknown));
                } else {
                    mbsc.invoke(on, "useServerUnknown",
                                new Object[] {serverUnknown},
                                new String[] {"java.lang.Object"});
                }
                System.out.println("TEST FAILS: " + what + " with " +
                                   "class unknown to server should fail " +
                                   "but did not");
                ok = false;
            } catch (IOException e) {
                Throwable cause = e.getCause();
                if (cause instanceof MARSHAL)  // see CR 4935098
                    cause = cause.getCause();
                if (cause instanceof ClassNotFoundException) {
                    System.out.println("Success: got an IOException " +
                                       "wrapping a ClassNotFoundException");
                } else {
                    System.out.println("TEST FAILS: Caught IOException (" + e +
                                       ") but cause should be " +
                                       "ClassNotFoundException: " + cause);
                    e.printStackTrace(System.out); // XXX
                    ok = false;
                }
            }
        }

        System.out.println("Doing queryNames to ensure connection alive");
        names = mbsc.queryNames(null, null);
        System.out.println("queryNames returned " + names);

        System.out.println("Trying to get unserializable attribute");
        try {
            mbsc.getAttribute(on, "Unserializable");
            System.out.println("TEST FAILS: get unserializable worked " +
                               "but should not");
            ok = false;
        } catch (IOException e) {
            System.out.println("Success: got an IOException: " + e +
                               " (cause: " + e.getCause() + ")");
        }

        System.out.println("Doing queryNames to ensure connection alive");
        names = mbsc.queryNames(null, null);
        System.out.println("queryNames returned " + names);

        System.out.println("Trying to set unserializable attribute");
        try {
            Attribute attr =
                new Attribute("Unserializable", unserializableObject);
            mbsc.setAttribute(on, attr);
            System.out.println("TEST FAILS: set unserializable worked " +
                               "but should not");
            ok = false;
        } catch (IOException e) {
            System.out.println("Success: got an IOException: " + e +
                               " (cause: " + e.getCause() + ")");
        }

        System.out.println("Doing queryNames to ensure connection alive");
        names = mbsc.queryNames(null, null);
        System.out.println("queryNames returned " + names);

        System.out.println("Trying to throw unserializable exception");
        try {
            mbsc.invoke(on, "throwUnserializable", NO_OBJECTS, NO_STRINGS);
            System.out.println("TEST FAILS: throw unserializable worked " +
                               "but should not");
            ok = false;
        } catch (IOException e) {
            System.out.println("Success: got an IOException: " + e +
                               " (cause: " + e.getCause() + ")");
        }

        client.removeConnectionNotificationListener(cnListener);
        ok = ok && !cnListener.failed;

        client.close();
        cs.stop();

        if (ok)
            System.out.println("Test passed for protocol " + proto);

        System.out.println();
        return ok;
    }

    private static class TestListener implements NotificationListener {
        TestListener(LostListener ll) {
            this.lostListener = ll;
        }

        public void handleNotification(Notification n, Object h) {
            /* Connectors can handle unserializable notifications in
               one of two ways.  Either they can arrange for the
               client to get a NotSerializableException from its
               fetchNotifications call (RMI connector), or they can
               replace the unserializable notification by a
               JMXConnectionNotification.NOTIFS_LOST (JMXMP
               connector).  The former case is handled by code within
               the connector client which will end up sending a
               NOTIFS_LOST to our LostListener.  The logic here
               handles the latter case by converting it into the
               former.
             */
            if (n instanceof JMXConnectionNotification
                && n.getType().equals(JMXConnectionNotification.NOTIFS_LOST)) {
                lostListener.handleNotification(n, h);
                return;
            }

            synchronized (result) {
                if (!n.getType().equals("interesting")
                    || !n.getUserData().equals("known")) {
                    System.out.println("TestListener received strange notif: "
                                       + notificationString(n));
                    result.failed = true;
                    result.notifyAll();
                } else {
                    result.knownCount++;
                    if (result.knownCount == NNOTIFS)
                        result.notifyAll();
                }
            }
        }

        private LostListener lostListener;
    }

    private static class LostListener implements NotificationListener {
        public void handleNotification(Notification n, Object h) {
            synchronized (result) {
                handle(n, h);
            }
        }

        private void handle(Notification n, Object h) {
            if (!(n instanceof JMXConnectionNotification)) {
                System.out.println("LostListener received strange notif: " +
                                   notificationString(n));
                result.failed = true;
                result.notifyAll();
                return;
            }

            JMXConnectionNotification jn = (JMXConnectionNotification) n;
            if (!jn.getType().equals(jn.NOTIFS_LOST)) {
                System.out.println("Ignoring JMXConnectionNotification: " +
                                   notificationString(jn));
                return;
            }
            final String msg = jn.getMessage();
            if ((!msg.startsWith("Dropped ")
                 || !msg.endsWith("classes were missing locally"))
                && (!msg.startsWith("Not serializable: "))) {
                System.out.println("Surprising NOTIFS_LOST getMessage: " +
                                   msg);
            }
            if (!(jn.getUserData() instanceof Long)) {
                System.out.println("JMXConnectionNotification userData " +
                                   "not a Long: " + jn.getUserData());
                result.failed = true;
            } else {
                int lost = ((Long) jn.getUserData()).intValue();
                result.lostCount += lost;
                if (result.lostCount == NNOTIFS*2)
                    result.notifyAll();
            }
        }
    }

    private static class TestFilter implements NotificationFilter {
        public boolean isNotificationEnabled(Notification n) {
            return (n.getType().equals("interesting"));
        }
    }

    private static class Result {
        int knownCount, lostCount;
        boolean failed;
    }
    private static Result result;

    /* Send a bunch of notifications to exercise the logic to recover
       from unknown notification classes.  We have four kinds of
       notifications: "known" ones are of a class known to the client
       and which match its filters; "unknown" ones are of a class that
       match the client's filters but that the client can't load;
       "tricky" ones are unserializable; and "boring" notifications
       are of a class that the client knows but that doesn't match its
       filters.  We emit NNOTIFS notifications of each kind.  We do a
       random shuffle on these 4*NNOTIFS notifications so it is likely
       that we will cover the various different cases in the logic.

       Specifically, what we are testing here is the logic that
       recovers from a fetchNotifications request that gets a
       ClassNotFoundException.  Because the request can contain
       several notifications, the client doesn't know which of them
       generated the exception.  So it redoes a request that asks for
       just one notification.  We need to be sure that this works when
       that one notification is of an unknown class and when it is of
       a known class, and in both cases when there are filtered
       notifications that are skipped.

       We are also testing the behaviour in the server when it tries
       to include an unserializable notification in the response to a
       fetchNotifications, and in the client when that happens.

       If the test succeeds, the listener should receive the NNOTIFS
       "known" notifications, and the connection listener should
       receive an indication of NNOTIFS lost notifications
       representing the "unknown" notifications.

       We depend on some implementation-specific features here:

       1. The buffer size is sufficient to contain the 4*NNOTIFS
       notifications which are all sent at once, before the client
       gets a chance to start receiving them.

       2. When one or more notifications are dropped because they are
       of unknown classes, the NOTIFS_LOST notification contains a
       userData that is a Long with a count of the number dropped.

       3. If a notification is not serializable on the server, the
       client gets told about it somehow, rather than having it just
       dropped on the floor.  The somehow might be through an RMI
       exception, or it might be by the server replacing the
       unserializable notif by a JMXConnectionNotification.NOTIFS_LOST.
    */
    private static boolean notifyTest(JMXConnector client,
                                      MBeanServerConnection mbsc)
            throws Exception {
        System.out.println("Send notifications including unknown ones");
        result = new Result();
        LostListener ll = new LostListener();
        client.addConnectionNotificationListener(ll, null, null);
        TestListener nl = new TestListener(ll);
        mbsc.addNotificationListener(on, nl, new TestFilter(), null);
        mbsc.invoke(on, "sendNotifs", NO_OBJECTS, NO_STRINGS);

        // wait for the listeners to receive all their notifs
        // or to fail
        long deadline = System.currentTimeMillis() + 60000;
        long remain;
        while ((remain = deadline - System.currentTimeMillis()) >= 0) {
            synchronized (result) {
                if (result.failed
                    || (result.knownCount >= NNOTIFS
                        && result.lostCount >= NNOTIFS*2))
                    break;
                result.wait(remain);
            }
        }
        Thread.sleep(2);  // allow any spurious extra notifs to arrive
        if (result.failed) {
            System.out.println("TEST FAILS: Notification strangeness");
            return false;
        } else if (result.knownCount == NNOTIFS
                   && result.lostCount == NNOTIFS*2) {
            System.out.println("Success: received known notifications and " +
                               "got NOTIFS_LOST for unknown and " +
                               "unserializable ones");
            return true;
        } else if (result.knownCount >= NNOTIFS
                || result.lostCount >= NNOTIFS*2) {
            System.out.println("TEST FAILS: Received too many notifs: " +
                    "known=" + result.knownCount + "; lost=" + result.lostCount);
            return false;
        } else {
            System.out.println("TEST FAILS: Timed out without receiving " +
                               "all notifs: known=" + result.knownCount +
                               "; lost=" + result.lostCount);
            return false;
        }
    }

    public static interface TestMBean {
        public Object getClientUnknown() throws Exception;
        public void throwClientUnknown() throws Exception;
        public void setServerUnknown(Object o) throws Exception;
        public void useServerUnknown(Object o) throws Exception;
        public Object getUnserializable() throws Exception;
        public void setUnserializable(Object un) throws Exception;
        public void throwUnserializable() throws Exception;
        public void sendNotifs() throws Exception;
    }

    public static class Test extends NotificationBroadcasterSupport
            implements TestMBean {

        public Object getClientUnknown() {
            return clientUnknown;
        }

        public void throwClientUnknown() throws Exception {
            throw clientUnknown;
        }

        public void setServerUnknown(Object o) {
            throw new IllegalArgumentException("setServerUnknown succeeded "+
                                               "but should not have");
        }

        public void useServerUnknown(Object o) {
            throw new IllegalArgumentException("useServerUnknown succeeded "+
                                               "but should not have");
        }

        public Object getUnserializable() {
            return unserializableObject;
        }

        public void setUnserializable(Object un) {
            throw new IllegalArgumentException("setUnserializable succeeded " +
                                               "but should not have");
        }

        public void throwUnserializable() throws Exception {
            throw new Exception() {
                private Object unserializable = unserializableObject;
            };
        }

        public void sendNotifs() {
            /* We actually send the same four notification objects
               NNOTIFS times each.  This doesn't particularly matter,
               but note that the MBeanServer will replace "this" by
               the sender's ObjectName the first time.  Since that's
               always the same, no problem.  */
            Notification known =
                new Notification("interesting", this, 1L, 1L, "known");
            known.setUserData("known");
            Notification unknown =
                new Notification("interesting", this, 1L, 1L, "unknown");
            unknown.setUserData(clientUnknown);
            Notification boring =
                new Notification("boring", this, 1L, 1L, "boring");
            Notification tricky =
                new Notification("interesting", this, 1L, 1L, "tricky");
            tricky.setUserData(unserializableObject);

            // check that the tricky notif is indeed unserializable
            try {
                new ObjectOutputStream(new ByteArrayOutputStream())
                    .writeObject(tricky);
                System.out.println("TEST INCORRECT: tricky notif is " +
                                   "serializable");
                System.exit(1);
            } catch (NotSerializableException e) {
                // OK: tricky notif is not serializable
            } catch (IOException e) {
                System.out.println("TEST INCORRECT: tricky notif " +
                                   "serialization check failed");
                System.exit(1);
            }

            /* Now shuffle an imaginary deck of cards where K, U, T, and
               B (known, unknown, tricky, boring) each appear NNOTIFS times.
               We explicitly seed the random number generator so we
               can reproduce rare test failures if necessary.  We only
               use a StringBuffer so we can print the shuffled deck --
               otherwise we could just emit the notifications as the
               cards are placed.  */
            long seed = System.currentTimeMillis();
            System.out.println("Random number seed is " + seed);
            Random r = new Random(seed);
            int knownCount = NNOTIFS;   // remaining K cards
            int unknownCount = NNOTIFS; // remaining U cards
            int trickyCount = NNOTIFS;  // remaining T cards
            int boringCount = NNOTIFS;  // remaining B cards
            StringBuffer notifList = new StringBuffer();
            for (int i = NNOTIFS * 4; i > 0; i--) {
                int rand = r.nextInt(i);
                // use rand to pick a card from the remaining ones
                if ((rand -= knownCount) < 0) {
                    notifList.append('k');
                    knownCount--;
                } else if ((rand -= unknownCount) < 0) {
                    notifList.append('u');
                    unknownCount--;
                } else if ((rand -= trickyCount) < 0) {
                    notifList.append('t');
                    trickyCount--;
                } else {
                    notifList.append('b');
                    boringCount--;
                }
            }
            if (knownCount != 0 || unknownCount != 0
                || trickyCount != 0 || boringCount != 0) {
                System.out.println("TEST INCORRECT: Shuffle failed: " +
                                   "known=" + knownCount +" unknown=" +
                                   unknownCount + " tricky=" + trickyCount +
                                   " boring=" + boringCount +
                                   " deal=" + notifList);
                System.exit(1);
            }
            String notifs = notifList.toString();
            System.out.println("Shuffle: " + notifs);
            for (int i = 0; i < NNOTIFS * 4; i++) {
                Notification n;
                switch (notifs.charAt(i)) {
                case 'k': n = known; break;
                case 'u': n = unknown; break;
                case 't': n = tricky; break;
                case 'b': n = boring; break;
                default:
                    System.out.println("TEST INCORRECT: Bad shuffle char: " +
                                       notifs.charAt(i));
                    System.exit(1);
                    throw new Error();
                }
                sendNotification(n);
            }
        }
    }

    private static String notificationString(Notification n) {
        return n.getClass().getName() + "/" + n.getType() + " \"" +
            n.getMessage() + "\" <" + n.getUserData() + ">";
    }

    //
    private static class CNListener implements NotificationListener {
        public void handleNotification(Notification n, Object o) {
            if (n instanceof JMXConnectionNotification) {
                JMXConnectionNotification jn = (JMXConnectionNotification)n;
                if (JMXConnectionNotification.FAILED.equals(jn.getType())) {
                    failed = true;
                }
            }
        }

        public boolean failed = false;
    }
}
