1/*
2 * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 6692027
27 * @summary Check that custom subclasses of QueryEval can be serialized.
28 * @author Eamonn McManus
29 */
30
31import java.io.ByteArrayInputStream;
32import java.io.ByteArrayOutputStream;
33import java.io.ObjectInputStream;
34import java.io.ObjectOutputStream;
35import java.lang.management.ManagementFactory;
36import java.util.Set;
37import java.util.concurrent.atomic.AtomicInteger;
38import javax.management.MBeanServer;
39import javax.management.MalformedObjectNameException;
40import javax.management.ObjectName;
41import javax.management.QueryEval;
42import javax.management.QueryExp;
43
44public class CustomQueryTest {
45    public static interface CountMBean {
46        public int getCount();
47        public void increment();
48    }
49
50    public static class Count implements CountMBean {
51        private AtomicInteger count = new AtomicInteger();
52
53        public int getCount() {
54            return count.get();
55        }
56
57        public void increment() {
58            count.incrementAndGet();
59        }
60
61    }
62
63    public static final ObjectName countName;
64    static {
65        try {
66            countName = new ObjectName("d:type=Count");
67        } catch (MalformedObjectNameException e) {
68            throw new AssertionError(e);
69        }
70    }
71
72    /* A query that calls the increment method of the Count MBean every time
73     * it is evaluated.  If there is no ObjectName filter, the query will be
74     * evaluated for every MBean in the MBean Server, so the count will be
75     * incremented by the number of MBeans.
76     */
77    public static class IncrQuery extends QueryEval implements QueryExp {
78        public boolean apply(ObjectName name) {
79            try {
80                getMBeanServer().invoke(countName, "increment", null, null);
81                return true;
82            } catch (Throwable t) {
83                t.printStackTrace();
84                System.exit(1);
85                throw new AssertionError(); // not reached
86            }
87        }
88    }
89
90    public static void main(String[] args) throws Exception {
91        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
92        mbs.registerMBean(new Count(), countName);
93        int mbeanCount = mbs.getMBeanCount();
94        QueryExp query = new IncrQuery();
95        Set<ObjectName> names = mbs.queryNames(null, query);
96        assertEquals(mbeanCount, names.size());
97        assertEquals(mbeanCount, mbs.getAttribute(countName, "Count"));
98        ByteArrayOutputStream bout = new ByteArrayOutputStream();
99        ObjectOutputStream oout = new ObjectOutputStream(bout);
100        oout.writeObject(query);
101        oout.close();
102        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
103        ObjectInputStream oin = new ObjectInputStream(bin);
104        query = (QueryExp) oin.readObject();
105        names = mbs.queryNames(null, query);
106        assertEquals(mbeanCount * 2, mbs.getAttribute(countName, "Count"));
107    }
108
109    private static void assertEquals(Object expected, Object actual)
110            throws Exception {
111        if (!expected.equals(actual)) {
112            String failure = "FAILED: expected " + expected + ", got " + actual;
113            throw new Exception(failure);
114        }
115    }
116}
117