Mercurial > hg > release > thermostat-1.2
changeset 1545:722862a0c335
Compiler project for prepared statement - part I
review-thread: http://icedtea.classpath.org/pipermail/thermostat/2014-November/011554.html
reviewed-by: omajid
line wrap: on
line diff
--- a/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/ThreadCollector.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/ThreadCollector.java Tue Nov 18 16:02:57 2014 +0100 @@ -39,6 +39,7 @@ import com.redhat.thermostat.common.model.Range; import com.redhat.thermostat.storage.dao.AgentInfoDAO; import com.redhat.thermostat.thread.dao.ThreadDao; +import com.redhat.thermostat.thread.model.SessionID; import com.redhat.thermostat.thread.model.ThreadContentionSample; import com.redhat.thermostat.thread.model.ThreadHeader; import com.redhat.thermostat.thread.model.ThreadState; @@ -54,9 +55,12 @@ boolean startHarvester(); boolean stopHarvester(); boolean isHarvesterCollecting(); - - ThreadSummary getLatestThreadSummary(); - List<ThreadSummary> getThreadSummary(long since); + + List<SessionID> getAvailableThreadSummarySessions(Range<Long> range); + SessionID getLastThreadSummarySession(); + + ThreadSummary getLatestThreadSummary(SessionID session); + List<ThreadSummary> getThreadSummary(SessionID session, Range<Long> range); /** * Return the range of all {@link ThreadState} data (timestamp of first and
--- a/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java Tue Nov 18 16:02:57 2014 +0100 @@ -49,6 +49,7 @@ import com.redhat.thermostat.thread.client.common.collector.ThreadCollector; import com.redhat.thermostat.thread.collector.HarvesterCommand; import com.redhat.thermostat.thread.dao.ThreadDao; +import com.redhat.thermostat.thread.model.SessionID; import com.redhat.thermostat.thread.model.ThreadContentionSample; import com.redhat.thermostat.thread.model.ThreadHarvestingStatus; import com.redhat.thermostat.thread.model.ThreadHeader; @@ -131,14 +132,33 @@ } return status.isHarvesting(); } - + + @Override + public List<SessionID> getAvailableThreadSummarySessions(Range<Long> range) { + return threadDao.getAvailableThreadSummarySessions(ref, range, Integer.MAX_VALUE); + } + @Override - public ThreadSummary getLatestThreadSummary() { - ThreadSummary summary = threadDao.loadLastestSummary(ref); - if (summary == null) { + public SessionID getLastThreadSummarySession() { + List<SessionID> sessions = + threadDao.getAvailableThreadSummarySessions(ref, + new Range<>(0l, Long.MAX_VALUE), + 1); + return sessions.isEmpty() ? null : sessions.get(0); + } + + @Override + public ThreadSummary getLatestThreadSummary(SessionID session) { + List<ThreadSummary> summaries = + threadDao.getSummary(ref, session, new Range<>(0l, Long.MAX_VALUE), 1); + ThreadSummary summary = null; + if (summaries.isEmpty()) { // default to all 0 summary = new ThreadSummary(); + } else { + summary = summaries.get(0); } + return summary; } @@ -158,8 +178,8 @@ } @Override - public List<ThreadSummary> getThreadSummary(long since) { - List<ThreadSummary> summary = threadDao.loadSummary(ref, since); + public List<ThreadSummary> getThreadSummary(SessionID session, Range<Long> range) { + List<ThreadSummary> summary = threadDao.getSummary(ref, session, range, Integer.MAX_VALUE); return summary; }
--- a/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadCountController.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadCountController.java Tue Nov 18 16:02:57 2014 +0100 @@ -36,6 +36,8 @@ package com.redhat.thermostat.thread.client.controller.impl; +import com.redhat.thermostat.common.model.Range; +import com.redhat.thermostat.thread.model.SessionID; import java.util.List; import java.util.concurrent.TimeUnit; @@ -65,17 +67,24 @@ @Override public void run() { + SessionID lastSession = collector.getLastThreadSummarySession(); + if (lastSession == null) { + return; + } + ThreadCountView view = (ThreadCountView) ThreadCountController.this.view; // load the very latest thread summary - ThreadSummary latestSummary = collector.getLatestThreadSummary(); + ThreadSummary latestSummary = collector.getLatestThreadSummary(lastSession); if (latestSummary.getTimeStamp() != 0) { view.setLiveThreads(Long.toString(latestSummary.getCurrentLiveThreads())); view.setDaemonThreads(Long.toString(latestSummary.getCurrentDaemonThreads())); } - + + long now = System.currentTimeMillis(); long lastHour = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1); - List<ThreadSummary> summaries = collector.getThreadSummary(lastHour); + + List<ThreadSummary> summaries = collector.getThreadSummary(lastSession, new Range<Long>(lastHour, now)); if (summaries.size() != 0) { for (ThreadSummary summary : summaries) { model.addData(summary.getTimeStamp(), summary.getCurrentLiveThreads(), summary.getCurrentDaemonThreads());
--- a/thread/client-controllers/src/test/java/com/redhat/thermostat/thread/client/controller/impl/ThreadCountControllerTest.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/client-controllers/src/test/java/com/redhat/thermostat/thread/client/controller/impl/ThreadCountControllerTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -36,20 +36,20 @@ package com.redhat.thermostat.thread.client.controller.impl; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.anyLong; - +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.Timer; +import com.redhat.thermostat.common.model.Range; +import com.redhat.thermostat.thread.client.common.chart.LivingDaemonThreadDifferenceChart; +import com.redhat.thermostat.thread.client.common.collector.ThreadCollector; +import com.redhat.thermostat.thread.client.common.view.ThreadCountView; +import com.redhat.thermostat.thread.model.SessionID; +import com.redhat.thermostat.thread.model.ThreadSummary; import java.awt.Color; import java.util.ArrayList; import java.util.List; - -import static org.junit.Assert.*; - import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; - import org.jfree.chart.JFreeChart; import org.jfree.data.xy.XYDataset; import org.junit.Before; @@ -57,14 +57,13 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -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.Timer; -import com.redhat.thermostat.thread.client.common.chart.LivingDaemonThreadDifferenceChart; -import com.redhat.thermostat.thread.client.common.collector.ThreadCollector; -import com.redhat.thermostat.thread.client.common.view.ThreadCountView; -import com.redhat.thermostat.thread.model.ThreadSummary; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; // this is not a GUI test, but testGetThreadInformation uses AWT under the hood @RunWith(CacioFESTRunner.class) @@ -110,13 +109,18 @@ List<ThreadSummary> summaries = new ArrayList<>(); summaries.add(summary); summaries.add(summary0); - - when(collector.getLatestThreadSummary()).thenReturn(summary); - when(collector.getThreadSummary(anyLong())).thenReturn(summaries); - + + SessionID lastSession = mock(SessionID.class); + when(collector.getLastThreadSummarySession()).thenReturn(lastSession); + + when(collector.getLatestThreadSummary(lastSession)).thenReturn(summary); + when(collector.getThreadSummary(any(SessionID.class), any(Range.class))).thenReturn(summaries); + threadAction = captor.getValue(); threadAction.run(); - + + verify(collector).getLatestThreadSummary(lastSession); + verify(view).setLiveThreads("42"); verify(view).setDaemonThreads("2");
--- a/thread/collector/pom.xml Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/pom.xml Tue Nov 18 16:02:57 2014 +0100 @@ -76,7 +76,13 @@ <artifactId>thermostat-client-command</artifactId> <version>${project.version}</version> </dependency> - + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-storage-testutils</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> @@ -115,6 +121,7 @@ <Private-Package> com.redhat.thermostat.thread.common.osgi, com.redhat.thermostat.thread.dao.impl, + com.redhat.thermostat.thread.dao.impl.descriptor, </Private-Package> <!-- Do not autogenerate uses clauses in Manifests --> <_nouses>true</_nouses>
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/ThreadDao.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/ThreadDao.java Tue Nov 18 16:02:57 2014 +0100 @@ -40,6 +40,7 @@ import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.Key; import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.thread.model.SessionID; import com.redhat.thermostat.thread.model.ThreadContentionSample; import com.redhat.thermostat.thread.model.ThreadHarvestingStatus; import com.redhat.thermostat.thread.model.ThreadHeader; @@ -59,21 +60,6 @@ static final String THREAD_ALLOCATED_MEMORY = "thread-allocated-memory"; /* - * vm-thread-summary schema - */ - static final Key<Long> LIVE_THREADS_KEY = new Key<Long>("currentLiveThreads"); - static final Key<Long> DAEMON_THREADS_KEY = new Key<Long>("currentDaemonThreads"); - static final Category<ThreadSummary> THREAD_SUMMARY = - new Category<>("vm-thread-summary", ThreadSummary.class, - Arrays.<Key<?>>asList( - Key.AGENT_ID, - Key.VM_ID, - Key.TIMESTAMP, - LIVE_THREADS_KEY, - DAEMON_THREADS_KEY), - Arrays.<Key<?>>asList(Key.TIMESTAMP)); - - /* * vm-thread-harvesting schema */ static final Key<Boolean> HARVESTING_STATUS_KEY = new Key<Boolean>("harvesting"); @@ -145,13 +131,9 @@ THREAD_CONTENTION_WAITED_TIME_KEY, THREAD_HEADER_UUID, Key.TIMESTAMP)); - /* - * API methods - */ - void saveSummary(ThreadSummary summary); - ThreadSummary loadLastestSummary(VmRef ref); - List<ThreadSummary> loadSummary(VmRef ref, long since); + List<ThreadSummary> getSummary(VmRef ref, SessionID session, Range<Long> range, int limit); + List<SessionID> getAvailableThreadSummarySessions(VmRef ref, Range<Long> range, int limit); /** * Gets the total time interval for the entire data related to
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOCategoryRegistration.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOCategoryRegistration.java Tue Nov 18 16:02:57 2014 +0100 @@ -57,7 +57,7 @@ categories.add(ThreadDao.THREAD_HARVESTING_STATUS.getName()); categories.add(ThreadDao.THREAD_HEADER.getName()); categories.add(ThreadDao.THREAD_STATE.getName()); - categories.add(ThreadDao.THREAD_SUMMARY.getName()); + categories.add(ThreadDaoCategories.THREAD_SUMMARY.getName()); categories.add(ThreadDao.THREAD_CONTENTION_SAMPLE.getName()); return categories; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoCategories.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,59 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.dao.impl; + +import com.redhat.thermostat.storage.core.Category; +import com.redhat.thermostat.storage.core.Key; +import com.redhat.thermostat.thread.model.ThreadSummary; +import java.util.Arrays; + +/** + * + */ +public class ThreadDaoCategories { + + public static final Category<ThreadSummary> THREAD_SUMMARY = + new Category<>("vm-thread-summary", ThreadSummary.class, + Arrays.<Key<?>>asList( + Key.AGENT_ID, + Key.VM_ID, + ThreadDaoKeys.SESSION, + Key.TIMESTAMP, + ThreadDaoKeys.LIVE_THREADS_KEY, + ThreadDaoKeys.DAEMON_THREADS_KEY), + Arrays.<Key<?>>asList(Key.TIMESTAMP, ThreadDaoKeys.SESSION)); +}
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Tue Nov 18 16:02:57 2014 +0100 @@ -49,13 +49,15 @@ import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.model.Pojo; import com.redhat.thermostat.thread.dao.ThreadDao; +import com.redhat.thermostat.thread.dao.impl.descriptor.SummaryDescriptor; +import com.redhat.thermostat.thread.dao.impl.descriptor.SummaryDescriptorBuilder; +import com.redhat.thermostat.thread.model.SessionID; import com.redhat.thermostat.thread.model.ThreadContentionSample; import com.redhat.thermostat.thread.model.ThreadHarvestingStatus; import com.redhat.thermostat.thread.model.ThreadHeader; import com.redhat.thermostat.thread.model.ThreadState; import com.redhat.thermostat.thread.model.ThreadSummary; import com.redhat.thermostat.thread.model.VmDeadLockData; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -65,20 +67,11 @@ public class ThreadDaoImpl implements ThreadDao { private static final Logger logger = LoggingUtils.getLogger(ThreadDaoImpl.class); - + + static final SummaryDescriptor SUMMARY = new SummaryDescriptorBuilder().build(); + // Queries - static final String QUERY_LATEST_SUMMARY = "QUERY " - + THREAD_SUMMARY.getName() + " WHERE '" - + Key.AGENT_ID.getName() + "' = ?s AND '" - + Key.VM_ID.getName() + "' = ?s SORT '" - + Key.TIMESTAMP.getName() + "' DSC LIMIT 1"; - static final String QUERY_SUMMARY_SINCE = "QUERY " - + THREAD_SUMMARY.getName() + " WHERE '" - + Key.AGENT_ID.getName() + "' = ?s AND '" - + Key.VM_ID.getName() + "' = ?s AND '" - + Key.TIMESTAMP.getName() + "' > ?l SORT '" - + Key.TIMESTAMP.getName() + "' DSC"; static final String QUERY_LATEST_HARVESTING_STATUS = "QUERY " + THREAD_HARVESTING_STATUS.getName() + " WHERE '" + Key.AGENT_ID.getName() + "' = ?s AND '" @@ -135,18 +128,7 @@ + THREAD_PROBE_START.getName() + "' ASC"; // Data modifying descriptors - - // ADD vm-thread-summary SET 'agentId' = ?s , \ - // 'vmId' = ?s , \ - // 'currentLiveThreads' = ?l , \ - // 'currentDaemonThreads' = ?l , \ - // 'timeStamp' = ?l - static final String DESC_ADD_THREAD_SUMMARY = "ADD " + THREAD_SUMMARY.getName() + - " SET '" + Key.AGENT_ID.getName() + "' = ?s , " + - "'" + Key.VM_ID.getName() + "' = ?s , " + - "'" + LIVE_THREADS_KEY.getName() + "' = ?l , " + - "'" + DAEMON_THREADS_KEY.getName() + "' = ?l , " + - "'" + Key.TIMESTAMP.getName() + "' = ?l"; + // ADD vm-thread-harvesting SET 'agentId' = ?s , \ // 'vmId' = ?s , \ // 'timeStamp' = ?l , \ @@ -211,7 +193,9 @@ public ThreadDaoImpl(Storage storage) { this.storage = storage; - storage.registerCategory(THREAD_SUMMARY); + + storage.registerCategory(SUMMARY.getCategory()); + storage.registerCategory(THREAD_HARVESTING_STATUS); storage.registerCategory(THREAD_HEADER); storage.registerCategory(THREAD_STATE); @@ -219,7 +203,7 @@ storage.registerCategory(DEADLOCK_INFO); } - + @Override public List<ThreadHeader> getThreads(VmRef ref) { @@ -469,41 +453,43 @@ @Override public void saveSummary(ThreadSummary summary) { - StatementDescriptor<ThreadSummary> desc = new StatementDescriptor<>(THREAD_SUMMARY, DESC_ADD_THREAD_SUMMARY); - PreparedStatement<ThreadSummary> prepared; + try { - prepared = storage.prepareStatement(desc); - prepared.setString(0, summary.getAgentId()); - prepared.setString(1, summary.getVmId()); - prepared.setLong(2, summary.getCurrentLiveThreads()); - prepared.setLong(3, summary.getCurrentDaemonThreads()); - prepared.setLong(4, summary.getTimeStamp()); - prepared.execute(); - } catch (DescriptorParsingException e) { - logger.log(Level.SEVERE, "Preparing stmt '" + desc + "' failed!", e); - } catch (StatementExecutionException e) { - logger.log(Level.SEVERE, "Executing stmt '" + desc + "' failed!", e); - } + SUMMARY.statementAdd(summary, storage); + + } catch (Exception ignore) { ignore.printStackTrace(); } } - + @Override - public ThreadSummary loadLastestSummary(VmRef ref) { - PreparedStatement<ThreadSummary> stmt = prepareQuery(THREAD_SUMMARY, QUERY_LATEST_SUMMARY, ref); - if (stmt == null) { - return null; - } - - return getFirstResult(stmt); + public List<ThreadSummary> getSummary(VmRef ref, SessionID session, Range<Long> range, int limit) { + + List<ThreadSummary> result = new ArrayList<>(); + try { + Cursor<ThreadSummary> cursor = SUMMARY.queryGet(ref, session, range, limit, storage); + while (cursor.hasNext()) { + ThreadSummary summary = cursor.next(); + result.add(summary); + } + } catch (Exception ignore) { ignore.printStackTrace(); } + + return result; } - + @Override - public List<ThreadSummary> loadSummary(VmRef ref, long since) { - PreparedStatement<ThreadSummary> stmt = prepareQuery(THREAD_SUMMARY, QUERY_SUMMARY_SINCE, ref, since, null); - if (stmt == null) { - return Collections.emptyList(); - } + public List<SessionID> getAvailableThreadSummarySessions(VmRef ref, Range<Long> range, int limit) { + List<SessionID> result = new ArrayList<>(); + + Cursor<ThreadSummary> cursor = null; - return getAllResults(stmt); + try { + cursor = SUMMARY.queryGet(ref, range, limit, storage); + while (cursor.hasNext()) { + ThreadSummary summary = cursor.next(); + result.add(new SessionID(summary.getSession())); + } + } catch (Exception ignore) { ignore.printStackTrace(); } + + return result; } @Override
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplStatementDescriptorRegistration.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplStatementDescriptorRegistration.java Tue Nov 18 16:02:57 2014 +0100 @@ -58,11 +58,11 @@ descs = new HashSet<>(); descs.add(ThreadDaoImpl.QUERY_LATEST_DEADLOCK_INFO); descs.add(ThreadDaoImpl.QUERY_LATEST_HARVESTING_STATUS); - descs.add(ThreadDaoImpl.QUERY_LATEST_SUMMARY); - descs.add(ThreadDaoImpl.QUERY_SUMMARY_SINCE); + + descs.addAll(ThreadDaoImpl.SUMMARY.describe()); + descs.add(ThreadDaoImpl.DESC_ADD_THREAD_DEADLOCK_DATA); descs.add(ThreadDaoImpl.DESC_ADD_THREAD_HARVESTING_STATUS); - descs.add(ThreadDaoImpl.DESC_ADD_THREAD_SUMMARY); descs.add(ThreadDaoImpl.ADD_THREAD_HEADER); descs.add(ThreadDaoImpl.QUERY_THREAD_HEADER);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoKeys.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.dao.impl; + +import com.redhat.thermostat.storage.core.Key; + +/** + * + */ +public class ThreadDaoKeys { + public static final Key<String> SESSION = new Key<>("session"); + + public static final Key<Long> LIVE_THREADS_KEY = new Key<Long>("currentLiveThreads"); + public static final Key<Long> DAEMON_THREADS_KEY = new Key<Long>("currentDaemonThreads"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/descriptor/Descriptor.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,58 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.dao.impl.descriptor; + +import com.redhat.thermostat.storage.core.Category; +import com.redhat.thermostat.storage.model.Pojo; +import java.util.Set; + +/** + * + */ +public abstract class Descriptor<T extends Pojo> { + + protected Category<T> category; + protected void setCategory(Category<T> category) { + this.category = category; + } + + public Category<T> getCategory() { + return category; + } + + public abstract Set<String> describe(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/descriptor/DescriptorBuilder.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.dao.impl.descriptor; + +import com.redhat.thermostat.storage.core.Category; +import com.redhat.thermostat.storage.model.Pojo; + +/** + * + */ +abstract class DescriptorBuilder<T extends Pojo> { + + protected String document; + protected Category<T> category; + + DescriptorBuilder(Category<T> category) { + this.document = category.getName(); + this.category = category; + } + + public Category<T> getCategory() { + return category; + } + + abstract public Descriptor<T> build(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/descriptor/SummaryDescriptor.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,171 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.dao.impl.descriptor; + +import com.redhat.thermostat.common.model.Range; +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.storage.core.Cursor; +import com.redhat.thermostat.storage.core.DescriptorParsingException; +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.thread.model.SessionID; +import com.redhat.thermostat.thread.model.ThreadSummary; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + */ +public class SummaryDescriptor extends Descriptor<ThreadSummary> { + + private static final Logger logger = LoggingUtils.getLogger(SummaryDescriptor.class); + + protected String rangeDesc; + protected String addDesc; + + protected String sessionsDesc; + + public Set<String> describe() { + Set<String> description = new HashSet<>(); + + description.add(rangeDesc); + description.add(addDesc); + description.add(sessionsDesc); + + return description; + } + + public Cursor<ThreadSummary> queryGet(VmRef ref, SessionID session, + Range<Long> range, int limit, + Storage storage) + throws DescriptorParsingException, StatementExecutionException + { + // "QUERY vm-thread-summary WHERE 'session' = ?s + // AND 'timeStamp' >= ?l + // AND 'timeStamp' <= ?l SORT 'timeStamp' DSC"; + + StatementDescriptor<ThreadSummary> desc = null; + try { + desc = new StatementDescriptor<>(getCategory(), rangeDesc); + PreparedStatement<ThreadSummary> prepared = + storage.prepareStatement(desc); + + int i = 0; + prepared.setString(i++, session.getId()); + + prepared.setLong(i++, range.getMin()); + prepared.setLong(i++, range.getMax()); + + prepared.setInt(i++, limit); + + return prepared.executeQuery(); + + } catch (Exception e) { + logger.log(Level.WARNING, + "exception executing statement: " + desc, e); + throw e; + } + } + + public Cursor<ThreadSummary> queryGet(VmRef ref, Range<Long> range, + int limit, Storage storage) + throws DescriptorParsingException, StatementExecutionException + { + // "QUERY vm-thread-summary WHERE 'vmId' = ?s , 'timeStamp' >= ?l + // AND 'timeStamp' <= ?l SORT 'timeStamp' DSC LIMIT ?i"; + + StatementDescriptor<ThreadSummary> desc = null; + try { + desc = new StatementDescriptor<>(getCategory(), sessionsDesc); + PreparedStatement<ThreadSummary> prepared = + storage.prepareStatement(desc); + + int i = 0; + prepared.setString(i++, ref.getVmId()); + + prepared.setLong(i++, range.getMin()); + prepared.setLong(i++, range.getMax()); + + prepared.setInt(i++, limit); + + return prepared.executeQuery(); + + } catch (Exception e) { + logger.log(Level.WARNING, + "exception executing statement: " + desc, e); + throw e; + } + } + + public void statementAdd(ThreadSummary summary, Storage storage) + throws DescriptorParsingException, StatementExecutionException + { + + // "ADD vm-thread-summary SET 'agentId' = ?s , 'vmId' = ?s , + // 'session' = ?s , 'currentLiveThreads' = ?l , + // 'currentDaemonThreads' = ?l , 'timeStamp' = ?l"; + + StatementDescriptor<ThreadSummary> desc = + new StatementDescriptor<>(getCategory(), addDesc); + + PreparedStatement<ThreadSummary> prepared; + try { + + prepared = storage.prepareStatement(desc); + + int i = 0; + prepared.setString(i++, summary.getAgentId()); + prepared.setString(i++, summary.getVmId()); + prepared.setString(i++, summary.getSession()); + + prepared.setLong(i++, summary.getCurrentLiveThreads()); + prepared.setLong(i++, summary.getCurrentDaemonThreads()); + prepared.setLong(i++, summary.getTimeStamp()); + + prepared.execute(); + + } catch (Exception e) { + logger.log(Level.WARNING, "exception executing statement: " + desc, e); + throw e; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/descriptor/SummaryDescriptorBuilder.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,96 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.dao.impl.descriptor; + +import com.redhat.thermostat.storage.core.Key; +import com.redhat.thermostat.thread.dao.impl.ThreadDaoCategories; +import com.redhat.thermostat.thread.dao.impl.ThreadDaoKeys; +import com.redhat.thermostat.thread.model.ThreadSummary; + +/** + * + */ +public class SummaryDescriptorBuilder extends DescriptorBuilder<ThreadSummary> { + + public SummaryDescriptorBuilder() { + super(ThreadDaoCategories.THREAD_SUMMARY); + } + + @Override + public SummaryDescriptor build() { + + SummaryDescriptor descriptor = new SummaryDescriptor(); + descriptor.setCategory(category); + + StringBuilder querySessions = new StringBuilder(); + querySessions.append("QUERY").append(" "); + querySessions.append(document).append(" "); + querySessions.append("WHERE").append(" '"); + querySessions.append(Key.VM_ID.getName()).append("' = ?s AND '"); + querySessions.append(Key.TIMESTAMP.getName()).append("' >= ?l AND '"); + querySessions.append(Key.TIMESTAMP.getName()).append("' <= ?l SORT '"); + querySessions.append(Key.TIMESTAMP.getName()).append("' DSC LIMIT ?i"); + + descriptor.sessionsDesc = querySessions.toString(); + + StringBuilder summarySinceBuilder = new StringBuilder(); + summarySinceBuilder.append("QUERY").append(" "); + summarySinceBuilder.append(document).append(" "); + summarySinceBuilder.append("WHERE").append(" '"); + summarySinceBuilder.append(ThreadDaoKeys.SESSION.getName()).append("' = ?s AND '"); + summarySinceBuilder.append(Key.TIMESTAMP.getName()).append("' >= ?l AND '"); + summarySinceBuilder.append(Key.TIMESTAMP.getName()).append("' <= ?l SORT '"); + summarySinceBuilder.append(Key.TIMESTAMP.getName()).append("' DSC LIMIT ?i"); + + descriptor.rangeDesc = summarySinceBuilder.toString(); + + StringBuilder addDesc = new StringBuilder(); + addDesc.append("ADD").append(" "); + addDesc.append(document).append(" "); + addDesc.append("SET '"); + addDesc.append(Key.AGENT_ID.getName()).append("' = ?s , '"); + addDesc.append(Key.VM_ID.getName()).append("' = ?s , '"); + addDesc.append(ThreadDaoKeys.SESSION.getName()).append("' = ?s , '"); + addDesc.append(ThreadDaoKeys.LIVE_THREADS_KEY.getName()).append("' = ?l , '"); + addDesc.append(ThreadDaoKeys.DAEMON_THREADS_KEY.getName()).append("' = ?l , '"); + addDesc.append(Key.TIMESTAMP.getName()).append("' = ?l"); + + descriptor.addDesc = addDesc.toString(); + + return descriptor; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/model/SessionID.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,77 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.model; + +import java.util.UUID; + +/** + * + */ +public class SessionID { + + private String id; + + public SessionID() { + id = UUID.randomUUID().toString(); + } + + public SessionID(String id) { + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SessionID sessionID = (SessionID) o; + + if (id != null ? !id.equals(sessionID.id) : sessionID.id != null) + return false; + + return true; + } + + public String getId() { + return id; + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } +}
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/model/ThreadPojo.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/model/ThreadPojo.java Tue Nov 18 16:02:57 2014 +0100 @@ -45,6 +45,7 @@ private ThreadHeader header; private String referenceID; + private String sessionID; private String vmId; @@ -88,6 +89,15 @@ return referenceID; } + @Persist + public void setSessionID(String sessionID) { + this.sessionID = sessionID; + } + + public String getSessionID() { + return sessionID; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -98,6 +108,8 @@ if (header != null ? !header.equals(that.header) : that.header != null) return false; + if (sessionID != null ? !sessionID.equals(that.sessionID) : that.sessionID != null) + return false; return true; } @@ -106,6 +118,7 @@ public int hashCode() { int result = super.hashCode(); result = 31 * result + (header != null ? header.hashCode() : 0); + result = 31 * result + (sessionID != null ? sessionID.hashCode() : 0); return result; } }
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/model/ThreadSummary.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/model/ThreadSummary.java Tue Nov 18 16:02:57 2014 +0100 @@ -51,6 +51,8 @@ private long timestamp; + private String session; + public ThreadSummary() { this(null); } @@ -98,11 +100,21 @@ public void setTimeStamp(long timestamp) { this.timestamp = timestamp; } - + @Override public String toString() { return "[timestamp: " + timestamp + ", currentLiveThreads: " + currentLiveThreads + ", daemonThreads: " + daemonThreads + "]"; } + + @Persist + public void setSession(String session) { + this.session = session; + } + + @Persist + public String getSession() { + return session; + } }
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOCategoryRegistrationTest.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOCategoryRegistrationTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -63,7 +63,7 @@ assertTrue(categories.contains(ThreadDao.DEADLOCK_INFO.getName())); assertTrue(categories.contains(ThreadDao.THREAD_HEADER.getName())); assertTrue(categories.contains(ThreadDao.THREAD_STATE.getName())); - assertTrue(categories.contains(ThreadDao.THREAD_SUMMARY.getName())); + assertTrue(categories.contains(ThreadDaoCategories.THREAD_SUMMARY.getName())); assertTrue(categories.contains(ThreadDao.THREAD_HARVESTING_STATUS.getName())); assertTrue(categories.contains(ThreadDao.THREAD_CONTENTION_SAMPLE.getName())); }
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementDescriptorRegistrationTest.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementDescriptorRegistrationTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -146,16 +146,7 @@ DescriptorMetadata data = factory.getDescriptorMetadata(ThreadDaoImpl.QUERY_LATEST_HARVESTING_STATUS, triple.third); assertThreadMetadata(triple, data); } - - @Test - public void canGetMetadataForLatestSummaryQuery() { - Triple<String, String, PreparedParameter[]> triple = setupForMetaDataTest(); - - StatementDescriptorMetadataFactory factory = new ThreadDaoImplStatementDescriptorRegistration(); - DescriptorMetadata data = factory.getDescriptorMetadata(ThreadDaoImpl.QUERY_LATEST_SUMMARY, triple.third); - assertThreadMetadata(triple, data); - } - + @Test public void canGetMetadataForThreadHeader() { Triple<String, String, PreparedParameter[]> triple = setupForMetaDataTest(); @@ -213,15 +204,7 @@ assertNull(data.getVmId()); } - @Test - public void canGetMetadataQuerySummarySince() { - Triple<String, String, PreparedParameter[]> triple = setupForMetaDataTest(); - StatementDescriptorMetadataFactory factory = new ThreadDaoImplStatementDescriptorRegistration(); - DescriptorMetadata data = factory.getDescriptorMetadata(ThreadDaoImpl.QUERY_SUMMARY_SINCE, triple.third); - assertThreadMetadata(triple, data); - } - @Test public void canGetMetadataOldestThreadState() { Triple<String, String, PreparedParameter[]> triple = setupForMetaDataTest();
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -89,12 +89,6 @@ @Test public void preparedQueryDescriptorsAreSane() { - String expectedQueryLatestSummary = "QUERY vm-thread-summary WHERE 'agentId' = ?s AND 'vmId' = ?s SORT 'timeStamp' DSC LIMIT 1"; - assertEquals(expectedQueryLatestSummary, ThreadDaoImpl.QUERY_LATEST_SUMMARY); - - String expectedQuerySummarySince = "QUERY vm-thread-summary WHERE 'agentId' = ?s AND 'vmId' = ?s AND 'timeStamp' > ?l SORT 'timeStamp' DSC"; - assertEquals(expectedQuerySummarySince, ThreadDaoImpl.QUERY_SUMMARY_SINCE); - String expectedQueryLatestHarvestingStatus = "QUERY vm-thread-harvesting WHERE 'agentId' = ?s AND 'vmId' = ?s SORT 'timeStamp' DSC LIMIT 1"; assertEquals(expectedQueryLatestHarvestingStatus, ThreadDaoImpl.QUERY_LATEST_HARVESTING_STATUS); @@ -113,13 +107,6 @@ String expectedQueryThreadLatestDeadlockInfo = "QUERY vm-deadlock-data WHERE 'agentId' = ?s AND 'vmId' = ?s SORT 'timeStamp' DSC LIMIT 1"; assertEquals(expectedQueryThreadLatestDeadlockInfo, ThreadDaoImpl.QUERY_LATEST_DEADLOCK_INFO); - String addThreadSummary = "ADD vm-thread-summary SET 'agentId' = ?s , " + - "'vmId' = ?s , " + - "'currentLiveThreads' = ?l , " + - "'currentDaemonThreads' = ?l , " + - "'timeStamp' = ?l"; - assertEquals(addThreadSummary, ThreadDaoImpl.DESC_ADD_THREAD_SUMMARY); - String addThreadHarvesting = "ADD vm-thread-harvesting SET 'agentId' = ?s , " + "'vmId' = ?s , " + "'timeStamp' = ?l , " + @@ -176,7 +163,7 @@ ThreadDaoImpl dao = new ThreadDaoImpl(storage); verify(storage).registerCategory(ThreadDao.THREAD_HARVESTING_STATUS); - verify(storage).registerCategory(ThreadDao.THREAD_SUMMARY); + verify(storage).registerCategory(ThreadDaoCategories.THREAD_SUMMARY); } @SuppressWarnings("unchecked")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/descriptor/SummaryDescriptorBuilderTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,90 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.dao.impl.descriptor; + +import com.redhat.thermostat.storage.core.StatementDescriptor; +import com.redhat.thermostat.storage.testutils.StatementDescriptorTester; +import com.redhat.thermostat.thread.dao.impl.ThreadDaoCategories; +import com.redhat.thermostat.thread.model.ThreadSummary; +import junit.framework.TestCase; +import org.junit.Test; + +public class SummaryDescriptorBuilderTest extends TestCase { + + @Test + public void testBuild() { + + SummaryDescriptor summary = new SummaryDescriptorBuilder().build(); + assertNotNull(summary); + } + + @Test + public void testCategory() { + + SummaryDescriptor summary = new SummaryDescriptorBuilder().build(); + assertEquals(ThreadDaoCategories.THREAD_SUMMARY, summary.getCategory()); + } + + @Test + public void testAddDesc() throws Exception { + SummaryDescriptor summary = new SummaryDescriptorBuilder().build(); + testStatement(summary.addDesc); + } + + @Test + public void testRangeDesc() throws Exception { + + SummaryDescriptor summary = new SummaryDescriptorBuilder().build(); + testStatement(summary.rangeDesc); + } + + @Test + public void testSessionDesc() throws Exception { + + SummaryDescriptor summary = new SummaryDescriptorBuilder().build(); + testStatement(summary.sessionsDesc); + } + + private void testStatement(String statement) throws Exception { + + StatementDescriptorTester<ThreadSummary> tester = new StatementDescriptorTester<>(); + StatementDescriptor<ThreadSummary> desc = + new StatementDescriptor<>(ThreadDaoCategories.THREAD_SUMMARY, statement); + tester.testParseBasic(desc); + tester.testParseSemantic(desc); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/descriptor/SummaryDescriptorTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -0,0 +1,72 @@ +/* + * Copyright 2012-2014 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 + * <http://www.gnu.org/licenses/>. + * + * 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.thread.dao.impl.descriptor; + +import junit.framework.TestCase; +import org.junit.Before; + +public class SummaryDescriptorTest extends TestCase { + + private SummaryDescriptor descriptor; + @Before + public void setUp() { + descriptor = new SummaryDescriptorBuilder().build(); + } + + public void testGetSummaryRange() throws Exception { + + String expected = + "QUERY vm-thread-summary WHERE 'session' = ?s AND 'timeStamp' >= ?l AND 'timeStamp' <= ?l SORT 'timeStamp' DSC LIMIT ?i"; + assertEquals(expected, descriptor.rangeDesc); + } + + public void testGetSessionsRange() throws Exception { + + String expected = + "QUERY vm-thread-summary WHERE 'vmId' = ?s AND 'timeStamp' >= ?l AND 'timeStamp' <= ?l SORT 'timeStamp' DSC LIMIT ?i"; + assertEquals(expected, descriptor.sessionsDesc); + + } + + public void testAddSummary() throws Exception { + + String expected = + "ADD vm-thread-summary SET 'agentId' = ?s , 'vmId' = ?s , 'session' = ?s , 'currentLiveThreads' = ?l , 'currentDaemonThreads' = ?l , 'timeStamp' = ?l"; + assertEquals(expected, descriptor.addDesc); + + } +}
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/Harvester.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/Harvester.java Tue Nov 18 16:02:57 2014 +0100 @@ -42,6 +42,7 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.thread.dao.ThreadDao; +import com.redhat.thermostat.thread.model.SessionID; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.util.concurrent.ScheduledExecutorService; @@ -102,7 +103,7 @@ return false; } - harvester = threadPool.scheduleAtFixedRate(new HarvesterAction(), + harvester = threadPool.scheduleAtFixedRate(new HarvesterAction(true), DEFAULT_INITIAL_DELAY, DEFAULT_PERIOD, DEFAULT_TIME_UNIT); @@ -195,6 +196,14 @@ } private class HarvesterAction implements Runnable { + + private boolean newSession; + private SessionID sessionID; + + private HarvesterAction(boolean newSession) { + this.newSession = newSession; + } + @Override public void run() { if (collectorBean == null) { @@ -220,7 +229,13 @@ } } catch (UnsupportedOperationException ignore) {} - harvesterHelper.collectAndSaveThreadData(collectorBean); + if (newSession) { + sessionID = new SessionID(); + newSession = false; + } + + harvesterHelper.collectAndSaveThreadData(sessionID, collectorBean); + } else { logger.log(Level.WARNING, "ThreadMXBean is null, is JMX available?"); }
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/HarvesterHelper.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/HarvesterHelper.java Tue Nov 18 16:02:57 2014 +0100 @@ -41,6 +41,7 @@ import com.redhat.thermostat.thread.dao.ThreadDao; import com.redhat.thermostat.thread.model.ThreadContentionSample; import com.redhat.thermostat.thread.model.ThreadHeader; +import com.redhat.thermostat.thread.model.SessionID; import com.redhat.thermostat.thread.model.ThreadState; import com.redhat.thermostat.thread.model.ThreadSummary; import java.lang.management.ThreadInfo; @@ -83,11 +84,14 @@ this.contentionHelper = contentionHelper; } - synchronized void collectAndSaveThreadData(ThreadMXBean collectorBean) { + synchronized void collectAndSaveThreadData(SessionID session, + ThreadMXBean collectorBean) + { long timestamp = clock.getRealTimeMillis(); ThreadSummary summary = summaryHelper.createThreadSummary(collectorBean, - timestamp); + timestamp, + session); summaryHelper.saveSummary(summary); // this two can't be null, but the check is there to allow for
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadStateHelper.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadStateHelper.java Tue Nov 18 16:02:57 2014 +0100 @@ -54,7 +54,8 @@ this.vmId = vmId; this.threadDao = threadDao; } - +iqQ:q! + public ThreadState createThreadState(ThreadHeader header, ThreadInfo beanInfo, long timestamp) {
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadSummaryHelper.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadSummaryHelper.java Tue Nov 18 16:02:57 2014 +0100 @@ -38,6 +38,7 @@ import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.thread.dao.ThreadDao; +import com.redhat.thermostat.thread.model.SessionID; import com.redhat.thermostat.thread.model.ThreadSummary; import java.lang.management.ThreadMXBean; @@ -56,7 +57,7 @@ this.threadDao = threadDao; } - ThreadSummary createThreadSummary(ThreadMXBean collectorBean, long timestamp) { + ThreadSummary createThreadSummary(ThreadMXBean collectorBean, long timestamp, SessionID session) { String wId = writerId.getWriterID(); @@ -67,6 +68,8 @@ summary.setTimeStamp(timestamp); summary.setVmId(vmId); + summary.setSession(session.getId()); + return summary; }
--- a/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterHelperTest.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterHelperTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -38,15 +38,15 @@ import com.redhat.thermostat.common.Clock; import com.redhat.thermostat.thread.dao.ThreadDao; +import com.redhat.thermostat.thread.model.SessionID; import com.redhat.thermostat.thread.model.ThreadHeader; import com.redhat.thermostat.thread.model.ThreadState; import com.redhat.thermostat.thread.model.ThreadSummary; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import org.junit.Before; import org.junit.Test; -import java.lang.management.ThreadInfo; -import java.lang.management.ThreadMXBean; - import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; @@ -71,7 +71,7 @@ private ThreadContentionHelper contentionHelper; private ThreadMXBean collectorBean; - + private SessionID sessionID; @Before public void setUp() { summaryHelper = mock(ThreadSummaryHelper.class); @@ -87,6 +87,8 @@ when(clock.getRealTimeMillis()).thenReturn(DEFAULT_TIMESTAMP); vmId = "42"; + + sessionID = new SessionID("0xcafe"); } @Test @@ -94,7 +96,8 @@ ThreadSummary summary = mock(ThreadSummary.class); when(summaryHelper.createThreadSummary(collectorBean, - DEFAULT_TIMESTAMP)). + DEFAULT_TIMESTAMP, + sessionID)). thenReturn(summary); HarvesterHelper harvester = new HarvesterHelper(threadDao, clock, vmId, @@ -102,11 +105,12 @@ headerHelper, stateHelper, contentionHelper); - harvester.collectAndSaveThreadData(collectorBean); + harvester.collectAndSaveThreadData(sessionID, collectorBean); verify(clock).getRealTimeMillis(); verify(summaryHelper).createThreadSummary(collectorBean, - DEFAULT_TIMESTAMP); + DEFAULT_TIMESTAMP, + sessionID); verify(summaryHelper).saveSummary(summary); } @@ -121,7 +125,7 @@ headerHelper, stateHelper, contentionHelper); - harvester.collectAndSaveThreadData(collectorBean); + harvester.collectAndSaveThreadData(sessionID, collectorBean); verify(collectorBean).getAllThreadIds(); verify(collectorBean).getThreadInfo(ids, true, true); @@ -164,7 +168,7 @@ headerHelper, stateHelper, contentionHelper); - harvester.collectAndSaveThreadData(collectorBean); + harvester.collectAndSaveThreadData(sessionID, collectorBean); verify(headerHelper, times(2)).checkAndSaveThreadHeader(header1); verify(headerHelper).checkAndSaveThreadHeader(header2);
--- a/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterTest.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -40,6 +40,7 @@ import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.thread.dao.ThreadDao; +import com.redhat.thermostat.thread.model.SessionID; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -56,6 +57,7 @@ import static junit.framework.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -101,7 +103,6 @@ thenReturn(null); HarvesterHelper helper = mock(HarvesterHelper.class); - Harvester harvester = new Harvester(pid, executor, pool, helper, deadlockHelper); @@ -125,7 +126,6 @@ // Mostly the same as testStart, but we call harvester.start() twice HarvesterHelper helper = mock(HarvesterHelper.class); - Harvester harvester = new Harvester(pid, executor, pool, helper, deadlockHelper); @@ -150,7 +150,6 @@ thenReturn(future); HarvesterHelper helper = mock(HarvesterHelper.class); - Harvester harvester = new Harvester(pid, executor, pool, helper, deadlockHelper); @@ -174,7 +173,6 @@ thenReturn(future); HarvesterHelper helper = mock(HarvesterHelper.class); - Harvester harvester = new Harvester(pid, executor, pool, helper, deadlockHelper); @@ -200,7 +198,6 @@ thenReturn(future); HarvesterHelper helper = mock(HarvesterHelper.class); - Harvester harvester = new Harvester(pid, executor, pool, helper, deadlockHelper); @@ -234,7 +231,6 @@ HarvesterHelper helper = mock(HarvesterHelper.class); - Harvester harvester = new Harvester(pid, executor, pool, helper, deadlockHelper); @@ -245,7 +241,7 @@ harvesterRunnable.run(); - verify(helper).collectAndSaveThreadData(sunBean); + verify(helper).collectAndSaveThreadData(any(SessionID.class), eq(sunBean)); } @Test @@ -281,7 +277,7 @@ harvesterRunnable.run(); - verify(helper).collectAndSaveThreadData(mxBean); + verify(helper).collectAndSaveThreadData(any(SessionID.class), eq(mxBean)); } @Test @@ -289,6 +285,7 @@ final ThreadMXBean mxBean = mock(ThreadMXBean.class); HarvesterHelper helper = mock(HarvesterHelper.class); + Harvester harvester = new Harvester(pid, executor, pool, helper, deadlockHelper) { @@ -313,6 +310,7 @@ final ThreadMXBean mxBean = mock(ThreadMXBean.class); HarvesterHelper helper = mock(HarvesterHelper.class); + Harvester harvester = new Harvester(pid, executor, pool, helper, deadlockHelper) {
--- a/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/ThreadHarvesterTest.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/ThreadHarvesterTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -118,7 +118,7 @@ public void testStop() { ThreadDao dao = mock(ThreadDao.class); Request request = mock(Request.class); - + final Harvester harverster = mock(Harvester.class); ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
--- a/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/ThreadSummaryHelperTest.java Wed Nov 05 16:55:16 2014 +0100 +++ b/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/ThreadSummaryHelperTest.java Tue Nov 18 16:02:57 2014 +0100 @@ -38,12 +38,12 @@ import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.thread.dao.ThreadDao; +import com.redhat.thermostat.thread.model.SessionID; import com.redhat.thermostat.thread.model.ThreadSummary; +import java.lang.management.ThreadMXBean; import org.junit.Before; import org.junit.Test; -import java.lang.management.ThreadMXBean; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; @@ -64,6 +64,8 @@ private ThreadMXBean collectorBean; + private SessionID sessionID; + @Before public void setUp() throws Exception { vmId = "testVM"; @@ -75,6 +77,8 @@ collectorBean = mock(ThreadMXBean.class); when(collectorBean.getThreadCount()).thenReturn(DEFAULT_THREAD_COUNT); when(collectorBean.getDaemonThreadCount()).thenReturn(DEFAULT_DAEMON_THREAD_COUNT); + + sessionID = new SessionID("0xcafe"); } @Test @@ -84,7 +88,7 @@ long timestamp = -1l; - ThreadSummary summary = helper.createThreadSummary(collectorBean, timestamp); + ThreadSummary summary = helper.createThreadSummary(collectorBean, timestamp, sessionID); assertNotNull(summary); @@ -95,6 +99,8 @@ assertEquals(summary.getAgentId(), DEFAULT_W_ID); assertEquals(summary.getVmId(), vmId); + assertEquals(summary.getSession(), sessionID.getId()); + assertEquals(summary.getCurrentLiveThreads(), DEFAULT_THREAD_COUNT); assertEquals(summary.getCurrentDaemonThreads(), DEFAULT_DAEMON_THREAD_COUNT); assertEquals(summary.getTimeStamp(), timestamp);