# HG changeset patch # User Elliott Baron # Date 1375300235 14400 # Node ID e810fb4143b5b158780c46257d5bc83c7addd5cc # Parent e7bdfcace2b039486953ee6ae3c74f7b6c5d3bf8 Move createQuery to new BackingStorage interface In order to enforce that clients must use prepared statements in their queries, this commit removes createQuery from the Storage interface. Since it is still necessary for prepared statement parsers to create queries, this commit makes a distinction from storages that are intermediaries (e.g. WebStorage) and backend storage implementations (e.g. MongoStorage). MongoStorage now implements a BackingStorage interface which contains the old createQuery method. Thus, it is only possible to create queries directly when interacting with a BackingStorage interface and not with the web layer. This is secure since when running the Thermostat web service, the backend storage is never accessible to the client. Once write operations are moved to using prepared statements, their create* methods can be moved to BackingStorage and removed from the web API. Reviewed-by: omajid, jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-July/007633.html diff -r e7bdfcace2b0 -r e810fb4143b5 integration-tests/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java --- a/integration-tests/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java Wed Jul 31 21:07:28 2013 +0200 +++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -57,6 +57,7 @@ import com.redhat.thermostat.host.cpu.common.model.CpuStat; import com.redhat.thermostat.storage.config.StartupConfiguration; import com.redhat.thermostat.storage.core.Add; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.Connection.ConnectionListener; import com.redhat.thermostat.storage.core.Connection.ConnectionStatus; import com.redhat.thermostat.storage.core.Cursor; @@ -131,7 +132,7 @@ * Make a connection to mongo storage (returning the Storage object). Before * initiating the connection, add the ConnectionListener to Storage. */ - private static Storage getAndConnectStorage(ConnectionListener listener) { + private static BackingStorage getAndConnectStorage(ConnectionListener listener) { final String url = "mongodb://127.0.0.1:27518"; StartupConfiguration config = new StartupConfiguration() { @@ -141,7 +142,7 @@ } }; - Storage storage = new MongoStorage(config); + BackingStorage storage = new MongoStorage(config); if (listener != null) { storage.getConnection().addListener(listener); } @@ -241,7 +242,7 @@ public void canQueryNoWhere() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -258,7 +259,7 @@ public void canQueryEqualTo() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -277,7 +278,7 @@ public void canQueryNotEqualTo() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -296,7 +297,7 @@ public void canQueryGreaterThan() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -315,7 +316,7 @@ public void canQueryGreaterThanOrEqualTo() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -334,7 +335,7 @@ public void canQueryLessThan() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -353,7 +354,7 @@ public void canQueryLessThanOrEqualTo() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -372,7 +373,7 @@ public void canQueryIn() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -392,7 +393,7 @@ public void canQueryNotIn() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -411,7 +412,7 @@ public void canQueryNot() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -430,7 +431,7 @@ public void canQueryAnd() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -450,7 +451,7 @@ public void canQueryOr() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); mongoStorage.registerCategory(CpuStatDAO.cpuStatCategory); @@ -504,7 +505,7 @@ public void setDefaultAgentID() throws Exception { CountDownLatch latch = new CountDownLatch(1); ConnectionListener listener = new CountdownConnectionListener(ConnectionStatus.CONNECTED, latch); - Storage mongoStorage = getAndConnectStorage(listener); + BackingStorage mongoStorage = getAndConnectStorage(listener); latch.await(); mongoStorage.getConnection().removeListener(listener); UUID uuid = new UUID(42, 24); diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/main/java/com/redhat/thermostat/storage/core/BackingStorage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/BackingStorage.java Wed Jul 31 15:50:35 2013 -0400 @@ -0,0 +1,57 @@ +/* + * 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 + * . + * + * 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; + +import com.redhat.thermostat.storage.model.Pojo; + +/** + * This subclass of {@link Storage} should be implemented by classes that + * interact directly with a form of storage (e.g. a database). + * + * This interface contains methods which provide capabilities we do not want to + * expose directly to clients. Clients should instead prepare statements using + * {@link Storage#prepareStatement(StatementDescriptor)}. The methods in this + * interface then provide the mechanisms to execute the prepared statement, and + * should only be used by the prepared statement implementations. + */ +public interface BackingStorage extends Storage { + + Query createQuery(Category category); + + // TODO Move createUpdate and createRemove here + +} diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatementFactory.java --- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatementFactory.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatementFactory.java Wed Jul 31 15:50:35 2013 -0400 @@ -9,7 +9,7 @@ */ public class PreparedStatementFactory { - public static PreparedStatement getInstance(Storage storage, + public static PreparedStatement getInstance(BackingStorage storage, StatementDescriptor desc) throws DescriptorParsingException { // This is the sole method in order to avoid leaking impl details of // this OSGi module. Storage implementations will have to use this diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/main/java/com/redhat/thermostat/storage/core/QueuedBackingStorage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/QueuedBackingStorage.java Wed Jul 31 15:50:35 2013 -0400 @@ -0,0 +1,73 @@ +/* + * 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 + * . + * + * 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; + +import java.util.concurrent.ExecutorService; + +import com.redhat.thermostat.storage.model.Pojo; + +public class QueuedBackingStorage extends QueuedStorage implements + BackingStorage { + + public QueuedBackingStorage(BackingStorage delegate) { + super(delegate); + } + + QueuedBackingStorage(BackingStorage delegate, ExecutorService executor, + ExecutorService fileExecutor) { + super(delegate, executor, fileExecutor); + } + + @Override + public Query createQuery(Category category) { + return ((BackingStorage) delegate).createQuery(category); + } + + @Override + public PreparedStatement prepareStatement( + StatementDescriptor desc) throws DescriptorParsingException { + // FIXME: Use some kind of cache in order to avoid parsing of + // descriptors each time this is called. At least if the descriptor + // class is the same we should be able to do something here. + + // Don't just defer to the delegate, since we want statements + // prepared by this method to create queries using the + // createQuery method in this class. + return PreparedStatementFactory.getInstance(this, desc); + } + +} diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/main/java/com/redhat/thermostat/storage/core/QueuedStorage.java --- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/QueuedStorage.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/QueuedStorage.java Wed Jul 31 15:50:35 2013 -0400 @@ -229,11 +229,6 @@ } @Override - public Query createQuery(Category category) { - return delegate.createQuery(category); - } - - @Override public Update createUpdate(Category category) { QueuedUpdate update = new QueuedUpdate(delegate.createUpdate(category)); return update; diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/main/java/com/redhat/thermostat/storage/core/Storage.java --- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Storage.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/Storage.java Wed Jul 31 15:50:35 2013 -0400 @@ -96,8 +96,6 @@ InputStream loadFile(String filename); - Query createQuery(Category category); - Update createUpdate(Category category); Remove createRemove(); diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImpl.java --- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImpl.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImpl.java Wed Jul 31 15:50:35 2013 -0400 @@ -36,6 +36,7 @@ package com.redhat.thermostat.storage.internal.statement; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.Cursor; import com.redhat.thermostat.storage.core.DataModifyingStatement; import com.redhat.thermostat.storage.core.DescriptorParsingException; @@ -48,7 +49,6 @@ import com.redhat.thermostat.storage.core.Statement; import com.redhat.thermostat.storage.core.StatementDescriptor; import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.model.Pojo; /** @@ -63,7 +63,7 @@ private final PreparedParameters params; private final ParsedStatementImpl parsedStatement; - public PreparedStatementImpl(Storage storage, StatementDescriptor desc) throws DescriptorParsingException { + public PreparedStatementImpl(BackingStorage storage, StatementDescriptor desc) throws DescriptorParsingException { this.desc = desc; StatementDescriptorParser parser = new StatementDescriptorParser<>(storage, desc); this.parsedStatement = (ParsedStatementImpl)parser.parse(); diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorParser.java --- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorParser.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorParser.java Wed Jul 31 15:50:35 2013 -0400 @@ -40,6 +40,7 @@ import java.util.List; import java.util.StringTokenizer; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.DescriptorParsingException; import com.redhat.thermostat.storage.core.Key; @@ -47,7 +48,6 @@ import com.redhat.thermostat.storage.core.Query; import com.redhat.thermostat.storage.core.Query.SortDirection; import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.model.Pojo; import com.redhat.thermostat.storage.query.BinaryComparisonOperator; import com.redhat.thermostat.storage.query.BinaryLogicalOperator; @@ -117,14 +117,14 @@ private final String[] tokens; private final StatementDescriptor desc; - private final Storage storage; + private final BackingStorage storage; private int currTokenIndex; private int placeHolderCount; // the parsed statement private ParsedStatementImpl parsedStatement; private SuffixExpression tree; - StatementDescriptorParser(Storage storage, StatementDescriptor desc) { + StatementDescriptorParser(BackingStorage storage, StatementDescriptor desc) { this.tokens = getTokens(desc.getQueryDescriptor()); this.currTokenIndex = 0; this.placeHolderCount = 0; diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/test/java/com/redhat/thermostat/storage/core/QueuedBackingStorageTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/storage/core/src/test/java/com/redhat/thermostat/storage/core/QueuedBackingStorageTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -0,0 +1,214 @@ +/* + * 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 + * . + * + * 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; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.storage.model.Pojo; + + +public class QueuedBackingStorageTest { + + private static class TestExecutor implements ExecutorService { + + private Runnable task; + private boolean shutdown; + + @Override + public void execute(Runnable task) { + this.task = task; + } + + Runnable getTask() { + return task; + } + + @Override + public void shutdown() { + shutdown = true; + } + + @Override + public List shutdownNow() { + // Not used. + shutdown = true; + return null; + } + + @Override + public boolean isShutdown() { + return shutdown; + } + + @Override + public boolean isTerminated() { + // Not used. + return shutdown; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + return true; + } + + @Override + public Future submit(Callable task) { + // Not used. + return null; + } + + @Override + public Future submit(Runnable task, T result) { + // Not used. + return null; + } + + @Override + public Future submit(Runnable task) { + // Not used. + return null; + } + + @Override + public List> invokeAll( + Collection> tasks) + throws InterruptedException { + // Not used. + return null; + } + + @Override + public List> invokeAll( + Collection> tasks, long timeout, + TimeUnit unit) throws InterruptedException { + // Not used. + return null; + } + + @Override + public T invokeAny(Collection> tasks) + throws InterruptedException, ExecutionException { + // Not used. + return null; + } + + @Override + public T invokeAny(Collection> tasks, + long timeout, TimeUnit unit) throws InterruptedException, + ExecutionException, TimeoutException { + // Not used. + return null; + } + + } + + private QueuedBackingStorage queuedStorage; + private BackingStorage delegateStorage; + private Query delegateQuery; + + private TestExecutor executor; + private TestExecutor fileExecutor; + + private Cursor expectedResults; + + @SuppressWarnings("unchecked") + @Before + public void setUp() { + executor = new TestExecutor(); + fileExecutor = new TestExecutor(); + delegateStorage = mock(BackingStorage.class); + + delegateQuery = (Query) mock(Query.class); + expectedResults = (Cursor) mock(Cursor.class); + when(delegateStorage.createQuery(any(Category.class))).thenReturn(delegateQuery); + when(delegateQuery.execute()).thenReturn(expectedResults); + + queuedStorage = new QueuedBackingStorage(delegateStorage, executor, fileExecutor); + } + + @After + public void tearDown() { + expectedResults = null; + queuedStorage = null; + delegateStorage = null; + fileExecutor = null; + executor = null; + delegateQuery = null; + } + + @Test + public void testCreateQuery() { + @SuppressWarnings("unchecked") + Category category = (Category) mock(Category.class); + Query query = queuedStorage.createQuery(category); + verify(delegateStorage).createQuery(category); + verifyNoMoreInteractions(delegateStorage); + + Cursor result = query.execute(); + verify(delegateQuery).execute(); + assertSame(expectedResults, result); + + assertNull(executor.getTask()); + assertNull(fileExecutor.getTask()); + } + + private static class TestPojo implements Pojo { + + } + +} + diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/test/java/com/redhat/thermostat/storage/core/QueuedStorageTest.java --- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/QueuedStorageTest.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/core/src/test/java/com/redhat/thermostat/storage/core/QueuedStorageTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -194,24 +194,16 @@ } } - private static class TestPojo implements Pojo { - - } - private QueuedStorage queuedStorage; private Storage delegateStorage; private Add delegateAdd; private Replace delegateReplace; - private Query delegateQuery; private TestExecutor executor; private TestExecutor fileExecutor; - @SuppressWarnings("rawtypes") - private Cursor expectedResults; private InputStream expectedFile; - @SuppressWarnings("unchecked") @Before public void setUp() { executor = new TestExecutor(); @@ -222,30 +214,23 @@ delegateReplace = mock(Replace.class); Remove remove = mock(Remove.class); - delegateQuery = mock(Query.class); when(delegateStorage.createAdd(any(Category.class))).thenReturn(delegateAdd); when(delegateStorage.createReplace(any(Category.class))).thenReturn(delegateReplace); when(delegateStorage.createRemove()).thenReturn(remove); - when(delegateStorage.createQuery(any(Category.class))).thenReturn(delegateQuery); - expectedResults = mock(Cursor.class); - when(delegateQuery.execute()).thenReturn(expectedResults); when(delegateStorage.getCount(any(Category.class))).thenReturn(42l); expectedFile = mock(InputStream.class); when(delegateStorage.loadFile(anyString())).thenReturn(expectedFile); when(delegateStorage.getAgentId()).thenReturn("huzzah"); queuedStorage = new QueuedStorage(delegateStorage, executor, fileExecutor); - } @After public void tearDown() { expectedFile = null; - expectedResults = null; queuedStorage = null; delegateStorage = null; fileExecutor = null; executor = null; - delegateQuery = null; } @Test @@ -329,22 +314,6 @@ } @Test - public void testFindAllPojos() { - @SuppressWarnings("unchecked") - Category category = mock(Category.class); - Query query = queuedStorage.createQuery(category); - verify(delegateStorage).createQuery(category); - verifyNoMoreInteractions(delegateStorage); - - Cursor result = query.execute(); - verify(delegateQuery).execute(); - assertSame(expectedResults, result); - - assertNull(executor.getTask()); - assertNull(fileExecutor.getTask()); - } - - @Test public void testGetCount() { Category category = mock(Category.class); @@ -535,12 +504,6 @@ } @Override - public Query createQuery(Category category) { - // not implemented - throw new AssertionError(); - } - - @Override public Update createUpdate(Category category) { // not implemented throw new AssertionError(); @@ -564,7 +527,7 @@ } @Override - public PreparedStatement prepareStatement(StatementDescriptor desc) + public PreparedStatement prepareStatement(StatementDescriptor desc) throws DescriptorParsingException { // not implemented return null; diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImplTest.java --- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImplTest.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImplTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -44,13 +44,13 @@ import org.junit.Test; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.Cursor; import com.redhat.thermostat.storage.core.Key; import com.redhat.thermostat.storage.core.Query; import com.redhat.thermostat.storage.core.StatementDescriptor; import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.model.Pojo; import com.redhat.thermostat.storage.query.BinaryComparisonExpression; import com.redhat.thermostat.storage.query.BinaryComparisonOperator; @@ -100,7 +100,7 @@ Category mockCategory = (Category) mock(Category.class); when(desc.getCategory()).thenReturn(mockCategory); when(mockCategory.getName()).thenReturn("foo"); - Storage storage = mock(Storage.class); + BackingStorage storage = mock(BackingStorage.class); StubQuery stmt = new StubQuery(); when(storage.createQuery(mockCategory)).thenReturn(stmt); PreparedStatementImpl preparedStatement = new PreparedStatementImpl<>(storage, desc); @@ -124,7 +124,7 @@ Category mockCategory = (Category) mock(Category.class); when(desc.getCategory()).thenReturn(mockCategory); when(mockCategory.getName()).thenReturn("foo"); - Storage storage = mock(Storage.class); + BackingStorage storage = mock(BackingStorage.class); StubQuery stmt = new StubQuery(); when(storage.createQuery(mockCategory)).thenReturn(stmt); PreparedStatementImpl preparedStatement = new PreparedStatementImpl<>(storage, desc); diff -r e7bdfcace2b0 -r e810fb4143b5 storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorParserTest.java --- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorParserTest.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorParserTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -51,12 +51,12 @@ import org.junit.Before; import org.junit.Test; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.DescriptorParsingException; import com.redhat.thermostat.storage.core.Key; import com.redhat.thermostat.storage.core.Query; import com.redhat.thermostat.storage.core.Query.SortDirection; import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.dao.AgentInfoDAO; import com.redhat.thermostat.storage.model.AgentInformation; import com.redhat.thermostat.storage.internal.statement.BinaryExpressionNode; @@ -77,14 +77,14 @@ public class StatementDescriptorParserTest { - private Storage storage; + private BackingStorage storage; private Query mockQuery; private StatementDescriptorParser parser; @SuppressWarnings("unchecked") @Before public void setup() { - storage = mock(Storage.class); + storage = mock(BackingStorage.class); mockQuery = mock(Query.class); when(storage.createQuery(any(AgentInfoDAO.CATEGORY.getClass()))).thenReturn(mockQuery); } diff -r e7bdfcace2b0 -r e810fb4143b5 storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/MongoStorageProvider.java --- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/MongoStorageProvider.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/MongoStorageProvider.java Wed Jul 31 15:50:35 2013 -0400 @@ -37,7 +37,7 @@ package com.redhat.thermostat.storage.mongodb; import com.redhat.thermostat.storage.config.StartupConfiguration; -import com.redhat.thermostat.storage.core.QueuedStorage; +import com.redhat.thermostat.storage.core.QueuedBackingStorage; import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.core.StorageProvider; import com.redhat.thermostat.storage.mongodb.internal.MongoStorage; @@ -53,7 +53,7 @@ @Override public Storage createStorage() { MongoStorage storage = new MongoStorage(configuration); - return new QueuedStorage(storage); + return new QueuedBackingStorage(storage); } @Override diff -r e7bdfcace2b0 -r e810fb4143b5 storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorage.java --- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorage.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorage.java Wed Jul 31 15:50:35 2013 -0400 @@ -55,6 +55,7 @@ import com.redhat.thermostat.storage.config.StartupConfiguration; import com.redhat.thermostat.storage.core.AbstractQuery.Sort; import com.redhat.thermostat.storage.core.Add; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.BasePut; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.Connection; @@ -69,7 +70,6 @@ import com.redhat.thermostat.storage.core.Remove; import com.redhat.thermostat.storage.core.Replace; 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.model.Pojo; @@ -78,7 +78,7 @@ * * In this implementation, each CATEGORY is given a distinct collection. */ -public class MongoStorage implements Storage { +public class MongoStorage implements BackingStorage { private class MongoAdd extends BasePut implements Add { diff -r e7bdfcace2b0 -r e810fb4143b5 storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorageProviderTest.java --- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorageProviderTest.java Wed Jul 31 21:07:28 2013 +0200 +++ b/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorageProviderTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -36,14 +36,15 @@ package com.redhat.thermostat.storage.mongodb.internal; -import org.junit.Test; - import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.junit.Test; + import com.redhat.thermostat.storage.config.StartupConfiguration; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.QueuedStorage; import com.redhat.thermostat.storage.core.SecureStorage; import com.redhat.thermostat.storage.core.Storage; @@ -59,6 +60,7 @@ provider.setConfig(config); Storage result = provider.createStorage(); assertTrue(result instanceof QueuedStorage); + assertTrue(result instanceof BackingStorage); assertFalse(result instanceof SecureStorage); } } diff -r e7bdfcace2b0 -r e810fb4143b5 web/client/src/main/java/com/redhat/thermostat/web/client/internal/WebStorage.java --- a/web/client/src/main/java/com/redhat/thermostat/web/client/internal/WebStorage.java Wed Jul 31 21:07:28 2013 +0200 +++ b/web/client/src/main/java/com/redhat/thermostat/web/client/internal/WebStorage.java Wed Jul 31 15:50:35 2013 -0400 @@ -101,7 +101,6 @@ import com.redhat.thermostat.storage.core.Key; import com.redhat.thermostat.storage.core.PreparedParameter; import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.Query; import com.redhat.thermostat.storage.core.Remove; import com.redhat.thermostat.storage.core.Replace; import com.redhat.thermostat.storage.core.SecureStorage; @@ -513,14 +512,6 @@ } @Override - public Query createQuery(Category category) { - // There isn't going to be a query end-point on server side. - String msg = "createQuery() not supported for Web storage. " + - "Please use prepareStatement() instead."; - throw new IllegalStateException(msg); - } - - @Override public Remove createRemove() { return new WebRemove(categoryIds); } diff -r e7bdfcace2b0 -r e810fb4143b5 web/client/src/test/java/com/redhat/thermostat/web/client/internal/WebStorageProviderTest.java --- a/web/client/src/test/java/com/redhat/thermostat/web/client/internal/WebStorageProviderTest.java Wed Jul 31 21:07:28 2013 +0200 +++ b/web/client/src/test/java/com/redhat/thermostat/web/client/internal/WebStorageProviderTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -36,16 +36,18 @@ package com.redhat.thermostat.web.client.internal; -import org.junit.Test; -import org.mockito.Mockito; - +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import org.junit.Test; +import org.mockito.Mockito; + import com.redhat.thermostat.storage.config.AuthenticationConfiguration; import com.redhat.thermostat.storage.config.StartupConfiguration; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.QueuedStorage; import com.redhat.thermostat.storage.core.SecureStorage; import com.redhat.thermostat.storage.core.Storage; @@ -61,6 +63,7 @@ Storage storage = provider.createStorage(); assertTrue(storage instanceof SecureStorage); assertTrue(storage instanceof QueuedStorage); + assertFalse(storage instanceof BackingStorage); verify(config, Mockito.atLeastOnce()).getUsername(); verify(config, Mockito.atLeastOnce()).getPassword(); } diff -r e7bdfcace2b0 -r e810fb4143b5 web/client/src/test/java/com/redhat/thermostat/web/client/internal/WebStorageTest.java --- a/web/client/src/test/java/com/redhat/thermostat/web/client/internal/WebStorageTest.java Wed Jul 31 21:07:28 2013 +0200 +++ b/web/client/src/test/java/com/redhat/thermostat/web/client/internal/WebStorageTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -391,17 +391,6 @@ } @Test - public void createQueryFailsCorrectly() throws UnsupportedEncodingException, IOException { - try { - storage.createQuery(category); - fail("createQuery() should fail for WebStorage."); - } catch (IllegalStateException e) { - // pass - assertTrue(e.getMessage().contains("createQuery() not supported")); - } - } - - @Test public void testPut() throws IOException, JsonSyntaxException, ClassNotFoundException { TestObj obj = new TestObj(); diff -r e7bdfcace2b0 -r e810fb4143b5 web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java --- a/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java Wed Jul 31 21:07:28 2013 +0200 +++ b/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java Wed Jul 31 15:50:35 2013 -0400 @@ -92,6 +92,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.redhat.thermostat.storage.core.Add; +import com.redhat.thermostat.storage.core.BackingStorage; import com.redhat.thermostat.storage.core.Categories; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.Cursor; @@ -164,7 +165,7 @@ private Server server; private int port; - private Storage mockStorage; + private BackingStorage mockStorage; private Integer categoryId; private static Key key1; @@ -197,7 +198,7 @@ assertTrue(fakeHome.canRead()); System.setProperty("THERMOSTAT_HOME", fakeHome.getAbsolutePath()); - mockStorage = mock(Storage.class); + mockStorage = mock(BackingStorage.class); StorageWrapper.setStorage(mockStorage); factory = new ExpressionFactory();