# HG changeset patch # User Andrew Azores # Date 1488811110 18000 # Node ID f06bab0506205720c4c6d7fa1900e91ad4c965c9 # Parent 3572e808e4cf1698de83833d61286267bc02b17d Add vm-shenandoah plugin Provides a shenandoahvisualizer-based visualization of memory regions and GC status for Shenandoah. See http://icedtea.classpath.org/people/rkennke/shenandoahvisualizer Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-March/022332.html diff -r 3572e808e4cf -r f06bab050620 distribution/assembly/plugin-assembly-agent.xml --- a/distribution/assembly/plugin-assembly-agent.xml Thu Mar 09 13:36:40 2017 -0500 +++ b/distribution/assembly/plugin-assembly-agent.xml Mon Mar 06 09:38:30 2017 -0500 @@ -65,6 +65,7 @@ com.redhat.thermostat:thermostat-vm-profiler-distribution com.redhat.thermostat:thermostat-killvm-distribution com.redhat.thermostat:thermostat-vm-numa-distribution + com.redhat.thermostat:thermostat-vm-shenandoah-distribution diff -r 3572e808e4cf -r f06bab050620 distribution/assembly/plugin-assembly.xml --- a/distribution/assembly/plugin-assembly.xml Thu Mar 09 13:36:40 2017 -0500 +++ b/distribution/assembly/plugin-assembly.xml Mon Mar 06 09:38:30 2017 -0500 @@ -80,6 +80,7 @@ com.redhat.thermostat:thermostat-platform-swing-distribution com.redhat.thermostat:thermostat-dependency-tool-distribution com.redhat.thermostat:thermostat-gui-distribution + com.redhat.thermostat:thermostat-vm-shenandoah-distribution diff -r 3572e808e4cf -r f06bab050620 distribution/packaging/fedora/0002_shared_osgi_spec_fixes.patch --- a/distribution/packaging/fedora/0002_shared_osgi_spec_fixes.patch Thu Mar 09 13:36:40 2017 -0500 +++ b/distribution/packaging/fedora/0002_shared_osgi_spec_fixes.patch Mon Mar 06 09:38:30 2017 -0500 @@ -2258,6 +2258,86 @@ com.redhat.thermostat +diff --git a/vm-shenandoah/agent/pom.xml b/vm-shenandoah/agent/pom.xml +--- a/vm-shenandoah/agent/pom.xml ++++ b/vm-shenandoah/agent/pom.xml +@@ -82,14 +82,8 @@ + test + + +- org.osgi +- org.osgi.core +- provided +- +- +- org.osgi +- org.osgi.compendium +- provided ++ org.apache.felix ++ org.apache.felix.framework + + + com.redhat.thermostat +diff --git a/vm-shenandoah/client-core/pom.xml b/vm-shenandoah/client-core/pom.xml +--- a/vm-shenandoah/client-core/pom.xml ++++ b/vm-shenandoah/client-core/pom.xml +@@ -89,14 +89,8 @@ + test + + +- org.osgi +- org.osgi.core +- provided +- +- +- org.osgi +- org.osgi.compendium +- provided ++ org.apache.felix ++ org.apache.felix.framework + + + com.redhat.thermostat +diff --git a/vm-shenandoah/client-swing/pom.xml b/vm-shenandoah/client-swing/pom.xml +--- a/vm-shenandoah/client-swing/pom.xml ++++ b/vm-shenandoah/client-swing/pom.xml +@@ -99,14 +99,8 @@ + test + + +- org.osgi +- org.osgi.core +- provided +- +- +- org.osgi +- org.osgi.compendium +- provided ++ org.apache.felix ++ org.apache.felix.framework + + + com.redhat.thermostat +diff --git a/vm-shenandoah/common/pom.xml b/vm-shenandoah/common/pom.xml +--- a/vm-shenandoah/common/pom.xml ++++ b/vm-shenandoah/common/pom.xml +@@ -102,14 +102,8 @@ + test + + +- org.osgi +- org.osgi.core +- provided +- +- +- org.osgi +- org.osgi.compendium +- provided ++ org.apache.felix ++ org.apache.felix.framework + + + com.redhat.thermostat diff --git a/web/client/pom.xml b/web/client/pom.xml --- a/web/client/pom.xml +++ b/web/client/pom.xml diff -r 3572e808e4cf -r f06bab050620 distribution/pom.xml --- a/distribution/pom.xml Thu Mar 09 13:36:40 2017 -0500 +++ b/distribution/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -751,6 +751,12 @@ com.redhat.thermostat + thermostat-vm-shenandoah-distribution + ${project.version} + zip + + + com.redhat.thermostat thermostat-web-endpoint-distribution ${project.version} zip diff -r 3572e808e4cf -r f06bab050620 pom.xml --- a/pom.xml Thu Mar 09 13:36:40 2017 -0500 +++ b/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -390,6 +390,7 @@ vm-io vm-jmx vm-profiler + vm-shenandoah notes numa vm-numa diff -r 3572e808e4cf -r f06bab050620 storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/LongArrayCodec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/LongArrayCodec.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,84 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.storage.mongodb.internal; + +import org.bson.BsonReader; +import org.bson.BsonType; +import org.bson.BsonWriter; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.codecs.LongCodec; + +import java.util.ArrayList; +import java.util.List; + +public class LongArrayCodec implements Codec { + + private final LongCodec primCodec = new LongCodec(); + + @Override + public void encode(BsonWriter writer, long[] value, + EncoderContext encoderContext) { + writer.writeStartArray(); + for (long i: value) { + primCodec.encode(writer, i, encoderContext); + } + writer.writeEndArray(); + } + + @Override + public Class getEncoderClass() { + return long[].class; + } + + @Override + public long[] decode(BsonReader reader, DecoderContext decoderContext) { + reader.readStartArray(); + List values = new ArrayList<>(); + while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { + long val = primCodec.decode(reader, decoderContext); + values.add(val); + } + reader.readEndArray(); + long[] result = new long[values.size()]; + for (int i = 0; i < values.size(); i++) { + result[i] = values.get(i); + } + return result; + } +} diff -r 3572e808e4cf -r f06bab050620 storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java --- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java Thu Mar 09 13:36:40 2017 -0500 +++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java Mon Mar 06 09:38:30 2017 -0500 @@ -151,6 +151,7 @@ CodecRegistry arrayCodecRegistry = CodecRegistries.fromCodecs( new DoubleArrayCodec(), new IntegerArrayCodec(), + new LongArrayCodec(), new StringArrayCodec()); CodecRegistry ourCodecRegistry = CodecRegistries.fromRegistries( defaultCodecRegistry, diff -r 3572e808e4cf -r f06bab050620 storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoPojoConverter.java --- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoPojoConverter.java Thu Mar 09 13:36:40 2017 -0500 +++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoPojoConverter.java Mon Mar 06 09:38:30 2017 -0500 @@ -42,6 +42,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; diff -r 3572e808e4cf -r f06bab050620 storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/LongArrayCodecTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/LongArrayCodecTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,92 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.storage.mongodb.internal; + +import org.bson.BsonReader; +import org.bson.BsonWriter; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.json.JsonReader; +import org.bson.json.JsonWriter; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.matchers.JUnitMatchers.containsString; + +public class LongArrayCodecTest { + + @Test + public void canEncodeLongArray() { + long[] values = new long[]{ + 333, Long.MAX_VALUE, -902 + }; + LongArrayCodec codec = new LongArrayCodec(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + BsonWriter writer = new JsonWriter(new PrintWriter(baos)); + EncoderContext ctxt = EncoderContext.builder().build(); + + writer.writeStartDocument(); + writer.writeName("foo"); + codec.encode(writer, values, ctxt); + writer.writeEndDocument(); + writer.flush(); + String json = new String(baos.toByteArray()); + assertThat(json, containsString("\"foo\"")); + assertThat(json, containsString("{ \"foo\" : [{ \"$numberLong\" : \"" + values[0] + "\" }, " + + "{ \"$numberLong\" : \"" + values[1] + "\" }, { \"$numberLong\" : \"" + values[2] + "\" }] }")); + } + + @Test + public void canDecodeLongArray() { + String json = "{ \"foo\" : [{ \"$numberLong\" : \"333\" }, { \"$numberLong\" : \"9223372036854775807\" }, { \"$numberLong\" : \"-902\" }] }"; + BsonReader reader = new JsonReader(json); + reader.readStartDocument(); + String name = reader.readName(); + assertEquals("foo", name); + LongArrayCodec codec = new LongArrayCodec(); + long[] decoded = codec.decode(reader, DecoderContext.builder().build()); + reader.readEndDocument(); + assertEquals(333, decoded[0]); + assertEquals(Long.MAX_VALUE, decoded[1]); + assertEquals(-902, decoded[2]); + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,121 @@ + + + + 4.0.0 + + thermostat-vm-shenandoah + com.redhat.thermostat + 1.99.12-SNAPSHOT + + thermostat-vm-shenandoah-agent + bundle + Thermostat VM Shenandoah Agent plugin + + + + org.apache.felix + maven-bundle-plugin + true + + + Red Hat, Inc. + com.redhat.thermostat.vm.shenandoah.agent + com.redhat.thermostat.vm.shenandoah.agent.internal.Activator + + com.redhat.thermostat.vm.shenandoah.agent, + + + com.redhat.thermostat.vm.shenandoah.agent.internal, + + + <_nouses>true + + + + + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.osgi + org.osgi.core + provided + + + org.osgi + org.osgi.compendium + provided + + + com.redhat.thermostat + thermostat-agent-core + ${project.version} + + + com.redhat.thermostat + thermostat-common-core + ${project.version} + + + com.redhat.thermostat + thermostat-storage-core + ${project.version} + + + com.redhat.thermostat + thermostat-common-test + ${project.version} + test + + + com.redhat.thermostat + thermostat-vm-shenandoah-common + ${project.version} + + + diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/src/main/java/com/redhat/thermostat/vm/shenandoah/agent/internal/Activator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/src/main/java/com/redhat/thermostat/vm/shenandoah/agent/internal/Activator.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,91 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.agent.internal; + +import com.redhat.thermostat.agent.VmStatusListenerRegistrar; +import com.redhat.thermostat.backend.Backend; +import com.redhat.thermostat.backend.BackendService; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +public class Activator implements BundleActivator { + + private MultipleServiceTracker tracker; + private VmShenandoahBackend backend; + private ServiceRegistration registration; + + @Override + public void start(final BundleContext bundleContext) throws Exception { + Class[] deps = new Class[] { + BackendService.class, + VmShenandoahDao.class, + WriterID.class + }; + + final VmStatusListenerRegistrar registrar = new VmStatusListenerRegistrar(bundleContext); + + tracker = new MultipleServiceTracker(bundleContext, deps, new MultipleServiceTracker.Action() { + @Override + public void dependenciesAvailable(MultipleServiceTracker.DependencyProvider services) { + VmShenandoahDao dao = services.get(VmShenandoahDao.class); + Version version = new Version(bundleContext.getBundle()); + WriterID writerID = services.get(WriterID.class); + backend = new VmShenandoahBackend(dao, version, registrar, writerID); + registration = bundleContext.registerService(Backend.class.getName(), backend, null); + } + + @Override + public void dependenciesUnavailable() { + if (backend.isActive()) { + backend.deactivate(); + } + registration.unregister(); + } + }); + tracker.open(); + } + + @Override + public void stop(BundleContext bundleContext) throws Exception { + tracker.close(); + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/src/main/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahBackend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/src/main/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahBackend.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.agent.internal; + +import com.redhat.thermostat.agent.VmStatusListenerRegistrar; +import com.redhat.thermostat.backend.VmListenerBackend; +import com.redhat.thermostat.backend.VmUpdateListener; +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; + +public class VmShenandoahBackend extends VmListenerBackend { + + private final VmShenandoahDao dao; + + public VmShenandoahBackend(VmShenandoahDao dao, Version version, + VmStatusListenerRegistrar registrar, WriterID writerID) { + super("VM Shenandoah Backend", + "Gathers Shenandoah-GC-specific statistics", + "Red Hat, Inc.", version.getVersionNumber(), true, registrar, writerID); + this.dao = dao; + } + + @Override + protected VmUpdateListener createVmListener(String writerId, String vmId, int pid) { + return new VmShenandoahListener(writerId, vmId, dao); + } + + @Override + public int getOrderValue() { + return ORDER_MEMORY_GROUP + 21; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/src/main/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahDataExtractor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/src/main/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahDataExtractor.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,74 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.agent.internal; + +import com.redhat.thermostat.backend.VmUpdate; +import com.redhat.thermostat.backend.VmUpdateException; + +public class VmShenandoahDataExtractor { + + private final VmUpdate vmUpdate; + + public VmShenandoahDataExtractor(VmUpdate vmUpdate) { + this.vmUpdate = vmUpdate; + } + + public long getTimestamp() throws VmUpdateException { + return vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.timestamp"); + } + + public long getMaxRegions() throws VmUpdateException { + return vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.max_regions"); + } + + public long getRegionSize() throws VmUpdateException { + return vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.region_size"); + } + + public long getStatus() throws VmUpdateException { + return vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.status"); + } + + public long[] getRegionData() throws VmUpdateException { + long[] data = new long[(int) getMaxRegions()]; + for (int i = 0; i < data.length; i++) { + data[i] = vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.region." + i + ".data"); + } + return data; + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/src/main/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/src/main/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahListener.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,90 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.agent.internal; + +import com.redhat.thermostat.backend.VmUpdate; +import com.redhat.thermostat.backend.VmUpdateException; +import com.redhat.thermostat.backend.VmUpdateListener; +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.SystemClock; +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class VmShenandoahListener implements VmUpdateListener { + + private static final Logger logger = LoggingUtils.getLogger(VmShenandoahListener.class); + + private final String writerID; + private final String vmId; + private final VmShenandoahDao dao; + private final Clock clock; + private boolean isActive = true; + + public VmShenandoahListener(String writerID, String vmId, VmShenandoahDao dao) { + this(writerID, vmId, dao, new SystemClock()); + } + + // Package-private for testing + VmShenandoahListener(String writerID, String vmId, VmShenandoahDao dao, Clock clock) { + this.writerID = writerID; + this.vmId = vmId; + this.dao = dao; + this.clock = clock; + } + + @Override + public void countersUpdated(VmUpdate update) { + if (!isActive) { + return; + } + try { + VmShenandoahDataExtractor extractor = new VmShenandoahDataExtractor(update); + VmShenandoahStat stat = new VmShenandoahStat(writerID, vmId, clock.getRealTimeMillis(), + extractor.getTimestamp(), extractor.getMaxRegions(), extractor.getRegionSize(), extractor.getStatus(), extractor.getRegionData()); + dao.putShenandoahStat(stat); + } catch (VmUpdateException e) { + logger.log(Level.WARNING, "Error gathering Shenandoah statistics for VM " + vmId, e); + } catch (NullPointerException e) { + // VM is not running Shenandoah + isActive = false; + } + } +} \ No newline at end of file diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/src/test/java/com/redhat/thermostat/vm/shenandoah/agent/internal/ActivatorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/src/test/java/com/redhat/thermostat/vm/shenandoah/agent/internal/ActivatorTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,107 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.agent.internal; + +import com.redhat.thermostat.backend.Backend; +import com.redhat.thermostat.backend.BackendService; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.Version; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ActivatorTest { + + private StubBundleContext context; + private Activator activator; + + @Before + public void setup() { + context = new StubBundleContext(); + activator = new Activator(); + } + + @Test + public void testActivatorDoesNothingWithMissingDeps() throws Exception { + activator.start(context); + + assertTrue(context.getAllServices().isEmpty()); + assertNotSame(context.getServiceListeners().size(), 1); + + activator.stop(context); + + assertTrue(context.getAllServices().isEmpty()); + assertTrue(context.getServiceListeners().isEmpty()); + } + + @Test + public void testRegistersBackend() throws Exception { + context = new StubBundleContext() { + @Override + public Bundle getBundle() { + Bundle result = mock(Bundle.class); + when(result.getVersion()).thenReturn(Version.emptyVersion); + return result; + } + }; + + BackendService backendService = mock(BackendService.class); + VmShenandoahDao vmShenandoahDao = mock(VmShenandoahDao.class); + WriterID writerID = mock(WriterID.class); + + context.registerService(BackendService.class, backendService, null); + context.registerService(VmShenandoahDao.class, vmShenandoahDao, null); + context.registerService(WriterID.class, writerID, null); + + activator.start(context); + + assertTrue(context.isServiceRegistered(Backend.class.getName(), VmShenandoahBackend.class)); + + activator.stop(context); + + assertFalse(context.isServiceRegistered(Backend.class.getName(), VmShenandoahBackend.class)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/src/test/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahBackendTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/src/test/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahBackendTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,81 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.agent.internal; + +import com.redhat.thermostat.agent.VmStatusListenerRegistrar; +import com.redhat.thermostat.common.Ordered; +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class VmShenandoahBackendTest { + + private VmShenandoahBackend backend; + + @Before + public void setup() { + VmShenandoahDao dao = mock(VmShenandoahDao.class); + + Version version = mock(Version.class); + when(version.getVersionNumber()).thenReturn("0.0.0"); + + VmStatusListenerRegistrar registrar = mock(VmStatusListenerRegistrar.class); + + WriterID id = mock(WriterID.class); + backend = new VmShenandoahBackend(dao, version, registrar, id); + } + + @Test + public void testOrderValue() { + int order = backend.getOrderValue(); + assertTrue(order >= Ordered.ORDER_MEMORY_GROUP); + assertTrue(order < Ordered.ORDER_NETWORK_GROUP); + } + + @Test + public void testCreateVmListener() { + assertNotNull(backend.createVmListener("foo-writerID", "foo-vmId", 100)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/src/test/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahDataExtractorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/src/test/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahDataExtractorTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,95 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.agent.internal; + +import com.redhat.thermostat.backend.VmUpdate; +import com.redhat.thermostat.backend.VmUpdateException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InOrder; + +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class VmShenandoahDataExtractorTest { + + private VmShenandoahDataExtractor extractor; + private VmUpdate update; + + @Before + public void setup() { + update = mock(VmUpdate.class); + extractor = new VmShenandoahDataExtractor(update); + } + + @Test + public void testGetTimestamp() throws VmUpdateException { + extractor.getTimestamp(); + verify(update).getPerformanceCounterLong("sun.gc.shenandoah.regions.timestamp"); + } + + @Test + public void testGetMaxRegions() throws VmUpdateException { + extractor.getMaxRegions(); + verify(update).getPerformanceCounterLong("sun.gc.shenandoah.regions.max_regions"); + } + + @Test + public void testGetRegionSize() throws VmUpdateException { + extractor.getRegionSize(); + verify(update).getPerformanceCounterLong("sun.gc.shenandoah.regions.region_size"); + } + + @Test + public void testGetStatus() throws VmUpdateException { + extractor.getStatus(); + verify(update).getPerformanceCounterLong("sun.gc.shenandoah.regions.status"); + } + + @Test + public void testGetRegionData() throws VmUpdateException { + when(update.getPerformanceCounterLong("sun.gc.shenandoah.regions.max_regions")).thenReturn(2L); + extractor.getRegionData(); + InOrder inOrder = inOrder(update); + inOrder.verify(update).getPerformanceCounterLong("sun.gc.shenandoah.regions.max_regions"); + inOrder.verify(update).getPerformanceCounterLong("sun.gc.shenandoah.regions.region.0.data"); + inOrder.verify(update).getPerformanceCounterLong("sun.gc.shenandoah.regions.region.1.data"); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/agent/src/test/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahListenerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/agent/src/test/java/com/redhat/thermostat/vm/shenandoah/agent/internal/VmShenandoahListenerTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,123 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.agent.internal; + +import com.redhat.thermostat.backend.VmUpdate; +import com.redhat.thermostat.backend.VmUpdateException; +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +public class VmShenandoahListenerTest { + + private String writerID; + private String vmId; + private VmShenandoahDao dao; + private Clock clock; + private VmUpdate vmUpdate; + + private VmShenandoahListener listener; + + @Before + public void setup() throws VmUpdateException { + writerID = "foo-writerID"; + vmId = "foo-vmId"; + dao = mock(VmShenandoahDao.class); + clock = mock(Clock.class); + when(clock.getRealTimeMillis()).thenReturn(100L); + vmUpdate = mock(VmUpdate.class); + when(vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.timestamp")).thenReturn(50L); + when(vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.max_regions")).thenReturn(2L); + when(vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.region_size")).thenReturn(1024L); + when(vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.status")).thenReturn(4L); + when(vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.region.0.data")).thenReturn(10L); + when(vmUpdate.getPerformanceCounterLong("sun.gc.shenandoah.regions.region.1.data")).thenReturn(10L); + + listener = new VmShenandoahListener(writerID, vmId, dao, clock); + } + + @Test + public void testCountersUpdated() throws VmUpdateException { + listener.countersUpdated(vmUpdate); + + verify(clock).getRealTimeMillis(); + verify(vmUpdate).getPerformanceCounterLong("sun.gc.shenandoah.regions.timestamp"); + verify(vmUpdate, times(2)).getPerformanceCounterLong("sun.gc.shenandoah.regions.max_regions"); + verify(vmUpdate).getPerformanceCounterLong("sun.gc.shenandoah.regions.region_size"); + verify(vmUpdate).getPerformanceCounterLong("sun.gc.shenandoah.regions.status"); + verify(vmUpdate).getPerformanceCounterLong("sun.gc.shenandoah.regions.region.0.data"); + verify(vmUpdate).getPerformanceCounterLong("sun.gc.shenandoah.regions.region.1.data"); + verifyNoMoreInteractions(vmUpdate); + + ArgumentCaptor daoCaptor = ArgumentCaptor.forClass(VmShenandoahStat.class); + verify(dao).putShenandoahStat(daoCaptor.capture()); + VmShenandoahStat stat = daoCaptor.getValue(); + assertThat(stat.getTimeStamp(), is(100L)); + assertThat(stat.getMaxRegions(), is(2L)); + assertThat(stat.getRegionSize(), is(1024L)); + assertThat(stat.getRegionStatus(), is(4L)); + assertThat(stat.getRegionData(), is(equalTo(new long[]{10L, 10L}))); + verifyNoMoreInteractions(dao); + } + + @Test + public void testDisablesIfNotRunningShenandoah() throws VmUpdateException { + when(vmUpdate.getPerformanceCounterLong(anyString())).thenThrow(NullPointerException.class); + when(vmUpdate.getPerformanceCounterString(anyString())).thenThrow(NullPointerException.class); + listener.countersUpdated(vmUpdate); + verify(vmUpdate).getPerformanceCounterLong("sun.gc.shenandoah.regions.timestamp"); + listener.countersUpdated(vmUpdate); + verify(vmUpdate).getPerformanceCounterLong("sun.gc.shenandoah.regions.timestamp"); // still just once + + verifyZeroInteractions(dao); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,122 @@ + + + + 4.0.0 + + thermostat-vm-shenandoah + com.redhat.thermostat + 1.99.12-SNAPSHOT + + thermostat-vm-shenandoah-client-core + bundle + Thermostat VM Shenandoah GC Core Client plugin + + + + org.apache.felix + maven-bundle-plugin + true + + + Red Hat, Inc. + com.redhat.thermostat.vm.shenandoah.client.core + com.redhat.thermostat.vm.shenandoah.client.core.internal.Activator + + com.redhat.thermostat.vm.shenandoah.client.core, + com.redhat.thermostat.vm.shenandoah.client.core.locale, + + + com.redhat.thermostat.vm.shenandoah.client.core.internal + + + <_nouses>true + + + + + + + + junit + junit + test + + + com.redhat.thermostat + thermostat-common-test + ${project.version} + test + + + org.mockito + mockito-core + test + + + org.osgi + org.osgi.core + provided + + + org.osgi + org.osgi.compendium + provided + + + com.redhat.thermostat + thermostat-common-core + ${project.version} + + + com.redhat.thermostat + thermostat-client-core + ${project.version} + + + com.redhat.thermostat + thermostat-storage-core + ${project.version} + + + com.redhat.thermostat + thermostat-vm-shenandoah-common + ${project.version} + + + diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/VmShenandoahService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/VmShenandoahService.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core; + +import com.redhat.thermostat.client.core.InformationService; +import com.redhat.thermostat.storage.core.VmRef; + +public interface VmShenandoahService extends InformationService { + String SERVICE_ID = "com.redhat.thermostat.vm.shenandoah"; +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/VmShenandoahView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/VmShenandoahView.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core; + +import com.redhat.thermostat.client.core.views.BasicView; +import com.redhat.thermostat.client.core.views.UIComponent; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; + +public abstract class VmShenandoahView extends BasicView implements UIComponent { + + public abstract void setEnabled(boolean enabled); + + public abstract void setData(VmShenandoahStat vmShenandoahStat); + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/VmShenandoahViewProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/VmShenandoahViewProvider.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core; + +import com.redhat.thermostat.annotations.ExtensionPoint; +import com.redhat.thermostat.client.core.views.ViewProvider; + +@ExtensionPoint +public interface VmShenandoahViewProvider extends ViewProvider { + @Override + VmShenandoahView createView(); +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/Activator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/Activator.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,104 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core.internal; + +import com.redhat.thermostat.client.core.InformationService; +import com.redhat.thermostat.common.ApplicationService; +import com.redhat.thermostat.common.Constants; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.dao.AgentInfoDAO; +import com.redhat.thermostat.storage.dao.VmInfoDAO; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahService; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import java.util.Dictionary; +import java.util.Hashtable; + +public class Activator implements BundleActivator { + + private MultipleServiceTracker serviceTracker; + private ServiceRegistration registration; + + @Override + public void start(final BundleContext context) throws Exception { + final Class[] deps = new Class[] { + ApplicationService.class, + AgentInfoDAO.class, + VmInfoDAO.class, + VmShenandoahDao.class, + VmShenandoahViewProvider.class + }; + + serviceTracker = new MultipleServiceTracker(context, deps, new MultipleServiceTracker.Action() { + @Override + public void dependenciesAvailable(MultipleServiceTracker.DependencyProvider services) { + ApplicationService appSvc = services.get(ApplicationService.class); + AgentInfoDAO agentInfoDAO = services.get(AgentInfoDAO.class); + VmInfoDAO vmInfoDAO = services.get(VmInfoDAO.class); + VmShenandoahDao vmShenandoahDao = services.get(VmShenandoahDao.class); + VmShenandoahViewProvider viewProvider = services.get(VmShenandoahViewProvider.class); + + VmShenandoahService shenandoahService = + new VmShenandoahServiceImpl(appSvc, agentInfoDAO, vmInfoDAO, vmShenandoahDao, viewProvider); + Dictionary properties = new Hashtable<>(); + properties.put(Constants.GENERIC_SERVICE_CLASSNAME, VmRef.class.getName()); + properties.put(InformationService.KEY_SERVICE_ID, VmShenandoahService.SERVICE_ID); + registration = context.registerService(InformationService.class.getName(), shenandoahService, properties); + } + + @Override + public void dependenciesUnavailable() { + if (registration != null) { + registration.unregister(); + } + } + }); + serviceTracker.open(); + } + + @Override + public void stop(BundleContext context) throws Exception { + if (serviceTracker != null) { + serviceTracker.close(); + } + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/VmShenandoahController.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/VmShenandoahController.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,132 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core.internal; + +import com.redhat.thermostat.client.core.controllers.InformationServiceController; +import com.redhat.thermostat.client.core.views.BasicView; +import com.redhat.thermostat.client.core.views.UIComponent; +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.common.ApplicationService; +import com.redhat.thermostat.common.NotImplementedException; +import com.redhat.thermostat.common.Timer; +import com.redhat.thermostat.common.Timers; +import com.redhat.thermostat.shared.locale.LocalizedString; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.model.TimeStampedPojoComparator; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahView; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; +import com.redhat.thermostat.vm.shenandoah.client.core.locale.LocaleResources; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class VmShenandoahController implements InformationServiceController { + + private static final Translate t = LocaleResources.createLocalizer(); + + private final VmRef ref; + private final VmShenandoahDao dao; + private final VmShenandoahView view; + private final Timer timer; + + private long lastSeenTimestamp; + + public VmShenandoahController(ApplicationService appSvc, VmRef ref, VmShenandoahDao dao, VmShenandoahViewProvider viewProvider) { + this.ref = ref; + this.dao = dao; + this.view = viewProvider.createView(); + + timer = Timers.createDataRefreshTimer(appSvc.getTimerFactory(), new Runnable() { + @Override + public void run() { + doUpdateData(); + } + }); + timer.setDelay(1L); + + view.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + switch (actionEvent.getActionId()) { + case HIDDEN: + stop(); + break; + case VISIBLE: + start(); + break; + default: + throw new NotImplementedException("unknown action: " + actionEvent.getActionId()); + } + } + }); + } + + private void start() { + timer.start(); + } + + private void stop() { + timer.stop(); + } + + private void doUpdateData() { + List stats = dao.getLatestShenandoahStats(ref, lastSeenTimestamp); + boolean hasStats = !stats.isEmpty(); + view.setEnabled(hasStats); + if (hasStats) { + Collections.sort(stats, new TimeStampedPojoComparator()); + VmShenandoahStat stat = stats.get(stats.size() - 1); + lastSeenTimestamp = stat.getTimeStamp(); + view.setData(stat); + } + } + + @Override + public UIComponent getView() { + return view; + } + + @Override + public LocalizedString getLocalizedName() { + return t.localize(LocaleResources.TAB_TITLE); + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/VmShenandoahServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/VmShenandoahServiceImpl.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,103 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core.internal; + +import com.redhat.thermostat.client.core.controllers.InformationServiceController; +import com.redhat.thermostat.common.ApplicationService; +import com.redhat.thermostat.common.Filter; +import com.redhat.thermostat.storage.core.AgentId; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.dao.AgentInfoDAO; +import com.redhat.thermostat.storage.dao.VmInfoDAO; +import com.redhat.thermostat.storage.model.AgentInformation; +import com.redhat.thermostat.storage.model.VmInfo; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahService; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class VmShenandoahServiceImpl implements VmShenandoahService { + + private final Filter filter; + private final ApplicationService appSvc; + private final VmShenandoahDao vmShenandoahDao; + private final VmShenandoahViewProvider viewProvider; + private final Map controllers = new ConcurrentHashMap<>(); + + public VmShenandoahServiceImpl(ApplicationService appSvc, final AgentInfoDAO agentInfoDAO, final VmInfoDAO vmInfoDAO, + final VmShenandoahDao vmShenandoahDao, VmShenandoahViewProvider viewProvider) { + this.appSvc = appSvc; + this.vmShenandoahDao = vmShenandoahDao; + this.viewProvider = viewProvider; + this.filter = new Filter() { + @Override + public boolean matches(VmRef toMatch) { + return isAlive(toMatch) && hasStats(toMatch); + } + + private boolean isAlive(VmRef ref) { + VmInfo vmInfo = vmInfoDAO.getVmInfo(ref); + AgentInformation agentInformation = agentInfoDAO.getAgentInformation(new AgentId(vmInfo.getAgentId())); + return VmInfo.AliveStatus.RUNNING.equals(vmInfo.isAlive(agentInformation)); + } + + private boolean hasStats(VmRef ref) { + return vmShenandoahDao.getCount(ref) > 0; + } + }; + } + + @Override + public InformationServiceController getInformationServiceController(VmRef ref) { + if (controllers.get(ref) == null) { + controllers.put(ref, new VmShenandoahController(appSvc, ref, vmShenandoahDao, viewProvider)); + } + return controllers.get(ref); + } + + @Override + public Filter getFilter() { + return filter; + } + + @Override + public int getOrderValue() { + return ORDER_MEMORY_GROUP + 21; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/locale/LocaleResources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/main/java/com/redhat/thermostat/vm/shenandoah/client/core/locale/LocaleResources.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core.locale; + +import com.redhat.thermostat.shared.locale.Translate; + +public enum LocaleResources { + + TAB_TITLE, + TAB_DETAIL, + SHENANDOAH_UNAVAILABLE, + + ; + + static final String RESOURCE_BUNDLE = + "com.redhat.thermostat.vm.shenandoah.client.core.locale.strings"; + + public static Translate createLocalizer() { + return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class); + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/main/resources/com/redhat/thermostat/vm/shenandoah/client/core/locale/strings.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/main/resources/com/redhat/thermostat/vm/shenandoah/client/core/locale/strings.properties Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,3 @@ +TAB_TITLE=Shenandoah +TAB_DETAIL=Memory Regions +SHENANDOAH_UNAVAILABLE=Shenandoah is unavailable on this VM \ No newline at end of file diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/test/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/ActivatorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/test/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/ActivatorTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,101 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core.internal; + +import com.redhat.thermostat.client.core.InformationService; +import com.redhat.thermostat.common.ApplicationService; +import com.redhat.thermostat.storage.dao.AgentInfoDAO; +import com.redhat.thermostat.storage.dao.VmInfoDAO; +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +public class ActivatorTest { + + private StubBundleContext context; + private Activator activator; + + @Before + public void setup() { + context = new StubBundleContext(); + activator = new Activator(); + } + + @Test + public void testActivatorDoesNothingWithMissingDeps() throws Exception { + activator.start(context); + + assertTrue(context.getAllServices().isEmpty()); + assertNotSame(context.getServiceListeners().size(), 1); + + activator.stop(context); + + assertTrue(context.getAllServices().isEmpty()); + assertTrue(context.getServiceListeners().isEmpty()); + } + + @Test + public void verifyServiceRegistered() throws Exception { + ApplicationService appSvc = mock(ApplicationService.class); + AgentInfoDAO agentInfoDAO = mock(AgentInfoDAO.class); + VmInfoDAO vmInfoDAO = mock(VmInfoDAO.class); + VmShenandoahDao vmShenandoahDao = mock(VmShenandoahDao.class); + VmShenandoahViewProvider viewProvider = mock(VmShenandoahViewProvider.class); + + context.registerService(ApplicationService.class, appSvc, null); + context.registerService(AgentInfoDAO.class, agentInfoDAO, null); + context.registerService(VmInfoDAO.class, vmInfoDAO, null); + context.registerService(VmShenandoahDao.class, vmShenandoahDao, null); + context.registerService(VmShenandoahViewProvider.class, viewProvider, null); + + activator.start(context); + + assertTrue(context.isServiceRegistered(InformationService.class.getName(), VmShenandoahServiceImpl.class)); + + activator.stop(context); + + assertFalse(context.isServiceRegistered(InformationService.class.getName(), VmShenandoahServiceImpl.class)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/test/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/VmShenandoahControllerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/test/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/VmShenandoahControllerTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,178 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core.internal; + +import com.redhat.thermostat.client.core.views.BasicView; +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.common.ApplicationService; +import com.redhat.thermostat.common.Timer; +import com.redhat.thermostat.common.TimerFactory; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahView; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; +import com.redhat.thermostat.vm.shenandoah.client.core.locale.LocaleResources; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; + +import java.util.Arrays; +import java.util.Collections; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class VmShenandoahControllerTest { + + private static final Translate t = LocaleResources.createLocalizer(); + + private ApplicationService appSvc; + private VmRef ref; + private VmShenandoahDao dao; + private VmShenandoahViewProvider viewProvider; + private VmShenandoahView view; + private TimerFactory timerFactory; + private Timer timer; + + private VmShenandoahController controller; + + @Before + public void setup() { + appSvc = mock(ApplicationService.class); + ref = mock(VmRef.class); + dao = mock(VmShenandoahDao.class); + viewProvider = mock(VmShenandoahViewProvider.class); + view = mock(VmShenandoahView.class); + timerFactory = mock(TimerFactory.class); + timer = mock(Timer.class); + + when(viewProvider.createView()).thenReturn(view); + when(timerFactory.createTimer()).thenReturn(timer); + when(appSvc.getTimerFactory()).thenReturn(timerFactory); + + controller = new VmShenandoahController(appSvc, ref, dao, viewProvider); + } + + @Test + public void testTabTitle() { + assertThat(controller.getLocalizedName().getContents(), is(t.localize(LocaleResources.TAB_TITLE).getContents())); + } + + @Test + public void verifyCreatesView() { + verify(viewProvider).createView(); + } + + @Test + public void testReturnsCorrectView() { + assertThat((VmShenandoahView) controller.getView(), is(view)); + } + + @Test + public void verifyUsesTimerFactory() { + verify(timerFactory).createTimer(); + } + + @Test + public void verifyAddsViewActionListener() { + verify(view).addActionListener(isA(ActionListener.class)); + } + + @Test + public void testStopsOnViewHidden() { + ArgumentCaptor captor = ArgumentCaptor.forClass(ActionListener.class); + verify(view).addActionListener(captor.capture()); + ActionListener listener = captor.getValue(); + listener.actionPerformed(new ActionEvent(controller, BasicView.Action.HIDDEN)); + verify(timer).stop(); + } + + @Test + public void testStartsOnViewVisible() { + ArgumentCaptor captor = ArgumentCaptor.forClass(ActionListener.class); + verify(view).addActionListener(captor.capture()); + ActionListener listener = captor.getValue(); + listener.actionPerformed(new ActionEvent(controller, BasicView.Action.VISIBLE)); + verify(timer).start(); + } + + @Test + public void testUpdateActionWithNoDaoData() { + when(dao.getCount(ref)).thenReturn(0L); + when(dao.getLatestShenandoahStats(eq(ref), anyLong())).thenReturn(Collections.emptyList()); + ArgumentCaptor actionCaptor = ArgumentCaptor.forClass(Runnable.class); + verify(timer).setAction(actionCaptor.capture()); + Runnable action = actionCaptor.getValue(); + action.run(); + + InOrder inOrder = inOrder(dao, view); + inOrder.verify(dao).getLatestShenandoahStats(eq(ref), anyLong()); + inOrder.verify(view).setEnabled(false); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testUpdateActionWithDaoData() { + VmShenandoahStat stat1 = new VmShenandoahStat("writerID", "vmId", 150L, 50L, 2L, 1024L, 0L, new long[]{1L, 2L}); + VmShenandoahStat stat2 = new VmShenandoahStat("writerID", "vmId", 100L, 50L, 2L, 1024L, 1L, new long[]{3L, 4L}); + + when(dao.getCount(ref)).thenReturn(2L); + when(dao.getLatestShenandoahStats(eq(ref), anyLong())).thenReturn(Arrays.asList(stat1, stat2)); + ArgumentCaptor actionCaptor = ArgumentCaptor.forClass(Runnable.class); + verify(timer).setAction(actionCaptor.capture()); + Runnable action = actionCaptor.getValue(); + action.run(); + + InOrder inOrder = inOrder(dao, view); + inOrder.verify(dao).getLatestShenandoahStats(eq(ref), anyLong()); + inOrder.verify(view).setEnabled(true); + inOrder.verify(view).setData(stat1); + inOrder.verifyNoMoreInteractions(); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/test/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/VmShenandoahServiceImplTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/test/java/com/redhat/thermostat/vm/shenandoah/client/core/internal/VmShenandoahServiceImplTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,158 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core.internal; + +import com.redhat.thermostat.common.ApplicationService; +import com.redhat.thermostat.common.Filter; +import com.redhat.thermostat.common.Ordered; +import com.redhat.thermostat.storage.core.AgentId; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.dao.AgentInfoDAO; +import com.redhat.thermostat.storage.dao.VmInfoDAO; +import com.redhat.thermostat.storage.model.AgentInformation; +import com.redhat.thermostat.storage.model.VmInfo; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class VmShenandoahServiceImplTest { + + private ApplicationService appSvc; + private AgentInfoDAO agentInfoDAO; + private VmInfoDAO vmInfoDAO; + private VmShenandoahDao vmShenandoahDao; + private VmShenandoahViewProvider viewProvider; + private VmRef vmRef; + + private VmShenandoahServiceImpl service; + + @Before + public void setup() { + appSvc = mock(ApplicationService.class); + agentInfoDAO = mock(AgentInfoDAO.class); + vmInfoDAO = mock(VmInfoDAO.class); + vmShenandoahDao = mock(VmShenandoahDao.class); + viewProvider = mock(VmShenandoahViewProvider.class); + vmRef = mock(VmRef.class); + + service = new VmShenandoahServiceImpl(appSvc, agentInfoDAO, vmInfoDAO, vmShenandoahDao, viewProvider); + } + + @Test + public void testFilterDeadVm() { + Filter filter = service.getFilter(); + + AgentInformation agentInformation = new AgentInformation(); + agentInformation.setAgentId("foo-agentId"); + agentInformation.setAlive(true); + when(agentInfoDAO.getAgentInformation(isA(AgentId.class))).thenReturn(agentInformation); + VmInfo vmInfo = new VmInfo(); + vmInfo.setAgentId(agentInformation.getAgentId()); + vmInfo.setStartTimeStamp(0L); + vmInfo.setStopTimeStamp(100L); + when(vmInfoDAO.getVmInfo(eq(vmRef))).thenReturn(vmInfo); + + assertFalse(filter.matches(vmRef)); + } + + @Test + public void testFilterUnknownVm() { + Filter filter = service.getFilter(); + + AgentInformation agentInformation = new AgentInformation(); + agentInformation.setAgentId("foo-agentId"); + agentInformation.setAlive(false); + when(agentInfoDAO.getAgentInformation(isA(AgentId.class))).thenReturn(agentInformation); + VmInfo vmInfo = new VmInfo(); + vmInfo.setAgentId(agentInformation.getAgentId()); + vmInfo.setStartTimeStamp(0L); + vmInfo.setStopTimeStamp(100L); + when(vmInfoDAO.getVmInfo(eq(vmRef))).thenReturn(vmInfo); + + assertFalse(filter.matches(vmRef)); + } + + @Test + public void testFilterAliveVmWithShenandoahStats() { + Filter filter = service.getFilter(); + + AgentInformation agentInformation = new AgentInformation(); + agentInformation.setAgentId("foo-agentId"); + agentInformation.setAlive(true); + when(agentInfoDAO.getAgentInformation(isA(AgentId.class))).thenReturn(agentInformation); + VmInfo vmInfo = new VmInfo(); + vmInfo.setAgentId(agentInformation.getAgentId()); + when(vmInfoDAO.getVmInfo(eq(vmRef))).thenReturn(vmInfo); + + when(vmShenandoahDao.getCount(eq(vmRef))).thenReturn(2L); + + assertTrue(filter.matches(vmRef)); + } + + @Test + public void testFilterAliveVmWithoutShenandoahStats() { + Filter filter = service.getFilter(); + + AgentInformation agentInformation = new AgentInformation(); + agentInformation.setAgentId("foo-agentId"); + agentInformation.setAlive(true); + when(agentInfoDAO.getAgentInformation(isA(AgentId.class))).thenReturn(agentInformation); + VmInfo vmInfo = new VmInfo(); + vmInfo.setAgentId(agentInformation.getAgentId()); + when(vmInfoDAO.getVmInfo(eq(vmRef))).thenReturn(vmInfo); + + when(vmShenandoahDao.getCount(eq(vmRef))).thenReturn(0L); + + assertFalse(filter.matches(vmRef)); + } + + @Test + public void testOrderValue() { + assertThat(service.getOrderValue(), is(Ordered.ORDER_MEMORY_GROUP + 21)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-core/src/test/java/com/redhat/thermostat/vm/shenandoah/client/core/locale/LocaleResourcesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-core/src/test/java/com/redhat/thermostat/vm/shenandoah/client/core/locale/LocaleResourcesTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.core.locale; + +import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest; + +public class LocaleResourcesTest extends AbstractLocaleResourcesTest { + + @Override + protected Class getEnumClass() { + return LocaleResources.class; + } + + @Override + protected String getResourceBundle() { + return LocaleResources.RESOURCE_BUNDLE; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,137 @@ + + + + 4.0.0 + + thermostat-vm-shenandoah + com.redhat.thermostat + 1.99.12-SNAPSHOT + + thermostat-vm-shenandoah-client-swing + bundle + Thermostat VM Shenandoah GC Swing Client plugin + + + + org.apache.felix + maven-bundle-plugin + true + + + Red Hat, Inc. + com.redhat.thermostat.vm.shenandoah.client.swing + com.redhat.thermostat.vm.shenandoah.client.swing.internal.Activator + + com.redhat.thermostat.vm.shenandoah.client.swing + + + com.redhat.thermostat.vm.shenandoah.client.swing.internal, + com.redhat.thermostat.vm.shenandoah.client.swing.internal.locale + + + <_nouses>true + + + + + + + + junit + junit + test + + + com.redhat.thermostat + thermostat-common-test + ${project.version} + test + + + org.mockito + mockito-core + test + + + org.easytesting + fest-swing + test + + + net.java.openjdk.cacio + cacio-tta + test + + + org.osgi + org.osgi.core + provided + + + org.osgi + org.osgi.compendium + provided + + + com.redhat.thermostat + thermostat-common-core + ${project.version} + + + com.redhat.thermostat + thermostat-client-core + ${project.version} + + + com.redhat.thermostat + thermostat-storage-core + ${project.version} + + + com.redhat.thermostat + thermostat-client-swing + ${project.version} + + + com.redhat.thermostat + thermostat-vm-shenandoah-client-core + ${project.version} + + + diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/Activator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/Activator.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +public class Activator implements BundleActivator { + + private ServiceRegistration viewProviderRegistration; + + @Override + public void start(final BundleContext context) throws Exception { + viewProviderRegistration = context.registerService(VmShenandoahViewProvider.class.getName(), new SwingVmShenandoahViewProvider(), null); + } + + @Override + public void stop(BundleContext context) throws Exception { + if (viewProviderRegistration != null) { + viewProviderRegistration.unregister(); + } + } + +} + diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/Colors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/Colors.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import java.awt.Color; + +public enum Colors { + + USED_ALLOC(new Color(0, 250, 250)), + USED(new Color(150, 150, 150)), + LIVE(new Color(0, 200, 0)), + LIVE_BORDER(new Color(0, 100, 0)), + CSET(Color.YELLOW), + HUMONGOUS(Color.RED), + ; + + private final Color color; + + Colors(Color color) { + this.color = color; + } + + public Color getColor() { + return color; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/RegionFlag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/RegionFlag.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +public enum RegionFlag { + UNUSED, + HUMONGOUS, + IN_COLLECTION_SET, + RECENTLY_ALLOCATED, + PINNED, + ; +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/RegionStat.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/RegionStat.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,170 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.EnumSet; + +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.Colors.LIVE; +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.Colors.LIVE_BORDER; +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.Colors.USED; +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.Colors.USED_ALLOC; + +public class RegionStat { + + private static final int USED_MASK = 0x1fffffff; + private static final int USED_SHIFT = 0; + private static final int LIVE_MASK = 0x1fffffff; + private static final int LIVE_SHIFT = 29; + private static final int FLAGS_MASK = 0x3f; + private static final int FLAGS_SHIFT = 58; + + private final EnumSet flags; + private final double liveLvl; + private final double usedLvl; + + public RegionStat(double usedLvl, double liveLvl, EnumSet flags) { + this.usedLvl = usedLvl; + this.liveLvl = liveLvl; + this.flags = flags; + } + + public RegionStat(long maxSize, long data) { + long used = (data >>> USED_SHIFT) & USED_MASK; + usedLvl = Math.min(1D, 1D * used / maxSize); + + long live = (data >>> LIVE_SHIFT) & LIVE_MASK; + liveLvl = Math.min(1D, 1D * live / maxSize); + + long stat = (data >>> FLAGS_SHIFT) & FLAGS_MASK; + + flags = EnumSet.noneOf(RegionFlag.class); + + if ((stat & 1) > 0) flags.add(RegionFlag.UNUSED); + if ((stat & 2) > 0) flags.add(RegionFlag.IN_COLLECTION_SET); + if ((stat & 4) > 0) flags.add(RegionFlag.HUMONGOUS); + if ((stat & 8) > 0) flags.add(RegionFlag.RECENTLY_ALLOCATED); + if ((stat & 16) > 0) flags.add(RegionFlag.PINNED); + } + + public void render(Graphics g, int x, int y, int width, int height) { + g.setColor(Color.WHITE); + g.fillRect(x, y, width, height); + + int usedWidth = (int) (width * usedLvl); + g.setColor( + flags.contains(RegionFlag.RECENTLY_ALLOCATED) ? + USED_ALLOC.getColor() : USED.getColor() + ); + g.fillRect(x, y, usedWidth, height); + + if (!flags.contains(RegionFlag.RECENTLY_ALLOCATED)) { + int liveWidth = (int) (width * liveLvl); + g.setColor(LIVE.getColor()); + g.fillRect(x, y, liveWidth, height); + + g.setColor(LIVE_BORDER.getColor()); + g.drawLine(x + liveWidth, y, x + liveWidth, y + height); + } + + if (flags.contains(RegionFlag.IN_COLLECTION_SET)) { + g.setColor(Colors.CSET.getColor()); + g.fillRect(x, y, width, height / 3); + g.setColor(Color.BLACK); + g.drawRect(x, y, width, height / 3); + } + + if (flags.contains(RegionFlag.HUMONGOUS)) { + g.setColor(Colors.HUMONGOUS.getColor()); + g.fillRect(x, y, width, height / 3); + g.setColor(Color.BLACK); + g.drawRect(x, y, width, height / 3); + } + + if (flags.contains(RegionFlag.UNUSED)) { + g.setColor(Color.BLACK); + g.drawLine(x, y, x + width, y + height); + g.drawLine(x, y + height, x + width, y); + } + + if (flags.contains(RegionFlag.PINNED)) { + g.setColor(Color.RED); + g.fillOval(x + width/2, y + height/2, width/4, height/4); + } + + g.setColor(Color.BLACK); + g.drawRect(x, y, width, height); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RegionStat that = (RegionStat) o; + + if (Double.compare(that.liveLvl, liveLvl) != 0) return false; + if (Double.compare(that.usedLvl, usedLvl) != 0) return false; + return flags.equals(that.flags); + } + + @Override + public int hashCode() { + int result; + long temp; + result = flags.hashCode(); + temp = Double.doubleToLongBits(liveLvl); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(usedLvl); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + public double live() { + return liveLvl; + } + + public double used() { + return usedLvl; + } + + public EnumSet flags() { + return flags; + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/ShenandoahVisualizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/ShenandoahVisualizer.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,380 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.vm.shenandoah.client.swing.internal.locale.LocaleResources; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; + +import javax.swing.JPanel; +import java.awt.Color; +import java.awt.Container; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.font.TextAttribute; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.Deque; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.RegionFlag.HUMONGOUS; +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.RegionFlag.IN_COLLECTION_SET; +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.RegionFlag.PINNED; +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.RegionFlag.RECENTLY_ALLOCATED; +import static com.redhat.thermostat.vm.shenandoah.client.swing.internal.RegionFlag.UNUSED; + +/** + * See http://icedtea.classpath.org/people/rkennke/shenandoahvisualizer + */ +class ShenandoahVisualizer extends JPanel { + + private static final Translate t = LocaleResources.createLocalizer(); + + private final Render render; + private VmShenandoahStat stat; + + ShenandoahVisualizer() { + setLayout(new GridBagLayout()); + + DataProvider dataProvider = new DataProvider(); + + this.render = new Render(dataProvider, this); + + JPanel regionsPanel = new JPanel() { + public void paint(Graphics g) { + render.renderRegions(g); + } + }; + + JPanel legendPanel = new JPanel() { + @Override + public void paint(Graphics g) { + render.renderLegend(g); + } + }; + + JPanel statusPanel = new JPanel() { + @Override + public void paint(Graphics g) { + render.renderStats(g); + } + }; + + JPanel graphPanel = new JPanel() { + @Override + public void paint(Graphics g) { + render.renderGraph(g); + } + }; + + regionsPanel.addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent ev) { + render.notifyRegionResized(ev.getComponent().getWidth(), ev.getComponent().getHeight()); + } + }); + + graphPanel.addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent ev) { + render.notifyGraphResized(ev.getComponent().getWidth(), ev.getComponent().getHeight()); + } + }); + + Insets pad = new Insets(8, 2, 8, 2); + + { + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.BOTH; + c.gridx = 0; + c.gridy = 0; + c.weightx = 3; + c.weighty = 1; + c.insets = pad; + this.add(graphPanel, c); + } + + { + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.BOTH; + c.gridx = 0; + c.gridy = 1; + c.weightx = 3; + c.weighty = 5; + c.insets = pad; + this.add(regionsPanel, c); + } + + { + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.BOTH; + c.gridx = 1; + c.gridy = 0; + c.weightx = 2; + c.weighty = 1; + c.insets = pad; + this.add(statusPanel, c); + } + + { + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.BOTH; + c.gridx = 1; + c.gridy = 1; + c.weightx = 2; + c.weighty = 1; + c.insets = pad; + this.add(legendPanel, c); + } + } + + public void setStat(VmShenandoahStat stat) { + this.stat = stat; + render.run(); + } + + private static class Render implements Runnable { + static final Map TEXT_ATTRIBUTES = new HashMap<>(); + + static { + TEXT_ATTRIBUTES.put(TextAttribute.FAMILY, Font.SANS_SERIF); + TEXT_ATTRIBUTES.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_LIGHT); + TEXT_ATTRIBUTES.put(TextAttribute.SIZE, 11); + } + + final DataProvider data; + final Container container; + + int regionWidth, regionHeight; + int graphWidth, graphHeight; + + final Deque lastSnapshots; + volatile Snapshot snapshot; + + public Render(DataProvider data, Container container) { + this.data = data; + this.container = container; + this.lastSnapshots = new LinkedList<>(); + this.snapshot = data.snapshot(); + } + + @Override + public synchronized void run() { + Snapshot cur = data.snapshot(); + if (!cur.equals(snapshot)) { + snapshot = cur; + lastSnapshots.add(new SnapshotView(cur)); + if (lastSnapshots.size() > graphWidth) { + lastSnapshots.removeFirst(); + } + container.repaint(); + } + } + + public synchronized void renderGraph(Graphics g) { + if (lastSnapshots.size() < 2) return; + + g.setColor(Color.BLACK); + g.fillRect(0, 0, graphWidth, graphHeight); + + double stepY = 1D * graphHeight / snapshot.total(); + long firstTime = lastSnapshots.getFirst().time(); + long lastTime = lastSnapshots.getLast().time(); + double stepX = 1D * Math.min(lastSnapshots.size(), graphWidth) / (lastTime - firstTime); + for (SnapshotView s : lastSnapshots) { + int x = (int) Math.round((s.time() - firstTime) * stepX); + + if (s.isMarking()) { + g.setColor(new Color(100, 100, 0)); + g.drawRect(x, 0, 1, graphHeight); + } + + if (s.isEvacuating()) { + g.setColor(new Color(100, 0, 0)); + g.drawRect(x, 0, 1, graphHeight); + } + + g.setColor(Colors.USED.getColor()); + g.drawRect(x, (int) Math.round(graphHeight - s.used() * stepY), 1, 1); + g.setColor(Colors.USED_ALLOC.getColor()); + g.drawRect(x, (int) Math.round(graphHeight - s.recentlyAllocated() * stepY), 1, 1); + g.setColor(Colors.HUMONGOUS.getColor()); + g.drawRect(x, (int) Math.round(graphHeight - s.humongous() * stepY), 1, 1); + g.setColor(Colors.LIVE.getColor()); + g.drawRect(x, (int) Math.round(graphHeight - s.live() * stepY), 1, 1); + g.setColor(Colors.CSET.getColor()); + g.drawRect(x, (int) Math.round(graphHeight - s.collectionSet() * stepY), 1, 1); + } + } + + public synchronized void renderLegend(Graphics g) { + g.setFont(Font.getFont(TEXT_ATTRIBUTES)); + final int sqSize = line(); + + Map items = new LinkedHashMap<>(); + + items.put(t.localize(LocaleResources.UNUSED_REGION_LABEL).getContents(), + new RegionStat(0.0, 0.0, EnumSet.of(UNUSED))); + + items.put(t.localize(LocaleResources.EMPTY_REGION_LABEL).getContents(), + new RegionStat(0.0, 0.0, EnumSet.noneOf(RegionFlag.class))); + + items.put(t.localize(LocaleResources.HALF_USED_REGION_LABEL).getContents(), + new RegionStat(0.5, 0.0, EnumSet.noneOf(RegionFlag.class))); + + items.put(t.localize(LocaleResources.FULLY_USED_REGION_LABEL).getContents(), + new RegionStat(1.0, 0.0, EnumSet.noneOf(RegionFlag.class))); + + items.put(t.localize(LocaleResources.FULLY_USED_RECENTLY_ALLOCATED_REGION_LABEL).getContents(), + new RegionStat(1.0, 0.0, EnumSet.of(RECENTLY_ALLOCATED))); + + items.put(t.localize(LocaleResources.FULLY_LIVE_REGION_LABEL).getContents(), + new RegionStat(1.0, 1.0, EnumSet.noneOf(RegionFlag.class))); + + items.put(t.localize(LocaleResources.FULLY_LIVE_HUMONGOUS_REGION_LABEL).getContents(), + new RegionStat(1.0, 1.0, EnumSet.of(HUMONGOUS))); + + items.put(t.localize(LocaleResources.THIRD_LIVE_REGION_LABEL).getContents(), + new RegionStat(1.0, 0.3, EnumSet.noneOf(RegionFlag.class))); + + items.put(t.localize(LocaleResources.THIRD_LIVE_COLLECITON_SET_REGION_LABEL).getContents(), + new RegionStat(1.0, 0.3, EnumSet.of(IN_COLLECTION_SET))); + + items.put(t.localize(LocaleResources.THIRD_LIVE_PINNED_REGION_LABEL).getContents(), + new RegionStat(1.0, 0.3, EnumSet.of(PINNED))); + + int i = 1; + for (String key : items.keySet()) { + int y = (int) (i * sqSize * 1.5); + items.get(key).render(g, 0, y, sqSize, sqSize); + g.drawString(key, (int) (sqSize * 1.5), y + sqSize); + i++; + } + } + + public synchronized void renderRegions(Graphics g) { + try { + int area = regionWidth * regionHeight; + int sqSize = Math.max(1, (int) Math.sqrt(1D * area / snapshot.regionCount())); + int cols = regionWidth / sqSize; + + for (int i = 0; i < snapshot.regionCount(); i++) { + int rectx = (i % cols) * sqSize; + int recty = (i / cols) * sqSize; + + RegionStat s = snapshot.get(i); + s.render(g, rectx, recty, sqSize, sqSize); + } + } catch (ArithmeticException ignored) { + } + } + + public synchronized void renderStats(Graphics g) { + g.setFont(Font.getFont(TEXT_ATTRIBUTES)); + + String status; + if (snapshot.isMarking() && snapshot.isEvacuating()) { + status = t.localize(LocaleResources.MARKING_AND_EVACUATING_STATUS).getContents(); + } else if (snapshot.isMarking()) { + status = t.localize(LocaleResources.MARKING_STATUS).getContents(); + } else if (snapshot.isEvacuating()) { + status = t.localize(LocaleResources.EVACUATING_STATUS).getContents(); + } else { + status = t.localize(LocaleResources.IDLE_STATUS).getContents(); + } + + g.setColor(Color.BLACK); + g.drawString(t.localize(LocaleResources.TIME_STAT_LABEL, Clock.DEFAULT_DATE_FORMAT.format(new Date(snapshot.time()))).getContents(), + 0, 1 * line()); + g.drawString(t.localize(LocaleResources.STATUS_STAT_LABEL, status).getContents(), 0, 2 * line()); + g.drawString(t.localize(LocaleResources.TOTAL_STAT_LABEL, Long.toString(snapshot.total())).getContents(), 0, 3 * line()); + g.drawString(t.localize(LocaleResources.USED_STAT_LABEL, Long.toString(snapshot.used())).getContents(), 0, 4 * line()); + g.drawString(t.localize(LocaleResources.LIVE_STAT_LABEL, Long.toString(snapshot.live())).getContents(), 0, 5 * line()); + } + + public synchronized void notifyRegionResized(int width, int height) { + this.regionWidth = width; + this.regionHeight = height; + } + + public synchronized void notifyGraphResized(int width, int height) { + this.graphWidth = width; + this.graphHeight = height; + } + + private int line() { + int result = (int) (container.getSize().getHeight() / 30); + if (result % 2 == 1) { + result--; + } + return result; + } + } + + private class DataProvider { + public Snapshot snapshot() { + if (stat == null) { + return new Snapshot(0L, 0L, Collections.emptyList(), false, false); + } + long maxSize = stat.getRegionSize(); + long[] data = stat.getRegionData(); + long timestamp = stat.getTimeStamp(); + long status = stat.getRegionStatus(); + + List stats = new ArrayList<>(); + for (long l : data) { + stats.add(new RegionStat(maxSize, l)); + } + boolean isMarking = (status & 0x1) > 0; + boolean isEvacuating = (status & 0x2) > 0; + + return new Snapshot(timestamp, maxSize, stats, isMarking, isEvacuating); + } + } +} + + diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/Snapshot.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/Snapshot.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,149 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import java.util.List; +import java.util.Objects; + +public class Snapshot { + + private final long time; + private final long regionSize; + private final List stats; + private final boolean isMarking; + private final boolean isEvacuating; + + public Snapshot(long time, long regionSize, List stats, boolean isMarking, boolean isEvacuating) { + this.time = time; + this.regionSize = regionSize; + this.stats = stats; + this.isMarking = isMarking; + this.isEvacuating = isEvacuating; + } + + public boolean isMarking() { + return isMarking; + } + + public boolean isEvacuating() { + return isEvacuating; + } + + public RegionStat get(int i) { + return stats.get(i); + } + + public long time() { + return time; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Snapshot snapshot = (Snapshot) o; + + if (time != snapshot.time) return false; + if (isMarking != snapshot.isMarking) return false; + if (isEvacuating != snapshot.isEvacuating) return false; + return Objects.equals(stats, snapshot.stats); + } + + @Override + public int hashCode() { + int result = (int) (time ^ (time >>> 32)); + result = 31 * result + (stats != null ? stats.hashCode() : 0); + result = 31 * result + (isMarking ? 1 : 0); + result = 31 * result + (isEvacuating ? 1 : 0); + return result; + } + + public int regionCount() { + return stats.size(); + } + + public long total() { + return regionSize * regionCount(); + } + + public long used() { + long used = 0L; + for (RegionStat rs : stats) { + used += regionSize * rs.used(); + } + return used; + } + + public long recentlyAllocated() { + long used = 0L; + for (RegionStat rs : stats) { + if (rs.flags().contains(RegionFlag.RECENTLY_ALLOCATED)) { + used += regionSize * rs.used(); + } + } + return used; + } + + public long collectionSet() { + long used = 0L; + for (RegionStat rs : stats) { + if (rs.flags().contains(RegionFlag.IN_COLLECTION_SET)) { + used += regionSize * rs.used(); + } + } + return used; + } + + public long humongous() { + long used = 0L; + for (RegionStat rs : stats) { + if (rs.flags().contains(RegionFlag.HUMONGOUS)) { + used += regionSize * rs.used(); + } + } + return used; + } + + public long live() { + long live = 0L; + for (RegionStat rs : stats) { + live += regionSize * rs.live(); + } + return live; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/SnapshotView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/SnapshotView.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,98 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +public class SnapshotView { + + private final long time; + private final boolean isMarking; + private final boolean isEvacuating; + private final long total; + private final long used; + private final long live; + private final long recentlyAllocated; + private final long humongous; + private final long collectionSet; + + public SnapshotView(Snapshot s) { + this.time = s.time(); + this.isEvacuating = s.isEvacuating(); + this.isMarking = s.isMarking(); + total = s.total(); + used = s.used(); + live = s.live(); + recentlyAllocated = s.recentlyAllocated(); + humongous = s.humongous(); + collectionSet = s.collectionSet(); + } + + public boolean isMarking() { + return isMarking; + } + + public boolean isEvacuating() { + return isEvacuating; + } + + public long time() { + return time; + } + + public long total() { + return total; + } + + public long used() { + return used; + } + + public long recentlyAllocated() { + return recentlyAllocated; + } + + public long collectionSet() { + return collectionSet; + } + + public long humongous() { + return humongous; + } + + public long live() { + return live; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/SwingVmShenandoahView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/SwingVmShenandoahView.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,96 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import com.redhat.thermostat.client.swing.SwingComponent; +import com.redhat.thermostat.client.swing.components.HeaderPanel; +import com.redhat.thermostat.client.swing.experimental.ComponentVisibilityNotifier; +import com.redhat.thermostat.shared.locale.LocalizedString; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahView; +import com.redhat.thermostat.vm.shenandoah.client.core.locale.LocaleResources; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import java.awt.BorderLayout; +import java.awt.Component; + +public class SwingVmShenandoahView extends VmShenandoahView implements SwingComponent { + + private static final Translate t = LocaleResources.createLocalizer(); + + private final HeaderPanel headerPanel = new HeaderPanel(t.localize(LocaleResources.TAB_DETAIL)); + private final ShenandoahVisualizer visualizer = new ShenandoahVisualizer(); + + public SwingVmShenandoahView() { + super(); + + new ComponentVisibilityNotifier().initialize(headerPanel, notifier); + } + + @Override + public void setEnabled(boolean enabled) { + if (enabled) { + headerPanel.setContent(visualizer); + } else { + JPanel statusPanel = new JPanel(new BorderLayout()); + + String wrappedText = "" + t.localize(LocaleResources.SHENANDOAH_UNAVAILABLE).getContents() + ""; + JLabel descriptionLabel = new JLabel(wrappedText); + statusPanel.add(descriptionLabel, BorderLayout.PAGE_START); + + headerPanel.setContent(statusPanel); + } + } + + @Override + public void setData(final VmShenandoahStat vmShenandoahStat) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + visualizer.setStat(vmShenandoahStat); + } + }); + } + + @Override + public Component getUiComponent() { + return headerPanel; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/SwingVmShenandoahViewProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/SwingVmShenandoahViewProvider.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahView; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; + +public class SwingVmShenandoahViewProvider implements VmShenandoahViewProvider { + @Override + public VmShenandoahView createView() { + return new SwingVmShenandoahView(); + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/locale/LocaleResources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/locale/LocaleResources.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,72 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal.locale; + +import com.redhat.thermostat.shared.locale.Translate; + +public enum LocaleResources { + + UNUSED_REGION_LABEL, + EMPTY_REGION_LABEL, + HALF_USED_REGION_LABEL, + FULLY_USED_REGION_LABEL, + FULLY_USED_RECENTLY_ALLOCATED_REGION_LABEL, + FULLY_LIVE_REGION_LABEL, + FULLY_LIVE_HUMONGOUS_REGION_LABEL, + THIRD_LIVE_REGION_LABEL, + THIRD_LIVE_COLLECITON_SET_REGION_LABEL, + THIRD_LIVE_PINNED_REGION_LABEL, + + MARKING_STATUS, + EVACUATING_STATUS, + MARKING_AND_EVACUATING_STATUS, + IDLE_STATUS, + + TIME_STAT_LABEL, + STATUS_STAT_LABEL, + TOTAL_STAT_LABEL, + USED_STAT_LABEL, + LIVE_STAT_LABEL, + ; + + static final String RESOURCE_BUNDLE = + "com.redhat.thermostat.vm.shenandoah.client.swing.internal.locale.strings"; + + public static Translate createLocalizer() { + return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class); + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/main/resources/com/redhat/thermostat/vm/shenandoah/client/swing/internal/locale/strings.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/main/resources/com/redhat/thermostat/vm/shenandoah/client/swing/internal/locale/strings.properties Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,21 @@ +UNUSED_REGION_LABEL=Unused +EMPTY_REGION_LABEL=Empty +HALF_USED_REGION_LABEL=1/2 Used +FULLY_USED_REGION_LABEL=Fully Used +FULLY_USED_RECENTLY_ALLOCATED_REGION_LABEL=Fully Used, Recently Allocated +FULLY_LIVE_REGION_LABEL=Fully Live +FULLY_LIVE_HUMONGOUS_REGION_LABEL=Fully Live + Humongous +THIRD_LIVE_REGION_LABEL=1/3 Live +THIRD_LIVE_COLLECITON_SET_REGION_LABEL=1/3 Live + In Collection Set +THIRD_LIVE_PINNED_REGION_LABEL=1/3 Live + Pinned + +MARKING_STATUS=marking +EVACUATING_STATUS=evacuating +MARKING_AND_EVACUATING_STATUS=marking, evacuating +IDLE_STATUS=idle + +TIME_STAT_LABEL=Time: {0} +STATUS_STAT_LABEL=Status: {0} +TOTAL_STAT_LABEL=Total: {0} KB +USED_STAT_LABEL=Used: {0} KB +LIVE_STAT_LABEL=Live: {0} KB \ No newline at end of file diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/test/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/ActivatorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/test/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/ActivatorTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahViewProvider; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class ActivatorTest { + + private StubBundleContext context; + private Activator activator; + + @Before + public void setup() { + context = new StubBundleContext(); + activator = new Activator(); + } + + @Test + public void verifyViewProviderRegistered() throws Exception { + assertFalse(context.isServiceRegistered(VmShenandoahViewProvider.class.getName(), SwingVmShenandoahViewProvider.class)); + activator.start(context); + assertTrue(context.isServiceRegistered(VmShenandoahViewProvider.class.getName(), SwingVmShenandoahViewProvider.class)); + activator.stop(context); + assertFalse(context.isServiceRegistered(VmShenandoahViewProvider.class.getName(), SwingVmShenandoahViewProvider.class)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/test/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/RegionStatTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/test/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/RegionStatTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,78 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import org.junit.Test; + +import java.util.EnumSet; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class RegionStatTest { + + private RegionStat stat; + + @Test + public void testConstructor() { + stat = new RegionStat(0xfffffff, 0xffff0000); + assertThat(stat.used(), is(1.0)); + assertThat(stat.live(), is(1.0)); + EnumSet flags = stat.flags(); + assertTrue(flags.contains(RegionFlag.UNUSED)); + assertTrue(flags.contains(RegionFlag.IN_COLLECTION_SET)); + assertTrue(flags.contains(RegionFlag.HUMONGOUS)); + assertTrue(flags.contains(RegionFlag.RECENTLY_ALLOCATED)); + assertTrue(flags.contains(RegionFlag.PINNED)); + } + + @Test + public void testConstructor2() { + stat = new RegionStat(0x0f, 0x00f); + assertThat(stat.used(), is(1.0)); + assertThat(stat.live(), is(0.0)); + EnumSet flags = stat.flags(); + assertFalse(flags.contains(RegionFlag.UNUSED)); + assertFalse(flags.contains(RegionFlag.IN_COLLECTION_SET)); + assertFalse(flags.contains(RegionFlag.HUMONGOUS)); + assertFalse(flags.contains(RegionFlag.RECENTLY_ALLOCATED)); + assertFalse(flags.contains(RegionFlag.PINNED)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/test/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/SwingVmShenandoahViewProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/test/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/SwingVmShenandoahViewProviderTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal; + +import com.redhat.thermostat.annotations.internal.CacioTest; +import com.redhat.thermostat.vm.shenandoah.client.core.VmShenandoahView; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import static junit.framework.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +@Category(CacioTest.class) +public class SwingVmShenandoahViewProviderTest { + + private SwingVmShenandoahViewProvider viewProvider; + + @Before + public void setup() { + viewProvider = new SwingVmShenandoahViewProvider(); + } + + @Test + public void testCreateView() { + VmShenandoahView view = viewProvider.createView(); + assertNotNull(view); + assertTrue(view instanceof SwingVmShenandoahView); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/client-swing/src/test/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/locale/LocaleResourcesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/client-swing/src/test/java/com/redhat/thermostat/vm/shenandoah/client/swing/internal/locale/LocaleResourcesTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.client.swing.internal.locale; + +import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest; + +public class LocaleResourcesTest extends AbstractLocaleResourcesTest { + + @Override + protected Class getEnumClass() { + return LocaleResources.class; + } + + @Override + protected String getResourceBundle() { + return LocaleResources.RESOURCE_BUNDLE; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,131 @@ + + + + 4.0.0 + + thermostat-vm-shenandoah + com.redhat.thermostat + 1.99.12-SNAPSHOT + + thermostat-vm-shenandoah-common + bundle + Thermostat VM Shenandoah Common plugin + + + + src/main/resources + true + + **/*.png + **/*.xml + **/*.xsd + + + + src/main/resources + false + + **/*.png + **/*.xml + **/*.xsd + + + + + + org.apache.felix + maven-bundle-plugin + true + + + Red Hat, Inc. + com.redhat.thermostat.vm.shenandoah.common + com.redhat.thermostat.vm.shenandoah.common.internal.Activator + + com.redhat.thermostat.vm.shenandoah.common, + + + com.redhat.thermostat.vm.shenandoah.common.internal, + + + <_nouses>true + + + + + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.osgi + org.osgi.core + provided + + + org.osgi + org.osgi.compendium + provided + + + com.redhat.thermostat + thermostat-common-core + ${project.version} + + + com.redhat.thermostat + thermostat-storage-core + ${project.version} + + + com.redhat.thermostat + thermostat-common-test + ${project.version} + test + + + diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/VmShenandoahDao.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/VmShenandoahDao.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common; + +import com.redhat.thermostat.annotations.Service; +import com.redhat.thermostat.storage.core.Category; +import com.redhat.thermostat.storage.core.Key; +import com.redhat.thermostat.storage.core.VmRef; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@Service +public interface VmShenandoahDao { + + Key REGION_TIMESTAMP_KEY = new Key<>("regionTimeStamp"); + Key MAX_REGIONS_KEY = new Key<>("maxRegions"); + Key REGION_SIZE_KEY = new Key<>("regionSize"); + Key REGION_STATUS_KEY = new Key<>("regionStatus"); + Key REGION_DATA_KEY = new Key<>("regionData"); + + Category VM_SHENANDOAH_STAT_CATEGORY = new Category<>("vm-shenandoah-stats", VmShenandoahStat.class, + Arrays.>asList(Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, REGION_TIMESTAMP_KEY, MAX_REGIONS_KEY, REGION_SIZE_KEY, REGION_STATUS_KEY, REGION_DATA_KEY), + Collections.>singletonList(Key.TIMESTAMP)); + + void putShenandoahStat(VmShenandoahStat vmShenandoahStat); + + List getLatestShenandoahStats(VmRef ref, long since); + + long getCount(VmRef ref); + +} \ No newline at end of file diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/VmShenandoahStat.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/VmShenandoahStat.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,172 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common; + +import com.redhat.thermostat.storage.core.Entity; +import com.redhat.thermostat.storage.core.Persist; +import com.redhat.thermostat.storage.model.BasePojo; +import com.redhat.thermostat.storage.model.TimeStampedPojo; + +import java.util.Arrays; + +@Entity +public class VmShenandoahStat extends BasePojo implements TimeStampedPojo { + + private String vmId; + private long timeStamp; + private long regionTimeStamp; + private long maxRegions; + private long regionSize; + private long regionStatus; + private long[] regionData; + + public VmShenandoahStat() { + super(null); + } + + public VmShenandoahStat(String writerId, String vmId, long timeStamp, + long regionTimeStamp, long maxRegions, long regionSize, long regionStatus, long[] regionData) { + super(writerId); + this.vmId = vmId; + this.timeStamp = timeStamp; + this.regionTimeStamp = regionTimeStamp; + this.maxRegions = maxRegions; + this.regionSize = regionSize; + this.regionStatus = regionStatus; + this.regionData = regionData; + } + + @Persist + public String getVmId() { + return vmId; + } + + @Persist + public void setVmId(String vmId) { + this.vmId = vmId; + } + + @Persist + public long getTimeStamp() { + return timeStamp; + } + + @Persist + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + + @Persist + public long getRegionTimeStamp() { + return regionTimeStamp; + } + + @Persist + public void setRegionTimeStamp(long regionTimeStamp) { + this.regionTimeStamp = regionTimeStamp; + } + + @Persist + public long getMaxRegions() { + return maxRegions; + } + + @Persist + public void setMaxRegions(long maxRegions) { + this.maxRegions = maxRegions; + } + + @Persist + public long getRegionSize() { + return regionSize; + } + + @Persist + public void setRegionSize(long regionSize) { + this.regionSize = regionSize; + } + + @Persist + public long getRegionStatus() { + return regionStatus; + } + + @Persist + public void setRegionStatus(long regionStatus) { + this.regionStatus = regionStatus; + } + + @Persist + public long[] getRegionData() { + return regionData; + } + + @Persist + public void setRegionData(long[] regionData) { + this.regionData = regionData; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + VmShenandoahStat that = (VmShenandoahStat) o; + + if (getTimeStamp() != that.getTimeStamp()) return false; + if (getRegionTimeStamp() != that.getRegionTimeStamp()) return false; + if (getMaxRegions() != that.getMaxRegions()) return false; + if (getRegionSize() != that.getRegionSize()) return false; + if (getRegionStatus() != that.getRegionStatus()) return false; + if (!getVmId().equals(that.getVmId())) return false; + return Arrays.equals(getRegionData(), that.getRegionData()); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + getVmId().hashCode(); + result = 31 * result + (int) (getTimeStamp() ^ (getTimeStamp() >>> 32)); + result = 31 * result + (int) (getRegionTimeStamp() ^ (getRegionTimeStamp() >>> 32)); + result = 31 * result + (int) (getMaxRegions() ^ (getMaxRegions() >>> 32)); + result = 31 * result + (int) (getRegionSize() ^ (getRegionSize() >>> 32)); + result = 31 * result + (int) (getRegionStatus() ^ (getRegionStatus() >>> 32)); + result = 31 * result + Arrays.hashCode(getRegionData()); + return result; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/internal/Activator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/internal/Activator.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,75 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common.internal; + +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +public class Activator implements BundleActivator { + + private MultipleServiceTracker tracker; + private ServiceRegistration registration; + + @Override + public void start(final BundleContext bundleContext) throws Exception { + tracker = new MultipleServiceTracker(bundleContext, new Class[]{Storage.class}, new MultipleServiceTracker.Action() { + @Override + public void dependenciesAvailable(MultipleServiceTracker.DependencyProvider services) { + Storage storage = services.get(Storage.class); + registration = bundleContext.registerService(VmShenandoahDao.class.getName(), new VmShenandoahDaoImpl(storage), null); + } + + @Override + public void dependenciesUnavailable() { + registration.unregister(); + } + }); + tracker.open(); + } + + @Override + public void stop(BundleContext bundleContext) throws Exception { + if (tracker != null) { + tracker.close(); + } + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahDaoImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahDaoImpl.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,125 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common.internal; + +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.storage.core.Category; +import com.redhat.thermostat.storage.core.CategoryAdapter; +import com.redhat.thermostat.storage.core.Key; +import com.redhat.thermostat.storage.core.PreparedStatement; +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.storage.core.VmLatestPojoListGetter; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.dao.AbstractDao; +import com.redhat.thermostat.storage.dao.AbstractDaoQuery; +import com.redhat.thermostat.storage.dao.AbstractDaoStatement; +import com.redhat.thermostat.storage.model.AggregateCount; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; + +import java.util.List; +import java.util.logging.Logger; + +public class VmShenandoahDaoImpl extends AbstractDao implements VmShenandoahDao { + + private static final Logger logger = LoggingUtils.getLogger(VmShenandoahDaoImpl.class); + + static final String DESC_ADD_VM_SHENANDOAH_STAT = "ADD " + VM_SHENANDOAH_STAT_CATEGORY.getName() + + " SET '" + Key.AGENT_ID.getName() + "' = ?s , " + + "'" + Key.VM_ID.getName() + "' = ?s , " + + "'" + Key.TIMESTAMP.getName() + "' = ?l , " + + "'" + REGION_TIMESTAMP_KEY.getName() + "' = ?l , " + + "'" + MAX_REGIONS_KEY.getName() + "' = ?l , " + + "'" + REGION_SIZE_KEY.getName() + "' = ?l , " + + "'" + REGION_STATUS_KEY.getName() + "' = ?l , " + + "'" + REGION_DATA_KEY.getName() + "' = ?l["; + + static final String QUERY_COUNT_SHENANDOAH_STATS_BY_VM_ID = "" + + "QUERY-COUNT " + VM_SHENANDOAH_STAT_CATEGORY.getName() + " " + + "WHERE '" + Key.VM_ID.getName() + "' = ?s"; + + private final Storage storage; + final Category aggregateCountCategory; + final VmLatestPojoListGetter getter; + + public VmShenandoahDaoImpl(Storage storage) { + this.storage = storage; + storage.registerCategory(VM_SHENANDOAH_STAT_CATEGORY); + this.aggregateCountCategory = new CategoryAdapter(VM_SHENANDOAH_STAT_CATEGORY).getAdapted(AggregateCount.class); + storage.registerCategory(aggregateCountCategory); + this.getter = new VmLatestPojoListGetter<>(storage, VM_SHENANDOAH_STAT_CATEGORY); + } + + @Override + public void putShenandoahStat(final VmShenandoahStat vmShenandoahStat) { + executeStatement(new AbstractDaoStatement(storage, VM_SHENANDOAH_STAT_CATEGORY, DESC_ADD_VM_SHENANDOAH_STAT) { + @Override + public PreparedStatement customize(PreparedStatement preparedStatement) { + preparedStatement.setString(0, vmShenandoahStat.getAgentId()); + preparedStatement.setString(1, vmShenandoahStat.getVmId()); + preparedStatement.setLong(2, vmShenandoahStat.getTimeStamp()); + preparedStatement.setLong(3, vmShenandoahStat.getRegionTimeStamp()); + preparedStatement.setLong(4, vmShenandoahStat.getMaxRegions()); + preparedStatement.setLong(5, vmShenandoahStat.getRegionSize()); + preparedStatement.setLong(6, vmShenandoahStat.getRegionStatus()); + preparedStatement.setLongList(7, vmShenandoahStat.getRegionData()); + return preparedStatement; + } + }); + } + + @Override + public List getLatestShenandoahStats(VmRef ref, long since) { + return getter.getLatest(ref, since); + } + + @Override + public long getCount(final VmRef ref) { + return executeQuery(new AbstractDaoQuery(storage, aggregateCountCategory, QUERY_COUNT_SHENANDOAH_STATS_BY_VM_ID) { + @Override + public PreparedStatement customize(PreparedStatement preparedStatement) { + preparedStatement.setString(0, ref.getVmId()); + return preparedStatement; + } + }).head().getCount(); + } + + @Override + protected Logger getLogger() { + return logger; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahDaoImplStatementDescriptorRegistration.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahDaoImplStatementDescriptorRegistration.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common.internal; + +import com.redhat.thermostat.storage.core.VmLatestPojoListGetter; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; + +import java.util.HashSet; +import java.util.Set; + +public class VmShenandoahDaoImplStatementDescriptorRegistration implements StatementDescriptorRegistration { + + static final String descriptor = String.format( + VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT, + VmShenandoahDao.VM_SHENANDOAH_STAT_CATEGORY.getName()); + + @Override + public Set getStatementDescriptors() { + Set descs = new HashSet<>(2); + descs.add(descriptor); + descs.add(VmShenandoahDaoImpl.DESC_ADD_VM_SHENANDOAH_STAT); + descs.add(VmShenandoahDaoImpl.QUERY_COUNT_SHENANDOAH_STATS_BY_VM_ID); + return descs; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahStatCategoryRegistration.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/main/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahStatCategoryRegistration.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common.internal; + +import com.redhat.thermostat.storage.core.auth.CategoryRegistration; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; + +import java.util.HashSet; +import java.util.Set; + +public class VmShenandoahStatCategoryRegistration implements CategoryRegistration { + @Override + public Set getCategoryNames() { + Set categories = new HashSet<>(1); + categories.add(VmShenandoahDao.VM_SHENANDOAH_STAT_CATEGORY.getName()); + return categories; + } +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.shenandoah.common.internal.VmShenandoahStatCategoryRegistration \ No newline at end of file diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.shenandoah.common.internal.VmShenandoahDaoImplStatementDescriptorRegistration \ No newline at end of file diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/test/java/com/redhat/thermostat/vm/shenandoah/common/internal/ActivatorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/test/java/com/redhat/thermostat/vm/shenandoah/common/internal/ActivatorTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,87 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common.internal; + +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +public class ActivatorTest { + + private Storage storage; + private StubBundleContext context; + private Activator activator; + + @Before + public void setup() { + storage = mock(Storage.class); + context = new StubBundleContext(); + activator = new Activator(); + } + + @Test + public void testDoesNotRegisterDaoIfStorageUnavailable() throws Exception { + assertFalse(context.isServiceRegistered(VmShenandoahDao.class.getName(), VmShenandoahDaoImpl.class)); + activator.start(context); + assertFalse(context.isServiceRegistered(VmShenandoahDao.class.getName(), VmShenandoahDaoImpl.class)); + } + + @Test + public void testRegistersDaoWhenStorageAvailable() throws Exception { + context.registerService(Storage.class.getName(), storage, null); + assertFalse(context.isServiceRegistered(VmShenandoahDao.class.getName(), VmShenandoahDaoImpl.class)); + activator.start(context); + assertTrue(context.isServiceRegistered(VmShenandoahDao.class.getName(), VmShenandoahDaoImpl.class)); + } + + @Test + public void testUnregistersDaoWhenStopped() throws Exception { + context.registerService(Storage.class.getName(), storage, null); + assertFalse(context.isServiceRegistered(VmShenandoahDao.class.getName(), VmShenandoahDaoImpl.class)); + activator.start(context); + assertTrue(context.isServiceRegistered(VmShenandoahDao.class.getName(), VmShenandoahDaoImpl.class)); + activator.stop(context); + assertFalse(context.isServiceRegistered(VmShenandoahDao.class.getName(), VmShenandoahDaoImpl.class)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/test/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahDaoImplStatementDescriptorRegistrationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/test/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahDaoImplStatementDescriptorRegistrationTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,62 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common.internal; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.testutils.ServiceLoaderTest; +import org.junit.Test; + +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +public class VmShenandoahDaoImplStatementDescriptorRegistrationTest extends ServiceLoaderTest { + + public VmShenandoahDaoImplStatementDescriptorRegistrationTest() { + super(StatementDescriptorRegistration.class, STORAGE_SERVICES, VmShenandoahDaoImplStatementDescriptorRegistration.class); + } + + @Test + public void registersAllDescriptors() { + VmShenandoahDaoImplStatementDescriptorRegistration reg = new VmShenandoahDaoImplStatementDescriptorRegistration(); + Set descriptors = reg.getStatementDescriptors(); + assertEquals(3, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/test/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahDaoImplTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/test/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahDaoImplTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,155 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common.internal; + +import com.redhat.thermostat.storage.core.BasicBatchCursor; +import com.redhat.thermostat.storage.core.Cursor; +import com.redhat.thermostat.storage.core.DescriptorParsingException; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.Key; +import com.redhat.thermostat.storage.core.PreparedStatement; +import com.redhat.thermostat.storage.core.StatementDescriptor; +import com.redhat.thermostat.storage.core.StatementExecutionException; +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.model.AggregateCount; +import com.redhat.thermostat.storage.model.Pojo; +import com.redhat.thermostat.storage.model.VmInfo; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahStat; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import java.util.Collection; +import java.util.NoSuchElementException; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class VmShenandoahDaoImplTest { + + private Storage storage; + private PreparedStatement stmt; + private VmShenandoahDaoImpl dao; + + @Before + public void seup() throws DescriptorParsingException { + storage = mock(Storage.class); + stmt = mock(PreparedStatement.class); + when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(stmt); + dao = new VmShenandoahDaoImpl(storage); + } + + @Test + public void testRegistersStatCategory() { + verify(storage).registerCategory(VmShenandoahDao.VM_SHENANDOAH_STAT_CATEGORY); + } + + @Test + public void testRegistersAggregateCategory() { + verify(storage).registerCategory(dao.aggregateCountCategory); + } + + @Test + public void testCategory() { + assertEquals("vm-shenandoah-stats", VmShenandoahDao.VM_SHENANDOAH_STAT_CATEGORY.getName()); + Collection> keys = VmShenandoahDao.VM_SHENANDOAH_STAT_CATEGORY.getKeys(); + assertTrue(keys.contains(new Key<>("agentId"))); + assertTrue(keys.contains(new Key("vmId"))); + assertTrue(keys.contains(new Key("timeStamp"))); + assertTrue(keys.contains(new Key("regionTimeStamp"))); + assertTrue(keys.contains(new Key("maxRegions"))); + assertTrue(keys.contains(new Key("regionSize"))); + assertTrue(keys.contains(new Key("regionStatus"))); + assertTrue(keys.contains(new Key("regionData"))); + assertEquals(8, keys.size()); + } + + @Test + @SuppressWarnings("unchecked") + public void testPutShenandoahStat() throws DescriptorParsingException { + VmShenandoahStat stat = new VmShenandoahStat("foo-writerId", "foo-vmId", 100L, 50L, 2L, 1024L, 1L, new long[]{1L, 2L}); + stat.setAgentId("foo-agentId"); + dao.putShenandoahStat(stat); + + ArgumentCaptor descriptorCaptor = ArgumentCaptor.forClass(StatementDescriptor.class); + verify(storage).prepareStatement(descriptorCaptor.capture()); + StatementDescriptor descriptor = descriptorCaptor.getValue(); + assertThat(descriptor.getCategory(), is(VmShenandoahDao.VM_SHENANDOAH_STAT_CATEGORY)); + assertThat(descriptor.getDescriptor(), is(VmShenandoahDaoImpl.DESC_ADD_VM_SHENANDOAH_STAT)); + + verify(stmt).setString(0, stat.getAgentId()); + verify(stmt).setString(1, stat.getVmId()); + verify(stmt).setLong(2, stat.getTimeStamp()); + verify(stmt).setLong(3, stat.getRegionTimeStamp()); + verify(stmt).setLong(4, stat.getMaxRegions()); + verify(stmt).setLong(5, stat.getRegionSize()); + verify(stmt).setLong(6, stat.getRegionStatus()); + verify(stmt).setLongList(7, stat.getRegionData()); + } + + @Test + @SuppressWarnings("unchecked") + public void testGetCount() throws DescriptorParsingException, StatementExecutionException { + AggregateCount aggregateCount = new AggregateCount(); + aggregateCount.setCount(2L); + + Cursor cursor = mock(Cursor.class); + when(cursor.hasNext()).thenReturn(true).thenReturn(false); + when(cursor.next()).thenReturn(aggregateCount).thenThrow(NoSuchElementException.class); + + when(stmt.executeQuery()).thenReturn(cursor); + + HostRef hostRef = new HostRef("host-id", "host-name"); + VmInfo vmInfo = new VmInfo(); + dao.getCount(new VmRef(hostRef, vmInfo)); + + ArgumentCaptor descriptorCaptor = ArgumentCaptor.forClass(StatementDescriptor.class); + verify(storage).prepareStatement(descriptorCaptor.capture()); + StatementDescriptor descriptor = descriptorCaptor.getValue(); + assertThat(descriptor.getCategory(), is(dao.aggregateCountCategory)); + assertThat(descriptor.getDescriptor(), is(VmShenandoahDaoImpl.QUERY_COUNT_SHENANDOAH_STATS_BY_VM_ID)); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/common/src/test/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahStatCategoryRegistrationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/common/src/test/java/com/redhat/thermostat/vm/shenandoah/common/internal/VmShenandoahStatCategoryRegistrationTest.java Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.shenandoah.common.internal; + +import com.redhat.thermostat.storage.core.auth.CategoryRegistration; +import com.redhat.thermostat.testutils.ServiceLoaderTest; +import com.redhat.thermostat.vm.shenandoah.common.VmShenandoahDao; +import org.junit.Test; + +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class VmShenandoahStatCategoryRegistrationTest extends ServiceLoaderTest { + + public VmShenandoahStatCategoryRegistrationTest() { + super(CategoryRegistration.class, STORAGE_SERVICES, VmShenandoahStatCategoryRegistration.class); + } + + @Test + public void testRegistersAllCategories() { + VmShenandoahStatCategoryRegistration reg = new VmShenandoahStatCategoryRegistration(); + Set categories = reg.getCategoryNames(); + assertEquals(1, categories.size()); + assertFalse("null descriptor not allowed", categories.contains(null)); + assertTrue(categories.contains(VmShenandoahDao.VM_SHENANDOAH_STAT_CATEGORY.getName())); + } + +} diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/distribution/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/distribution/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,112 @@ + + + + 4.0.0 + + + com.redhat.thermostat + thermostat-vm-shenandoah + 1.99.12-SNAPSHOT + + + thermostat-vm-shenandoah-distribution + pom + + Thermostat Shenandoah GC plug-in - Distribution + + + vm-shenandoah + + + + + + maven-assembly-plugin + + + com.redhat.thermostat + thermostat-assembly + ${project.version} + + + + + plugin-assembly + + false + + + + assemble-plugin + package + + single + + + + + + + + + + + com.redhat.thermostat + thermostat-vm-shenandoah-agent + ${project.version} + + + com.redhat.thermostat + thermostat-vm-shenandoah-common + ${project.version} + + + com.redhat.thermostat + thermostat-vm-shenandoah-client-core + ${project.version} + + + com.redhat.thermostat + thermostat-vm-shenandoah-client-swing + ${project.version} + + + + diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/distribution/thermostat-plugin.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/distribution/thermostat-plugin.xml Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,58 @@ + + + + + + gui + + com.redhat.thermostat.vm.shenandoah.client.core${project.version} + com.redhat.thermostat.vm.shenandoah.client.swing${project.version} + + + + agent + + com.redhat.thermostat.vm.shenandoah.common${project.version} + com.redhat.thermostat.vm.shenandoah.agent${project.version} + + + + diff -r 3572e808e4cf -r f06bab050620 vm-shenandoah/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-shenandoah/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -0,0 +1,59 @@ + + + + 4.0.0 + + com.redhat.thermostat + thermostat + 1.99.12-SNAPSHOT + + + thermostat-vm-shenandoah + pom + + Thermostat Shenandoah GC plug-in + + + agent + common + client-core + client-swing + distribution + + \ No newline at end of file diff -r 3572e808e4cf -r f06bab050620 web/war/pom.xml --- a/web/war/pom.xml Thu Mar 09 13:36:40 2017 -0500 +++ b/web/war/pom.xml Mon Mar 06 09:38:30 2017 -0500 @@ -204,6 +204,11 @@ com.redhat.thermostat + thermostat-vm-shenandoah-common + ${project.version} + + + com.redhat.thermostat thermostat-vm-heap-analysis-common ${project.version}