Mercurial > hg > release > thermostat-0.15
changeset 1183:9ec44cd38946
Implement mechanism so as to allow only trusted stmt descriptors.
Reviewed-by: ebaron
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-July/007598.html
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host-cpu/common/src/main/java/com/redhat/thermostat/host/cpu/common/internal/CpuStatDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright 2012, 2013 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.host.cpu.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.host.cpu.common.CpuStatDAO; +import com.redhat.thermostat.storage.core.HostLatestPojoListGetter; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +/** + * Registers the prepared query issued by this maven module via + * {@link HostLatestPojoListGetter}. + * + */ +public class CpuStatDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(); + String descriptor = String.format( + HostLatestPojoListGetter.HOST_LATEST_QUERY_FORMAT, + CpuStatDAO.cpuStatCategory.getName()); + descs.add(descriptor); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host-cpu/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.host.cpu.common.internal.CpuStatDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host-cpu/common/src/test/java/com/redhat/thermostat/host/cpu/common/internal/CpuStatDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 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.host.cpu.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class CpuStatDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + CpuStatDAOImplStatementDescriptorRegistration reg = new CpuStatDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(1, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(CpuStatDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, CpuStatDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration cpuStatReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(CpuStatDAOImplStatementDescriptorRegistration.class.getName())) { + cpuStatReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(cpuStatReg); + assertEquals(1, cpuStatReg.getStatementDescriptors().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host-memory/common/src/main/java/com/redhat/thermostat/host/memory/common/internal/MemoryStatDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright 2012, 2013 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.host.memory.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.host.memory.common.MemoryStatDAO; +import com.redhat.thermostat.storage.core.HostLatestPojoListGetter; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +/** + * Registers the prepared query issued by this maven module via + * {@link HostLatestPojoListGetter}. + * + */ +public class MemoryStatDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(1); + String descriptor = String.format(HostLatestPojoListGetter.HOST_LATEST_QUERY_FORMAT, + MemoryStatDAO.memoryStatCategory.getName()); + descs.add(descriptor); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host-memory/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.host.memory.common.internal.MemoryStatDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host-memory/common/src/test/java/com/redhat/thermostat/host/memory/common/internal/MemoryStatDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 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.host.memory.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class MemoryStatDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + MemoryStatDAOImplStatementDescriptorRegistration reg = new MemoryStatDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(1, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(MemoryStatDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, MemoryStatDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration memoryStatReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(MemoryStatDAOImplStatementDescriptorRegistration.class.getName())) { + memoryStatReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(memoryStatReg); + assertEquals(1, memoryStatReg.getStatementDescriptors().size()); + } +}
--- a/integration-tests/src/test/java/com/redhat/thermostat/itest/WebAppTest.java Wed Jul 24 13:56:13 2013 -0400 +++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/WebAppTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -40,6 +40,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.File; @@ -50,8 +51,12 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Properties; +import java.util.Set; import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; @@ -73,6 +78,8 @@ import com.redhat.thermostat.storage.core.Connection.ConnectionListener; import com.redhat.thermostat.storage.core.Connection.ConnectionStatus; import com.redhat.thermostat.storage.core.Cursor; +import com.redhat.thermostat.storage.core.DescriptorParsingException; +import com.redhat.thermostat.storage.core.IllegalDescriptorException; import com.redhat.thermostat.storage.core.PreparedStatement; import com.redhat.thermostat.storage.core.StatementDescriptor; import com.redhat.thermostat.storage.core.StatementExecutionException; @@ -106,6 +113,49 @@ */ public class WebAppTest extends IntegrationTest { + /* + * Registry of descriptors this test needs to allow in order to avoid + * illegal statement descriptor exceptions being thrown. See also: + * WebAppTestStatementDescriptorRegistration + */ + public static final Set<String> TRUSTED_DESCRIPTORS; + // descriptive name -> descriptor mapping + private static final Map<String, String> DESCRIPTOR_MAP; + + private static final String KEY_AUTHORIZED_QUERY = "authorizedQuery"; + private static final String KEY_AUTHORIZED_QUERY_EQUAL_TO = "authorizedQueryEqualTo"; + private static final String KEY_AUTHORIZED_QUERY_NOT_EQUAL_TO = "authorizedQueryNotEqualTo"; + private static final String KEY_AUTHORIZED_QUERY_GREATER_THAN = "authorizedQueryGreaterThan"; + private static final String KEY_AUTHORIZED_QUERY_GREATER_THAN_OR_EQUAL_TO = "authorizedQueryGreaterThanOrEqualTo"; + private static final String KEY_AUTHORIZED_QUERY_LESS_THAN = "authorizedQueryLessThan"; + private static final String KEY_AUTHORIZED_QUERY_LESS_THAN_OR_EQUAL_TO = "authorizedQueryLessThanOrEqualTo"; + private static final String KEY_AUTHORIZED_QUERY_NOT = "authorizedQueryNot"; + private static final String KEY_AUTHORIZED_QUERY_AND = "authorizedQueryAnd"; + private static final String KEY_AUTHORIZED_QUERY_OR = "authorizedQueryOr"; + private static final String KEY_SET_DEFAULT_AGENT_ID = "setDefaultAgentID"; + + static { + Map<String, String> descMap = new HashMap<>(); + descMap.put(KEY_AUTHORIZED_QUERY, "QUERY cpu-stats SORT ?s ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_EQUAL_TO, "QUERY cpu-stats WHERE 'timeStamp' = ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_NOT_EQUAL_TO, "QUERY cpu-stats WHERE 'timeStamp' != ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_GREATER_THAN, "QUERY cpu-stats WHERE 'timeStamp' > ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_GREATER_THAN_OR_EQUAL_TO, "QUERY cpu-stats WHERE 'timeStamp' >= ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_LESS_THAN, "QUERY cpu-stats WHERE 'timeStamp' < ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_LESS_THAN_OR_EQUAL_TO, "QUERY cpu-stats WHERE 'timeStamp' <= ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_NOT, "QUERY cpu-stats WHERE NOT 'timeStamp' > ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_AND, "QUERY cpu-stats WHERE 'timeStamp' > 0 AND 'timeStamp' < ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_AUTHORIZED_QUERY_OR, "QUERY cpu-stats WHERE 'timeStamp' > ?l OR 'timeStamp' < ?l SORT 'timeStamp' ASC"); + descMap.put(KEY_SET_DEFAULT_AGENT_ID, "QUERY vm-cpu-stats"); + Set<String> trustedDescriptors = new HashSet<>(); + for (String val: descMap.values()) { + trustedDescriptors.add(val); + } + TRUSTED_DESCRIPTORS = trustedDescriptors; + DESCRIPTOR_MAP = descMap; + } + + private static class CountdownConnectionListener implements ConnectionListener { private final ConnectionStatus target; @@ -287,6 +337,14 @@ String version = appInfo.getMavenVersion(); String warfile = "target/libs/thermostat-web-war-" + version + ".war"; WebAppContext ctx = new WebAppContext(warfile, "/thermostat"); + + // We need to set this to true in order for WebStorageEndPoint to pick + // up the descriptor registrations from WebAppTestStatementDescriptorRegistration + // which would result in + // "java.util.ServiceConfigurationError: com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration: Provider com.redhat.thermostat.itest.WebAppTestStatementDescriptorRegistration not a subtype" + // errors. + ctx.setParentLoaderPriority(true); + WebAppContextListener listener = new WebAppContextListener(contextStartedLatch); ctx.addLifeCycleListener(listener); /* The web archive has a jetty-web.xml config file which sets up the @@ -404,7 +462,7 @@ webStorage.getConnection().disconnect(); } - + @Test public void authorizedQuery() throws Exception { @@ -418,7 +476,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats SORT ?s ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); @@ -442,7 +500,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE 'timeStamp' = ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_EQUAL_TO); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2l); @@ -465,7 +523,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE 'timeStamp' != ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_NOT_EQUAL_TO); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2l); @@ -488,7 +546,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE 'timeStamp' > ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_GREATER_THAN); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2l); @@ -511,7 +569,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE 'timeStamp' >= ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_GREATER_THAN_OR_EQUAL_TO); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2l); @@ -534,7 +592,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE 'timeStamp' < ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_LESS_THAN); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2l); @@ -557,7 +615,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE 'timeStamp' <= ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_LESS_THAN_OR_EQUAL_TO); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2l); @@ -580,7 +638,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE NOT 'timeStamp' > ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_NOT); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2l); @@ -603,7 +661,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE 'timeStamp' > 0 AND 'timeStamp' < ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_AND); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2l); @@ -626,7 +684,7 @@ Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); webStorage.registerCategory(CpuStatDAO.cpuStatCategory); - String strDesc = "QUERY cpu-stats WHERE 'timeStamp' > ?l OR 'timeStamp' < ?l SORT 'timeStamp' ASC"; + String strDesc = DESCRIPTOR_MAP.get(KEY_AUTHORIZED_QUERY_OR); StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); PreparedStatement<CpuStat> query = webStorage.prepareStatement(queryDesc); query.setLong(0, 2); @@ -636,6 +694,37 @@ webStorage.getConnection().disconnect(); } + + @Test + public void refuseUnknownQueryDescriptor() throws IOException { + + String[] roleNames = new String[] { + Roles.REGISTER_CATEGORY, + Roles.READ, + Roles.LOGIN, + Roles.ACCESS_REALM, + Roles.PREPARE_STATEMENT + }; + Storage webStorage = getAndConnectStorage(TEST_USER, TEST_PASSWORD, roleNames); + webStorage.registerCategory(CpuStatDAO.cpuStatCategory); + + String strDesc = "QUERY cpu-stats WHERE 'fooBarTest' = ?s"; + assertFalse("wanted this descriptor to be untrusted!", TRUSTED_DESCRIPTORS.contains(strDesc)); + StatementDescriptor<CpuStat> queryDesc = new StatementDescriptor<>(CpuStatDAO.cpuStatCategory, strDesc); + + try { + webStorage.prepareStatement(queryDesc); + } catch (IllegalDescriptorException e) { + // pass + String expectedMsg = "Unknown query descriptor which endpoint of com.redhat.thermostat.web.client.internal.WebStorage refused to accept!"; + assertEquals(expectedMsg, e.getMessage()); + } catch (DescriptorParsingException e) { + // should have been able to parse the descriptor + fail(e.getMessage()); + } + + webStorage.getConnection().disconnect(); + } @Test public void authorizedLoadSave() throws Exception { @@ -712,7 +801,7 @@ add.setPojo(pojo); add.apply(); - String strDesc = "QUERY vm-cpu-stats"; + String strDesc = DESCRIPTOR_MAP.get(KEY_SET_DEFAULT_AGENT_ID); StatementDescriptor<VmCpuStat> queryDesc = new StatementDescriptor<>(VmCpuStatDAO.vmCpuStatCategory, strDesc); PreparedStatement<VmCpuStat> query = storage.prepareStatement(queryDesc); Cursor<VmCpuStat> cursor = query.executeQuery();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/WebAppTestStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright 2012, 2013 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.itest; + +import java.util.Set; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +public class WebAppTestStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + return WebAppTest.TRUSTED_DESCRIPTORS; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/integration-tests/src/test/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.itest.WebAppTestStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/numa/common/src/main/java/com/redhat/thermostat/numa/common/internal/NumaDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright 2012, 2013 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.numa.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.numa.common.NumaDAO; +import com.redhat.thermostat.storage.core.HostLatestPojoListGetter; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +/** + * Registers prepared queries issued by this maven module via + * {@link HostLatestPojoListGetter} and via {@link NumaDAOImpl}. + * + */ +public class NumaDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(2); + String descriptor = String.format( + HostLatestPojoListGetter.HOST_LATEST_QUERY_FORMAT, + NumaDAO.numaStatCategory.getName()); + descs.add(descriptor); + descs.add(NumaDAOImpl.QUERY_NUMA_INFO); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/numa/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.numa.common.internal.NumaDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/numa/common/src/test/java/com/redhat/thermostat/numa/common/internal/NumaDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 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.numa.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class NumaDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + NumaDAOImplStatementDescriptorRegistration reg = new NumaDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(2, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(NumaDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, NumaDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration numaReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(NumaDAOImplStatementDescriptorRegistration.class.getName())) { + numaReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(numaReg); + assertEquals(2, numaReg.getStatementDescriptors().size()); + } +}
--- a/storage/core/pom.xml Wed Jul 24 13:56:13 2013 -0400 +++ b/storage/core/pom.xml Mon Jul 22 20:01:46 2013 +0200 @@ -64,6 +64,7 @@ <Bundle-Activator>com.redhat.thermostat.storage.internal.Activator</Bundle-Activator> <Export-Package> com.redhat.thermostat.storage.core, + com.redhat.thermostat.storage.core.auth, com.redhat.thermostat.storage.config, com.redhat.thermostat.storage.model, com.redhat.thermostat.storage.dao,
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetter.java Wed Jul 24 13:56:13 2013 -0400 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetter.java Mon Jul 22 20:01:46 2013 +0200 @@ -47,6 +47,10 @@ public class HostLatestPojoListGetter<T extends TimeStampedPojo> { + public static final String HOST_LATEST_QUERY_FORMAT = "QUERY %s WHERE '" + + Key.AGENT_ID.getName() + "' = ?s AND '" + + Key.TIMESTAMP.getName() + "' > ?l SORT '" + + Key.TIMESTAMP.getName() + "' DSC"; private static final Logger logger = LoggingUtils.getLogger(HostLatestPojoListGetter.class); private final Storage storage; @@ -56,10 +60,7 @@ public HostLatestPojoListGetter(Storage storage, Category<T> cat) { this.storage = storage; this.cat = cat; - this.queryLatest = "QUERY " + cat.getName() + " WHERE '" - + Key.AGENT_ID.getName() + "' = ?s AND '" - + Key.TIMESTAMP.getName() + "' > ?l SORT '" - + Key.TIMESTAMP.getName() + "' DSC"; + this.queryLatest = String.format(HOST_LATEST_QUERY_FORMAT, cat.getName()); } public List<T> getLatest(HostRef hostRef, long since) {
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Storage.java Wed Jul 24 13:56:13 2013 -0400 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/Storage.java Mon Jul 22 20:01:46 2013 +0200 @@ -59,10 +59,15 @@ /** * Prepares the given statement for execution. * - * @param desc The statement descriptor to prepare. - * @return A {@link PreparedStatement} if the given statement was - * something Storage knows about, {@code null} otherwise. - * @throws DescriptorParsingException If the descriptor string was invalid. + * @param desc + * The statement descriptor to prepare. + * @return A {@link PreparedStatement} if the given statement descriptor was + * known and did not fail to parse. + * @throws DescriptorParsingException + * If the descriptor string failed to parse. + * @throws IllegalDescriptorException + * If storage refused to prepare a statement descriptor for + * security reasons. */ <T extends Pojo> PreparedStatement<T> prepareStatement(StatementDescriptor<T> desc) throws DescriptorParsingException;
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetter.java Wed Jul 24 13:56:13 2013 -0400 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetter.java Mon Jul 22 20:01:46 2013 +0200 @@ -47,8 +47,13 @@ public class VmLatestPojoListGetter<T extends TimeStampedPojo> { + public static final String VM_LATEST_QUERY_FORMAT = "QUERY %s WHERE '" + + Key.AGENT_ID.getName() + "' = ?s AND '" + + Key.VM_ID.getName() + "' = ?s AND '" + + Key.TIMESTAMP.getName() + "' > ?l SORT '" + + Key.TIMESTAMP.getName() + "' DSC"; private static final Logger logger = LoggingUtils.getLogger(VmLatestPojoListGetter.class); - + private final Storage storage; private final Category<T> cat; private final String queryLatest; @@ -56,11 +61,7 @@ public VmLatestPojoListGetter(Storage storage, Category<T> cat) { this.storage = storage; this.cat = cat; - this.queryLatest = "QUERY " + cat.getName() + " WHERE '" - + Key.AGENT_ID.getName() + "' = ?s AND '" - + Key.VM_ID.getName() + "' = ?s AND '" - + Key.TIMESTAMP.getName() + "' > ?l SORT '" - + Key.TIMESTAMP.getName() + "' DSC"; + this.queryLatest = String.format(VM_LATEST_QUERY_FORMAT, cat.getName()); } public List<T> getLatest(VmRef vmRef, long since) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/auth/StatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright 2012, 2013 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.storage.core.auth; + +import java.util.ServiceLoader; +import java.util.Set; + + +/** + * {@link ServiceLoader} interface used for registering + * trusted statement descriptors. The web storage endpoint + * uses implementations of this interface in order to collect + * the set of all trusted statement descriptors. + * + */ +public interface StatementDescriptorRegistration { + + /** + * + * @return A set of string descriptors which should get + * added to the trusted registry. + */ + Set<String> getStatementDescriptors(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/DAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright 2012, 2013 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.storage.internal.dao; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +/** + * Registers prepared queries issued by this maven module + * via various DAOs. + * + */ +public class DAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> daoDescs = new HashSet<>(); + daoDescs.add(AgentInfoDAOImpl.QUERY_AGENT_INFO); + daoDescs.add(AgentInfoDAOImpl.QUERY_ALIVE_AGENTS); + daoDescs.add(AgentInfoDAOImpl.QUERY_ALL_AGENTS); + daoDescs.add(BackendInfoDAOImpl.QUERY_BACKEND_INFO); + daoDescs.add(HostInfoDAOImpl.QUERY_HOST_INFO); + daoDescs.add(HostInfoDAOImpl.QUERY_ALL_HOSTS); + daoDescs.add(NetworkInterfaceInfoDAOImpl.QUERY_NETWORK_INFO); + daoDescs.add(VmInfoDAOImpl.QUERY_ALL_VMS); + daoDescs.add(VmInfoDAOImpl.QUERY_VM_INFO); + return daoDescs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/core/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration \ No newline at end of file
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetterTest.java Wed Jul 24 13:56:13 2013 -0400 +++ b/storage/core/src/test/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetterTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -99,6 +99,13 @@ } @Test + public void verifyQueryDescriptorFormat() { + String expected = "QUERY %s WHERE 'agentId' = ?s AND " + + "'timeStamp' > ?l SORT 'timeStamp' DSC"; + assertEquals(expected, HostLatestPojoListGetter.HOST_LATEST_QUERY_FORMAT); + } + + @Test public void verifyQueryDescriptorIsSane() { Storage storage = mock(Storage.class); HostLatestPojoListGetter<TestPojo> getter = new HostLatestPojoListGetter<>(storage, cat);
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetterTest.java Wed Jul 24 13:56:13 2013 -0400 +++ b/storage/core/src/test/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetterTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -91,6 +91,13 @@ } @Test + public void verifyQueryDescriptorFormat() { + String expected = "QUERY %s WHERE 'agentId' = ?s AND " + + "'vmId' = ?s AND 'timeStamp' > ?l SORT 'timeStamp' DSC"; + assertEquals(expected, VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT); + } + + @Test public void verifyQueryDescriptorIsSane() { Storage storage = mock(Storage.class); VmLatestPojoListGetter<TestPojo> getter = new VmLatestPojoListGetter<>(storage, cat);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/DAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright 2012, 2013 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.storage.internal.dao; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.ArrayList; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +public class DAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + DAOImplStatementDescriptorRegistration reg = new DAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(9, descriptors.size()); + assertFalse(descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, DAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + for (StatementDescriptorRegistration r: loader) { + registrations.add(r); + } + assertEquals(1, registrations.size()); + assertEquals(9, registrations.get(0).getStatementDescriptors().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright 2012, 2013 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 java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +/** + * Registers prepared queries issued by this maven module via + * via {@link ThreadDaoImpl}. + * + */ +public class ThreadDaoImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(6); + 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.add(ThreadDaoImpl.QUERY_THREAD_CAPS); + descs.add(ThreadDaoImpl.QUERY_THREAD_INFO); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.thread.dao.impl.ThreadDaoImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class ThreadDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + ThreadDaoImplStatementDescriptorRegistration reg = new ThreadDaoImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(6, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(ThreadDaoImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, ThreadDaoImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration threadDaoReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(ThreadDaoImplStatementDescriptorRegistration.class.getName())) { + threadDaoReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(threadDaoReg); + assertEquals(6, threadDaoReg.getStatementDescriptors().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-classstat/common/src/main/java/com/redhat/thermostat/vm/classstat/common/internal/VmClassStatDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright 2012, 2013 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.vm.classstat.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.VmLatestPojoListGetter; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.vm.classstat.common.VmClassStatDAO; + +/** + * Registers the prepared query issued by this maven module via + * {@link VmLatestPojoListGetter}. + * + */ +public class VmClassStatDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(); + String vmLatestClassStatQuery = String.format(VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT, + VmClassStatDAO.vmClassStatsCategory.getName()); + descs.add(vmLatestClassStatQuery); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-classstat/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.classstat.common.internal.VmClassStatDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-classstat/common/src/test/java/com/redhat/thermostat/vm/classstat/common/internal/VmClassStatDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright 2012, 2013 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.vm.classstat.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class VmClassStatDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + VmClassStatDAOImplStatementDescriptorRegistration reg = new VmClassStatDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(1, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(VmClassStatDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, VmClassStatDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration vmClassStatReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(VmClassStatDAOImplStatementDescriptorRegistration.class.getName())) { + vmClassStatReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(vmClassStatReg); + assertEquals(1, vmClassStatReg.getStatementDescriptors().size()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-cpu/common/src/main/java/com/redhat/thermostat/vm/cpu/common/internal/VmCpuStatDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright 2012, 2013 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.vm.cpu.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.VmLatestPojoListGetter; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.vm.cpu.common.VmCpuStatDAO; + +/** + * Registers the prepared query issued by this maven module via + * {@link VmLatestPojoListGetter}. + * + */ +public class VmCpuStatDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(); + String descriptor = String.format(VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT, + VmCpuStatDAO.vmCpuStatCategory.getName()); + descs.add(descriptor); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-cpu/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.cpu.common.internal.VmCpuStatDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-cpu/common/src/test/java/com/redhat/thermostat/vm/cpu/common/internal/VmCpuStatDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 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.vm.cpu.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class VmCpuStatDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + VmCpuStatDAOImplStatementDescriptorRegistration reg = new VmCpuStatDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(1, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(VmCpuStatDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, VmCpuStatDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration vmCpuStatReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(VmCpuStatDAOImplStatementDescriptorRegistration.class.getName())) { + vmCpuStatReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(vmCpuStatReg); + assertEquals(1, vmCpuStatReg.getStatementDescriptors().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright 2012, 2013 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.vm.gc.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.VmLatestPojoListGetter; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.vm.gc.common.VmGcStatDAO; + +/** + * Registers the prepared query issued by this maven module via + * {@link VmLatestPojoListGetter}. + * + */ +public class VmGcStatDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(); + String descriptor = String.format(VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT, + VmGcStatDAO.vmGcStatCategory.getName()); + descs.add(descriptor); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.gc.common.internal.VmGcStatDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/common/src/test/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +package com.redhat.thermostat.vm.gc.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +/* + * Copyright 2012, 2013 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. + */ + +public class VmGcStatDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + VmGcStatDAOImplStatementDescriptorRegistration reg = new VmGcStatDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(1, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(VmGcStatDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, VmGcStatDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration vmGcStatReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(VmGcStatDAOImplStatementDescriptorRegistration.class.getName())) { + vmGcStatReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(vmGcStatReg); + assertEquals(1, vmGcStatReg.getStatementDescriptors().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/common/src/main/java/com/redhat/thermostat/vm/heap/analysis/common/internal/HeapDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright 2012, 2013 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.vm.heap.analysis.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +/** + * Registers prepared queries issued by this maven module + * via {@link HeapDAOImpl}. + * + */ +public class HeapDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(2); + descs.add(HeapDAOImpl.QUERY_ALL_HEAPS); + descs.add(HeapDAOImpl.QUERY_HEAP_INFO); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.heap.analysis.common.internal.HeapDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-heap-analysis/common/src/test/java/com/redhat/thermostat/vm/heap/analysis/common/internal/HeapDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 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.vm.heap.analysis.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class HeapDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + HeapDAOImplStatementDescriptorRegistration reg = new HeapDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(2, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(HeapDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, HeapDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration heapDaoReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(HeapDAOImplStatementDescriptorRegistration.class.getName())) { + heapDaoReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(heapDaoReg); + assertEquals(2, heapDaoReg.getStatementDescriptors().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-jmx/common/src/main/java/com/redhat/thermostat/vm/jmx/common/internal/JmxNotificationDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright 2012, 2013 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.vm.jmx.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +/** + * Registers prepared queries issued by this maven module + * via {@link JmxNotificationDAOImpl}. + * + */ +public class JmxNotificationDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(2); + descs.add(JmxNotificationDAOImpl.QUERY_LATEST_NOTIFICATION_STATUS); + descs.add(JmxNotificationDAOImpl.QUERY_NOTIFICATIONS); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-jmx/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.jmx.common.internal.JmxNotificationDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-jmx/common/src/test/java/com/redhat/thermostat/vm/jmx/common/internal/JmxNotificationDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 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.vm.jmx.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class JmxNotificationDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + JmxNotificationDAOImplStatementDescriptorRegistration reg = new JmxNotificationDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(2, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(JmxNotificationDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, JmxNotificationDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration jmxDaoReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(JmxNotificationDAOImplStatementDescriptorRegistration.class.getName())) { + jmxDaoReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(jmxDaoReg); + assertEquals(2, jmxDaoReg.getStatementDescriptors().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOImplStatementDescriptorRegistration.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright 2012, 2013 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.vm.memory.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.VmLatestPojoListGetter; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +/** + * Registers prepared queries issued by this maven module via + * {@link VmLatestPojoListGetter} and {@link VmMemoryStatDAOImpl}. + * + */ +public class VmMemoryStatDAOImplStatementDescriptorRegistration implements + StatementDescriptorRegistration { + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(2); + String descriptor = String.format(VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT, + VmMemoryStatDAO.vmMemoryStatsCategory.getName()); + descs.add(descriptor); + descs.add(VmMemoryStatDAOImpl.QUERY_LATEST); + return descs; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.memory.common.internal.VmMemoryStatDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOImplStatementDescriptorRegistrationTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2012, 2013 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.vm.memory.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration; + +public class VmMemoryStatDAOImplStatementDescriptorRegistrationTest { + + @Test + public void registersAllQueries() { + VmMemoryStatDAOImplStatementDescriptorRegistration reg = new VmMemoryStatDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(2, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known registrations. This test is to ensure service loading + * works for this module's regs. E.g. renaming of the impl class without + * changing META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration + */ + @Test + public void serviceLoaderCanLoadRegistration() { + Set<String> expectedClassNames = new HashSet<>(); + expectedClassNames.add(DAOImplStatementDescriptorRegistration.class.getName()); + expectedClassNames.add(VmMemoryStatDAOImplStatementDescriptorRegistration.class.getName()); + ServiceLoader<StatementDescriptorRegistration> loader = ServiceLoader.load(StatementDescriptorRegistration.class, VmMemoryStatDAOImplStatementDescriptorRegistration.class.getClassLoader()); + List<StatementDescriptorRegistration> registrations = new ArrayList<>(1); + StatementDescriptorRegistration vmMemoryDaoReg = null; + for (StatementDescriptorRegistration r: loader) { + assertTrue(expectedClassNames.contains(r.getClass().getName())); + if (r.getClass().getName().equals(VmMemoryStatDAOImplStatementDescriptorRegistration.class.getName())) { + vmMemoryDaoReg = r; + } + registrations.add(r); + } + // storage-core + this module + assertEquals(2, registrations.size()); + assertNotNull(vmMemoryDaoReg); + assertEquals(2, vmMemoryDaoReg.getStatementDescriptors().size()); + } +}
--- a/web/client/src/main/java/com/redhat/thermostat/web/client/internal/WebStorage.java Wed Jul 24 13:56:13 2013 -0400 +++ b/web/client/src/main/java/com/redhat/thermostat/web/client/internal/WebStorage.java Mon Jul 22 20:01:46 2013 +0200 @@ -784,7 +784,7 @@ if (statementId == WebPreparedStatementResponse.ILLEGAL_STATEMENT) { // we've got a descriptor the endpoint doesn't know about or // refuses to accept for security reasons. - String msg = "Unknown query descriptor which endpoint of " + WebStorage.class.getName() + "refused to accept!"; + String msg = "Unknown query descriptor which endpoint of " + WebStorage.class.getName() + " refused to accept!"; throw new IllegalDescriptorException(msg, desc.getQueryDescriptor()); } else if (statementId == WebPreparedStatementResponse.DESCRIPTOR_PARSE_FAILED) { String msg = "Statement descriptor failed to parse. " +
--- a/web/common/src/main/java/com/redhat/thermostat/web/common/WebPreparedStatementResponse.java Wed Jul 24 13:56:13 2013 -0400 +++ b/web/common/src/main/java/com/redhat/thermostat/web/common/WebPreparedStatementResponse.java Mon Jul 22 20:01:46 2013 +0200 @@ -41,7 +41,14 @@ */ public class WebPreparedStatementResponse { + /** + * Response code for untrusted/unknown descriptors. + */ public static final int ILLEGAL_STATEMENT = -1; + + /** + * Response code for descriptor parsing exceptions. + */ public static final int DESCRIPTOR_PARSE_FAILED = -2; public WebPreparedStatementResponse() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/KnownDescriptorRegistry.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,76 @@ +/* + * Copyright 2012, 2013 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.web.server; + +import java.util.Collections; +import java.util.HashSet; +import java.util.ServiceLoader; +import java.util.Set; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +/** + * Registers trusted statement descriptors. + * + */ +final class KnownDescriptorRegistry { + + private static final ServiceLoader<StatementDescriptorRegistration> TRUSTED_DESCS = ServiceLoader + .load(StatementDescriptorRegistration.class); + private final Iterable<StatementDescriptorRegistration> actualTrustedDescs; + + KnownDescriptorRegistry() { + this.actualTrustedDescs = TRUSTED_DESCS; + } + + KnownDescriptorRegistry(Iterable<StatementDescriptorRegistration> trustedDescs) { + this.actualTrustedDescs = trustedDescs; + } + + final Set<String> getRegisteredDescriptors() { + Set<String> trustedSet = new HashSet<>(); + for (StatementDescriptorRegistration reg: actualTrustedDescs) { + Set<String> newCandidates = reg.getStatementDescriptors(); + if (newCandidates.contains(null)) { + throw new IllegalStateException("null statement descriptor not acceptable!"); + } + trustedSet.addAll(newCandidates); + } + // return a read-only set of all descriptors + return Collections.unmodifiableSet(trustedSet); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/KnownDescriptorRegistryFactory.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright 2012, 2013 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.web.server; + +final class KnownDescriptorRegistryFactory { + + private static KnownDescriptorRegistry reg; + + final static KnownDescriptorRegistry getInstance() { + if (reg == null) { + return new KnownDescriptorRegistry(); + } else { + return reg; + } + } + + final static void setKnownDescriptorRegistry(KnownDescriptorRegistry reg) { + KnownDescriptorRegistryFactory.reg = reg; + } + +}
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Wed Jul 24 13:56:13 2013 -0400 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Mon Jul 22 20:01:46 2013 +0200 @@ -46,6 +46,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -135,6 +136,9 @@ // Lock to be held for setting/getting prepared queries in the above maps private Object preparedStmtLock = new Object(); private int currentPreparedStmtId; + + // read-only set of all known statement descriptors we trust and allow + private Set<String> knownStatementDescriptors; @Override public void init(ServletConfig config) throws ServletException { @@ -165,6 +169,10 @@ tokenManager.setTimeout(Integer.parseInt(timeoutParam)); } getServletContext().setAttribute(TOKEN_MANAGER_KEY, tokenManager); + + // Set the set of statement descriptors which we trust + KnownDescriptorRegistry descRegistry = KnownDescriptorRegistryFactory.getInstance(); + knownStatementDescriptors = descRegistry.getRegisteredDescriptors(); } @Override @@ -290,6 +298,16 @@ return; } StatementDescriptor<?> desc = new StatementDescriptor<>(cat, queryDescrParam); + // Check if descriptor is trusted (i.e. known) + if (!knownStatementDescriptors.contains(desc.getQueryDescriptor())) { + String msg = "Attempted to prepare a statement descriptor which we " + + "don't trust! Descriptor was: ->" + desc.getQueryDescriptor() + "<-"; + logger.log(Level.WARNING, msg); + response.setStatementId(WebPreparedStatementResponse.ILLEGAL_STATEMENT); + writeResponse(resp, response, WebPreparedStatementResponse.class); + return; + } + synchronized (preparedStmtLock) { // see if we've prepared this query already if (preparedStmts.containsKey(desc)) { @@ -304,7 +322,6 @@ WebPreparedStatementResponse.class); return; } - // TODO: Check if descriptor is trusted (i.e. known) // Prepare the target statement and put it into our prepared statement // maps.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/server/src/test/java/com/redhat/thermostat/web/server/KnownDescriptorRegistryTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -0,0 +1,120 @@ +/* + * Copyright 2012, 2013 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.web.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; + +public class KnownDescriptorRegistryTest { + + @Test + public void canAddDescriptors() { + Set<String> descs = new HashSet<>(); + descs.add("QUERY test WHERE 'a' = ?s"); + descs.add("QUERY agent-config"); + Iterable<StatementDescriptorRegistration> regs = getRegs(descs); + KnownDescriptorRegistry reg = new KnownDescriptorRegistry(regs); + Set<String> registeredDescs = null; + try { + registeredDescs = reg.getRegisteredDescriptors(); + } catch (IllegalStateException e) { + fail(e.getMessage()); + } + assertNotNull(registeredDescs); + for (String d: registeredDescs) { + assertTrue(descs.contains(d)); + } + } + + @Test + public void testServiceLoadersInClassPath() { + KnownDescriptorRegistry reg = new KnownDescriptorRegistry(); + Set<String> trustedDescs = reg.getRegisteredDescriptors(); + assertNotNull(trustedDescs); + // storage-core registers 9 queries; this module has + // only storage-core as maven dep which registers queries. + // see DAOImplStatementDescriptorRegistration + assertEquals(9, trustedDescs.size()); + } + + @Test + public void cannotAddNullDescriptors() { + Set<String> descs = new HashSet<>(); + descs.add("QUERY test WHERE 'a' = ?s"); + descs.add(null); + Iterable<StatementDescriptorRegistration> regs = getRegs(descs); + KnownDescriptorRegistry reg = new KnownDescriptorRegistry(regs); + try { + reg.getRegisteredDescriptors(); + fail("Should not have accepted null descriptor"); + } catch (IllegalStateException e) { + assertEquals("null statement descriptor not acceptable!", e.getMessage()); + } + } + + private Iterable<StatementDescriptorRegistration> getRegs(Set<String> descs) { + StatementDescriptorRegistration reg = new TestStatementDescriptorRegistration( + descs); + StatementDescriptorRegistration[] regs = new StatementDescriptorRegistration[] { reg }; + return Arrays.asList(regs); + } + + private static class TestStatementDescriptorRegistration implements StatementDescriptorRegistration { + + private final Set<String> descs; + + private TestStatementDescriptorRegistration(Set<String> descs) { + this.descs = descs; + } + + @Override + public Set<String> getStatementDescriptors() { + return descs; + } + + } +}
--- a/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java Wed Jul 24 13:56:13 2013 -0400 +++ b/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java Mon Jul 22 20:01:46 2013 +0200 @@ -62,8 +62,12 @@ import java.net.ProtocolException; import java.net.URL; import java.net.URLEncoder; +import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -103,6 +107,7 @@ import com.redhat.thermostat.storage.core.StatementDescriptor; import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.core.Update; +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; import com.redhat.thermostat.storage.model.BasePojo; import com.redhat.thermostat.storage.model.Pojo; import com.redhat.thermostat.storage.query.Expression; @@ -272,10 +277,61 @@ } assertEquals(authPaths.length, methodsReqAuthorization); } + + @Test + public void authorizedPrepareQueryWithUnTrustedDescriptor() throws Exception { + String strDescriptor = "QUERY " + category.getName() + " WHERE '" + key1.getName() + "' = ?s SORT '" + key1.getName() + "' DSC LIMIT 42"; + // setup a statement descriptor set so as to mimic a not trusted desc + String wrongDescriptor = "QUERY something-other WHERE 'a' = true"; + setupTrustedStatementRegistry(wrongDescriptor); + + String[] roleNames = new String[] { + Roles.REGISTER_CATEGORY, + Roles.PREPARE_STATEMENT + }; + String testuser = "testuser"; + String password = "testpassword"; + final LoginService loginService = new TestLoginService(testuser, password, roleNames); + port = FreePortFinder.findFreePort(new TryPort() { + + @Override + public void tryPort(int port) throws Exception { + startServer(port, loginService); + } + }); + registerCategory(testuser, password); + + String endpoint = getEndpoint(); + URL url = new URL(endpoint + "/prepare-statement"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + sendAuthentication(conn, testuser, password); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setDoInput(true); + conn.setDoOutput(true); + Gson gson = new GsonBuilder() + .registerTypeHierarchyAdapter(WebQueryResponse.class, new WebQueryResponseSerializer<>()) + .registerTypeAdapter(Pojo.class, new ThermostatGSONConverter()) + .registerTypeAdapter(WebPreparedStatement.class, new WebPreparedStatementSerializer()) + .registerTypeAdapter(PreparedParameter.class, new PreparedParameterSerializer()).create(); + OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); + String body = "query-descriptor=" + URLEncoder.encode(strDescriptor, "UTF-8") + "&category-id=" + categoryId; + out.write(body + "\n"); + out.flush(); + + Reader in = new InputStreamReader(conn.getInputStream()); + WebPreparedStatementResponse response = gson.fromJson(in, WebPreparedStatementResponse.class); + assertEquals("descriptor not trusted, so expected number should be negative!", -1, response.getNumFreeVariables()); + assertEquals(WebPreparedStatementResponse.ILLEGAL_STATEMENT, response.getStatementId()); + assertEquals("application/json; charset=UTF-8", conn.getContentType()); + } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void authorizedPrepareQuery() throws Exception { + public void authorizedPrepareQueryWithTrustedDescriptor() throws Exception { + String strDescriptor = "QUERY " + category.getName() + " WHERE '" + key1.getName() + "' = ?s SORT '" + key1.getName() + "' DSC LIMIT 42"; + setupTrustedStatementRegistry(strDescriptor); + String[] roleNames = new String[] { Roles.REGISTER_CATEGORY, Roles.PREPARE_STATEMENT, @@ -320,7 +376,6 @@ // And the mongo layer when(mockMongoQuery.execute()).thenReturn(cursor); - String strDescriptor = "QUERY " + category.getName() + " WHERE '" + key1.getName() + "' = ?s SORT '" + key1.getName() + "' DSC LIMIT 42"; String endpoint = getEndpoint(); URL url = new URL(endpoint + "/prepare-statement"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); @@ -379,6 +434,17 @@ verifyNoMoreInteractions(mockMongoQuery); } + private void setupTrustedStatementRegistry(String strDescriptor) { + Set<String> descs = new HashSet<>(); + descs.add(strDescriptor); + StatementDescriptorRegistration reg = mock(StatementDescriptorRegistration.class); + when(reg.getStatementDescriptors()).thenReturn(descs); + List<StatementDescriptorRegistration> regs = new ArrayList<>(1); + regs.add(reg); + KnownDescriptorRegistry registry = new KnownDescriptorRegistry(regs); + KnownDescriptorRegistryFactory.setKnownDescriptorRegistry(registry); + } + @Test public void unauthorizedPrepareStmt() throws Exception { String failMsg = "thermostat-prepare-statement role missing, expected Forbidden!";