Mercurial > hg > thermostat-ng > agent
changeset 2656:12b1a2662939
Remove Storage service and most of the Statement API code
review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/023145.html
reviewed-by: ebaron
author | Mario Torre <neugens.limasoftware@gmail.com> |
---|---|
date | Fri, 19 May 2017 11:58:05 +0200 |
parents | 6d9c3f8c910f |
children | 209c6fbeab9c |
files | agent/cli/src/main/java/com/redhat/thermostat/agent/cli/internal/AgentApplication.java agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java distribution/pom.xml launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java plugins/pom.xml plugins/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOImpl.java plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/Activator.java plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOImpl.java plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOImpl.java plugins/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/ActivatorTest.java storage/core/src/main/java/com/redhat/thermostat/storage/core/AbstractQuery.java storage/core/src/main/java/com/redhat/thermostat/storage/core/Add.java storage/core/src/main/java/com/redhat/thermostat/storage/core/AggregateQuery.java storage/core/src/main/java/com/redhat/thermostat/storage/core/BackingStorage.java storage/core/src/main/java/com/redhat/thermostat/storage/core/DataModifyingStatement.java storage/core/src/main/java/com/redhat/thermostat/storage/core/DbService.java storage/core/src/main/java/com/redhat/thermostat/storage/core/DbServiceFactory.java storage/core/src/main/java/com/redhat/thermostat/storage/core/HostBoundaryPojoGetter.java storage/core/src/main/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetter.java storage/core/src/main/java/com/redhat/thermostat/storage/core/HostTimeIntervalPojoListGetter.java storage/core/src/main/java/com/redhat/thermostat/storage/core/ParsedStatement.java storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedParameter.java storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedParameters.java storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatement.java storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatementFactory.java storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatementSetter.java storage/core/src/main/java/com/redhat/thermostat/storage/core/Query.java storage/core/src/main/java/com/redhat/thermostat/storage/core/QueuedStorage.java storage/core/src/main/java/com/redhat/thermostat/storage/core/Remove.java storage/core/src/main/java/com/redhat/thermostat/storage/core/Replace.java storage/core/src/main/java/com/redhat/thermostat/storage/core/SecureQueuedStorage.java storage/core/src/main/java/com/redhat/thermostat/storage/core/SecureStorage.java storage/core/src/main/java/com/redhat/thermostat/storage/core/Statement.java storage/core/src/main/java/com/redhat/thermostat/storage/core/StatementDescriptor.java storage/core/src/main/java/com/redhat/thermostat/storage/core/StatementExecutionException.java storage/core/src/main/java/com/redhat/thermostat/storage/core/Storage.java storage/core/src/main/java/com/redhat/thermostat/storage/core/StorageProvider.java storage/core/src/main/java/com/redhat/thermostat/storage/core/Update.java storage/core/src/main/java/com/redhat/thermostat/storage/core/VmBoundaryPojoGetter.java storage/core/src/main/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetter.java storage/core/src/main/java/com/redhat/thermostat/storage/core/VmTimeIntervalPojoListGetter.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDao.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDaoOperation.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDaoOperationResult.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDaoQuery.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDaoStatement.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/BaseCountable.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/DaoOperation.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/DaoQuery.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/DaoStatement.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/QueryResult.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/SimpleDaoQuery.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/SimpleDaoStatement.java storage/core/src/main/java/com/redhat/thermostat/storage/dao/StatementResult.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/CountingDecorator.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/DbServiceImpl.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/LoggingUtil.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/AbstractUnfinished.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/BasicDescriptorParser.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/BinaryExpressionNode.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/LimitExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Node.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/NotBooleanExpressionNode.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Operator.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/ParsedStatementImpl.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Patchable.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PatchedExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PatchedSetListMember.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PatchedSortMember.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PatchedWhereExpressionImpl.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImpl.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Printable.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SemanticsEnabledDescriptorParser.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SetList.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SetListValue.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SortExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SortMember.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorParser.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SuffixExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/TerminalNode.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/UnaryExpressionNode.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Unfinished.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/UnfinishedLimitValue.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/UnfinishedSortKey.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/UnfinishedValueNode.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/WhereExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryComparisonExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryComparisonOperator.java storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryLogicalExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryLogicalOperator.java storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryOperator.java storage/core/src/main/java/com/redhat/thermostat/storage/query/BinarySetMembershipExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/BinarySetMembershipOperator.java storage/core/src/main/java/com/redhat/thermostat/storage/query/ComparisonExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/Expression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/ExpressionFactory.java storage/core/src/main/java/com/redhat/thermostat/storage/query/LiteralExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/LiteralSetExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/LogicalExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/Operator.java storage/core/src/main/java/com/redhat/thermostat/storage/query/UnaryExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/UnaryLogicalExpression.java storage/core/src/main/java/com/redhat/thermostat/storage/query/UnaryLogicalOperator.java storage/core/src/main/java/com/redhat/thermostat/storage/query/UnaryOperator.java storage/core/src/test/java/com/redhat/thermostat/storage/core/AggregateQueryTest.java storage/core/src/test/java/com/redhat/thermostat/storage/core/HostBoundaryPojoGetterTest.java storage/core/src/test/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetterTest.java storage/core/src/test/java/com/redhat/thermostat/storage/core/PreparedParamentersTest.java storage/core/src/test/java/com/redhat/thermostat/storage/core/QueuedStorageTest.java storage/core/src/test/java/com/redhat/thermostat/storage/core/StatementDescriptorTest.java storage/core/src/test/java/com/redhat/thermostat/storage/core/VmBoundaryPojoGetterTest.java storage/core/src/test/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetterTest.java storage/core/src/test/java/com/redhat/thermostat/storage/core/VmTimeIntervalPojoListGetterTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoOperationResultTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoOperationTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoQueryTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoStatementTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/BaseCountableTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/QueryResultTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/SimpleDaoQueryTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/SimpleDaoStatementTest.java storage/core/src/test/java/com/redhat/thermostat/storage/dao/StatementResultTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/ActivatorTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/DbServiceImplTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/BasicDescriptorParserTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/DescriptorParserImplFactory.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/LimitExpressionTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/ParsedStatementImplTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/ParserType.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImplTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/SemanticsEnabledDescriptorParserTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/SetListValueTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/SortMemberTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorTester.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/TerminalNodeTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/TestParser.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/WhereExpressions.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/WhereExpressionsTest.java storage/core/src/test/java/com/redhat/thermostat/storage/query/BinaryExpressionTest.java storage/core/src/test/java/com/redhat/thermostat/storage/query/ExpressionFactoryTest.java storage/core/src/test/java/com/redhat/thermostat/storage/query/LiteralExpressionTest.java storage/core/src/test/java/com/redhat/thermostat/storage/query/LiteralSetExpressionTest.java storage/core/src/test/java/com/redhat/thermostat/storage/query/UnaryExpressionTest.java storage/pom.xml storage/testutils/pom.xml storage/testutils/src/main/java/com/redhat/thermostat/storage/internal/statement/DescriptorParserImplFactory.java storage/testutils/src/main/java/com/redhat/thermostat/storage/internal/statement/TestParser.java storage/testutils/src/main/java/com/redhat/thermostat/storage/testutils/ParserType.java storage/testutils/src/main/java/com/redhat/thermostat/storage/testutils/StatementDescriptorTester.java storage/testutils/src/main/java/com/redhat/thermostat/storage/testutils/package-info.java storage/testutils/src/test/java/com/redhat/thermostat/storage/testutils/StatementDescriptorTesterTest.java |
diffstat | 154 files changed, 40 insertions(+), 19170 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/internal/AgentApplication.java Fri May 19 11:37:45 2017 +0200 +++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/internal/AgentApplication.java Fri May 19 11:58:05 2017 +0200 @@ -292,7 +292,7 @@ public void dependenciesUnavailable() { if (shutdownLatch.getCount() > 0) { // In the rare case we lose one of our deps, gracefully shutdown - logger.severe("Storage unexpectedly became unavailable"); + logger.severe("Dependencies unexpectedly became unavailable"); shutdown(ExitStatus.EXIT_ERROR); } }
--- a/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java Fri May 19 11:37:45 2017 +0200 +++ b/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java Fri May 19 11:58:05 2017 +0200 @@ -50,12 +50,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.commons.codec.binary.Base64; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; - - import com.redhat.thermostat.agent.command.ConfigurationServer; import com.redhat.thermostat.agent.command.ReceiverRegistry; import com.redhat.thermostat.agent.command.RequestReceiver; @@ -69,9 +63,6 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.shared.config.SSLConfiguration; import com.redhat.thermostat.shared.config.OS; -import com.redhat.thermostat.storage.core.AuthToken; -import com.redhat.thermostat.storage.core.SecureStorage; -import com.redhat.thermostat.storage.core.Storage; class CommandChannelDelegate implements ConfigurationServer, ThermostatIPCCallbacks { @@ -87,7 +78,6 @@ private final ReceiverRegistry receivers; private final SSLConfiguration sslConf; - private final StorageGetter storageGetter; private final File binPath; private final AgentIPCService ipcService; private final CountDownLatch readyLatch; @@ -103,16 +93,15 @@ CommandChannelDelegate(ReceiverRegistry receivers, SSLConfiguration sslConf, File binPath, AgentIPCService ipcService) { this(receivers, sslConf, binPath, ipcService, new CountDownLatch(1), new SSLConfigurationEncoder(), - new AgentRequestDecoder(), new AgentResponseEncoder(), new StorageGetter(), new ProcessUserInfoBuilder(), + new AgentRequestDecoder(), new AgentResponseEncoder(), new ProcessUserInfoBuilder(), new FileSystemUtils(), new ProcessCreator()); } /** For testing only */ CommandChannelDelegate(ReceiverRegistry receivers, SSLConfiguration sslConf, File binPath, AgentIPCService ipcService, CountDownLatch readyLatch, SSLConfigurationEncoder sslEncoder, - AgentRequestDecoder requestDecoder, AgentResponseEncoder responseEncoder, StorageGetter getter, + AgentRequestDecoder requestDecoder, AgentResponseEncoder responseEncoder, ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils, ProcessCreator procCreator) { - this.storageGetter = getter; this.receivers = receivers; this.sslConf = sslConf; this.binPath = binPath; @@ -302,37 +291,12 @@ } private boolean authenticateRequestIfNecessary(Request request) { - Storage storage = storageGetter.get(); - boolean result = false; - if (storage instanceof SecureStorage) { - result = authenticateRequest(request, (SecureStorage) storage); - if (result) { - logger.finest("Authentication and authorization for request " + request + " succeeded!"); - } else { - logger.finest("Request " + request + " failed to authenticate or authorize"); - } - } else { - result = true; - } - storageGetter.unget(); - return result; - } - - private boolean authenticateRequest(Request request, SecureStorage storage) { - String clientTokenStr = request.getParameter(Request.CLIENT_TOKEN); - byte[] clientToken = Base64.decodeBase64(clientTokenStr); - String authTokenStr = request.getParameter(Request.AUTH_TOKEN); - byte[] authToken = Base64.decodeBase64(authTokenStr); - AuthToken token = new AuthToken(authToken, clientToken); - String actionName = request.getParameter(Request.ACTION); - try { - // actionName must not be null here. If we somehow get a bogus request - // at this point where this does not exist, verifyToken will throw a - // NPE. - return storage.verifyToken(token, actionName); - } catch (NullPointerException e) { - return false; - } + /* + * FIXME Authentication no longer works after the introduction of the + * web gateway. For now, we bypass authentication until the new + * WebSockets command channel is integrated. + */ + return true; } private boolean checkStart(byte[] data) { @@ -361,22 +325,6 @@ } /** for testing only */ - static class StorageGetter { - Storage get() { - BundleContext bCtx = FrameworkUtil.getBundle(getClass()).getBundleContext(); - ServiceReference<Storage> storageRef = bCtx.getServiceReference(Storage.class); - Storage storage = (Storage) bCtx.getService(storageRef); - return storage; - } - - void unget() { - BundleContext bCtx = FrameworkUtil.getBundle(getClass()).getBundleContext(); - ServiceReference<Storage> storageRef = bCtx.getServiceReference(Storage.class); - bCtx.ungetService(storageRef); - } - } - - /** for testing only */ static class ProcessCreator { Process startProcess(ProcessBuilder builder) throws IOException { return builder.start();
--- a/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java Fri May 19 11:37:45 2017 +0200 +++ b/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java Fri May 19 11:58:05 2017 +0200 @@ -58,7 +58,6 @@ import java.util.List; import java.util.concurrent.CountDownLatch; -import org.apache.commons.codec.binary.Base64; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -69,7 +68,6 @@ import com.redhat.thermostat.agent.command.RequestReceiver; import com.redhat.thermostat.agent.command.internal.CommandChannelDelegate.FileSystemUtils; import com.redhat.thermostat.agent.command.internal.CommandChannelDelegate.ProcessCreator; -import com.redhat.thermostat.agent.command.internal.CommandChannelDelegate.StorageGetter; import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.ipc.server.IPCMessage; import com.redhat.thermostat.common.command.Request; @@ -78,8 +76,6 @@ import com.redhat.thermostat.common.command.Response.ResponseType; import com.redhat.thermostat.shared.config.OS; import com.redhat.thermostat.shared.config.SSLConfiguration; -import com.redhat.thermostat.storage.core.AuthToken; -import com.redhat.thermostat.storage.core.SecureStorage; public class CommandChannelDelegateTest { @@ -90,7 +86,6 @@ private static final byte[] ENCODED_RESPONSE_AUTH_FAILED = { 'A', 'U', 'T', 'H' }; private static final byte[] ENCODED_RESPONSE_ERROR = { 'E', 'R', 'R' }; - private StorageGetter storageGetter; private ProcessCreator processCreator; private ReceiverRegistry receivers; private File binPath; @@ -112,7 +107,6 @@ receivers = mock(ReceiverRegistry.class); sslConf = mock(SSLConfiguration.class); binPath = new File("/path/to/thermostat/home/"); - storageGetter = mock(StorageGetter.class); processCreator = mock(ProcessCreator.class); process = mock(Process.class); ipcService = mock(AgentIPCService.class); @@ -148,7 +142,7 @@ fsUtils = mock(FileSystemUtils.class); userInfoBuilder = mock(ProcessUserInfoBuilder.class); delegate = new CommandChannelDelegate(receivers, sslConf, binPath, ipcService, - latch, sslConfEncoder, requestDecoder, responseEncoder, storageGetter, userInfoBuilder, + latch, sslConfEncoder, requestDecoder, responseEncoder, userInfoBuilder, fsUtils, processCreator); startedMessage = mock(IPCMessage.class); @@ -395,84 +389,6 @@ assertArrayEquals(ENCODED_RESPONSE_ERROR, result); } - @Test - public void testAuthenticateSuccess() throws IOException { - SecureStorage secStorage = mock(SecureStorage.class); - when(storageGetter.get()).thenReturn(secStorage); - - RequestReceiver receiver = mock(RequestReceiver.class); - Request request = createRequest(receiver); - - // Create tokens - final String authToken = "TXlBdXRoVG9rZW4="; - final String clientToken = "TXlDbGllbnRUb2tlbg=="; - when(request.getParameter(Request.AUTH_TOKEN)).thenReturn(authToken); - when(request.getParameter(Request.CLIENT_TOKEN)).thenReturn(clientToken); - when(request.getParameter(Request.ACTION)).thenReturn("DoSomething"); - - mockVerifyToken(secStorage, authToken, clientToken); - - byte[] result = receiveRequestAndReturnResponse(request); - verify(receiver).receive(request); - assertArrayEquals(ENCODED_RESPONSE_OK, result); - } - - @Test - public void testAuthenticateFailed() throws IOException { - SecureStorage secStorage = mock(SecureStorage.class); - when(storageGetter.get()).thenReturn(secStorage); - - RequestReceiver receiver = mock(RequestReceiver.class); - Request request = createRequest(receiver); - - // Create tokens - final String authToken = "TXlBdXRoVG9rZW4="; - final String clientToken = "TXlDbGllbnRUb2tlbg=="; - when(request.getParameter(Request.AUTH_TOKEN)).thenReturn(authToken); - when(request.getParameter(Request.CLIENT_TOKEN)).thenReturn(clientToken); - when(request.getParameter(Request.ACTION)).thenReturn("DoSomething"); - - mockVerifyToken(secStorage, "TXlFdmlsVG9rZW4=", clientToken); - - byte[] result = receiveRequestAndReturnResponse(request); - verify(receiver, never()).receive(request); - assertArrayEquals(ENCODED_RESPONSE_AUTH_FAILED, result); - } - - @Test - public void testAuthenticateNPE() throws IOException { - SecureStorage secStorage = mock(SecureStorage.class); - when(storageGetter.get()).thenReturn(secStorage); - - RequestReceiver receiver = mock(RequestReceiver.class); - Request request = createRequest(receiver); - - // Create tokens - final String authToken = "TXlBdXRoVG9rZW4="; - final String clientToken = "TXlDbGllbnRUb2tlbg=="; - when(request.getParameter(Request.AUTH_TOKEN)).thenReturn(authToken); - when(request.getParameter(Request.CLIENT_TOKEN)).thenReturn(clientToken); - - when(secStorage.verifyToken(any(AuthToken.class), any(String.class))).thenThrow(new NullPointerException()); - - byte[] result = receiveRequestAndReturnResponse(request); - verify(receiver, never()).receive(request); - assertArrayEquals(ENCODED_RESPONSE_AUTH_FAILED, result); - } - - private void mockVerifyToken(SecureStorage secStorage, - final String authToken, final String clientToken) { - when(secStorage.verifyToken(any(AuthToken.class), eq("DoSomething"))).thenAnswer(new Answer<Boolean>() { - @Override - public Boolean answer(InvocationOnMock invocation) throws Throwable { - AuthToken token = (AuthToken) invocation.getArguments()[0]; - boolean authMatches = Arrays.equals(token.getToken(), Base64.decodeBase64(authToken)); - boolean clientMatches = Arrays.equals(token.getClientToken(), Base64.decodeBase64(clientToken)); - return authMatches && clientMatches; - } - }); - } - private Request createRequest(RequestReceiver receiver) { Request request = mock(Request.class); when(request.getType()).thenReturn(RequestType.RESPONSE_EXPECTED);
--- a/distribution/pom.xml Fri May 19 11:37:45 2017 +0200 +++ b/distribution/pom.xml Fri May 19 11:58:05 2017 +0200 @@ -554,12 +554,12 @@ <!--<version>${project.version}</version>--> <!--<type>zip</type>--> <!--</dependency>--> - <dependency> - <groupId>com.redhat.thermostat</groupId> - <artifactId>thermostat-vm-cpu-distribution</artifactId> - <version>${project.version}</version> - <type>zip</type> - </dependency> + <!--<dependency>--> + <!--<groupId>com.redhat.thermostat</groupId>--> + <!--<artifactId>thermostat-vm-cpu-distribution</artifactId>--> + <!--<version>${project.version}</version>--> + <!--<type>zip</type>--> + <!--</dependency>--> <dependency> <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-vm-gc-distribution</artifactId>
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Fri May 19 11:37:45 2017 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Fri May 19 11:58:05 2017 +0200 @@ -74,7 +74,6 @@ import com.redhat.thermostat.launcher.Launcher; import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.locale.Translate; -import com.redhat.thermostat.storage.core.Storage; /** * This class is thread-safe. @@ -183,13 +182,6 @@ // default to success for exit status int exitStatus = ExitStatus.EXIT_SUCCESS; if (context != null) { - ServiceReference storageRef = context.getServiceReference(Storage.class); - if (storageRef != null) { - Storage storage = (Storage) context.getService(storageRef); - if (storage != null) { - storage.shutdown(); - } - } ServiceReference exitStatusRef = context.getServiceReference(ExitStatus.class); if (exitStatusRef != null) { ExitStatus exitStatusService = (ExitStatus) context.getService(exitStatusRef);
--- a/plugins/pom.xml Fri May 19 11:37:45 2017 +0200 +++ b/plugins/pom.xml Fri May 19 11:58:05 2017 +0200 @@ -57,7 +57,7 @@ <!--<module>host-cpu</module>--> <!--<module>host-memory</module>--> <!--<module>vm-byteman</module>--> - <module>vm-cpu</module> + <!--<module>vm-cpu</module>--> <module>vm-gc</module> <!--<module>vm-classstat</module>--> <!--<module>vm-compiler</module>-->
--- a/plugins/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOImpl.java Fri May 19 11:37:45 2017 +0200 +++ b/plugins/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOImpl.java Fri May 19 11:58:05 2017 +0200 @@ -45,7 +45,6 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; import com.redhat.thermostat.vm.gc.common.VmGcStatDAO; import com.redhat.thermostat.vm.gc.common.model.VmGcStat; import org.eclipse.jetty.client.HttpClient; @@ -55,7 +54,7 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; -public class VmGcStatDAOImpl extends AbstractDao implements VmGcStatDAO { +public class VmGcStatDAOImpl implements VmGcStatDAO { private static final Logger logger = LoggingUtils.getLogger(VmGcStatDAOImpl.class); @@ -94,7 +93,6 @@ } } - @Override public Logger getLogger() { return logger; }
--- a/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/Activator.java Fri May 19 11:37:45 2017 +0200 +++ b/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/Activator.java Fri May 19 11:58:05 2017 +0200 @@ -36,16 +36,8 @@ package com.redhat.thermostat.vm.memory.common.internal; -import java.util.ArrayList; -import java.util.List; - import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; - -import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; import com.redhat.thermostat.vm.memory.common.VmTlabStatDAO;
--- a/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOImpl.java Fri May 19 11:37:45 2017 +0200 +++ b/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOImpl.java Fri May 19 11:58:05 2017 +0200 @@ -45,7 +45,6 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; import com.redhat.thermostat.vm.memory.common.model.VmMemoryStat; import org.eclipse.jetty.client.HttpClient; @@ -55,7 +54,7 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; -class VmMemoryStatDAOImpl extends AbstractDao implements VmMemoryStatDAO { +class VmMemoryStatDAOImpl implements VmMemoryStatDAO { private static final Logger logger = LoggingUtils.getLogger(VmMemoryStatDAOImpl.class); @@ -104,7 +103,6 @@ } } - @Override protected Logger getLogger() { return logger; }
--- a/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOImpl.java Fri May 19 11:37:45 2017 +0200 +++ b/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOImpl.java Fri May 19 11:58:05 2017 +0200 @@ -45,7 +45,6 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; import com.redhat.thermostat.vm.memory.common.VmTlabStatDAO; import com.redhat.thermostat.vm.memory.common.model.VmTlabStat; @@ -56,7 +55,7 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; -class VmTlabStatDAOImpl extends AbstractDao implements VmTlabStatDAO { +class VmTlabStatDAOImpl implements VmTlabStatDAO { private static final String GATEWAY_URL = "http://localhost:30000"; // TODO configurable private static final String GATEWAY_PATH = "/jvm-memory/0.0.2/"; @@ -106,7 +105,6 @@ } } - @Override protected Logger getLogger() { return logger; }
--- a/plugins/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/ActivatorTest.java Fri May 19 11:37:45 2017 +0200 +++ b/plugins/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/ActivatorTest.java Fri May 19 11:58:05 2017 +0200 @@ -38,11 +38,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; - import org.junit.Test; -import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.testutils.StubBundleContext; import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO;
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/AbstractQuery.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.redhat.thermostat.storage.model.Pojo; - -public abstract class AbstractQuery<T extends Pojo> implements Query<T> { - - public static class Sort { - private Key<?> key; - private SortDirection direction; - public Sort() { - this(null, null); - } - - public Sort(Key<?> key, SortDirection direction) { - this.key = key; - this.direction = direction; - } - public Key<?> getKey() { - return key; - } - public void setKey(Key<?> key) { - this.key = key; - } - public SortDirection getDirection() { - return direction; - } - public void setDirection(SortDirection direction) { - this.direction = direction; - } - - public int hashCode() { - return Objects.hash(key, direction); - } - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (obj == this) { - return true; - } - if (!(obj instanceof Sort)) { - return false; - } - Sort other = (Sort) obj; - return Objects.equals(key, other.key) && Objects.equals(direction, other.direction); - } - } - - private List<Sort> sorts; - private int limit = -1; - - public AbstractQuery() { - sorts = new ArrayList<>(); - } - - @Override - public void sort(Key<?> key, SortDirection direction) { - sorts.add(new Sort(key, direction)); - } - - public List<Sort> getSorts() { - return sorts; - } - - public void setSorts(List<Sort> sorts) { - this.sorts = sorts; - } - - @Override - public void limit(int limit) { - this.limit = limit; - } - - public int getLimit() { - return limit; - } - - public void setLimit(int limit) { - this.limit = limit; - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Add.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; - -/** - * Write operation to be used for adding new records into - * storage. - * - * @see Remove - * @see Replace - * @see Update - */ -public interface Add<T extends Pojo> extends DataModifyingStatement<T> { - - /** - * Sets a field to the specified value. If the same key is - * set more than once, the latest value overrides the former value for that - * key. - * - * @param key - * the name of the field to update. - * @param value - * the value with which to update the field. - */ - void set(String key, Object value); - - /** - * Applies this {@code Add} operation to storage. - * - * @throws StorageException if the operation fails - */ - int apply(); -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/AggregateQuery.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import java.util.Objects; - -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.Expression; - -/** - * Common super class for aggregate queries. - */ -public abstract class AggregateQuery<T extends Pojo> implements Query<T> { - - public enum AggregateFunction { - /** - * Aggregate records by counting them. - */ - COUNT, - /** - * Find distinct values for a {@link Key} - */ - DISTINCT, - } - - protected final Query<T> queryToAggregate; - private final AggregateFunction function; - // optional Key to aggregate values for - private Key<?> aggregateKey; - - public AggregateQuery(AggregateFunction function, Query<T> queryToAggregate) { - this.function = function; - this.queryToAggregate = queryToAggregate; - } - - @Override - public void where(Expression expr) { - queryToAggregate.where(expr); - } - - @Override - public void sort(Key<?> key, - SortDirection direction) { - queryToAggregate.sort(key, direction); - } - - @Override - public void limit(int n) { - queryToAggregate.limit(n); - } - - @Override - public Expression getWhereExpression() { - return queryToAggregate.getWhereExpression(); - } - - /** - * - * @return The function by which to aggregate by. - */ - public AggregateFunction getAggregateFunction() { - return this.function; - } - - /** - * - * @return An optional {@link Key} to aggregate values for. May be - * {@code null}; - */ - public Key<?> getAggregateKey() { - return aggregateKey; - } - - /** - * Sets an optional {@link Key} to aggregate values for. - * @param aggregateKey Must not be {@code null}. - * @throws NullPointerException If the aggregate key was {@code null} - */ - public void setAggregateKey(Key<?> aggregateKey) { - this.aggregateKey = Objects.requireNonNull(aggregateKey); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/BackingStorage.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.core.AggregateQuery.AggregateFunction; -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 { - - <T extends Pojo> Query<T> createQuery(Category<T> category); - - <T extends Pojo> AggregateQuery<T> createAggregateQuery(AggregateFunction function, Category<T> category); - - <T extends Pojo> Add<T> createAdd(Category<T> category); - - <T extends Pojo> Replace<T> createReplace(Category<T> category); - - <T extends Pojo> Update<T> createUpdate(Category<T> category); - - <T extends Pojo> Remove<T> createRemove(Category<T> category); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/DataModifyingStatement.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; - -/** - * Marker interface for {@link Statement}s which perform write operations on - * storage. These statements usually only return success/failure responses or - * more specific error codes. - * - */ -public interface DataModifyingStatement<T extends Pojo> extends Statement<T> { - - /** - * Default success status. The status code itself has no meaning other than - * indicating success. Suitable to be returned on {@link #apply()}. - */ - public static final int DEFAULT_STATUS_SUCCESS = 0; - /** - * Default failure status. The status code itself has no meaning other than - * indicating failure. Suitable to be returned on {@link #apply()}. - */ - public static final int DEFAULT_STATUS_FAILURE = -1; - - /** - * Executes this statement. - * - * @throws StorageException if this statement fails to apply - * - * @return a number greater than or equal to zero on success. A negative - * failure code otherwise. - */ - int apply(); -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/DbService.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.annotations.Service; -import com.redhat.thermostat.storage.core.ConnectionException; -import com.redhat.thermostat.storage.core.Connection.ConnectionListener; - -/** - * DbService provides API for handling database (i.e. {@link Storage}) - * connections. Once {@link DbService#connect()} has been called, the current - * instance can be retrieved as service. This registered service instance could - * then be used to disconnect from storage. - * - * @see {@link DbServiceFactory} - */ -@Service -public interface DbService { - - /** - * Connects to {@link Storage} and registers {@link Storage} instance which - * was used for the connection as a service. - * - * <br/> - * <br/> - * <strong>Pre:</strong> Neither DbService nor Storage are registered as - * services. <br/> - * <strong>Post:</strong> Both DbService and Storage are registered as - * services. - * - * @throws ConnectionException - * If DB connection cannot be established. - */ - void connect() throws ConnectionException; - - /** - * Disconnects from {@link Storage}. - * - * <br/> - * <br/> - * <strong>Pre:</strong> Both DbService and Storage are registered as - * services. - * <br/> - * <strong>Post:</strong> Neither DbService nor Storage are registered as - * services. - * - * @throws ConnectionException - */ - void disconnect() throws ConnectionException; - - /** - * @returns the storage URL which was used for connection. - * - * @throws IllegalStateException - * if not connected to storage. - */ - String getConnectionUrl(); - - /** - * @returns the username which was used for the connection - * @see Connection#getUsername() - */ - String getUserName(); - - /** - * Registers the supplied ConnectionListener to be notified when the status - * of the database connection changes. - * - * @param listener - * - the listener to be registered - */ - void addConnectionListener(ConnectionListener listener); - - /** - * Unregisters the supplied ConnectionListener if it was previously - * registered via {@link #addConnectionListener(ConnectionListener)}. - * - * @param listener - * - the listener to be unregistered - */ - void removeConnectionListener(ConnectionListener listener); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/DbServiceFactory.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.shared.config.SSLConfiguration; -import com.redhat.thermostat.storage.internal.DbServiceImpl; - -/* - * Factory in order to be able to hide the DbService implementation. Note that - * this package will be part of Export-Package whereas the package where *Impl - * classes are won't be. - * - */ -/** - * Factory for creating new {@link DbService} instances. - * - * @see {@link DbService}, {@link StorageProvider}. - * - */ -public class DbServiceFactory { - - /** - * Creates a <strong>new</strong> {@link DbService} instance which can be - * used to establish a connection with {@link Storage}. Note that the actual - * {@link StorageProvider} which will be used for the connection is looked - * up based on registered StorageProvider OSGi services and URLs they are - * able to handle. If a {@link DbService} instance is already registered as - * a service, users are encouraged to use that instance for disconnecting - * from storage. - * - * @param dbUrl - * The URL to the storage endpoint. For example - * {@code mongodb://127.0.0.1:27518} or - * {@code https://storage.example.com/storage}. - * @param creds - * The credentials to use for the connection. - * @param sslConf - * The TLS configuration to use for the connection. - * @return A new {@link DbService} instance which can be used for - * establishing new storage connections. - * @throws StorageException - * If no matching {@link StorageProvider} could be found for the - * given dbUrl. - */ - public DbService createDbService(String dbUrl, StorageCredentials creds, SSLConfiguration sslConf) throws StorageException { - return DbServiceImpl.create(dbUrl, creds, sslConf); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/HostBoundaryPojoGetter.java Fri May 19 11:37:45 2017 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/HostBoundaryPojoGetter.java Fri May 19 11:58:05 2017 +0200 @@ -39,11 +39,9 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; -import com.redhat.thermostat.storage.dao.AbstractDaoQuery; import com.redhat.thermostat.storage.model.TimeStampedPojo; -public class HostBoundaryPojoGetter<T extends TimeStampedPojo> extends AbstractDao { +public class HostBoundaryPojoGetter<T extends TimeStampedPojo> { // QUERY %s WHERE 'agentId' = ?s AND \ // SORT 'timeStamp' DSC \ @@ -63,13 +61,11 @@ private static final Logger logger = LoggingUtils.getLogger(HostBoundaryPojoGetter.class); - private final Storage storage; private final Category<T> cat; private final String queryNewest; private final String queryOldest; - public HostBoundaryPojoGetter(Storage storage, Category<T> cat) { - this.storage = storage; + public HostBoundaryPojoGetter(Category<T> cat) { this.cat = cat; this.queryNewest = String.format(DESC_NEWEST_HOST_STAT, cat.getName()); this.queryOldest = String.format(DESC_OLDEST_HOST_STAT, cat.getName()); @@ -100,13 +96,7 @@ } private T runAgentIdQuery(final String agentId, final String descriptor) { - return executeQuery(new AbstractDaoQuery<T>(storage, cat, descriptor) { - @Override - public PreparedStatement<T> customize(PreparedStatement<T> preparedStatement) { - preparedStatement.setString(0, agentId); - return preparedStatement; - } - }).head(); + return null; } //Package private for testing @@ -118,7 +108,6 @@ return queryOldest; } - @Override protected Logger getLogger() { return logger; }
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetter.java Fri May 19 11:37:45 2017 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetter.java Fri May 19 11:58:05 2017 +0200 @@ -40,14 +40,12 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; -import com.redhat.thermostat.storage.dao.AbstractDaoQuery; import com.redhat.thermostat.storage.model.TimeStampedPojo; /** * @see HostTimeIntervalPojoListGetter */ -public class HostLatestPojoListGetter<T extends TimeStampedPojo> extends AbstractDao { +public class HostLatestPojoListGetter<T extends TimeStampedPojo> { public static final String HOST_LATEST_QUERY_FORMAT = "QUERY %s WHERE '" + Key.AGENT_ID.getName() + "' = ?s AND '" @@ -56,12 +54,10 @@ private static final Logger logger = LoggingUtils.getLogger(HostLatestPojoListGetter.class); - private final Storage storage; private final Category<T> cat; private final String queryLatest; - public HostLatestPojoListGetter(Storage storage, Category<T> cat) { - this.storage = storage; + public HostLatestPojoListGetter(Category<T> cat) { this.cat = cat; this.queryLatest = String.format(HOST_LATEST_QUERY_FORMAT, cat.getName()); } @@ -75,14 +71,7 @@ } public List<T> getLatest(final AgentId agentId, final long since) { - return executeQuery(new AbstractDaoQuery<T>(storage, cat, queryLatest) { - @Override - public PreparedStatement<T> customize(PreparedStatement<T> preparedStatement) { - preparedStatement.setString(0, agentId.get()); - preparedStatement.setLong(1, since); - return preparedStatement; - } - }).asList(); + return null; } // package private for testing @@ -90,7 +79,6 @@ return queryLatest; } - @Override protected Logger getLogger() { return logger; }
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/HostTimeIntervalPojoListGetter.java Fri May 19 11:37:45 2017 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/HostTimeIntervalPojoListGetter.java Fri May 19 11:58:05 2017 +0200 @@ -40,14 +40,12 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; -import com.redhat.thermostat.storage.dao.AbstractDaoQuery; import com.redhat.thermostat.storage.model.TimeStampedPojo; /** * @see HostLatestPojoListGetter */ -public class HostTimeIntervalPojoListGetter<T extends TimeStampedPojo> extends AbstractDao { +public class HostTimeIntervalPojoListGetter<T extends TimeStampedPojo> { public static final String HOST_INTERVAL_QUERY_FORMAT = "QUERY %s WHERE '" + Key.AGENT_ID.getName() + "' = ?s AND '" @@ -57,12 +55,10 @@ private static final Logger logger = LoggingUtils.getLogger(HostTimeIntervalPojoListGetter.class); - private final Storage storage; private final Category<T> cat; private final String query; - public HostTimeIntervalPojoListGetter(Storage storage, Category<T> cat) { - this.storage = storage; + public HostTimeIntervalPojoListGetter(Category<T> cat) { this.cat = cat; this.query = String.format(HOST_INTERVAL_QUERY_FORMAT, cat.getName()); } @@ -76,15 +72,7 @@ } public List<T> getLatest(final AgentId agentId, final long since, final long to) { - return executeQuery(new AbstractDaoQuery<T>(storage, cat, query) { - @Override - public PreparedStatement<T> customize(PreparedStatement<T> preparedStatement) { - preparedStatement.setString(0, agentId.get()); - preparedStatement.setLong(1, since); - preparedStatement.setLong(2, to); - return preparedStatement; - } - }).asList(); + return null; } // package private for testing @@ -92,7 +80,6 @@ return query; } - @Override protected Logger getLogger() { return logger; }
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/ParsedStatement.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; - -/** - * An intermediary representation of a {@link PreparedStatement}. - * - */ -public interface ParsedStatement<T extends Pojo> { - - /** - * Patches a statement, setting free variables. After patching, the - * statement is ready for execution. - * - * @param params - * The ordered list of values/types of free parameters. - * @return The statement ready for execution. - * @throws IllegalPatchException - * If the patching fails for some reason. - */ - Statement<T> patchStatement(PreparedParameter[] params) - throws IllegalPatchException; - - /** - * - * @return The number of free variables which the original prepared - * statement string descriptor contained. - */ - int getNumParams(); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedParameter.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -/** - * Represents a prepared parameter. - * - * @see PreparedParameters - */ -public class PreparedParameter { - - private Object value; - // The type of the value field. This is the instantiable component type for - // Pojo array values. - private Class<?> type; - - PreparedParameter(Object value, Class<?> type) { - this.value = value; - this.type = type; - } - - public PreparedParameter() { - // nothing. Exists for serialization purposes. - } - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - public Class<?> getType() { - return type; - } - - public void setType(Class<?> type) { - this.type = type; - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedParameters.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import java.lang.reflect.Modifier; -import java.util.Objects; - -import com.redhat.thermostat.storage.model.Pojo; - -/** - * - * Shared class for setting prepared parameters. - * - */ -public final class PreparedParameters implements PreparedStatementSetter { - - private PreparedParameter[] params; - - public PreparedParameters(int numParams) { - params = new PreparedParameter[numParams]; - } - - @SuppressWarnings("unused") - private PreparedParameters() { - // nothing. Exists for serialization purposes. - } - - @Override - public void setLong(int paramIndex, long paramValue) { - setType(paramIndex, paramValue, long.class); - } - - @Override - public void setLongList(int paramIndex, long[] paramValue) { - setType(paramIndex, paramValue, long[].class); - } - - @Override - public void setInt(int paramIndex, int paramValue) { - setType(paramIndex, paramValue, int.class); - } - - @Override - public void setIntList(int paramIndex, int[] paramValue) { - setType(paramIndex, paramValue, int[].class); - } - - @Override - public void setBoolean(int paramIndex, boolean paramValue) { - setType(paramIndex, paramValue, boolean.class); - } - - @Override - public void setBooleanList(int paramIndex, boolean[] paramValue) { - setType(paramIndex, paramValue, boolean[].class); - } - - @Override - public void setString(int paramIndex, String paramValue) { - setType(paramIndex, paramValue, String.class); - } - - @Override - public void setStringList(int paramIndex, String[] paramValue) { - setType(paramIndex, paramValue, String[].class); - } - - @Override - public void setDouble(int paramIndex, double paramValue) { - setType(paramIndex, paramValue, double.class); - } - - @Override - public void setDoubleList(int paramIndex, double[] paramValue) { - setType(paramIndex, paramValue, double[].class); - } - - @Override - public void setPojo(int paramIndex, Pojo paramValue) { - // null Pojo value would make array and non-array types - // indistinguishable for serialization - Objects.requireNonNull(paramValue); - Class<?> runtimeType = paramValue.getClass(); - performPojoChecks(runtimeType, "Type"); - setType(paramIndex, paramValue, runtimeType); - } - - @Override - public void setPojoList(int paramIndex, Pojo[] paramValue) { - // null Pojo value would make array and non-array types - // indistinguishable for serialization - Objects.requireNonNull(paramValue); - Class<?> componentType = paramValue.getClass().getComponentType(); - performPojoChecks(componentType, "Component type"); - setType(paramIndex, paramValue, componentType); - } - - private void performPojoChecks(Class<?> type, String errorMsgPrefix) { - if (type.isInterface() || Modifier.isAbstract(type.getModifiers())) { - // Due to serealization we only allow concrete instantiable types. - // Instantiation would fail later in ThermostatGSONConverter for this - // reason anyway. Let's do this check early. - throw new IllegalArgumentException(errorMsgPrefix + "'" + - type.getName() + "' not instantiable!"); - } - } - - private void setType(int paramIndex, Object paramValue, Class<?> paramType) { - if (paramIndex >= params.length) { - throw new IllegalArgumentException("Parameter index '" + paramIndex + "' out of range."); - } - PreparedParameter param = new PreparedParameter(paramValue, paramType); - params[paramIndex] = param; - } - - public PreparedParameter[] getParams() { - return params; - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatement.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; - - -/** - * A prepared statement. - * - * @see Statement - * @see DataModifyingStatement - * @see Storage#prepareStatement(StatementDescriptor) - * - */ -public interface PreparedStatement<T extends Pojo> extends PreparedStatementSetter { - - void setBoolean(int paramIndex, boolean paramValue); - - void setLong(int paramIndex, long paramValue); - - void setInt(int paramIndex, int paramValue); - - void setString(int paramIndex, String paramValue); - - void setStringList(int paramIndex, String[] paramValue); - - /** - * Executes a predefined {@link DataModifyingStatement}. - * - * @return a non-zero error code on failure. Zero otherwise. - * - * @throws StatementExecutionException - * If the prepared statement wasn't valid for execution. - * @throws StorageException - * If the underlying storage throws an exception while executing - * this statement - */ - int execute() throws StatementExecutionException; - - /** - * Executes a predefined {@link Query}. - * - * @return a {@link Cursor} as a result to the underlying {@link Query} - * - * @throws StatementExecutionException - * If the prepared statement wasn't valid for execution. - * @throws StorageException - * If the underlying storage throws an exception while executing - * this query - */ - Cursor<T> executeQuery() throws StatementExecutionException; - - /** - * @return An intermediary representation of this prepared statement. - */ - ParsedStatement<T> getParsedStatement(); - -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatementFactory.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.internal.statement.PreparedStatementImpl; -import com.redhat.thermostat.storage.model.Pojo; - -/** - * Factory for instantiating a {@link PreparedStatement}. - * - */ -public class PreparedStatementFactory { - - public static <T extends Pojo> PreparedStatement<T> getInstance(BackingStorage storage, - StatementDescriptor<T> 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 - // factory. - return new PreparedStatementImpl<>(storage, desc); - } -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/PreparedStatementSetter.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; - -/** - * Package private interface in order to ensure consistency of - * setters between {@link PreparedStatement} and {@link PreparedParamenters}. - * - */ -interface PreparedStatementSetter { - - void setBoolean(int paramIndex, boolean paramValue); - - void setBooleanList(int paramIndex, boolean[] paramValue); - - void setLong(int paramIndex, long paramValue); - - void setLongList(int paramIndex, long[] paramValue); - - void setInt(int paramIndex, int paramValue); - - void setIntList(int paramIndex, int[] paramValue); - - void setString(int paramIndex, String paramValue); - - void setStringList(int paramIndex, String[] paramValue); - - void setDouble(int paramIndex, double paramValue); - - void setDoubleList(int paramIndex, double[] paramValue); - - void setPojo(int paramIndex, Pojo paramValue); - - void setPojoList(int paramIndex, Pojo[] paramValue); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Query.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.Expression; - -/** - * Describes what data should be fetched. - */ -public interface Query<T extends Pojo> extends Statement<T> { - - enum SortDirection { - ASCENDING(1), - DESCENDING(-1); - - private int value; - - private SortDirection(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - } - - void where(Expression expr); - - void sort(Key<?> key, SortDirection direction); - - void limit(int n); - - /** - * @throws StorageException - * If the operation fails - * - * @return a {@link Cursor} that can be used to iterate over the results. - */ - Cursor<T> execute(); - - Expression getWhereExpression(); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/QueuedStorage.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,609 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import java.io.InputStream; -import java.util.Objects; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.common.Constants; -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.perflog.PerformanceLogFormatter; -import com.redhat.thermostat.shared.perflog.PerformanceLogFormatter.LogTag; -import com.redhat.thermostat.storage.internal.CountingDecorator; -import com.redhat.thermostat.storage.internal.ThreadPoolSizeRetriever; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.Expression; - -public class QueuedStorage implements Storage { - - private static final Logger logger = LoggingUtils.getLogger(QueuedStorage.class); - private static final int SHUTDOWN_TIMEOUT_SECONDS = 3; - - /* - * True if and only if the delegate is a backing storage (such as mongodb) - * and it is used as a backing storage for proxied storage (such as web). - */ - protected final boolean isBackingStorageInProxy; - /* - * True if and only if statements should get timed and logged. - */ - protected final boolean isTimedStatements; - // performance logger. may be null - protected final PerformanceLogFormatter perfLogFormatter; - protected final Storage delegate; - protected final ExecutorService executor; - protected final ExecutorService fileExecutor; - - private abstract static class SettingDecorator<T extends Pojo> implements PreparedStatementSetter, PreparedStatement<T> { - - protected final PreparedStatement<T> stmtDelegate; - - private SettingDecorator(PreparedStatement<T> decoratee) { - this.stmtDelegate = decoratee; - } - - @Override - public void setBooleanList(int paramIndex, boolean[] paramValue) { - stmtDelegate.setBooleanList(paramIndex, paramValue); - } - - @Override - public void setLongList(int paramIndex, long[] paramValue) { - stmtDelegate.setLongList(paramIndex, paramValue); - } - - @Override - public void setIntList(int paramIndex, int[] paramValue) { - stmtDelegate.setIntList(paramIndex, paramValue); - } - - @Override - public void setDouble(int paramIndex, double paramValue) { - stmtDelegate.setDouble(paramIndex, paramValue); - } - - @Override - public void setDoubleList(int paramIndex, double[] paramValue) { - stmtDelegate.setDoubleList(paramIndex, paramValue); - } - - @Override - public void setPojo(int paramIndex, Pojo paramValue) { - stmtDelegate.setPojo(paramIndex, paramValue); - } - - @Override - public void setPojoList(int paramIndex, Pojo[] paramValue) { - stmtDelegate.setPojoList(paramIndex, paramValue); - } - - @Override - public void setBoolean(int paramIndex, boolean paramValue) { - stmtDelegate.setBoolean(paramIndex, paramValue); - } - - @Override - public void setLong(int paramIndex, long paramValue) { - stmtDelegate.setLong(paramIndex, paramValue); - } - - @Override - public void setInt(int paramIndex, int paramValue) { - stmtDelegate.setInt(paramIndex, paramValue); - } - - @Override - public void setString(int paramIndex, String paramValue) { - stmtDelegate.setString(paramIndex, paramValue); - } - - @Override - public void setStringList(int paramIndex, String[] paramValue) { - stmtDelegate.setStringList(paramIndex, paramValue); - } - - } - - class QueuedStatementDecorator<T extends Pojo> implements Statement<T> { - - private final Statement<T> stmt; - - private QueuedStatementDecorator(Statement<T> delegate) { - this.stmt = delegate; - } - - @Override - public Statement<T> getRawDuplicate() { - return stmt.getRawDuplicate(); - } - } - - abstract class QueuedQueryDecorator<T extends Pojo> extends QueuedStatementDecorator<T> implements Query<T> { - - protected final Query<T> query; - private QueuedQueryDecorator(Query<T> delegate) { - super(delegate); - this.query = delegate; - } - - @Override - public void where(Expression expr) { - query.where(expr); - } - - @Override - public void sort(Key<?> key, - com.redhat.thermostat.storage.core.Query.SortDirection direction) { - query.sort(key, direction); - } - - @Override - public void limit(int n) { - query.limit(n); - } - - public abstract Cursor<T> execute(); - - @Override - public Expression getWhereExpression() { - return query.getWhereExpression(); - } - - } - - class QueuedWrite<T extends Pojo> extends QueuedStatementDecorator<T> implements DataModifyingStatement<T> { - - protected final DataModifyingStatement<T> write; - - private QueuedWrite(DataModifyingStatement<T> delegate) { - super(delegate); - this.write = delegate; - } - - @Override - public int apply() { - executor.execute(new Runnable() { - - @Override - public void run() { - doApply(); - } - }); - return DataModifyingStatement.DEFAULT_STATUS_SUCCESS; - } - - // Allows for timed decoration - protected int doApply() { - return write.apply(); - } - - } - - abstract class QueuedParsedStatementDecorator<T extends Pojo> implements ParsedStatement<T> { - - protected final ParsedStatement<T> parsedDelegate; - - private QueuedParsedStatementDecorator(ParsedStatement<T> delegate) { - this.parsedDelegate = delegate; - } - - @Override - public abstract Statement<T> patchStatement(PreparedParameter[] params) throws IllegalPatchException; - - @Override - public int getNumParams() { - return parsedDelegate.getNumParams(); - } - - } - - class QueuedParsedStatement<T extends Pojo> extends QueuedParsedStatementDecorator<T> { - - private QueuedParsedStatement(ParsedStatement<T> delegate) { - super(delegate); - } - - @Override - public Statement<T> patchStatement(PreparedParameter[] params) - throws IllegalPatchException { - Statement<T> stmt = parsedDelegate.patchStatement(params); - if (stmt instanceof DataModifyingStatement) { - DataModifyingStatement<T> target = (DataModifyingStatement<T>)stmt; - return new QueuedWrite<>(target); - } else if (stmt instanceof Query) { - // Queries are not queued - return stmt; - } else { - // We only have two statement types: reads and writes. - throw new IllegalStateException("Should not reach here"); - } - } - - } - - static class TimedStatement { - private static final String DB_READ_PREFIX = "DB_READ"; - private static final String DB_WRITE_PREFIX = "DB_WRITE"; - private static final String DB_WRITE_FORMAT = DB_WRITE_PREFIX + "(%s) %s"; - private static final String DB_READ_FORMAT = DB_READ_PREFIX + " %s"; - } - - class TimedQuery<T extends Pojo> extends QueuedQueryDecorator<T> { - - private final Query<T> queryDelegate; - private final PerformanceLogFormatter perfLogFormatter; - private final String descriptor; - - private TimedQuery(Query<T> delegate, PerformanceLogFormatter perfLogFormatter, String descriptor) { - super(delegate); - this.queryDelegate = delegate; - this.perfLogFormatter = perfLogFormatter; - this.descriptor = descriptor; - } - - @Override - public Cursor<T> execute() { - long start = System.nanoTime(); - Cursor<T> result = queryDelegate.execute(); - long end = System.nanoTime(); - String msg = String.format(TimedStatement.DB_READ_FORMAT, descriptor); - logger.log(LoggingUtils.LogLevel.PERFLOG.getLevel(), perfLogFormatter.format(LogTag.STORAGE_BACKING_PROXIED, msg, (end - start))); - return result; - } - - } - - class TimedWrite<T extends Pojo> extends QueuedWrite<T> implements DataModifyingStatement<T> { - - private final QueuedWrite<T> write; - private final PerformanceLogFormatter perfLogFormatter; - private final String descriptor; - - private TimedWrite(QueuedWrite<T> delegate, PerformanceLogFormatter perfLogFormatter, String descriptor) { - super(delegate); - this.write = delegate; - this.perfLogFormatter = perfLogFormatter; - this.descriptor = descriptor; - } - - @Override - public int apply() { - executor.execute(new Runnable() { - - @Override - public void run() { - long start = System.nanoTime(); - int retval = write.doApply(); - long end = System.nanoTime(); - String msg = String.format(TimedStatement.DB_WRITE_FORMAT, retval, descriptor); - logger.log(LoggingUtils.LogLevel.PERFLOG.getLevel(), perfLogFormatter.format(LogTag.STORAGE_BACKING_PROXIED, msg, (end - start))); - } - - }); - return DataModifyingStatement.DEFAULT_STATUS_SUCCESS; - } - - } - - class TimedParsedStatement<T extends Pojo> extends QueuedParsedStatementDecorator<T> { - - private final PerformanceLogFormatter perfLogFormatter; - private final String descriptor; - - private TimedParsedStatement(ParsedStatement<T> delegate, PerformanceLogFormatter perfLogFormatter, String descriptor) { - super(delegate); - this.perfLogFormatter = perfLogFormatter; - this.descriptor = descriptor; - } - - @Override - public Statement<T> patchStatement(PreparedParameter[] params) - throws IllegalPatchException { - Statement<T> stmt = parsedDelegate.patchStatement(params); - if (stmt instanceof DataModifyingStatement) { - QueuedWrite<T> target = (QueuedWrite<T>)stmt; - return new TimedWrite<>(target, perfLogFormatter, descriptor); - } else if (stmt instanceof Query) { - Query<T> target = (Query<T>)stmt; - return new TimedQuery<>(target, perfLogFormatter, descriptor); - } else { - // We only have two statement types: reads and writes. - throw new IllegalStateException("Should not reach here"); - } - } - - } - - /* - * Decorates statement executions so that they get timed and results logged - * via the provided PerformanceLogger. - */ - class TimedPreparedStatement<T extends Pojo> extends SettingDecorator<T> implements PreparedStatement<T> { - - private static final String DB_READ_PREFIX = "DB_READ"; - private static final String DB_WRITE_PREFIX = "DB_WRITE"; - private static final String DB_WRITE_FORMAT = DB_WRITE_PREFIX + "(%s) %s"; - private static final String DB_READ_FORMAT = DB_READ_PREFIX + " %s"; - private final PerformanceLogFormatter perfLogFormatter; - private final String descriptor; - - private TimedPreparedStatement(QueuedPreparedStatement<T> decoratee, PerformanceLogFormatter perfLogFormatter, String descriptor) { - super(decoratee); - this.perfLogFormatter = perfLogFormatter; - this.descriptor = descriptor; - } - - @Override - public Cursor<T> executeQuery() throws StatementExecutionException { - long start = System.nanoTime(); - Cursor<T> result = stmtDelegate.executeQuery(); - long end = System.nanoTime(); - String msg = String.format(DB_READ_FORMAT, descriptor); - logger.log(LoggingUtils.LogLevel.PERFLOG.getLevel(), perfLogFormatter.format(LogTag.STORAGE_FRONT_END, msg, (end - start))); - return result; - } - - @Override - public int execute() throws StatementExecutionException { - executor.execute(new Runnable() { - - @Override - public void run() { - try { - long start = System.nanoTime(); - QueuedPreparedStatement<T> d = (QueuedPreparedStatement<T>)stmtDelegate; - int retval = d.doExecute(); - long end = System.nanoTime(); - String msg = String.format(DB_WRITE_FORMAT, retval, descriptor); - logger.log(LoggingUtils.LogLevel.PERFLOG.getLevel(), perfLogFormatter.format(LogTag.STORAGE_FRONT_END, msg, (end - start))); - } catch (StatementExecutionException e) { - // There isn't much we can do in case of invalid - // patch or the likes. Log it and move on. - logger.log(Level.WARNING, "Failed to execute statement", e); - } - } - }); - return DataModifyingStatement.DEFAULT_STATUS_SUCCESS; - } - - /* - * For proxied prepared statements we never actually call the underlying - * execute() and executeQuery() methods for performance reasons. We - * simply use previously prepared statements and use the parsed result - * of them. Thus, in order to make backing storages queued too, we - * need to decorate them this way. - */ - @Override - public ParsedStatement<T> getParsedStatement() { - if (isBackingStorageInProxy) { - ParsedStatement<T> target = stmtDelegate.getParsedStatement(); - return new TimedParsedStatement<>(target, perfLogFormatter, descriptor); - } else { - return stmtDelegate.getParsedStatement(); - } - } - - } - - /* - * Decorates PreparedStatement.execute() so that executions of writes - * are queued. - */ - class QueuedPreparedStatement<T extends Pojo> extends SettingDecorator<T> implements PreparedStatement<T> { - - private QueuedPreparedStatement(PreparedStatement<T> delegate) { - super(Objects.requireNonNull(delegate)); - } - - @Override - public int execute() throws StatementExecutionException { - if (isBackingStorageInProxy) { - String msg = "Did not expect to get called for backing storage in proxied setup."; - throw new AssertionError(msg); - } - executor.execute(new Runnable() { - - @Override - public void run() { - try { - doExecute(); - } catch (StatementExecutionException e) { - // There isn't much we can do in case of invalid - // patch or the likes. Log it and move on. - logger.log(Level.WARNING, "Failed to execute statement", e); - } - } - }); - return DataModifyingStatement.DEFAULT_STATUS_SUCCESS; - } - - @Override - public Cursor<T> executeQuery() throws StatementExecutionException { - if (isBackingStorageInProxy) { - String msg = "Did not expect to get called for backing storage in proxied setup."; - throw new AssertionError(msg); - } - return stmtDelegate.executeQuery(); - } - - /* - * For proxied prepared statements we never actually call the underlying - * execute() and executeQuery() methods for performance reasons. We - * simply use previously prepared statements and use the parsed result - * of them. Thus, in order to make backing storages queued too, we - * need to decorate them this way. - */ - @Override - public ParsedStatement<T> getParsedStatement() { - if (isBackingStorageInProxy) { - ParsedStatement<T> target = stmtDelegate.getParsedStatement(); - return new QueuedParsedStatement<>(target); - } else { - return stmtDelegate.getParsedStatement(); - } - } - - // This is to allow for proper decoration of it if timing is turned on. - private int doExecute() throws StatementExecutionException { - return stmtDelegate.execute(); - } - - } - - public QueuedStorage(Storage delegate) { - this(delegate, null); - } - - public QueuedStorage(Storage delegate, PerformanceLogFormatter perfLogFormatter) { - this(delegate, perfLogFormatter, new ThreadPoolSizeRetriever().getPoolSize()); - } - - QueuedStorage(Storage delegate, PerformanceLogFormatter perflogFormatter, int poolSize) { - this(delegate, Executors.newFixedThreadPool(poolSize), Executors.newFixedThreadPool(poolSize), perflogFormatter); - } - - QueuedStorage(Storage delegate, ExecutorService executor, ExecutorService fileExecutor) { - this(delegate, executor, fileExecutor, null); - } - - QueuedStorage(Storage delegate, ExecutorService executor, ExecutorService fileExecutor, PerformanceLogFormatter perfLogFormatter) { - this.delegate = delegate; - this.fileExecutor = fileExecutor; - this.isBackingStorageInProxy = !(delegate instanceof SecureStorage) && Boolean.getBoolean(Constants.IS_PROXIED_STORAGE); - this.isTimedStatements = LoggingUtils.getEffectiveLogLevel(logger).intValue() <= LoggingUtils.LogLevel.PERFLOG.getLevel().intValue(); - // set up queue counting executor if so requested - if (isTimedStatements) { - LogTag logTag = (isBackingStorageInProxy ? LogTag.STORAGE_BACKING_PROXIED : LogTag.STORAGE_FRONT_END); - this.executor = new CountingDecorator(executor, perfLogFormatter, logTag); - } else { - this.executor = executor; - } - this.perfLogFormatter = perfLogFormatter; - } - - ExecutorService getExecutor() { - return executor; - } - - ExecutorService getFileExecutor() { - return fileExecutor; - } - - @Override - public void purge(final String agentId) { - - executor.execute(new Runnable() { - - @Override - public void run() { - delegate.purge(agentId); - } - - }); - - } - - @Override - public void saveFile(final String filename, final InputStream data, final SaveFileListener listener) { - fileExecutor.execute(new Runnable() { - @Override - public void run() { - delegate.saveFile(filename, data, listener); - } - }); - } - - @Override - public InputStream loadFile(String filename) { - return delegate.loadFile(filename); - } - - @Override - public void registerCategory(final Category<?> category) { - delegate.registerCategory(category); - } - - @Override - public <T extends Pojo> PreparedStatement<T> prepareStatement(final StatementDescriptor<T> desc) - throws DescriptorParsingException { - PreparedStatement<T> decoratee = delegate.prepareStatement(desc); - QueuedPreparedStatement<T> queuedPreparedStatement = new QueuedPreparedStatement<>(decoratee); - return decorateWithTimingLoggerIfNecessary(queuedPreparedStatement, desc); - } - - private <T extends Pojo> PreparedStatement<T> decorateWithTimingLoggerIfNecessary(QueuedPreparedStatement<T> decoratee, StatementDescriptor<T> desc) { - if (isTimedStatements) { - return new TimedPreparedStatement<>(decoratee, this.perfLogFormatter, desc.getDescriptor()); - } - return decoratee; - } - - @Override - public Connection getConnection() { - return delegate.getConnection(); - } - - @Override - public void shutdown() { - /* - * First shut down executors. This may trigger some pushes to the - * storage implementation (a.k.a. delegate). Hence, this should get - * shut down last as this closes the connection etc. - */ - try { - executor.shutdown(); - executor.awaitTermination(SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS); - } catch (InterruptedException ex) { - // Fall through. - } - try { - fileExecutor.shutdown(); - fileExecutor.awaitTermination(SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS); - } catch (InterruptedException ex) { - // Fall through. - } - delegate.shutdown(); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Remove.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.Expression; - -/** - * Write operation to be used for removing records from storage. - * - * @see Add - * @see Update - * @see Replace - */ -public interface Remove<T extends Pojo> extends DataModifyingStatement<T> { - - /** - * Boolean expression in order to restrict the set of records to be removed - * from storage. - * - * @param where - * The boolean expression. - */ - void where(Expression where); - - /** - * Applies this remove operation. - * - * @throws StorageException if this operation fails - */ - int apply(); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Replace.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.Expression; - -/** - * Write operation which should be used if any existing record should get - * updated with new values. It can be thought of as {@link Update} for - * <strong>all</strong> properties of a record. - * <p> - * The only distinction to a regular {@link Update} is that if Replace is used - * and the associated {@code where} expression yields no result, a - * <strong>new</strong> record will be insterted into Storage. - * <p> - * The result of this operation is undefined if the {@code where} expression - * matches more than one record in storage. - * - * @see Add - * @see Remove - * @see Update - */ -public interface Replace<T extends Pojo> extends DataModifyingStatement<T> { - - /** - * Sets a field in a found record to the specified value. If the same key is - * set more than once, the latest value overrides the former value for that - * key. - * - * @param key - * the name of the field to update. - * @param value - * the value with which to update the field. - */ - void set(String key, Object value); - - /** - * Specifies what criteria to use to find the record to replace - */ - void where(Expression expression); - - /** - * Applies this {@code Replace} operation to the storage. - * - * @throws StorageException If the operation fails - */ - int apply(); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/SecureQueuedStorage.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.shared.perflog.PerformanceLogFormatter; - -/** - * Secure version of {@link QueuedStorage}. I.e. its delegate is an instance of - * {@link SecureStorage}. - * - * @see SecureStorage - * @see QueuedStorage - */ -public final class SecureQueuedStorage extends QueuedStorage implements SecureStorage { - - public SecureQueuedStorage(SecureStorage storage, PerformanceLogFormatter logger) { - super(storage, logger); - } - - public SecureQueuedStorage(SecureStorage storage) { - this(storage, null); - } - - @Override - public AuthToken generateToken(String actionName) throws StorageException { - return ((SecureStorage)delegate).generateToken(actionName); - } - - @Override - public boolean verifyToken(AuthToken token, String actionName) { - return ((SecureStorage)delegate).verifyToken(token, actionName); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/SecureStorage.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -/** - * Provides authentication service to the command channel API. - * - * The protocol works as follows: - * - * <ol> - * <li> The client asks the SecureStorage for an authentication token using {@link #generateToken(String)}. - * This should happen over an authenticated and secured connection, thus authenticating the client - * in the storage. The returned AuthToken will carry a client-token (that has been generated by the - * client) and an auth-token (generated by the storage). If authentication fails at this stage - * (e.g. because the client does not have the necessary privileges/roles), a StorageException is - * thrown. - * </li> - * <li> The AuthToken (both parts, client and auth token), are sent together with the command request to - * the command receiver (usually an agent). - * </li> - * <li> The agent takes the tokens, and calls the SecureStorage's {@link #verifyToken(AuthToken)} to - * verify the validity of the tokens. Again, this needs to happen through an authenticated and - * secured connection, thus authenticating the receiver. The storage verifies that it generated - * the same token for an authenticated client before, and replies with true if it succeeds, and - * false otherwise. - */ -public interface SecureStorage extends Storage { - - /** - * Generates a token in the storage that can be used to authenticate cmd - * channel requests. - * - * @param actionName - * A unique name of the type of action to be performed. - * - * @throws StorageException - * if authentication fails at this point - */ - AuthToken generateToken(String actionName) throws StorageException; - - /** - * Verifies the specified token and action in the storage. - * - * @param actionName - * A unique name of the type of action to be performed. This - * action name is used during verification. This means if - * verification succeeds, the given action name can be trusted - * and may be used for authorization checks. - * @param token The token to be verified. - * - * @return <code>true</code> if authentication succeeded, <code>false</code> - * otherwise - */ - boolean verifyToken(AuthToken token, String actionName); -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Statement.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; - -/** - * Implementations of this interface represent operations on storage. This - * includes queries and statements manipulating data. - * - * @see BackingStorage - * @see Query - * @see Update - * @see Replace - * @see Add - * @see Remove - */ -public interface Statement<T extends Pojo> { - - /** - * Produces a copy of this statement as if it was just created with the - * corresponding factory method in {@link BackingStorage}. - * - * @return A new raw instance of this statement. - */ - Statement<T> getRawDuplicate(); -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/StatementDescriptor.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import java.util.Objects; - -import com.redhat.thermostat.storage.model.Pojo; - -public final class StatementDescriptor<T extends Pojo> { - - private final Category<T> category; - private final String desc; - - public StatementDescriptor(Category<T> category, String desc) { - this.category = Objects.requireNonNull(category); - this.desc = Objects.requireNonNull(desc); - } - - /** - * Describes this statement for preparation. For example: - * - * <pre> - * QUERY host-info WHERE 'agentId' = ?s LIMIT 1 - * </pre> - * - * @return The statement descriptor. - */ - public String getDescriptor() { - return desc; - } - - public Category<T> getCategory() { - return category; - } - - @Override - public String toString() { - return desc; - } - - @Override - public int hashCode() { - /* - * Note that category's hash code gets generated on de-facto-immutable - * values. Hence, it is safe to use it here. - */ - return Objects.hash(desc, category); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof StatementDescriptor)) { - return false; - } - @SuppressWarnings("rawtypes") - StatementDescriptor o = (StatementDescriptor)other; - return desc.equals(o.desc) - && category.equals(o.category); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/StatementExecutionException.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -/** - * Exception thrown if something was wrong with a {@link PreparedStatement} - * and it was attempted to execute it. - * - */ -@SuppressWarnings("serial") -public class StatementExecutionException extends Exception { - - public StatementExecutionException(Throwable cause) { - super(cause); - } -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Storage.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import java.io.InputStream; - -import com.redhat.thermostat.annotations.Service; -import com.redhat.thermostat.storage.model.Pojo; - -/** - * A storage can be used to store, query, update and remove data. - * Implementations may use memory, a file, some database or even a network - * server as the backing store. - */ -@Service -public interface Storage { - - /** - * Register the category into the Storage. A Category must be registered - * into storage (normally handled by the Category's constructor) before it - * can be used. - * - * @throws StorageException - * If the category can not be registered for some reason - */ - void registerCategory(Category<?> category); - - /** - * Prepares the given statement for execution. - * - * @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; - - /** - * Returns the Connection object that may be used to manage connections - * to this Storage. Subsequent calls to this method should return - * the same Connection. - * @return the Connection for this Storage - */ - Connection getConnection(); - - /** - * Drop all data related to the specified agent. - * - * @param agentId - * The id of the agent - * @throws StorageException - * If the purge operation fails - */ - void purge(String agentId); - - /** - * Save the contents of the input stream as the given name. - * - * @param filename - * The name to save this data stream as. This must be unique - * across all machines and processes using the storage or it will - * overwrite data. - * @param data - * The data to save. - * @param listener - * The listener is notified upon various events related to the - * saving of the file. The types of events are defined by - * {@link SaveFileListener.EventTypes} Callers are responsible - * for handling events appropriately via this listener, including - * closing the InputStream when receiving an event indicating - * that Storage is no longer using it (such as SAVE_COMPLETE or - * EXCEPTION_OCCURRED). - */ - void saveFile(String filename, InputStream data, SaveFileListener listener); - - /** - * Load the file with the given name and return the data as an InputStream. - * - * @return the data as an {@link InputStream} or {@code null} if not found. - * - * @throws StorageException - * May be thrown if the load operation fails - */ - InputStream loadFile(String filename); - - /** - * Shutdown the storage - * - * @throws StorageException - * If the shutdown operation fails - */ - void shutdown(); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/StorageProvider.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.shared.config.SSLConfiguration; -import com.redhat.thermostat.storage.config.StartupConfiguration; - -/** - * Factory for creating a new {@link Storage} instance. - * - */ -public interface StorageProvider { - - /** - * Creates a new {@link Storage}. - * - * @return The new instance. - */ - Storage createStorage(); - - /** - * Sets the to-be-used configuration of this StorageProvider. Called prior - * {@link StorageProvider#canHandleProtocol()}. - * - * @param config - * @param sslConf - */ - void setConfig(String url, StorageCredentials creds, SSLConfiguration sslConf); - - /** - * Method which determines if this StorageProvider can handle the given - * protocol as set via - * {@link StorageProvider#setConfig(StartupConfiguration)}. - * - * <br/> - * <br/> - * <strong>Pre:</strong> Configuration has been set via - * {@link StorageProvider#setConfig(StartupConfiguration)}. - * - * @return true if this StorageProvider can handle the protocol prefix of - * the given StartupConfiguration. I.e. - * {@link StorageProvider#createStorage()} can be safely called - * given this config. false otherwise. - */ - boolean canHandleProtocol(); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/Update.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.Expression; - -/** - * Updates properties of a record in storage. - * - * @see Add - * @see Replace - * @see Remove - */ -public interface Update<T extends Pojo> extends DataModifyingStatement<T> { - - /** - * Given a boolean expression, this method specifies a where condition for - * this update operation. If an update is issued for which no entry can be - * found (i.e. the where-clause yields no results), a - * <code>StorageException</code> may get thrown. - * - * @param expr - * A boolean expression. - */ - void where(Expression expr); - - /** - * Sets a field in a found record to the specified value. If the same key is - * set more than once, the latest value overrides the former value for that - * key. - * - * @param key - * the name of the field to update. - * @param value - * the value with which to update the field. - */ - void set(String key, Object value); - - /** - * Applies this update operation. - * - * @throws StorageException if this operation fails - */ - int apply(); -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/VmBoundaryPojoGetter.java Fri May 19 11:37:45 2017 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/VmBoundaryPojoGetter.java Fri May 19 11:58:05 2017 +0200 @@ -39,11 +39,9 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; -import com.redhat.thermostat.storage.dao.AbstractDaoQuery; import com.redhat.thermostat.storage.model.TimeStampedPojo; -public class VmBoundaryPojoGetter<T extends TimeStampedPojo> extends AbstractDao { +public class VmBoundaryPojoGetter<T extends TimeStampedPojo> { // QUERY %s WHERE 'agentId' = ?s AND \ // 'vmId' = ?s \ @@ -67,13 +65,11 @@ private static final Logger logger = LoggingUtils.getLogger(VmBoundaryPojoGetter.class); - private final Storage storage; private final Category<T> cat; private final String queryNewest; private final String queryOldest; - public VmBoundaryPojoGetter(Storage storage, Category<T> cat) { - this.storage = storage; + public VmBoundaryPojoGetter(Category<T> cat) { this.cat = cat; this.queryNewest = String.format(DESC_NEWEST_VM_STAT, cat.getName()); this.queryOldest = String.format(DESC_OLDEST_VM_STAT, cat.getName()); @@ -104,14 +100,7 @@ } private T runAgentAndVmIdQuery(final String vmId, final String agentId, final String descriptor) { - return executeQuery(new AbstractDaoQuery<T>(storage, cat, descriptor) { - @Override - public PreparedStatement<T> customize(PreparedStatement<T> preparedStatement) { - preparedStatement.setString(0, agentId); - preparedStatement.setString(1, vmId); - return preparedStatement; - } - }).head(); + return null; } //Package private for testing @@ -124,7 +113,6 @@ return queryOldest; } - @Override protected Logger getLogger() { return logger; }
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetter.java Fri May 19 11:37:45 2017 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetter.java Fri May 19 11:58:05 2017 +0200 @@ -40,8 +40,6 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; -import com.redhat.thermostat.storage.dao.AbstractDaoQuery; import com.redhat.thermostat.storage.model.TimeStampedPojo; /** @@ -49,7 +47,7 @@ * * @see VmTimeIntervalPojoListGetter */ -public class VmLatestPojoListGetter<T extends TimeStampedPojo> extends AbstractDao { +public class VmLatestPojoListGetter<T extends TimeStampedPojo> { public static final String VM_LATEST_QUERY_FORMAT = "QUERY %s WHERE '" + Key.AGENT_ID.getName() + "' = ?s AND '" @@ -58,12 +56,10 @@ + 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; - public VmLatestPojoListGetter(Storage storage, Category<T> cat) { - this.storage = storage; + public VmLatestPojoListGetter(Category<T> cat) { this.cat = cat; this.queryLatest = String.format(VM_LATEST_QUERY_FORMAT, cat.getName()); } @@ -77,15 +73,7 @@ } public List<T> getLatest(final AgentId agentId, final VmId vmId, final long since) { - return executeQuery(new AbstractDaoQuery<T>(storage, cat, queryLatest) { - @Override - public PreparedStatement<T> customize(PreparedStatement<T> preparedStatement) { - preparedStatement.setString(0, agentId.get()); - preparedStatement.setString(1, vmId.get()); - preparedStatement.setLong(2, since); - return preparedStatement; - } - }).asList(); + return null; } // package private for tests @@ -93,7 +81,6 @@ return queryLatest; } - @Override public Logger getLogger() { return logger; }
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/core/VmTimeIntervalPojoListGetter.java Fri May 19 11:37:45 2017 +0200 +++ b/storage/core/src/main/java/com/redhat/thermostat/storage/core/VmTimeIntervalPojoListGetter.java Fri May 19 11:58:05 2017 +0200 @@ -40,8 +40,6 @@ import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.dao.AbstractDao; -import com.redhat.thermostat.storage.dao.AbstractDaoQuery; import com.redhat.thermostat.storage.model.TimeStampedPojo; /** @@ -50,7 +48,7 @@ * * @see VmLatestPojoListGetter */ -public class VmTimeIntervalPojoListGetter<T extends TimeStampedPojo> extends AbstractDao { +public class VmTimeIntervalPojoListGetter<T extends TimeStampedPojo> { // The query for VmTimeIntervalPojoListGetter should query for since <= timestamp < to // in order not to miss data for multiple consecutive queries of the form [a, b), [b, c), ... @@ -65,12 +63,10 @@ private static final Logger logger = LoggingUtils.getLogger(VmTimeIntervalPojoListGetter.class); - private final Storage storage; private final Category<T> cat; private final String query; - public VmTimeIntervalPojoListGetter(Storage storage, Category<T> cat) { - this.storage = storage; + public VmTimeIntervalPojoListGetter(Category<T> cat) { this.cat = cat; this.query = String.format(VM_INTERVAL_QUERY_FORMAT, cat.getName()); } @@ -84,16 +80,7 @@ } public List<T> getLatest(final AgentId agentId, final VmId vmId, final long since, final long to) { - return executeQuery(new AbstractDaoQuery<T>(storage, cat, query) { - @Override - public PreparedStatement<T> customize(PreparedStatement<T> preparedStatement) { - preparedStatement.setString(0, agentId.get()); - preparedStatement.setString(1, vmId.get()); - preparedStatement.setLong(2, since); - preparedStatement.setLong(3, to); - return preparedStatement; - } - }).asList(); + return null; } // package private for tests @@ -101,7 +88,6 @@ return query; } - @Override protected Logger getLogger() { return logger; }
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDao.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.model.Pojo; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -import static com.redhat.thermostat.storage.internal.dao.LoggingUtil.logDescriptorParsingException; -import static com.redhat.thermostat.storage.internal.dao.LoggingUtil.logStatementExecutionException; - -public abstract class AbstractDao { - - final <T extends Pojo> PreparedStatement<T> getCustomizedPreparedStatement(DaoOperation<T> daoOperation) throws DescriptorParsingException { - PreparedStatement<T> preparedStatement = daoOperation.getStorage() - .prepareStatement(daoOperation.getStatementDescriptor()); - return daoOperation.customize(preparedStatement); - } - - protected final <T extends Pojo> StatementResult<T> executeStatement(DaoStatement<T> daoOperation) { - List<Exception> exceptions = new ArrayList<>(); - try { - getCustomizedPreparedStatement(daoOperation).execute(); - } catch (DescriptorParsingException e) { - logDescriptorParsingException(getLogger(), daoOperation.getStatementDescriptor(), e); - exceptions.add(e); - } catch (StatementExecutionException e) { - logStatementExecutionException(getLogger(), daoOperation.getStatementDescriptor(), e); - exceptions.add(e); - } - - StatementResult<T> statementResult = new StatementResult<>(); - statementResult.addExceptions(exceptions); - return statementResult; - } - - protected final <T extends Pojo> QueryResult<T> executeQuery(DaoOperation<T> daoOperation) { - List<Exception> exceptions = new ArrayList<>(); - Cursor<T> cursor = getEmptyResultCursor(); - try { - cursor = getCustomizedPreparedStatement(daoOperation).executeQuery(); - } catch (DescriptorParsingException e) { - logDescriptorParsingException(getLogger(), daoOperation.getStatementDescriptor(), e); - exceptions.add(e); - } catch (StatementExecutionException e) { - logStatementExecutionException(getLogger(), daoOperation.getStatementDescriptor(), e); - exceptions.add(e); - } - - QueryResult<T> queryResult = new QueryResult<>(cursor); - queryResult.addExceptions(exceptions); - return queryResult; - } - - protected abstract Logger getLogger(); - - protected static <T extends Pojo> Cursor<T> getEmptyResultCursor() { - return new Cursor<T>() { - @Override - public void setBatchSize(int n) throws IllegalArgumentException { - } - - @Override - public int getBatchSize() { - return 0; - } - - @Override - public boolean hasNext() { - return false; - } - - @Override - public T next() { - return null; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDaoOperation.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.Pojo; - -public abstract class AbstractDaoOperation<T extends Pojo> implements DaoOperation<T> { - - protected final Storage storage; - protected final StatementDescriptor<T> statementDescriptor; - - public AbstractDaoOperation(Storage storage, Category<T> category, String descriptor) { - this.storage = storage; - this.statementDescriptor = new StatementDescriptor<>(category, descriptor); - } - - @Override - public Storage getStorage() { - return storage; - } - - @Override - public StatementDescriptor<T> getStatementDescriptor() { - return statementDescriptor; - } - -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDaoOperationResult.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.model.Pojo; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public abstract class AbstractDaoOperationResult<T extends Pojo> implements DaoOperationResult<T> { - - private final List<Exception> exceptions = new ArrayList<>(); - - @Override - public void addException(Exception e) { - exceptions.add(e); - } - - @Override - public void addExceptions(Iterable<Exception> exceptions) { - for (Exception e : exceptions) { - addException(e); - } - } - - @Override - public boolean hasExceptions() { - return !exceptions.isEmpty(); - } - - @Override - public List<Exception> getExceptions() { - return Collections.unmodifiableList(exceptions); - } -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDaoQuery.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.Pojo; - -public abstract class AbstractDaoQuery<T extends Pojo> extends AbstractDaoOperation<T> implements DaoQuery<T> { - - public AbstractDaoQuery(Storage storage, Category<T> category, String descriptor) { - super(storage, category, descriptor); - } - - @Override - public Cursor<T> execute(PreparedStatement<T> preparedStatement) throws DescriptorParsingException, StatementExecutionException { - return preparedStatement.executeQuery(); - } -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/AbstractDaoStatement.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.Pojo; - -public abstract class AbstractDaoStatement<T extends Pojo> extends AbstractDaoOperation<T> implements DaoStatement<T> { - - public AbstractDaoStatement(Storage storage, Category<T> category, String descriptor) { - super(storage, category, descriptor); - } - - @Override - public void execute(PreparedStatement<T> preparedStatement) throws DescriptorParsingException, StatementExecutionException { - preparedStatement.execute(); - } -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/BaseCountable.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import java.util.logging.Logger; - -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.AggregateCount; - -/** - * This class provides generic functionality for performing an aggregate count query. - */ -public class BaseCountable extends AbstractDao { - - private static final int ERROR_COUNT_RESULT = -1; - private static final Logger logger = LoggingUtils.getLogger(BaseCountable.class); - - /** - * Performs an aggregate count query as described by the given descriptor. - * - * @param storage the storage to use for preparing the descriptor. - * @param category the query category. - * @param descriptor the query descriptor. - * @return -1 if execution failed for some reason, the actual count of the - * query results if successful. - */ - protected long getCount(Storage storage, Category<AggregateCount> category, String descriptor) { - QueryResult<AggregateCount> result = executeQuery(new SimpleDaoQuery<>(storage, category, descriptor)); - AggregateCount count = result.head(); - if (count == null || result.hasExceptions()) { - return ERROR_COUNT_RESULT; - } else { - return count.getCount(); - } - } - - @Override - protected Logger getLogger() { - return logger; - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/DaoOperation.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao;/* - * Copyright 2012-2015 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. - */ - -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.Pojo; - -public interface DaoOperation<T extends Pojo> { - - PreparedStatement<T> customize(PreparedStatement<T> preparedStatement); - - Storage getStorage(); - - StatementDescriptor<T> getStatementDescriptor(); -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/DaoQuery.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao;/* - * Copyright 2012-2015 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. - */ - -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.model.Pojo; - -public interface DaoQuery<T extends Pojo> extends DaoOperation<T> { - - Cursor<T> execute(PreparedStatement<T> preparedStatement) - throws DescriptorParsingException, StatementExecutionException; - -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/DaoStatement.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao;/* - * Copyright 2012-2015 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. - */ - -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.model.Pojo; - -public interface DaoStatement<T extends Pojo> extends DaoOperation<T> { - - void execute(PreparedStatement<T> preparedStatement) - throws DescriptorParsingException, StatementExecutionException; - -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/QueryResult.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.common.utils.IteratorUtils; -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.model.Pojo; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -public class QueryResult<T extends Pojo> extends AbstractDaoOperationResult<T> { - - private final List<T> contents; - - public QueryResult(Cursor<T> cursor) { - contents = IteratorUtils.asList(cursor); - } - - public List<T> asList() { - return contents; - } - - public T head() { - if (contents.isEmpty()) { - return null; - } else { - return contents.get(0); - } - } - - @Override - public Iterator<T> iterator() { - return contents.iterator(); - } - -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/SimpleDaoQuery.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.Pojo; - -public class SimpleDaoQuery<T extends Pojo> extends AbstractDaoQuery<T> { - - public SimpleDaoQuery(Storage storage, Category<T> category, String descriptor) { - super(storage, category, descriptor); - } - - @Override - public PreparedStatement<T> customize(PreparedStatement<T> preparedStatement) { - return preparedStatement; - } - -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/SimpleDaoStatement.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.Pojo; - -public class SimpleDaoStatement<T extends Pojo> extends AbstractDaoStatement<T> { - - public SimpleDaoStatement(Storage storage, Category<T> category, String descriptor) { - super(storage, category, descriptor); - } - - @Override - public PreparedStatement<T> customize(PreparedStatement<T> preparedStatement) { - return preparedStatement; - } - -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/StatementResult.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.model.Pojo; - -import java.util.Collections; -import java.util.Iterator; - -public class StatementResult<T extends Pojo> extends AbstractDaoOperationResult<T> { - - @Override - public Iterator<T> iterator() { - return Collections.<T>emptyList().iterator(); - } -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/CountingDecorator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import java.util.Collection; -import java.util.List; -import java.util.Objects; -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 java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Logger; - -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.perflog.PerformanceLogFormatter; -import com.redhat.thermostat.shared.perflog.PerformanceLogFormatter.LogTag; -import com.redhat.thermostat.storage.core.QueuedStorage; - -/** - * Decorator for ExecutorService's based queued storage. Allows for inspecting - * and logging the queue size. - * - * @see QueuedStorage - */ -public class CountingDecorator implements ExecutorService { - - private static final String QUEUE_SIZE_PREFIX = "Q_SIZE"; - private static final String QUEUE_SIZE_FORMAT = QUEUE_SIZE_PREFIX + " %s"; - private static final Logger logger = LoggingUtils.getLogger(CountingDecorator.class); - private final LogTag logTag; - private final PerformanceLogFormatter perfLogFormatter; - private final ExecutorService decoratee; - private final AtomicLong queueLength; - - /** - * - * @param decoratee - * The executor service to decorate. - * @param perfLogFormatter - * The log formatter to use for logged messages. - * @param logTag The log tag to use when logging messages. - */ - public CountingDecorator(ExecutorService decoratee, PerformanceLogFormatter perfLogFormatter, LogTag logTag) { - this.decoratee = Objects.requireNonNull(decoratee); - this.perfLogFormatter = Objects.requireNonNull(perfLogFormatter); - this.logTag = logTag; - this.queueLength = new AtomicLong(); - } - - @Override - public void execute(final Runnable command) { - queueLength.incrementAndGet(); - decoratee.execute(new Runnable() { - - @Override - public void run() { - command.run(); - queueLength.decrementAndGet(); - } - - }); - String msg = String.format(QUEUE_SIZE_FORMAT, queueLength.get()); - logger.log(LoggingUtils.LogLevel.PERFLOG.getLevel(), perfLogFormatter.format(logTag, msg)); - } - - @Override - public void shutdown() { - decoratee.shutdown(); - } - - @Override - public List<Runnable> shutdownNow() { - return decoratee.shutdownNow(); - } - - @Override - public boolean isShutdown() { - return decoratee.isShutdown(); - } - - @Override - public boolean isTerminated() { - return decoratee.isTerminated(); - } - - @Override - public boolean awaitTermination(long timeout, TimeUnit unit) - throws InterruptedException { - return decoratee.awaitTermination(timeout, unit); - } - - @Override - public <T> Future<T> submit(Callable<T> task) { - return decoratee.submit(task); - } - - @Override - public <T> Future<T> submit(Runnable task, T result) { - return decoratee.submit(task, result); - } - - @Override - public Future<?> submit(Runnable task) { - return decoratee.submit(task); - } - - @Override - public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) - throws InterruptedException { - return decoratee.invokeAll(tasks); - } - - @Override - public <T> List<Future<T>> invokeAll( - Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) - throws InterruptedException { - return decoratee.invokeAll(tasks, timeout, unit); - } - - @Override - public <T> T invokeAny(Collection<? extends Callable<T>> tasks) - throws InterruptedException, ExecutionException { - return decoratee.invokeAny(tasks); - } - - @Override - public <T> T invokeAny(Collection<? extends Callable<T>> tasks, - long timeout, TimeUnit unit) throws InterruptedException, - ExecutionException, TimeoutException { - return decoratee.invokeAny(tasks, timeout, unit); - } - - public long getQueueLength() { - return queueLength.get(); - } - -}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/DbServiceImpl.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,300 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import java.util.concurrent.CountDownLatch; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; - -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.config.SSLConfiguration; -import com.redhat.thermostat.storage.core.Connection; -import com.redhat.thermostat.storage.core.Connection.ConnectionListener; -import com.redhat.thermostat.storage.core.Connection.ConnectionStatus; -import com.redhat.thermostat.storage.core.ConnectionException; -import com.redhat.thermostat.storage.core.DbService; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.core.StorageCredentials; -import com.redhat.thermostat.storage.core.StorageException; -import com.redhat.thermostat.storage.core.StorageProvider; - -public class DbServiceImpl implements DbService { - - private static Logger logger = LoggingUtils.getLogger(DbServiceImpl.class); - @SuppressWarnings("rawtypes") - private ServiceRegistration dbServiceReg; - @SuppressWarnings("rawtypes") - private ServiceRegistration storageReg; - - private Storage storage; - private BundleContext context; - private String dbUrl; - private String userName; - - DbServiceImpl(String dbUrl, StorageCredentials creds, SSLConfiguration sslConf) throws StorageException { - BundleContext context = FrameworkUtil.getBundle(DbService.class).getBundleContext(); - init(context, dbUrl, creds, sslConf); - } - - // for testing - DbServiceImpl(BundleContext context, String dbUrl, StorageCredentials creds, SSLConfiguration sslConf) { - init(context, dbUrl, creds, sslConf); - } - - // For testing. Injects custom storage. - DbServiceImpl(BundleContext context, Storage storage, StorageCredentials creds, SSLConfiguration sslConf) { - this.context = context; - this.storage = storage; - } - - private void init(BundleContext context, String dbUrl, StorageCredentials creds, SSLConfiguration sslConf) { - Storage storage = createStorage(context, dbUrl, creds, sslConf); - this.storage = storage; - this.context = context; - this.dbUrl = dbUrl; - } - - public void connect() throws ConnectionException { - // Storage and DbService must not be registered - // as service - ensureConnectPreCondition(); - try { - // connection needs to be synchronous, otherwise there is no - // way to guarantee the postcondition if there's a delayed exception - // during connection handling. - doSynchronousConnect(); - } catch (Exception cause) { - throw new ConnectionException(cause); - } - // Connection didn't throw an exception. Now it is safe to register - // services for general consumption. - dbServiceReg = context.registerService(DbService.class, this, null); - storageReg = context.registerService(Storage.class.getName(), this.storage, null); - } - - private void doSynchronousConnect() throws ConnectionException { - CountDownLatch latch = new CountDownLatch(1); - SynchronousConnectionListener listener = new SynchronousConnectionListener( - latch, ConnectionStatus.CONNECTED); - // Install listener in order to ensure connection is synchronous. - addConnectionListener(listener); - Connection connection = this.storage.getConnection(); - connection.connect(); - try { - // Wait for connection to finish. - // The synchronous connection listener gets removed once connection - // has finished. - latch.await(); - // Grab username after connection completes - this.userName = connection.getUsername(); - } catch (InterruptedException e) { - logger.log(Level.WARNING, e.getMessage(), e); - } - if (!listener.successful) { - throw new ConnectionException(); - } - } - - public void disconnect() throws ConnectionException { - // DbService and Storage must be registered as service at this point - ensureDisconnectPrecondition(); - try { - doSyncronousDisconnect(); - } catch (Exception cause) { - throw new ConnectionException(cause); - } - storageReg.unregister(); - dbServiceReg.unregister(); - } - - private void doSyncronousDisconnect() { - CountDownLatch latch = new CountDownLatch(1); - SynchronousConnectionListener listener = new SynchronousConnectionListener( - latch, ConnectionStatus.DISCONNECTED); - // Install listener in order to ensure connection is synchronous. - addConnectionListener(listener); - this.storage.getConnection().disconnect(); - try { - // Wait for disconnect to finish. - // The synchronous connection listener gets removed once connection - // has finished. - latch.await(); - this.userName = Connection.UNSET_USERNAME; - } catch (InterruptedException e) { - logger.log(Level.WARNING, e.getMessage(), e); - } - if (!listener.successful) { - throw new ConnectionException(); - } - } - - @Override - public String getConnectionUrl() { - return dbUrl; - } - - @Override - public String getUserName() { - return this.userName; - } - - /** - * Factory method for creating a DbService instance. - * - * @param dbUrl The storage url to use - * @param creds The storage credentials to use - * @param sslConf The SSL configuration to use - * @return a DbService instance - * @throws StorageException if no storage provider exists for the given {@code dbUrl}. - */ - public static DbService create(String dbUrl, StorageCredentials creds, SSLConfiguration sslConf) throws StorageException { - return new DbServiceImpl(dbUrl, creds, sslConf); - } - - @SuppressWarnings("rawtypes") - private void ensureDisconnectPrecondition() { - ServiceReference dbServiceReference = context - .getServiceReference(DbService.class); - ServiceReference storageReference = context - .getServiceReference(Storage.class); - if (dbServiceReference == null || storageReference == null) { - throw new IllegalStateException( - "DbService or Storage not registered as service when " - + "trying to disconnect"); - } - } - - @SuppressWarnings("rawtypes") - private void ensureConnectPreCondition() { - ServiceReference dbServiceReference = context - .getServiceReference(DbService.class); - ServiceReference storageReference = context - .getServiceReference(Storage.class); - if (dbServiceReference != null || storageReference != null) { - throw new IllegalStateException( - "DbService or Storage already registered as service when " - + "trying to connect"); - } - } - - private static Storage createStorage(BundleContext context, String dbUrl, StorageCredentials creds, SSLConfiguration sslConf) throws StorageException { - StorageProvider prov = getStorageProvider(context, dbUrl, creds, sslConf); - if (prov == null) { - // no suitable provider found - throw new StorageException("No storage found for URL " + dbUrl); - } - return prov.createStorage(); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static StorageProvider getStorageProvider(BundleContext context, String url, StorageCredentials creds, SSLConfiguration sslConf) { - try { - ServiceReference[] refs = context.getServiceReferences(StorageProvider.class.getName(), null); - if (refs == null) { - throw new StorageException("No storage provider available"); - } - for (int i = 0; i < refs.length; i++) { - StorageProvider prov = (StorageProvider) context.getService(refs[i]); - prov.setConfig(url, creds, sslConf); - if (prov.canHandleProtocol()) { - return prov; - } - else { - context.ungetService(refs[i]); - } - } - } catch (InvalidSyntaxException e) { - throw new AssertionError("Bad filter used to get StorageProviders", e); - } - return null; - } - - @Override - public void addConnectionListener(ConnectionListener listener) { - storage.getConnection().addListener(listener); - } - - @Override - public void removeConnectionListener(ConnectionListener listener) { - storage.getConnection().removeListener(listener); - } - - class SynchronousConnectionListener implements ConnectionListener { - - CountDownLatch latch; - boolean successful = false; - ConnectionStatus expectedType; - - public SynchronousConnectionListener(CountDownLatch latch, ConnectionStatus expectedType) { - this.latch = latch; - this.expectedType = expectedType; - } - - @Override - public void changed(ConnectionStatus newStatus) { - switch (newStatus) { - case CONNECTED: { - successful = (expectedType == ConnectionStatus.CONNECTED); - latch.countDown(); - removeConnectionListener(this); - break; - } - case FAILED_TO_CONNECT: { - latch.countDown(); - removeConnectionListener(this); - break; - } - case DISCONNECTED: { - successful = (expectedType == ConnectionStatus.DISCONNECTED); - latch.countDown(); - removeConnectionListener(this); - } - default: { - // nothing - } - } - } - - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/LoggingUtil.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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 com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.model.Pojo; - -import java.util.logging.Level; -import java.util.logging.Logger; - -public final class LoggingUtil { - - private LoggingUtil() {} - - public static <T extends Pojo> void logDescriptorParsingException(Logger logger, StatementDescriptor<T> desc, DescriptorParsingException e) { - logQueryStatementException(logger, Level.SEVERE, desc, e); - } - - public static <T extends Pojo> void logStatementExecutionException(Logger logger, StatementDescriptor<T> desc, StatementExecutionException e) { - logQueryStatementException(logger, Level.SEVERE, desc, e); - } - - static <T extends Pojo> void logQueryStatementException(Logger logger, Level level, StatementDescriptor<T> desc, Exception e) { - logger.log(level, "Executing query/statement '" + desc + "' failed!", e); - } - -} \ No newline at end of file
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/AbstractUnfinished.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.Objects; - -/** - * Abstract superclass for unfinished nodes (i.e. nodes in the prepared - * statements parse tree which need to be patched with their real values). - * - */ -abstract class AbstractUnfinished implements Unfinished { - - @Override - public boolean equals(Object other) { - if (other == null) { - return false; - } - if (!(other instanceof Unfinished)) { - return false; - } - Unfinished o = (Unfinished)other; - return getParameterIndex() == o.getParameterIndex(); - } - - @Override - public int hashCode() { - return Objects.hash(getParameterIndex()); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/BasicDescriptorParser.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,859 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.core.Add; -import com.redhat.thermostat.storage.core.AggregateQuery; -import com.redhat.thermostat.storage.core.AggregateQuery.AggregateFunction; -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; -import com.redhat.thermostat.storage.core.ParsedStatement; -import com.redhat.thermostat.storage.core.Query; -import com.redhat.thermostat.storage.core.Query.SortDirection; -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.Update; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.BinaryComparisonOperator; -import com.redhat.thermostat.storage.query.BinaryLogicalOperator; - -/** - * A parser for the string representation of {@link StatementDescriptor}s. - * Tokens have to be separated by whitespace. - * - * This parser implements the following simple grammar for statement descriptors. - * It supports the following statement types: - * <ul> - * <li>QUERY (read)</li> - * <li>QUERY-COUNT (read)</li> - * <li>ADD (write)</li> - * <li>UPDATE (write)</li> - * <li>REPLACE (write)</li> - * <li>REMOVE (write)</li> - * </ul> - * - * <p><strong>Grammar:</strong></p> - * <pre> - * statementDesc := statementType category setList suffix - * statementType := 'QUERY' | 'QUERY-COUNT' | - * 'ADD' | 'REPLACE' | 'UPDATE' | - * 'REMOVE' - * category := string - * setList := 'SET' setValues | \empty - * setValues := valuePair valueList - * valuePair := term '=' term - * valueList := ',' setValues | \empty - * suffix := 'WHERE' where | - * 'SORT' sortCond | - * 'LIMIT' term | \empty - * where := whereExp sort limit - * whereExp := andCond orCond - * orCond := 'OR' whereExp | \empty - * sort := 'SORT' sortCond | \empty - * sortCond := sortPair sortList - * sortPair := term sortModifier - * sortModifier := 'ASC' | 'DSC' - * sortList := ',' sortCond | \empty - * limit := 'LIMIT' term | \empty - * andCond := condition andBody - * andBody := 'AND' whereExp | \empty - * condition := 'NOT' condition | compExp - * compExp := term compExpRHS - * term := freeParam | literal - * freeParam := '?s' | '?i' | '?l' | '?s[' | '?b' - * literal := sQuote string sQuote | int | long | boolean - * sQuote := \' - * boolean := <true> | <false> - * int := <literal-int> - * long := <literal-long>longPostFix - * longPostFix := 'l' | 'L' - * string := <literal-string-value> - * compExpRHS := '!=' term | '=' term | '<=' term | '>=' term | - * '<' term | '>' term - * </pre> - * - * This implements the following logic precedence rules (in this order of - * precedence): - * - * <ol> - * <li>NOT</li> - * <li>AND</li> - * <li>OR</li> - * </ol> - * - * NOTE: Comparison expressions have equal precedence. - */ -class BasicDescriptorParser<T extends Pojo> implements StatementDescriptorParser<T> { - - private static final Logger logger = LoggingUtils.getLogger(BasicDescriptorParser.class); - private static final String TOKEN_DELIMS = " \t\r\n\f"; - private static final short IDX_QUERY = 0; - private static final short IDX_ADD = 1; - private static final short IDX_REPLACE = 2; - private static final short IDX_UPDATE = 3; - private static final short IDX_REMOVE = 4; - private static final String[] KNOWN_STATEMENT_TYPES = new String[] { - "QUERY", "ADD", "REPLACE", "UPDATE", "REMOVE" - }; - - // package-private for testing - static final String AGGREGATE_PARAM_REGEXP = "(?:\\(([a-zA-Z_]+)\\))?$"; - private static final String QUERY_COUNT_REGEXP = "QUERY-COUNT" + AGGREGATE_PARAM_REGEXP; - private static final String QUERY_DISTINCT_REGEXP = "QUERY-DISTINCT" + AGGREGATE_PARAM_REGEXP; - private static final Pattern QUERY_COUNT_PATTERN = Pattern.compile(QUERY_COUNT_REGEXP); - private static final Pattern QUERY_DISTINCT_PATTERN = Pattern.compile(QUERY_DISTINCT_REGEXP); - private static final String SORTLIST_SEP = ","; - private static final String SETLIST_SEP = SORTLIST_SEP; - private static final String KEYWORD_SET = "SET"; - private static final String KEYWORD_WHERE = "WHERE"; - private static final String KEYWORD_SORT = "SORT"; - private static final String KEYWORD_LIMIT = "LIMIT"; - private static final String KEYWORD_ASC = "ASC"; - private static final String KEYWORD_DSC = "DSC"; - private static final String POJO_FREE_PARAMETER_TYPE = "?p"; - private static final char PARAM_PLACEHOLDER = '?'; - - private final String[] tokens; - protected final StatementDescriptor<T> desc; - private final BackingStorage storage; - private int currTokenIndex; - private int placeHolderCount; - // the parsed statement - private ParsedStatementImpl<T> parsedStatement; - protected SuffixExpression tree; - protected SetList setList; - - BasicDescriptorParser(BackingStorage storage, StatementDescriptor<T> desc) { - this.tokens = getTokens(desc.getDescriptor()); - this.currTokenIndex = 0; - this.placeHolderCount = 0; - this.desc = desc; - this.storage = storage; - } - - private String[] getTokens(String str) { - StringTokenizer tokenizer = new StringTokenizer(str, TOKEN_DELIMS); - List<String> toks = new ArrayList<>(tokenizer.countTokens()); - while (tokenizer.hasMoreTokens()) { - toks.add(tokenizer.nextToken()); - } - return toks.toArray(new String[0]); - } - - public ParsedStatement<T> parse() throws DescriptorParsingException { - matchStatementType(); - matchCategory(); - // matched so far, create the raw statement - createStatement(); - this.setList = new SetList(); - matchSetList(setList); - this.tree = new SuffixExpression(); - matchSuffix(); - if (currTokenIndex != tokens.length) { - throw new DescriptorParsingException("Incomplete parse of '" + desc.toString() + "'"); - } - parsedStatement.setNumFreeParams(placeHolderCount); - parsedStatement.setSetList(setList); - parsedStatement.setSuffixExpression(tree); - return parsedStatement; - } - - /* - * Match set list for DML statements. - */ - private void matchSetList(final SetList setList) throws DescriptorParsingException { - if (tokens.length == currTokenIndex) { - // no set list - return; - } - if (tokens[currTokenIndex].equals(KEYWORD_SET)) { - currTokenIndex++; // SET - matchSetValues(setList); - } - // empty, proceed with suffix - } - - /* - * Match list of values in a SET expression - */ - private void matchSetValues(SetList setList) throws DescriptorParsingException { - matchValuePair(setList); - matchValueList(setList); - } - - /* - * Match more value pairs in a SET list - */ - private void matchValueList(SetList setList) throws DescriptorParsingException { - if (currTokenIndex == tokens.length) { - // empty - return; - } - if (tokens[currTokenIndex].equals(SETLIST_SEP)) { - currTokenIndex++; // , - matchSetValues(setList); - } - } - - /* - * Match one pair of values in a - */ - private void matchValuePair(SetList setList) throws DescriptorParsingException { - SetListValue value = new SetListValue(); - TerminalNode lval = new TerminalNode(null); - matchTerm(lval, true, true); - value.setKey(lval); - if (tokens[currTokenIndex].equals("=")) { - currTokenIndex++; // = - } else { - String msg = "Expected '=' after SET value LHS. Token was ->" + tokens[currTokenIndex] + "<-"; - throw new DescriptorParsingException(msg); - } - TerminalNode rval = new TerminalNode(null); - matchTerm(rval, false, true); - value.setValue(rval); - setList.addValue(value); - } - - /* - * Match optional suffixes. - */ - private void matchSuffix() throws DescriptorParsingException { - if (tokens.length == currTokenIndex) { - // no suffix - return; - } - if (tokens[currTokenIndex].equals(KEYWORD_WHERE)) { - currTokenIndex++; - WhereExpression expn = new WhereExpression(); - tree.setWhereExpn(expn); - matchWhereExp(expn.getRoot()); - matchSort(tree); - matchLimit(tree); - } else if (tokens[currTokenIndex].equals(KEYWORD_SORT)) { - // SORT token eaten up by matchSort() - matchSort(tree); - matchLimit(tree); - } else if (tokens[currTokenIndex].equals(KEYWORD_LIMIT)) { - // LIMIT token eaten up by matchLimit() - matchLimit(tree); - } else { - throw new DescriptorParsingException("Unexpected token: '" - + tokens[currTokenIndex] + "'. Expected one of " - + KEYWORD_WHERE + ", " + KEYWORD_SORT + ", " + KEYWORD_LIMIT); - } - } - - private void matchLimit(SuffixExpression tree) throws DescriptorParsingException { - if (currTokenIndex == tokens.length) { - // empty - return; - } else if (currTokenIndex < tokens.length) { - if (tokens[currTokenIndex].equals(KEYWORD_LIMIT)) { - LimitExpression node = new LimitExpression(); - tree.setLimitExpn(node); - currTokenIndex++; - matchTerm(node); - } - } else { - throw new DescriptorParsingException("Illegal statement descriptor: Reason LIMIT"); - } - } - - private void matchSort(SuffixExpression tree) throws DescriptorParsingException { - if (currTokenIndex < tokens.length - && tokens[currTokenIndex].equals(KEYWORD_SORT)) { - SortExpression sortExpn = new SortExpression(); - tree.setSortExpn(sortExpn); - currTokenIndex++; - matchSortList(sortExpn); - } - if (currTokenIndex > tokens.length) { - throw new DescriptorParsingException("Illegal statement descriptor."); - } - // empty - } - - private void matchSortList(SortExpression sortExpn) throws DescriptorParsingException { - matchSortPair(sortExpn); - matchSortListPreamble(sortExpn); - } - - private void matchSortListPreamble(SortExpression sortExpn) throws DescriptorParsingException { - if (currTokenIndex < tokens.length && tokens[currTokenIndex].equals(SORTLIST_SEP)) { - currTokenIndex++; // ',' token - matchSortList(sortExpn); - } - } - - private void matchSortPair(SortExpression expn) throws DescriptorParsingException { - SortMember member = new SortMember(); - matchTerm(member); - matchSortModifier(member); - // Add the member node to the list of the sort node - expn.addMember(member); - } - - private void matchSortModifier(SortMember member) throws DescriptorParsingException { - String msg = "Illegal statement decriptor: Reason SORT. Expected ASC or DSC"; - if (currTokenIndex >= tokens.length) { - throw new DescriptorParsingException(msg); - } - if (tokens[currTokenIndex].equals(KEYWORD_ASC)) { - member.setDirection(SortDirection.ASCENDING); - currTokenIndex++; - } else if (tokens[currTokenIndex].equals(KEYWORD_DSC)) { - member.setDirection(SortDirection.DESCENDING); - currTokenIndex++; - } else { - throw new DescriptorParsingException(msg); - } - } - - private void matchWhereExp(Node node) throws DescriptorParsingException { - if (currTokenIndex >= tokens.length) { - throw new DescriptorParsingException("Illegal where clause"); - } - assert(node != null); - matchAndCondition(node); - matchOrCondition(node); - } - - private void matchAndCondition(Node currNode) throws DescriptorParsingException { - matchCondition(currNode); - matchAndExpression(currNode); - } - - private void matchCondition(Node currNode) throws DescriptorParsingException { - if (currTokenIndex >= tokens.length) { - throw new DescriptorParsingException("Illegal statement descriptor: Reason sort clause"); - } - if (tokens[currTokenIndex].equals(Operator.NOT.getName())) { - NotBooleanExpressionNode notNode = new NotBooleanExpressionNode(currNode); - if (currNode instanceof BinaryExpressionNode) { - BinaryExpressionNode currNodeExpr = (BinaryExpressionNode)currNode; - Node available = currNodeExpr.getLeftChild(); - if (available != null) { - currNodeExpr.setRightChild(notNode); - } else { - currNodeExpr.setLeftChild(notNode); - } - } else { - assert(currNode instanceof NotBooleanExpressionNode || currNode instanceof Node); - currNode.setValue(notNode); - } - currTokenIndex++; // NOT keyword - - matchCondition(notNode); - } else { - matchComparisionExpression(currNode); - } - } - - private void matchComparisionExpression(Node currNode) throws DescriptorParsingException { - if (currTokenIndex >= tokens.length) { - throw new DescriptorParsingException("Illegal statement descriptor: Comparison expression"); - } - BinaryExpressionNode expr = new BinaryExpressionNode(currNode); - TerminalNode left = new TerminalNode(expr); - TerminalNode right = new TerminalNode(expr); - expr.setLeftChild(left); - expr.setRightChild(right); - - if (currNode instanceof BinaryExpressionNode) { - BinaryExpressionNode currNodeExpr = (BinaryExpressionNode)currNode; - Node available = currNodeExpr.getLeftChild(); - if (available == null) { - currNodeExpr.setLeftChild(expr); - } else { - assert(currNodeExpr.getRightChild() == null); - currNodeExpr.setRightChild(expr); - } - } else { - assert(currNode instanceof NotBooleanExpressionNode || currNode instanceof Node); - currNode.setValue(expr); - } - - matchTerm(left, true); - matchComparisonRHS(expr); - } - - private void matchComparisonRHS(BinaryExpressionNode currNode) throws DescriptorParsingException { - if (currTokenIndex >= tokens.length) { - // boolean literals are not allowed - throw new DescriptorParsingException("Illegal statement descriptor: Boolean literals are not allowed!"); - } - if (tokens[currTokenIndex].equals(Operator.EQUALS.getName())) { - currTokenIndex++; - currNode.setOperator(BinaryComparisonOperator.EQUALS); - matchTerm((TerminalNode)currNode.getRightChild(), false); - } else if (tokens[currTokenIndex].equals(Operator.LESS_THAN_OR_EQUAL_TO.getName())) { - currTokenIndex++; - currNode.setOperator(BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO); - matchTerm((TerminalNode)currNode.getRightChild(), false); - } else if (tokens[currTokenIndex].equals(Operator.GREATER_THAN_OR_EQUAL_TO.getName())) { - currTokenIndex++; - currNode.setOperator(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL_TO); - matchTerm((TerminalNode)currNode.getRightChild(), false); - } else if (tokens[currTokenIndex].equals(Operator.GREATER_THAN.getName())) { - currTokenIndex++; - currNode.setOperator(BinaryComparisonOperator.GREATER_THAN); - matchTerm((TerminalNode)currNode.getRightChild(), false); - } else if (tokens[currTokenIndex].equals(Operator.LESS_THAN.getName())) { - currTokenIndex++; - currNode.setOperator(BinaryComparisonOperator.LESS_THAN); - matchTerm((TerminalNode)currNode.getRightChild(), false); - } else if (tokens[currTokenIndex].equals(Operator.NOT_EQUAL_TO.getName())) { - currTokenIndex++; - currNode.setOperator(BinaryComparisonOperator.NOT_EQUAL_TO); - matchTerm((TerminalNode)currNode.getRightChild(), false); - } else { - throw new DescriptorParsingException("Illegal statement descriptor: Reason comparison expression!"); - } - } - - private void matchTerm(SortMember member) throws DescriptorParsingException { - String term = getTerm(); - if (term.charAt(0) == PARAM_PLACEHOLDER) { - assert(placeHolderCount > 0); - ensureValidType(term, "SORT"); - if (term.charAt(1) != 's') { - String msg = "Sort parameters only accept string types. Placeholder was: " + term; - throw new DescriptorParsingException(msg); - } - UnfinishedSortKey unfinishedKey = new UnfinishedSortKey(); - unfinishedKey.setParameterIndex(placeHolderCount - 1); - member.setSortKey(unfinishedKey); - return; - } - String stringTerm = getStringTerm(term); - member.setSortKey(stringTerm); - } - - /* - * Check if the free parameter type is valid in a given context. Currently, - * list and pojo free type parameters are invalid for LIMIT, SORT and WHERE. - * - * Currently, no list types and no Pojo types are allowed. - */ - private void ensureValidType(String term, String contextName) throws DescriptorParsingException { - if (term.length() > 2) { - // Don't allow list types for invalid contexts - // Only list type free variables have 3 characters - String format = "List free variable type not allowed in %s context"; - String msg = String.format(format, contextName); - throw new DescriptorParsingException(msg); - } - if (term.equals(POJO_FREE_PARAMETER_TYPE)) { - String format = "Pojo free variable type not allowed in %s context"; - String msg = String.format(format, contextName); - throw new DescriptorParsingException(msg); - } - } - - private void matchTerm(LimitExpression expn) throws DescriptorParsingException { - String term = getTerm(); - if (term.charAt(0) == PARAM_PLACEHOLDER) { - assert(placeHolderCount > 0); - ensureValidType(term, "LIMIT"); - if (term.charAt(1) != 'i') { - String msg = "Limit parameters only accept integer types. Placeholder was: " + term; - throw new DescriptorParsingException(msg); - } - UnfinishedLimitValue limitValue = new UnfinishedLimitValue(); - limitValue.setParameterIndex(placeHolderCount - 1); - expn.setValue(limitValue); - return; - } - int limitVal; - try { - limitVal = Integer.parseInt(term); - } catch (NumberFormatException e) { - throw new DescriptorParsingException("Invalid limit expression. '" + term + "' not an integer"); - } - expn.setValue(limitVal); - } - - /** - * Calls {@link #matchTerm(TerminalNode, boolean, boolean)} with a - * {@code false isSetListContext} parameter. - */ - private void matchTerm(TerminalNode node, boolean isLHS) throws DescriptorParsingException { - // default to false - matchTerm(node, isLHS, false); - } - - /** - * Match a terminal in a TerminalNode context. Only where expression, and - * set list context take this code path. - * - * @param node - * The terminal node which is parsed at this point. - * @param isLHS - * {@code true} if and only if the node is the left hand side of - * a binary expression. - * @param isSetListContext - * {@code true} if and only if the node is in a set list context - * or conversely NOT in a where expression context. - * @throws DescriptorParsingException - * If and error was encountered parsing the terminal string - * token. - */ - private void matchTerm(TerminalNode node, boolean isLHS, - boolean isSetListContext) throws DescriptorParsingException { - String term = getTerm(); - if (term.charAt(0) == PARAM_PLACEHOLDER) { - assert(placeHolderCount > 0); - if (!isSetListContext) { - ensureValidType(term, "WHERE"); - } - UnfinishedValueNode patchNode = new UnfinishedValueNode(); - patchNode.setParameterIndex(placeHolderCount - 1); - patchNode.setLHS(isLHS); - // figure out the expected type - Class<?> expectedType = getType(term.substring(1)); - if (expectedType == null) { - throw new DescriptorParsingException("Unknown type of free parameter: '" + term + "'"); - } - patchNode.setType(expectedType); - node.setValue(patchNode); - return; - } - // regular terminal. i.e. literal value - if (isLHS) { - // FIXME: In thermostat LHS of comparisons must be Key objects. I'm - // not sure if this restriction is very meaningful in a prepared - // statement context as the purpose of this was to ensure "type" - // compatibility between Key <=> value comparisons. - String stringTerm = getStringTerm(term); - Key<?> key = new Key<>(stringTerm); - node.setValue(key); - } else { - Object typedValue = getTypedValue(term); - node.setValue(typedValue); - } - } - - private Object getTypedValue(String term) throws DescriptorParsingException { - try { - String stringTerm = getStringTerm(term); - return stringTerm; - } catch (DescriptorParsingException e) { - // Must be integer (long/int) or boolean. First check for boolean, - // then for long and regular ints. - if (term.equals(Boolean.toString(false)) || term.equals(Boolean.toString(true))) { - boolean boolVal = Boolean.parseBoolean(term); - return boolVal; - } - // Next, parse long or int. - try { - int lastCharInTokenIndex = term.length() - 1; - // preceding l/L indicate long integer types. - if (term.charAt(lastCharInTokenIndex) == 'L' || term.charAt(lastCharInTokenIndex) == 'l') { - long longVal = Long.parseLong(term.substring(0, lastCharInTokenIndex)); - return longVal; - } - // must be integer or some invalid type - int intVal = Integer.parseInt(term); - return intVal; - } catch (NumberFormatException nfe) { - String msg = "Illegal terminal type. Token was ->" + term + "<-"; - throw new DescriptorParsingException(msg); - } - } - } - - private String getStringTerm(String term) throws DescriptorParsingException { - String errorMsg = - "Expected string value. Got term ->" - + term - + "<-" - + " Was the string properly quoted? Example: 'string'."; - if (term.charAt(0) != '\'' || term.charAt(term.length() - 1) != '\'') { - throw new DescriptorParsingException(errorMsg); - } - return term.substring(1, term.length() - 1); - } - - private Class<?> getType(String term) { - if (term.equals("")) { - // illegal type - return null; - } - // free variable types can have 1 or 2 characters. - assert(term.length() > 0 && term.length() < 3); - char switchChar = term.charAt(0); - Class<?> typeToken = null; - switch (switchChar) { - case 'i': { - if (term.length() == 1) { - typeToken = int.class; - } else if (term.length() == 2 && term.charAt(1) == '[') { - typeToken = int[].class; - } - break; - } - case 'l': { - if (term.length() == 1) { - typeToken = long.class; - } else if (term.length() == 2 && term.charAt(1) == '[') { - typeToken = long[].class; - } - break; - } - case 's': { - if (term.length() == 1) { - typeToken = String.class; - } else if (term.length() == 2 && term.charAt(1) == '[') { - typeToken = String[].class; - } - break; - } - case 'b': { - if (term.length() == 1) { - typeToken = boolean.class; - } else if (term.length() == 2 && term.charAt(1) == '[') { - typeToken = boolean[].class; - } - break; - } - case 'd': { - if (term.length() == 1) { - typeToken = double.class; - } else if (term.length() == 2 && term.charAt(1) == '[') { - typeToken = double[].class; - } - break; - } - case 'p': { - if (term.length() == 1) { - typeToken = Pojo.class; - } else if (term.length() == 2 && term.charAt(1) == '[') { - typeToken = Pojo[].class; - } - break; - } - default: - assert(typeToken == null); - break; - } - return typeToken; - } - - private String getTerm() throws DescriptorParsingException { - if (currTokenIndex >= tokens.length) { - throw new DescriptorParsingException("Invalid where clause. Reason: term expected but not given!"); - } - if (tokens[currTokenIndex].charAt(0) == PARAM_PLACEHOLDER) { - placeHolderCount++; - } - String term = tokens[currTokenIndex]; - currTokenIndex++; - return term; - } - - private void matchAndExpression(Node currNode) throws DescriptorParsingException { - if (currTokenIndex < tokens.length && - tokens[currTokenIndex].equals(Operator.AND.getName())) { - currTokenIndex++; // AND keyword - - Node parent = currNode; - if (currNode instanceof BinaryExpressionNode || - currNode instanceof NotBooleanExpressionNode) { - parent = currNode.getParent(); - assert(parent != null); - } - BinaryExpressionNode and = new BinaryExpressionNode(parent); - and.setOperator(BinaryLogicalOperator.AND); - if (currNode instanceof BinaryExpressionNode || - currNode instanceof NotBooleanExpressionNode) { - currNode.setParent(and); - and.setLeftChild(currNode); - parent.setValue(and); - } else { - // Root node case - and.setLeftChild((Node)parent.getValue()); - parent.setValue(and); - } - // Note the current AND expression node at this point of parsing - // must be at the root of the entire expression. - assert(and.getParent().getParent() == null); - - matchWhereExp(and); - - } - // empty - } - - private void matchOrCondition(Node currNode) throws DescriptorParsingException { - if (currTokenIndex < tokens.length && - tokens[currTokenIndex].equals(Operator.OR.getName())) { - currTokenIndex++; // OR keyword - - Node parent = currNode; - if (currNode instanceof BinaryExpressionNode || - currNode instanceof NotBooleanExpressionNode) { - parent = currNode.getParent(); - assert(parent != null); - } - BinaryExpressionNode or = new BinaryExpressionNode(parent); - or.setOperator(BinaryLogicalOperator.OR); - if (currNode instanceof BinaryExpressionNode || - currNode instanceof NotBooleanExpressionNode) { - currNode.setParent(or); - or.setLeftChild(currNode); - parent.setValue(or); - } else { - // Root node case - or.setLeftChild((Node)parent.getValue()); - parent.setValue(or); - } - // Note the current OR expression node at this point of parsing - // must be at the root of the entire expression. - assert(or.getParent().getParent() == null); - - matchWhereExp(or); - } - // empty - } - - private void createStatement() { - // matchStatementType and matchCategory advanced currTokenIndex, - // lets use idx of 0 here. - final String statementType = tokens[0]; - Matcher queryCountMatcher = QUERY_COUNT_PATTERN.matcher(statementType); - Matcher queryDistinctMatcher = QUERY_DISTINCT_PATTERN.matcher(statementType); - if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_QUERY])) { - // regular query case - Query<T> query = storage.createQuery(desc.getCategory()); - this.parsedStatement = new ParsedStatementImpl<>(query); - } else if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_ADD])) { - // create add - Add<T> add = storage.createAdd(desc.getCategory()); - this.parsedStatement = new ParsedStatementImpl<>(add); - } else if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_REPLACE])) { - // create replace - Replace<T> replace = storage.createReplace(desc.getCategory()); - this.parsedStatement = new ParsedStatementImpl<>(replace); - } else if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_UPDATE])) { - // create replace - Update<T> update = storage.createUpdate(desc.getCategory()); - this.parsedStatement = new ParsedStatementImpl<>(update); - } else if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_REMOVE])) { - // create remove - Remove<T> remove = storage.createRemove(desc.getCategory()); - this.parsedStatement = new ParsedStatementImpl<>(remove); - } else if (queryCountMatcher.matches()) { - this.parsedStatement = createAggregatePreparedStatement(AggregateFunction.COUNT, queryCountMatcher); - } else if (queryDistinctMatcher.matches()) { - this.parsedStatement = createAggregatePreparedStatement(AggregateFunction.DISTINCT, queryDistinctMatcher); - } else { - throw new IllegalStateException("Don't know how to create statement type '" + statementType + "'"); - } - } - - private ParsedStatementImpl<T> createAggregatePreparedStatement(final AggregateFunction function, final Matcher matcher) { - // create aggregate query - AggregateQuery<T> aggregateQuery = storage.createAggregateQuery(function, desc.getCategory()); - // We'll always have a match for at least one group. That group - // will be the keyName to use (if any). For old query descriptors - // the keyName may be null - String keyName = matcher.group(1); // groups start at 1 - if (keyName != null) { - Key<?> aggKey = new Key<>(keyName); - aggregateQuery.setAggregateKey(aggKey); - } - return new ParsedStatementImpl<>(aggregateQuery); - } - - private void matchCategory() throws DescriptorParsingException { - if (currTokenIndex >= tokens.length) { - throw new DescriptorParsingException("Missing category name in descriptor: '" + desc.getDescriptor() + "'"); - } - Category<?> category = desc.getCategory(); - if (!tokens[currTokenIndex].equals(category.getName())) { - throw new DescriptorParsingException( - "Category mismatch in descriptor. Category from descriptor string: '" - + tokens[currTokenIndex] - + "'. Category name from category: '" - + category.getName() + "'."); - } - currTokenIndex++; - } - - private void matchStatementType() throws DescriptorParsingException { - final String statementType = tokens[currTokenIndex]; - Matcher queryCountMatcher = QUERY_COUNT_PATTERN.matcher(statementType); - Matcher queryDistinctMatcher = QUERY_DISTINCT_PATTERN.matcher(statementType); - if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_QUERY])) { - // QUERY - currTokenIndex++; - } else if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_ADD])) { - // ADD - currTokenIndex++; - } else if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_REPLACE])) { - // REPLACE - currTokenIndex++; - } else if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_UPDATE])) { - // UPDATE - currTokenIndex++; - } else if (statementType.equals(KNOWN_STATEMENT_TYPES[IDX_REMOVE])) { - // REMOVE - currTokenIndex++; - } else if (queryCountMatcher.matches()) { - // QUERY-COUNT - currTokenIndex++; - } else if (queryDistinctMatcher.matches()) { - // QUERY-DISTINCT - currTokenIndex++; - } else { - throw new DescriptorParsingException("Unknown statement type: '" + statementType + "'"); - } - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/BinaryExpressionNode.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.Objects; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.query.BinaryComparisonExpression; -import com.redhat.thermostat.storage.query.BinaryComparisonOperator; -import com.redhat.thermostat.storage.query.BinaryLogicalExpression; -import com.redhat.thermostat.storage.query.BinaryLogicalOperator; -import com.redhat.thermostat.storage.query.Expression; -import com.redhat.thermostat.storage.query.LiteralExpression; -import com.redhat.thermostat.storage.query.Operator; - -class BinaryExpressionNode extends Node { - - private Node leftChild; - private Node rightChild; - private Operator operator; - - public Operator getOperator() { - return operator; - } - - public void setOperator(Operator operator) { - this.operator = operator; - } - - BinaryExpressionNode(Node parent) { - super(parent); - } - - public Node getLeftChild() { - return leftChild; - } - - public void setLeftChild(Node leftChild) { - this.leftChild = leftChild; - } - - public Node getRightChild() { - return rightChild; - } - - public void setRightChild(Node rightChild) { - this.rightChild = rightChild; - } - - @Override - public PatchedWhereExpression patch(PreparedParameter[] params) throws IllegalPatchException { - if (leftChild == null || rightChild == null || getOperator() == null) { - String msg = BinaryExpressionNode.class.getSimpleName() + - " invalid when attempted to patch"; - IllegalStateException cause = new IllegalStateException(msg); - throw new IllegalPatchException(cause); - } - PatchedWhereExpression left = leftChild.patch(params); - PatchedWhereExpression right = rightChild.patch(params); - - Expression leftExpression = left.getExpression(); - Expression rightExpression = right.getExpression(); - return createExpression(leftExpression, rightExpression); - } - - private PatchedWhereExpression createExpression(Expression leftExpression, - Expression rightExpression) { - if (operator instanceof BinaryComparisonOperator) { - return getBinaryComparisonExpression(leftExpression, (BinaryComparisonOperator) operator, rightExpression); - } else if (operator instanceof BinaryLogicalOperator) { - return getBinaryLogicalExpression(leftExpression, (BinaryLogicalOperator) operator, rightExpression); - } - return null; - } - - private PatchedWhereExpression getBinaryLogicalExpression(Expression a, - BinaryLogicalOperator op, Expression b) { - BinaryLogicalExpression<Expression, Expression> impl = new BinaryLogicalExpression<Expression, Expression>( - a, op, b); - return new PatchedWhereExpressionImpl(impl); - } - - @SuppressWarnings("unchecked") // Unchecked casts to LiteralExpression - private <T> PatchedWhereExpressionImpl getBinaryComparisonExpression(Expression a, BinaryComparisonOperator op, Expression b) { - LiteralExpression<Key<T>> leftOperand = (LiteralExpression<Key<T>>) a; - LiteralExpression<T> rightOperand = (LiteralExpression<T>)b; - BinaryComparisonExpression<T> impl = new BinaryComparisonExpression<>( - leftOperand, op, rightOperand); - return new PatchedWhereExpressionImpl(impl); - } - - @Override - public void print(int level) { - for (int i = 0; i < level; i++) { - System.out.print("-"); - } - System.out.print("B: " + getOperator()); - System.out.println(""); - int newLevel = level + 1; - if (leftChild != null) { - leftChild.print(newLevel); - } - if (rightChild != null) { - rightChild.print(newLevel); - } - } - - @Override - public boolean equals(Object other) { - if (other == null) { - return false; - } - if (!(other instanceof BinaryExpressionNode)) { - return false; - } - BinaryExpressionNode o = (BinaryExpressionNode)other; - return this.getOperator().equals(o.getOperator()) && - Objects.equals(leftChild, o.leftChild) && - Objects.equals(rightChild, o.rightChild); - } - - @Override - public int hashCode() { - return Objects.hash(getOperator(), leftChild, rightChild, getParent()); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/LimitExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; - -/** - * Represents a limit expression in the prepared statement's parse tree. - * - */ -class LimitExpression implements Printable, Patchable { - - private Object value; - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - @Override - public void print(int level) { - System.out.println("LIMIT: " + getValue()); - } - - @Override - public PatchedLimitExpression patch(PreparedParameter[] params) - throws IllegalPatchException { - if (value instanceof Unfinished) { - Unfinished unfinished = (Unfinished)value; - try { - PreparedParameter param = params[unfinished.getParameterIndex()]; - Class<?> typeClass = param.getType(); - if (typeClass != int.class) { - String msg = "Invalid parameter type for limit expression. Expected integer!"; - IllegalArgumentException e = new IllegalArgumentException(msg); - throw e; - } - int limitVal = (Integer)param.getValue(); - return new PatchedLimitExpressionImpl(limitVal); - } catch (Exception e) { - throw new IllegalPatchException(e); - } - } else { - // must have been int, since parsing would have failed otherwise - int limitVal = (int)getValue(); - return new PatchedLimitExpressionImpl(limitVal); - } - } - - private static class PatchedLimitExpressionImpl implements PatchedLimitExpression { - - private final int val; - - PatchedLimitExpressionImpl(int limitVal) { - this.val = limitVal; - } - - @Override - public int getLimitValue() { - return val; - } - - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Node.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.Objects; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; - -/** - * A basic node in the prepared statement parse tree. - * - */ -class Node implements Printable, Patchable { - - private Node parent; - - private Object value; - - Node(Node parent) { - this.parent = parent; - } - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - public Node getParent() { - return parent; - } - - public void setParent(Node parent) { - this.parent = parent; - } - - @Override - public void print(int level) { - for (int i = 0; i < level; i++) { - System.out.print("-"); - } - System.out.print(getValue()); - System.out.println(""); - if (value instanceof Node) { - Node node = (Node)value; - node.print(level + 1); - } - } - - @Override - public PatchedWhereExpression patch(PreparedParameter[] params) throws IllegalPatchException { - if (getValue() == null || !(getValue() instanceof Node) ) { - String msg = Node.class.getSimpleName() + - " invalid when attempted to patch"; - IllegalStateException cause = new IllegalStateException(msg); - throw new IllegalPatchException(cause); - } - Node node = (Node)getValue(); - return node.patch(params); - } - - @Override - public boolean equals(Object other) { - if (other == null) { - return false; - } - if (!(other instanceof Node)) { - return false; - } - Node o = (Node)other; - return Objects.equals(getValue(), o.getValue()); - } - - @Override - public int hashCode() { - return Objects.hash(getValue()); - } - - @Override - public String toString() { - return "Node: " + getValue(); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/NotBooleanExpressionNode.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.Objects; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.query.ComparisonExpression; -import com.redhat.thermostat.storage.query.UnaryLogicalExpression; -import com.redhat.thermostat.storage.query.UnaryLogicalOperator; - -/** - * A node representing a boolean not expression in the prepared statement's - * parse tree. - * - */ -class NotBooleanExpressionNode extends UnaryExpressionNode { - - NotBooleanExpressionNode(Node parent) { - super(parent); - } - - @Override - public UnaryLogicalOperator getOperator() { - return UnaryLogicalOperator.NOT; - } - - @Override - public PatchedWhereExpression patch(PreparedParameter[] params) throws IllegalPatchException { - if (getValue() == null || !(getValue() instanceof Node) ) { - String msg = getClass().getSimpleName() + - " invalid when attempted to patch"; - IllegalStateException cause = new IllegalStateException(msg); - throw new IllegalPatchException(cause); - } - Node node = (Node)getValue(); - PatchedWhereExpression patched = node.patch(params); - // If this cast fails we are in serious trouble. Mongodb doesn't support - // something like NOT ( a AND b ). However, the grammar does not support - // parenthesized expressions, NOT has higher precedence as AND/OR - // expressions and the LHS and RHS of binary boolean expressions are - // required to be binary comparison expressions. - // Hence, we wouldn't parse an expression such as the above anyway. - ComparisonExpression expr = (ComparisonExpression)patched.getExpression(); - UnaryLogicalExpression<ComparisonExpression> notExpr = new UnaryLogicalExpression<>( - expr, getOperator()); - return new PatchedWhereExpressionImpl(notExpr); - } - - @Override - public boolean equals(Object other) { - if (other == null) { - return false; - } - if (!(other instanceof NotBooleanExpressionNode)) { - return false; - } - NotBooleanExpressionNode o = (NotBooleanExpressionNode)other; - return Objects.equals(getValue(), o.getValue()); - } - - @Override - public int hashCode() { - return Objects.hash(getOperator(), getValue()); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Operator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -/** - * Valid operators in the string representation of a prepared statement - * descriptor. - * - */ -enum Operator { - - /** Logical AND operation */ - AND("AND"), - /** Logical OR operation */ - OR("OR"), - /** Logical NOT operation */ - NOT("NOT"), - /** Equality comparison */ - EQUALS("="), - /** Inequality comparison */ - NOT_EQUAL_TO("!="), - /** Greater than comparison */ - GREATER_THAN(">"), - /** Greater than or equal comparison */ - GREATER_THAN_OR_EQUAL_TO(">="), - /** Less than comparison */ - LESS_THAN("<"), - /** Less than or equal comparison */ - LESS_THAN_OR_EQUAL_TO("<="); - - private String name; - - Operator(String name) { - this.name = name; - } - - public String getName() { - return name; - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/ParsedStatementImpl.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,219 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.Add; -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.ParsedStatement; -import com.redhat.thermostat.storage.core.PreparedParameter; -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.Statement; -import com.redhat.thermostat.storage.core.Update; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.Expression; - -/** - * Result object as returned by {@link BasicDescriptorParser#parse()}. - * An instance of this plus a list of {@link PreparedParameter} should - * be sufficient to patch up a prepared statement with its real values. - * - * @see PreparedStatementImpl#executeQuery() - */ -class ParsedStatementImpl<T extends Pojo> implements ParsedStatement<T> { - - private final Statement<T> statement; - private int numParams; - private SuffixExpression suffixExpn; - private SetList setList; - - ParsedStatementImpl(Statement<T> statement) { - this.statement = statement; - } - - @Override - public int getNumParams() { - return numParams; - } - - @Override - public Statement<T> patchStatement(PreparedParameter[] params) throws IllegalPatchException { - if (suffixExpn == null) { - String msg = "Suffix expression must be set before patching!"; - IllegalStateException expn = new IllegalStateException(msg); - throw new IllegalPatchException(expn); - } - - /* - * Statements may not be stateless and hence, we need to create a - * duplicate prior every patch + execution. - */ - Statement<T> stmt = statement.getRawDuplicate(); - - patchSetList(stmt, params); - patchWhere(stmt, params); - patchSort(stmt, params); - patchLimit(stmt, params); - // TODO count actual patches and throw an exception if not all vars - // have been patched up. - return stmt; - } - - private void patchSetList(Statement<T> stmt, PreparedParameter[] params) throws IllegalPatchException { - if (setList.getValues().size() == 0) { - // no set list, nothing to do - return; - } - // do the patching - PatchedSetList patchedSetList = setList.patch(params); - // set the values - if (stmt instanceof Add) { - Add<T> add = (Add<T>)stmt; - for (PatchedSetListMember member: patchedSetList.getSetListMembers()) { - add.set(member.getKey().getName(), member.getValue()); - } - } - if (stmt instanceof Replace) { - Replace<T> replace = (Replace<T>)stmt; - for (PatchedSetListMember member: patchedSetList.getSetListMembers()) { - replace.set(member.getKey().getName(), member.getValue()); - } - } - if (stmt instanceof Update) { - Update<T> update = (Update<T>)stmt; - for (PatchedSetListMember member: patchedSetList.getSetListMembers()) { - update.set(member.getKey().getName(), member.getValue()); - } - } - } - - private void patchLimit(Statement<T> stmt, PreparedParameter[] params) throws IllegalPatchException { - LimitExpression expn = suffixExpn.getLimitExpn(); - if (expn == null) { - // no limit expn, nothing to do - return; - } - PatchedLimitExpression patchedExp = expn.patch(params); - if (stmt instanceof Query) { - Query<T> query = (Query<T>) stmt; - query.limit(patchedExp.getLimitValue()); - } else { - String msg = "Patching 'limit' of non-query types not supported! Class was:" - + stmt.getClass().getName(); - IllegalStateException invalid = new IllegalStateException(msg); - throw new IllegalPatchException(invalid); - } - } - - private void patchSort(Statement<T> stmt, PreparedParameter[] params) throws IllegalPatchException { - SortExpression expn = suffixExpn.getSortExpn(); - if (expn == null) { - // no sort expn, nothing to do - return; - } - PatchedSortExpression patchedExp = expn.patch(params); - if (stmt instanceof Query) { - Query<T> query = (Query<T>) stmt; - PatchedSortMember[] members = patchedExp.getSortMembers(); - for (int i = 0; i < members.length; i++) { - query.sort(members[i].getSortKey(), members[i].getDirection()); - } - } else { - String msg = "Patching 'sort' of non-query types not supported! Class was:" - + stmt.getClass().getName(); - IllegalStateException invalid = new IllegalStateException(msg); - throw new IllegalPatchException(invalid); - } - } - - private void patchWhere(Statement<T> stmt, PreparedParameter[] params) throws IllegalPatchException { - WhereExpression expn = suffixExpn.getWhereExpn(); - if (expn == null) { - // no where, nothing to do - return; - } - // walk the tree, create actual expressions and patch values along - // the way. - PatchedWhereExpression patchedExp = expn.patch(params); - Expression whereClause = patchedExp.getExpression(); - if (stmt instanceof Query) { - Query<T> query = (Query<T>) stmt; - query.where(whereClause); - } else if (stmt instanceof Replace) { - Replace<T> replace = (Replace<T>) stmt; - replace.where(whereClause); - } else if (stmt instanceof Update) { - Update<T> update = (Update<T>) stmt; - update.where(whereClause); - } else if (stmt instanceof Remove) { - Remove<T> remove = (Remove<T>) stmt; - remove.where(whereClause); - } else { - String msg = "Patching of where clause not supported! Class was:" - + stmt.getClass().getName(); - IllegalStateException invalid = new IllegalStateException(msg); - throw new IllegalPatchException(invalid); - } - } - - Statement<T> getRawStatement() { - return statement; - } - - void setNumFreeParams(int num) { - this.numParams = num; - } - - void setSuffixExpression(SuffixExpression tree) { - this.suffixExpn = tree; - } - - SuffixExpression getSuffixExpression() { - return suffixExpn; - } - - SetList getSetList() { - return setList; - } - - void setSetList(SetList setList) { - this.setList = setList; - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Patchable.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; - -/** - * Interface for patchable objects in a ParsedStatement. - * - */ -interface Patchable { - - /** - * - * @param params The parameters which should be used for patching. - * @return The finished (a.k.a patched) expression. - * @throws IllegalPatchException If something failed during patching. - */ - PatchedExpression patch(PreparedParameter[] params) throws IllegalPatchException; - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PatchedExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.Query; -import com.redhat.thermostat.storage.query.Expression; -import com.redhat.thermostat.storage.core.Query.SortDirection; -import com.redhat.thermostat.storage.core.Key; - -/** - * Return type for patched expressions - * - * @see Patchable - */ -interface PatchedExpression { - // marker interface -} - -interface PatchedWhereExpression extends PatchedExpression { - - /** - * @return The patched where expression. - * - * @see {@link Expression} - */ - Expression getExpression(); -} - -interface PatchedSortExpression extends PatchedExpression { - - /** - * - * @return The patched sorts. - * - * @see {@link PatchedSortMember} - * @see {@link Query#sort(Key, SortDirection)} - */ - PatchedSortMember[] getSortMembers(); - -} - -interface PatchedSortMemberExpression extends PatchedExpression { - - /** - * - * @return The patched sorts. - * - * @see {@link PatchedSortMember} - * @see {@link Query#sort(Key, SortDirection)} - */ - PatchedSortMember getSortMember(); - -} - -interface PatchedLimitExpression extends PatchedExpression { - - /** - * - * @return The patched limit value. - * - * @see {@link Query#limit(int)} - */ - int getLimitValue(); - -} - -interface PatchedSetListMemberExpression extends PatchedExpression { - - /** - * - * @return The patched set list member. - */ - PatchedSetListMember getSetListMember(); -} - -interface PatchedSetList extends PatchedExpression { - - /** - * @return The patched set list - * - */ - PatchedSetListMember[] getSetListMembers(); - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PatchedSetListMember.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.Key; - -/** - * Data structure representing patched SET lists members. - * - */ -class PatchedSetListMember { - - private final Key<?> key; - private final Object value; - - PatchedSetListMember(Key<?> key, Object value) { - this.key = key; - this.value = value; - } - - Key<?> getKey() { - return key; - } - - Object getValue() { - return value; - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PatchedSortMember.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.Query.SortDirection; - -/** - * Data structure representing patched sort members. - * - * @see Patchable - * @see PatchedSortExpression - * @see SortMember - */ -class PatchedSortMember { - - private final SortDirection direction; - private final Key<?> sortKey; - - PatchedSortMember(Key<?> sortKey, SortDirection direction) { - this.direction = direction; - this.sortKey = sortKey; - } - - SortDirection getDirection() { - return direction; - } - - Key<?> getSortKey() { - return sortKey; - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PatchedWhereExpressionImpl.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.query.Expression; - -/** - * Implementation of the return type of patchable where expressions. - * - */ -class PatchedWhereExpressionImpl implements PatchedWhereExpression { - - private final Expression expn; - - PatchedWhereExpressionImpl(Expression expn) { - this.expn = expn; - } - - @Override - public Expression getExpression() { - return expn; - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImpl.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.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; -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.ParsedStatement; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.core.PreparedParameters; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.Query; -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.model.Pojo; - -/** - * Main implementation of {@link PreparedStatement}s. - * - */ -final public class PreparedStatementImpl<T extends Pojo> implements PreparedStatement<T> { - - private StatementDescriptor<T> desc; - private Query<T> query; - private DataModifyingStatement<T> dmlStatement; - private final PreparedParameters params; - private final ParsedStatementImpl<T> parsedStatement; - - public PreparedStatementImpl(BackingStorage storage, StatementDescriptor<T> desc) throws DescriptorParsingException { - this.desc = desc; - StatementDescriptorParser<T> parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - this.parsedStatement = (ParsedStatementImpl<T>)parser.parse(); - int numParams = parsedStatement.getNumParams(); - params = new PreparedParameters(numParams); - Statement<T> statement = parsedStatement.getRawStatement(); - if (statement instanceof DataModifyingStatement) { - this.dmlStatement = (DataModifyingStatement<T>) statement; - } else if (statement instanceof Query) { - this.query = (Query<T>) statement; - } - } - - // used for testing ParsedStatements - PreparedStatementImpl(int numParams) { - params = new PreparedParameters(numParams); - this.parsedStatement = null; - } - - @Override - public void setLong(int paramIndex, long paramValue) { - params.setLong(paramIndex, paramValue); - } - - @Override - public void setLongList(int paramIndex, long[] paramValue) { - params.setLongList(paramIndex, paramValue); - } - - @Override - public void setInt(int paramIndex, int paramValue) { - params.setInt(paramIndex, paramValue); - } - - @Override - public void setIntList(int paramIndex, int[] paramValue) { - params.setIntList(paramIndex, paramValue); - } - - @Override - public void setStringList(int paramIndex, String[] paramValue) { - params.setStringList(paramIndex, paramValue); - } - - @Override - public void setBoolean(int paramIndex, boolean paramValue) { - params.setBoolean(paramIndex, paramValue); - } - - @Override - public void setBooleanList(int paramIndex, boolean[] paramValue) { - params.setBooleanList(paramIndex, paramValue); - } - - @Override - public void setDouble(int paramIndex, double paramValue) { - params.setDouble(paramIndex, paramValue); - } - - @Override - public void setDoubleList(int paramIndex, double[] paramValue) { - params.setDoubleList(paramIndex, paramValue); - } - - @Override - public void setPojo(int paramIndex, Pojo paramValue) { - params.setPojo(paramIndex, paramValue); - } - - @Override - public void setPojoList(int paramIndex, Pojo[] paramValue) { - params.setPojoList(paramIndex, paramValue); - } - - @Override - public int execute() throws StatementExecutionException { - if (dmlStatement == null) { - throw new IllegalStateException( - "Can't execute statement which isn't an instance of " - + DataModifyingStatement.class.getName()); - } - try { - dmlStatement = (DataModifyingStatement<T>)parsedStatement.patchStatement(params.getParams()); - } catch (Exception e) { - throw new StatementExecutionException(e); - } - return dmlStatement.apply(); - } - - @Override - public Cursor<T> executeQuery() throws StatementExecutionException{ - if (query == null) { - throw new IllegalStateException( - "Can't execute statement which isn't an instance of " - + Query.class.getName()); - } - try { - // FIXME: I'm sure we can improve on this. We should avoid walking the - // tree each time. Some cache with unfinished nodes and a reference - // to the matching expression should be sufficient. - query = (Query<T>)parsedStatement.patchStatement(params.getParams()); - } catch (IllegalPatchException e) { - throw new StatementExecutionException(e); - } - return query.execute(); - } - - @Override - public void setString(int paramIndex, String paramValue) { - params.setString(paramIndex, paramValue); - } - - // For testing only - PreparedParameter[] getParams() { - return params.getParams(); - } - - @Override - public ParsedStatement<T> getParsedStatement() { - return parsedStatement; - } - - @Override - public String toString() { - return desc.getDescriptor(); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Printable.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.PreparedStatement; - -/** - * Implement this interface for printable nodes in the - * {@link PreparedStatement} parse tree. This is mainly useful for debugging - * purposes. Most nodes of the prepared statement's parse tree implement it. - * - * - * @see SuffixExpression#printExpn(); - * @see WhereExpression#print(int); - * @see SortExpression#print(int); - * @see LimitExpression#print(int); - */ -interface Printable { - - /** - * Print a {@link Node} in a tree-like fashion. - * - * @param level The level of this node in the tree. - */ - void print(int level); -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SemanticsEnabledDescriptorParser.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,214 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import com.redhat.thermostat.storage.core.Add; -import com.redhat.thermostat.storage.core.AggregateQuery; -import com.redhat.thermostat.storage.core.BackingStorage; -import com.redhat.thermostat.storage.core.DataModifyingStatement; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.ParsedStatement; -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.Statement; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.Update; -import com.redhat.thermostat.storage.model.Pojo; - -class SemanticsEnabledDescriptorParser<T extends Pojo> extends - BasicDescriptorParser<T> { - - SemanticsEnabledDescriptorParser(BackingStorage storage, StatementDescriptor<T> desc) { - super(storage, desc); - } - - public ParsedStatement<T> parse() throws DescriptorParsingException { - ParsedStatementImpl<T> parsed = (ParsedStatementImpl<T>)super.parse(); - doSemanticAnalysis(parsed); - return parsed; - } - - private void doSemanticAnalysis(ParsedStatementImpl<T> parsed) throws DescriptorParsingException { - Statement<T> stmt = parsed.getRawStatement(); - // statement should never be null - Objects.requireNonNull(stmt); - if (stmt instanceof Add) { - // ADD don't take a WHERE - if (tree.getWhereExpn() != null) { - String msg = "WHERE clause not allowed for ADD"; - throw new DescriptorParsingException(msg); - } - // ADD requires all keys to be specified in the desc - ensureAllKeysSpecified(); - } - if (stmt instanceof Replace) { - // REPLACE requires a WHERE - if (tree.getWhereExpn() == null) { - String msg = "WHERE clause required for REPLACE"; - throw new DescriptorParsingException(msg); - } - // REPLACE requires all keys to be specified in the desc - ensureAllKeysSpecified(); - } - if (stmt instanceof Update) { - // WHERE required for UPDATE - if (tree.getWhereExpn() == null) { - String msg = "WHERE clause required for UPDATE"; - throw new DescriptorParsingException(msg); - } - // SET required for UPDATE - if (setList.getValues().size() == 0) { - String msg = "SET list required for UPDATE"; - throw new DescriptorParsingException(msg); - } - ensureKeyInSetIsKnown(); - } - if (stmt instanceof Remove && setList.getValues().size() > 0) { - String msg = "SET not allowed for REMOVE"; - throw new DescriptorParsingException(msg); - } - // matches for QUERY/QUERY-COUNT/QUERY-DISTINCT - if (stmt instanceof Query) { - if (setList.getValues().size() > 0) { - // Must not have SET for QUERYs - String msg = "SET not allowed for QUERY/QUERY-COUNT"; - throw new DescriptorParsingException(msg); - } - if (stmt instanceof AggregateQuery) { - AggregateQuery<T> aggQuery = (AggregateQuery<T>)stmt; - switch (aggQuery.getAggregateFunction()) { - case COUNT: - // count queries need a sane key param if present - performKeyParamChecksAllowNull(aggQuery); - break; - case DISTINCT: - // distinct queries must have a known key - performKeyParamChecks(aggQuery); - break; - default: - throw new IllegalStateException("Unknown aggregate function: " + aggQuery.getAggregateFunction()); - } - } - } else { - assert(stmt instanceof DataModifyingStatement); - // only queries can have sort/limit expressions - if (this.tree.getLimitExpn() != null || this.tree.getSortExpn() != null) { - String msg = "LIMIT/SORT only allowed for QUERY/QUERY-COUNT"; - throw new DescriptorParsingException(msg); - } - } - } - - private void performKeyParamChecksAllowNull(AggregateQuery<T> aggQuery) throws DescriptorParsingException { - if (aggQuery.getAggregateKey() != null) { - performKeyParamChecks(aggQuery); - } - } - - private void performKeyParamChecks(AggregateQuery<T> aggQuery) throws DescriptorParsingException { - Key<?> optionalKey = aggQuery.getAggregateKey(); - if (optionalKey == null) { - throw new DescriptorParsingException("Aggregate key for " - + aggQuery.getAggregateFunction() + " must not be null."); - } - // non-null case - String name = optionalKey.getName(); - Key<?> aggKey = desc.getCategory().getKey(name); - if (aggKey == null) { - throw new DescriptorParsingException("Unknown aggregate key '" + name + "'"); - } - } - - private void ensureKeyInSetIsKnown() throws DescriptorParsingException { - // retrieve the expected keys list from the category - Collection<Key<?>> keys = desc.getCategory().getKeys(); - Set<Key<?>> expectedSet = new HashSet<>(keys.size()); - expectedSet.addAll(keys); - List<String> unknownKeys = new ArrayList<>(); - try { - for (SetListValue val: setList.getValues()) { - // this may throw CCE if LHS is a free parameter. That's not - // allowed though. - Key<?> key = (Key<?>)val.getKey().getValue(); - if (!expectedSet.contains(key)) { - unknownKeys.add(key.getName()); - } - } - } catch (ClassCastException e) { - // LHS of set pair a free variable, which isn't allowed - String msg = "LHS of set list pair must not be a free variable."; - throw new DescriptorParsingException(msg); - } - if (!unknownKeys.isEmpty()) { - String msg = "Unknown key(s) in SET: '" + unknownKeys + "'"; - throw new DescriptorParsingException(msg); - } - } - - private void ensureAllKeysSpecified() throws DescriptorParsingException { - // retrieve the expected keys list from the category - Collection<Key<?>> keys = desc.getCategory().getKeys(); - Set<Key<?>> expectedSet = new HashSet<>(keys.size()); - expectedSet.addAll(keys); - Set<Key<?>> keysInSetList = new HashSet<>(keys.size()); - try { - for (SetListValue val: setList.getValues()) { - // this may throw CCE - Key<?> key = (Key<?>)val.getKey().getValue(); - keysInSetList.add(key); - } - } catch (ClassCastException e) { - // LHS of set pair a free variable, which isn't allowed - String msg = "LHS of set list pair must not be a free variable."; - throw new DescriptorParsingException(msg); - } - if (!keysInSetList.equals(expectedSet)) { - String msg = "Keys don't match keys in category. Expected the following keys: " + expectedSet + " got " + keysInSetList; - throw new DescriptorParsingException(msg); - }; - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SetList.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.ArrayList; -import java.util.List; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; - -/** - * Represents a set list of a prepared write statement. - * - */ -class SetList implements Patchable, Printable { - - private List<SetListValue> values = new ArrayList<>(); - - void addValue(SetListValue newValue) { - values.add(newValue); - } - - List<SetListValue> getValues() { - return values; - } - - @Override - public void print(int level) { - System.out.println("SET:"); - for (SetListValue val: getValues()) { - val.print(level); - } - } - - @Override - public PatchedSetList patch(PreparedParameter[] params) - throws IllegalPatchException { - List<PatchedSetListMember> patchedSetList = new ArrayList<>(); - for (SetListValue val: getValues()) { - PatchedSetListMemberExpression memberExp = val.patch(params); - patchedSetList.add(memberExp.getSetListMember()); - } - PatchedSetListMember[] members = patchedSetList.toArray(new PatchedSetListMember[0]); - PatchedSetListImpl setList = new PatchedSetListImpl(members); - return setList; - } - - private static class PatchedSetListImpl implements PatchedSetList { - - private final PatchedSetListMember[] members; - - private PatchedSetListImpl(PatchedSetListMember[] members) { - this.members = members; - } - - @Override - public PatchedSetListMember[] getSetListMembers() { - return members; - } - - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SetListValue.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.Objects; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.query.LiteralExpression; - -/** - * Represents a value pair in a set list of prepared writes. - * - */ -class SetListValue implements Patchable, Printable { - - private TerminalNode key; - private TerminalNode value; - - TerminalNode getKey() { - return key; - } - void setKey(TerminalNode key) { - this.key = key; - } - TerminalNode getValue() { - return value; - } - void setValue(TerminalNode value) { - this.value = value; - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof SetListValue)) { - return false; - } - SetListValue o = (SetListValue)other; - return Objects.equals(this.getValue(), o.getValue()) && - Objects.equals(this.getKey(), o.getKey()); - } - - @Override - public int hashCode() { - return Objects.hash(this.getKey(), this.getValue()); - } - - @Override - public String toString() { - return "{" + getKey() + " = " + getValue() + "}"; - } - - @Override - public void print(int level) { - for (int i = 0; i < level; i++) { - System.out.print(" "); - } - System.out.println(toString()); - - } - - @Override - public PatchedSetListMemberExpression patch(PreparedParameter[] params) - throws IllegalPatchException { - - // patch LHS - PatchedWhereExpression keyExp = key.patch(params); - @SuppressWarnings("unchecked") // we've generated the key - LiteralExpression<Key<?>> keyLiteral = (LiteralExpression<Key<?>>)keyExp.getExpression(); - Key<?> keyVal = (Key<?>) keyLiteral.getValue(); - - // patch RHS - PatchedWhereExpression valExp = value.patch(params); - LiteralExpression<?> valLiteral = (LiteralExpression<?>)valExp.getExpression(); - Object val = valLiteral.getValue(); - - PatchedSetListMember member = new PatchedSetListMember(keyVal, val); - PatchedSetListMemberExpressionImpl retval = new PatchedSetListMemberExpressionImpl(member); - return retval; - } - - private static class PatchedSetListMemberExpressionImpl implements PatchedSetListMemberExpression { - - private final PatchedSetListMember member; - - private PatchedSetListMemberExpressionImpl(PatchedSetListMember member) { - this.member = member; - } - - @Override - public PatchedSetListMember getSetListMember() { - return member; - } - - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SortExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.ArrayList; -import java.util.List; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; - -/** - * Represents a sort expression of a prepared statement's parse tree. - * - */ -class SortExpression implements Printable, Patchable { - - List<SortMember> members = new ArrayList<>(); - - public void addMember(SortMember member) { - members.add(member); - } - - public List<SortMember> getMembers() { - return members; - } - - @Override - public void print(int level) { - System.out.print("SORT: "); - for (int i = 0; i < members.size(); i++) { - SortMember member = members.get(i); - member.print(level); - if (i < members.size() - 1) { - System.out.print(", "); - } - } - System.out.println(""); - } - - @Override - public PatchedSortExpression patch(PreparedParameter[] params) - throws IllegalPatchException { - List<PatchedSortMember> patchedMembers = new ArrayList<>(); - for (SortMember member: members) { - PatchedSortMemberExpression expn = member.patch(params); - patchedMembers.add(expn.getSortMember()); - } - // worked so far (no exceptions) create impl exp and return - PatchedSortMember[] members = patchedMembers.toArray(new PatchedSortMember[0]); - return new PatchedSortExpressionImpl(members); - } - - private static class PatchedSortExpressionImpl implements PatchedSortExpression { - - private final PatchedSortMember[] members; - - private PatchedSortExpressionImpl(PatchedSortMember[] members) { - this.members = members; - } - - @Override - public PatchedSortMember[] getSortMembers() { - return members; - } - - - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SortMember.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.core.Query.SortDirection; - -/** - * Represents sort members. - * - * @see SortExpression - * - */ -class SortMember implements Printable, Patchable { - - private SortDirection direction; - private Object sortKey; - - public SortDirection getDirection() { - return direction; - } - - public void setDirection(SortDirection direction) { - this.direction = direction; - } - - public Object getSortKey() { - return sortKey; - } - - public void setSortKey(Object sortKey) { - this.sortKey = sortKey; - } - - @Override - public void print(int level) { - System.out.print(getSortKey() + " " + getDirection().name()); - } - - @Override - public PatchedSortMemberExpression patch(PreparedParameter[] params) - throws IllegalPatchException { - try { - String keyVal = null; - if (getSortKey() instanceof Unfinished) { - Unfinished unfinished = (Unfinished)getSortKey(); - PreparedParameter p = params[unfinished.getParameterIndex()]; - // Should only allow patching of ?s type NOT ?s[ - if (p.getType() != String.class) { - String msg = "Illegal parameter type for index " - + unfinished.getParameterIndex() - + ". Expected String!"; - IllegalArgumentException iae = new IllegalArgumentException(msg); - throw iae; - } - keyVal = (String)p.getValue(); - } else { - keyVal = (String)getSortKey(); - } - Key<?> sortKey = new Key<>(keyVal); - PatchedSortMember m = new PatchedSortMember(sortKey, getDirection()); - return new PatchedSortMemberExpressionImpl(m); - } catch (Exception e) { - throw new IllegalPatchException(e); - } - } - - private static class PatchedSortMemberExpressionImpl implements PatchedSortMemberExpression { - - private final PatchedSortMember member; - private PatchedSortMemberExpressionImpl(PatchedSortMember member) { - this.member = member; - } - - @Override - public PatchedSortMember getSortMember() { - return member; - } - - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorParser.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.ParsedStatement; -import com.redhat.thermostat.storage.model.Pojo; - -/** - * Common interface for statement descriptor parsers. - * - * @see BasicDescriptorParser - * @see SemanticsEnabledDescriptorParser - * - * @param <T> The {@link Pojo} model type pertaining to this parser. - */ -interface StatementDescriptorParser<T extends Pojo> { - - /** - * Parses a descriptor, possibly performing some semantic analysis after - * parsing. - * - * @throws DescriptorParsingException - * if the descriptor failed to parse or did not pass semantic - * analysis. - * @return An intermediary representation suitable for repeated execution of - * the prepared statement. - */ - ParsedStatement<T> parse() throws DescriptorParsingException; - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/SuffixExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -/** - * Container for where, sort and limit expressions. - * - */ -class SuffixExpression { - - private WhereExpression whereExpn; - private SortExpression sortExpn; - private LimitExpression limitExpn; - - public WhereExpression getWhereExpn() { - return whereExpn; - } - - public void setWhereExpn(WhereExpression whereExpn) { - this.whereExpn = whereExpn; - } - - public SortExpression getSortExpn() { - return sortExpn; - } - - public void setSortExpn(SortExpression sortExpn) { - this.sortExpn = sortExpn; - } - - public LimitExpression getLimitExpn() { - return limitExpn; - } - - public void setLimitExpn(LimitExpression limitExpn) { - this.limitExpn = limitExpn; - } - - /** - * Prints the entire suffix expression to stdout. - */ - public void printExpn() { - if (whereExpn != null) { - whereExpn.print(0); - } - if (sortExpn != null) { - sortExpn.print(0); - } - if (limitExpn != null) { - limitExpn.print(0); - } - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/TerminalNode.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.Objects; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.LiteralExpression; - -/** - * Node representing a leaf node in the prepared statement parse tree. - * - */ -class TerminalNode extends Node { - - TerminalNode(Node parent) { - super(parent); - } - - @Override - public PatchedWhereExpression patch(PreparedParameter[] params) throws IllegalPatchException { - if (getValue() == null) { - String msg = TerminalNode.class.getSimpleName() + - " invalid when attempted to patch"; - IllegalStateException cause = new IllegalStateException(msg); - throw new IllegalPatchException(cause); - } - Object actualValue; - if (getValue() instanceof UnfinishedValueNode) { - // need to patch the value - UnfinishedValueNode patch = (UnfinishedValueNode)getValue(); - PreparedParameter param = null; - try { - param = params[patch.getParameterIndex()]; - } catch (Exception e) { - throw new IllegalPatchException(e); - } - // Do some type sanity checking for free parameters - ensureTypeCompatibility(patch, param); - if (patch.isLHS()) { - // LHS need to get patched to keys - Key<?> valueKey = new Key<>((String)param.getValue()); - actualValue = valueKey; - } else { - actualValue = param.getValue(); - } - } else { - actualValue = getValue(); - } - LiteralExpression<?> literalExp = new LiteralExpression<>(actualValue); - return new PatchedWhereExpressionImpl(literalExp); - } - - private void ensureTypeCompatibility(UnfinishedValueNode patch, - PreparedParameter param) throws IllegalPatchException { - if (patch.getType() == Pojo.class) { - // handle pojo case - Object value = param.getValue(); - if (Pojo.class.isAssignableFrom(param.getType()) && - value != null && !value.getClass().isArray()) { - return; // pojo-type match: OK - } - // dead-end - IllegalArgumentException iae = constructIllegalArgumentException(patch, param); - throw new IllegalPatchException(iae); - } else if (patch.getType() == Pojo[].class) { - // handle pojo list case - Object value = param.getValue(); - if (Pojo.class.isAssignableFrom(param.getType()) && value != null - && value.getClass().isArray()) { - return; // pojo-list type match: OK - } - } else { - // primitive types or primitive list types - if (param.getType() != patch.getType()) { - IllegalArgumentException iae = constructIllegalArgumentException(patch, param); - throw new IllegalPatchException(iae); - } - // passed primitive (array) type check - } - } - - private IllegalArgumentException constructIllegalArgumentException( - UnfinishedValueNode patch, PreparedParameter param) { - Object value = param.getValue(); - String paramArrayPrefix = ""; - if (value != null && value.getClass().isArray()) { - paramArrayPrefix = "["; - } - String msg = TerminalNode.class.getSimpleName() - + " invalid type when attempting to patch. Expected " - + patch.getType().getName() + " but was " - + paramArrayPrefix + param.getType().getName(); - IllegalArgumentException iae = new IllegalArgumentException(msg); - return iae; - } - - @Override - public boolean equals(Object other) { - if (other == null) { - return false; - } - if (!(other instanceof TerminalNode)) { - return false; - } - TerminalNode o = (TerminalNode)other; - return Objects.equals(getValue(), o.getValue()); - } - - @Override - public int hashCode() { - return Objects.hash(getValue()); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/UnaryExpressionNode.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -/** - * @see NotBooleanExpressionNode - * - */ -abstract class UnaryExpressionNode extends Node { - - UnaryExpressionNode(Node parent) { - super(parent); - } - - public abstract Object getOperator(); - - @Override - public void print(int level) { - Node value = (Node)getValue(); - for (int i = 0; i < level; i++) { - System.out.print("-"); - } - System.out.print("U: " + getOperator()); - System.out.println(""); - value.print(level++); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/Unfinished.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -/** - * Marker interface for unfinished nodes in a prepared statement's parse tree. - * - */ -public interface Unfinished { - - /** - * @return The index which contains the actual value of this unfinished - * node. - */ - int getParameterIndex(); - - /** - * Sets the index which should be used for indexing into the list of - * parameters which contains actual values. - * - * @param parameterIndex - */ - void setParameterIndex(int parameterIndex); -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/UnfinishedLimitValue.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -/** - * - * Represents an {@link Unfinished} limit value. - * - * @see Patchable - * - */ -class UnfinishedLimitValue extends AbstractUnfinished { - - private int parameterIndex = -1; - - @Override - public int getParameterIndex() { - return parameterIndex; - } - - @Override - public void setParameterIndex(int parameterIndex) { - this.parameterIndex = parameterIndex; - } - - @Override - public String toString() { - return "Unfinished limit value (" + getParameterIndex() + ")"; - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/UnfinishedSortKey.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -/** - * - * Represents an {@link Unfinished} sort value. - * - * @see Patchable - * - */ -class UnfinishedSortKey extends AbstractUnfinished { - - private int paramIndex = -1; - - @Override - public int getParameterIndex() { - return paramIndex; - } - - @Override - public void setParameterIndex(int parameterIndex) { - this.paramIndex = parameterIndex; - } - - @Override - public String toString() { - return "Unfinished sort key (" + getParameterIndex() + ")"; - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/UnfinishedValueNode.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.Objects; - -/** - * - * Represents an {@link Unfinished} node in the where expressions parse tree - * of prepared statements. - * - * @see Patchable - * - */ -class UnfinishedValueNode extends AbstractUnfinished { - - private int parameterIndex = -1; - // determines if this patched value is a LHS or if false a RHS of a - // binary comparison. - private boolean isLHS; - // Specifies the expected (component) type of this free parameter. - private Class<?> type; - - Class<?> getType() { - return type; - } - - void setType(Class<?> type) { - this.type = type; - } - - boolean isLHS() { - return isLHS; - } - - void setLHS(boolean isLHS) { - this.isLHS = isLHS; - } - - @Override - public int getParameterIndex() { - return parameterIndex; - } - - @Override - public void setParameterIndex(int parameterIndex) { - this.parameterIndex = parameterIndex; - } - - @Override - public String toString() { - return "Unfinished value (" + getParameterIndex() + ") " + getType() + - ":" + ( isLHS ? "LHS" : "RHS" ); - } - - @Override - public boolean equals(Object other) { - boolean basics = super.equals(other); - if (!basics) { - return false; - } - if (!(other instanceof UnfinishedValueNode)) { - return false; - } - UnfinishedValueNode o = (UnfinishedValueNode)other; - return basics && Objects.equals(isLHS(), o.isLHS) && - Objects.equals(getType(), o.getType()); - } - - @Override - public int hashCode() { - return Objects.hash(getParameterIndex(), isLHS(), getType()); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/statement/WhereExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; - -/** - * Data structure representing a where expression. - * - * @see Node - * @see SuffixExpression - * @see BasicDescriptorParser - */ -class WhereExpression implements Printable, Patchable { - - private final Node root; - - WhereExpression() { - this.root = new Node(null); - } - - public Node getRoot() { - return root; - } - - @Override - public void print(int level) { - System.out.println("WHERE:"); - Node node = (Node)root.getValue(); - node.print(0); - } - - @Override - public PatchedWhereExpression patch(PreparedParameter[] params) - throws IllegalPatchException { - Node node = (Node)root.getValue(); - return node.patch(params); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryComparisonExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import com.redhat.thermostat.storage.core.Key; - -/** - * A {@link BinaryExpression} that corresponds to an algebraic comparison - * between a {@link Key} and a corresponding value. - * @param <T> - the type parameter of this expression's {@link Key} - */ -public final class BinaryComparisonExpression<T> - extends BinaryExpression<LiteralExpression<Key<T>>, LiteralExpression<T>, BinaryComparisonOperator> - implements ComparisonExpression { - - /** - * Constructs a {@link BinaryComparisonExpression} whose operands are - * a {@link LiteralExpression} for a {@link Key} and a {@link LiteralExpression} - * for the value to compare against the key. - * <p> - * This constructor exists mainly for JSON serialization, use methods in - * {@link ExpressionFactory} instead of this constructor. - * @param leftOperand - left operand for this expression - * @param operator - the operator for this expression - * @param rightOperand - right operand for this expression - */ - public BinaryComparisonExpression(LiteralExpression<Key<T>> leftOperand, - BinaryComparisonOperator operator, LiteralExpression<T> rightOperand) { - super(leftOperand, operator, rightOperand); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryComparisonOperator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * Operators to be used with {@link BinaryComparisonExpression} - */ -public enum BinaryComparisonOperator implements BinaryOperator { - /** Equality comparison */ - EQUALS, - /** Inequality comparison */ - NOT_EQUAL_TO, - /** Greater than comparison */ - GREATER_THAN, - /** Greater than or equal comparison */ - GREATER_THAN_OR_EQUAL_TO, - /** Less than comparison */ - LESS_THAN, - /** Less than or equal comparison */ - LESS_THAN_OR_EQUAL_TO, -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * An {@link Expression} with two operands and one operator. - * @param <S> - the type of {@link Expression} corresponding to the left operand - * @param <T> - the type of {@link Expression} corresponding to the right operand - * @param <U> - the type of {@link BinaryOperator} corresponding to the operator - */ -abstract class BinaryExpression<S extends Expression, T extends Expression, U extends BinaryOperator> - implements Expression { - - private S leftOperand; - private U operator; - private T rightOperand; - - /** - * Constructs a {@link BinaryExpression} given two operands and an operator. - * <p> - * This constructor exists mainly for JSON serialization, use methods in - * {@link ExpressionFactory} instead of this constructor. - * @param leftOperand - left operand for this expression - * @param operator - the operator for this expression - * @param rightOperand - right operand for this expression - */ - BinaryExpression(S leftOperand, U operator, T rightOperand) { - this.leftOperand = leftOperand; - this.operator = operator; - this.rightOperand = rightOperand; - } - - /** - * @return the left operand of this expression - */ - public S getLeftOperand() { - return leftOperand; - } - - /** - * @return the operator of this expression - */ - public U getOperator() { - return operator; - } - - /** - * @return the right operand of this expression - */ - public T getRightOperand() { - return rightOperand; - } - - @Override - public boolean equals(Object obj) { - boolean result = false; - if (obj != null && obj instanceof BinaryExpression) { - BinaryExpression<?, ?, ?> otherExpr = (BinaryExpression<?, ?, ?>) obj; - result = leftOperand.equals(otherExpr.leftOperand) - && rightOperand.equals(otherExpr.rightOperand) - && operator.equals(otherExpr.operator); - } - return result; - } - - @Override - public int hashCode() { - return leftOperand.hashCode() + operator.hashCode() + rightOperand.hashCode(); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("( "); - buf.append(leftOperand.toString()); - buf.append(" "); - buf.append(operator.toString()); - buf.append(" "); - buf.append(rightOperand.toString()); - buf.append(" )"); - return buf.toString(); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryLogicalExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * A {@link BinaryExpression} that represents a boolean formula - * with two expressions joined by a logical operator. - * @param <S> - the type of {@link Expression} corresponding to the left operand - * @param <T> - the type of {@link Expression} corresponding to the right operand - */ -public final class BinaryLogicalExpression<S extends Expression, T extends Expression> - extends BinaryExpression<S, T, BinaryLogicalOperator> - implements LogicalExpression { - - /** - * Constructs a {@link BinaryLogicalExpression} whose operands are - * expressions joined by a {@link BinaryLogicalOperator}. - * <p> - * This constructor exists mainly for JSON serialization, use methods in - * {@link ExpressionFactory} instead of this constructor. - * @param leftOperand - left operand for this expression - * @param operator - the operator for this expression - * @param rightOperand - right operand for this expression - */ - public BinaryLogicalExpression(S leftOperand, BinaryLogicalOperator operator, T rightOperand) { - super(leftOperand, operator, rightOperand); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryLogicalOperator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * Boolean operators to be used with {@link BinaryLogicalExpression}. - */ -public enum BinaryLogicalOperator implements BinaryOperator { - /** Logical AND operation */ - AND, - /** Logical OR operation */ - OR, -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/BinaryOperator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * Represents operators that take two operands. - */ -interface BinaryOperator extends Operator { - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/BinarySetMembershipExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import com.redhat.thermostat.storage.core.Key; - -/** - * A {@link BinaryExpression} that corresponds to an algebraic comparison - * between a {@link Key} and multiple values. - * @param <T> - the type parameter of this expression's {@link Key} - */ -public final class BinarySetMembershipExpression<T> - extends BinaryExpression<LiteralExpression<Key<T>>, LiteralSetExpression<T>, BinarySetMembershipOperator> - implements ComparisonExpression { - - /** - * Constructs a {@link BinarySetMembershipExpression} whose operands are - * a {@link LiteralExpression} for a {@link Key} and a {@link LiteralSetExpression} - * for the set of values to compare against the key. - * <p> - * This constructor exists mainly for JSON serialization, use methods in - * {@link ExpressionFactory} instead of this constructor. - * @param leftOperand - left operand for this expression - * @param operator - the operator for this expression - * @param rightOperand - right operand for this expression - */ - public BinarySetMembershipExpression(LiteralExpression<Key<T>> leftOperand, - BinarySetMembershipOperator operator, LiteralSetExpression<T> rightOperand) { - super(leftOperand, operator, rightOperand); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/BinarySetMembershipOperator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * Operators to be used with {@link BinarySetMembershipExpression} - */ -public enum BinarySetMembershipOperator implements BinaryOperator { - /** Compares if the left-hand value is equal to any of the - * right-hand values */ - IN, - /** Compares if the left-hand value is not equal to all of the - * right-hand values */ - NOT_IN, -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/ComparisonExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -public interface ComparisonExpression extends Expression { - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/Expression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import com.redhat.thermostat.storage.core.Query; - -/** - * Base interface for all expressions used in storage queries. - * @see Query#where(Expression) - */ -public interface Expression { - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/ExpressionFactory.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import java.util.Set; - -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.Query; - -/** - * This class provides convenience methods that should be used - * to create all expressions used in queries. - * - * @see Expression - * @see Query#where(Expression) - */ -public class ExpressionFactory { - - /** - * Creates a {@link BinaryComparisonExpression} comparing the - * provided key and value for equality. - * @param key - {@link Key} whose value to compare against the provided value - * @param value - the value to compare against the key - * @return the new comparison expression - */ - public <T> BinaryComparisonExpression<T> equalTo(Key<T> key, T value) { - return createComparisonExpression(key, value, BinaryComparisonOperator.EQUALS); - } - - /** - * Creates a {@link BinaryComparisonExpression} comparing the - * provided key and value for inequality. - * @param key - {@link Key} whose value to compare against the provided value - * @param value - the value to compare against the key - * @return the new comparison expression - */ - public <T> BinaryComparisonExpression<T> notEqualTo(Key<T> key, T value) { - return createComparisonExpression(key, value, BinaryComparisonOperator.NOT_EQUAL_TO); - } - - /** - * Creates a {@link BinaryComparisonExpression} comparing if the - * provided key has a value greater than the provided value. - * @param key - {@link Key} whose value to compare against the provided value - * @param value - the value to compare against the key - * @return the new comparison expression - */ - public <T> BinaryComparisonExpression<T> greaterThan(Key<T> key, T value) { - return createComparisonExpression(key, value, BinaryComparisonOperator.GREATER_THAN); - } - - /** - * Creates a {@link BinaryComparisonExpression} comparing if the - * provided key has a value less than the provided value. - * @param key - {@link Key} whose value to compare against the provided value - * @param value - the value to compare against the key - * @return the new comparison expression - */ - public <T> BinaryComparisonExpression<T> lessThan(Key<T> key, T value) { - return createComparisonExpression(key, value, BinaryComparisonOperator.LESS_THAN); - } - - /** - * Creates a {@link BinaryComparisonExpression} comparing if the - * provided key has a value greater than or equal to the provided value. - * @param key - {@link Key} whose value to compare against the provided value - * @param value - the value to compare against the key - * @return the new comparison expression - */ - public <T> BinaryComparisonExpression<T> greaterThanOrEqualTo(Key<T> key, T value) { - return createComparisonExpression(key, value, BinaryComparisonOperator.GREATER_THAN_OR_EQUAL_TO); - } - - /** - * Creates a {@link BinaryComparisonExpression} comparing if the - * provided key has a value less than or equal to the provided value. - * @param key - {@link Key} whose value to compare against the provided value - * @param value - the value to compare against the key - * @return the new comparison expression - */ - public <T> BinaryComparisonExpression<T> lessThanOrEqualTo(Key<T> key, T value) { - return createComparisonExpression(key, value, BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO); - } - - /** - * Creates a {@link BinarySetMembershipExpression} comparing if the - * provided key has a value equal to any of the provided values. - * @param key - {@link Key} whose value to compare against the provided values - * @param value - a set of values to compare against the key - * @param type - the type of values of stored in the provided set - * @return the new comparison expression - */ - public <T> BinarySetMembershipExpression<T> in(Key<T> key, Set<T> values, Class<T> type) { - return createSetMembershipExpression(key, values, BinarySetMembershipOperator.IN, type); - } - - /** - * Creates a {@link BinarySetMembershipExpression} comparing if the - * provided key has a value not equal to all of the provided values. - * @param key - {@link Key} whose value to compare against the provided values - * @param value - a set of values to compare against the key - * @param type - the type of values of stored in the provided set - * @return the new comparison expression - */ - public <T> BinarySetMembershipExpression<T> notIn(Key<T> key, Set<T> values, Class<T> type) { - return createSetMembershipExpression(key, values, BinarySetMembershipOperator.NOT_IN, type); - } - - /** - * Creates a {@link UnaryLogicalExpression} which is a logical - * negation of the provided expression. - * @param expr - the expression to negate - * @return the new negated expression - */ - public <T extends ComparisonExpression> UnaryLogicalExpression<T> not(T expr) { - return new UnaryLogicalExpression<>(expr, UnaryLogicalOperator.NOT); - } - - /** - * Creates a {@link BinaryLogicalExpression} with the two provided expressions - * joined in order by a logical AND operation. - * @param left - the left operand - * @param right - the right operand - * @return the new logical expression - */ - public <S extends Expression, T extends Expression> BinaryLogicalExpression<S, T> and(S left, T right) { - return new BinaryLogicalExpression<S, T>(left, BinaryLogicalOperator.AND, right); - } - - /** - * Creates a {@link BinaryLogicalExpression} with the two provided expressions - * joined in order by a logical OR operation. - * @param left - the left operand - * @param right - the right operand - * @return the new logical expression - */ - public <S extends Expression, T extends Expression> BinaryLogicalExpression<S, T> or(S left, T right) { - return new BinaryLogicalExpression<S, T>(left, BinaryLogicalOperator.OR, right); - } - - private <T> BinaryComparisonExpression<T> createComparisonExpression(Key<T> key, T value, BinaryComparisonOperator op) { - return new BinaryComparisonExpression<>(new LiteralExpression<>(key), op, new LiteralExpression<>(value)); - } - - private <T> BinarySetMembershipExpression<T> createSetMembershipExpression(Key<T> key, Set<T> values, - BinarySetMembershipOperator op, Class<T> type) { - return new BinarySetMembershipExpression<>(new LiteralExpression<>(key), op, - new LiteralSetExpression<>(values, type)); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/LiteralExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * An {@link Expression} that contains a value. - * @param <T> - the type of this expression's value - */ -public final class LiteralExpression<T> implements Expression { - - private T value; - - /** - * Constructs a {@link LiteralExpression} given a value. - * <p> - * This constructor exists mainly for JSON serialization, use methods in - * {@link ExpressionFactory} instead of this constructor. - * @param value - the value for this expression - */ - public LiteralExpression(T value) { - this.value = value; - } - - /** - * @return the value represented by this expression - */ - public T getValue() { - return value; - } - - @Override - public boolean equals(Object obj) { - boolean result = false; - if (obj != null && obj instanceof LiteralExpression) { - LiteralExpression<?> otherExpr = (LiteralExpression<?>) obj; - result = value.equals(otherExpr.value); - } - return result; - } - - @Override - public int hashCode() { - return value.hashCode(); - } - - @Override - public String toString() { - return value.toString(); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/LiteralSetExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import java.util.Collections; -import java.util.Set; - -/** - * An {@link Expression} that contains a set of values. - * @param <T> - the type of this expression's values - */ -public final class LiteralSetExpression<T> implements Expression { - - private Set<T> values; - private Class<T> type; - - /** - * Constructs a {@link LiteralSetExpression} given a list of values - * and its type. - * <p> - * This constructor exists mainly for JSON serialization, use methods in - * {@link ExpressionFactory} instead of this constructor. - * @param values - a list of values for this expression - * @param type - the type of values of stored in the provided set - * (needed for serialization) - */ - public LiteralSetExpression(Set<T> values, Class<T> type) { - // Don't need to write, make read-only copy - this.values = Collections.unmodifiableSet(values); - this.type = type; - } - - /** - * @return the values represented by this expression - */ - public Set<T> getValues() { - return values; - } - - /** - * @return the type of values stored in this expression - */ - public Class<T> getType() { - return type; - } - - @Override - public boolean equals(Object obj) { - boolean result = false; - if (obj != null && obj instanceof LiteralSetExpression) { - LiteralSetExpression<?> otherExpr = (LiteralSetExpression<?>) obj; - result = values.equals(otherExpr.values) - && type.equals(otherExpr.type); - } - return result; - } - - @Override - public int hashCode() { - return values.hashCode() + type.hashCode(); - } - - @Override - public String toString() { - return values.toString(); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/LogicalExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -public interface LogicalExpression extends Expression { - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/Operator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * Base interface for operators that are used with {@link Expression} objects. - * Concrete implementations must be enumeration types. - */ -public interface Operator { - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/UnaryExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * An {@link Expression} that has an operator and one operand. - * @param <S> - type of {@link Expression} used for the operand - * @param <T> - type of {@link UnaryOperator} used for the operator - */ -abstract class UnaryExpression<S extends Expression, T extends UnaryOperator> implements Expression { - - private S operand; - private T operator; - - /** - * Constructs a {@link UnaryExpression} given an operand and an operator. - * <p> - * This constructor exists mainly for JSON serialization, use methods in - * {@link ExpressionFactory} instead of this constructor. - * @param operand - operand for this expression - * @param operator - operator for this expression - */ - UnaryExpression(S operand, T operator) { - this.operand = operand; - this.operator = operator; - } - - /** - * @return the operand for this expression - */ - public S getOperand() { - return operand; - } - - /** - * @return the operator for this expression - */ - public T getOperator() { - return operator; - } - - @Override - public boolean equals(Object obj) { - boolean result = false; - if (obj != null && obj instanceof UnaryExpression) { - UnaryExpression<?, ?> otherExpr = (UnaryExpression<?, ?>) obj; - result = operand.equals(otherExpr.operand) - && operator.equals(otherExpr.operator); - } - return result; - } - - @Override - public int hashCode() { - return operand.hashCode() + operator.hashCode(); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("( "); - buf.append(operator.toString()); - buf.append(" "); - buf.append(operand.toString()); - buf.append(" )"); - return buf.toString(); - } -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/UnaryLogicalExpression.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * A {@link UnaryExpression} which represents a boolean formula - * with one comparison expression and a logical operator. - * @param <T> - type of {@link Expression} used for the operand - */ -public final class UnaryLogicalExpression<T extends ComparisonExpression> extends - UnaryExpression<T, UnaryLogicalOperator> - implements LogicalExpression { - - /** - * Constructs a {@link UnaryLogicalExpression} given an operand - * and a {@link UnaryLogicalOperator}. - * <p> - * This constructor exists mainly for JSON serialization, use methods in - * {@link ExpressionFactory} instead of this constructor. - * @param operand - the operand for this expression - * @param operator - the operator for this expression - */ - public UnaryLogicalExpression(T operand, UnaryLogicalOperator operator) { - super(operand, operator); - } - -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/UnaryLogicalOperator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * Operators to be used with {@link UnaryLogicalExpression}. - */ -public enum UnaryLogicalOperator implements UnaryOperator { - /** Logical NOT operation */ - NOT, -} -
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/query/UnaryOperator.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -/** - * Represents operators that take one operand. - */ -interface UnaryOperator extends Operator { - -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/AggregateQueryTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; - -import org.junit.Test; - -import com.redhat.thermostat.storage.core.AggregateQuery; -import com.redhat.thermostat.storage.core.AggregateQuery.AggregateFunction; -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.Statement; -import com.redhat.thermostat.storage.model.AggregateCount; - -public class AggregateQueryTest { - - @Test - public void testSetAggregateKey() { - @SuppressWarnings("unchecked") - Query<AggregateCount> query = mock(Query.class); - TestAggregateQuery aggregate = new TestAggregateQuery(AggregateFunction.COUNT, query); - assertNull(aggregate.getAggregateKey()); - try { - aggregate.setAggregateKey(null); - fail("Expected NPE."); - } catch (NullPointerException e) { - // pass - } - @SuppressWarnings("rawtypes") - Key<?> fooKey = new Key("foo"); - aggregate.setAggregateKey(fooKey); - assertEquals(fooKey, aggregate.getAggregateKey()); - } - - private static class TestAggregateQuery extends AggregateQuery<AggregateCount> { - - public TestAggregateQuery( - AggregateFunction function, - Query<AggregateCount> queryToAggregate) { - super(function, queryToAggregate); - } - - @Override - public Cursor<AggregateCount> execute() { - throw new AssertionError("not implemented"); - } - - @Override - public Statement<AggregateCount> getRawDuplicate() { - throw new AssertionError("not implemented"); - } - - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/HostBoundaryPojoGetterTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.model.TimeStampedPojo; - -public class HostBoundaryPojoGetterTest { - private static final String AGENT_ID = "agentid"; - private static final String HOSTNAME = "host.example.com"; - private static final String CATEGORY_NAME = "host-boundary-category"; - // Make this one static so we don't get IllegalStateException from trying - // to make category of same name while running tests in same classloader. - private static final Category<TestPojo> cat = new Category<>(CATEGORY_NAME, TestPojo.class); - - private static long t1 = 1; - private static long t2 = 5; - - private static long lc1 = 10; - private static long lc2 = 20; - - private HostRef hostRef; - private AgentId agentId; - private TestPojo result1, result2; - - @Before - public void setUp() { - hostRef = new HostRef(AGENT_ID, HOSTNAME); - agentId = new AgentId(AGENT_ID); - result1 = mock(TestPojo.class); - when(result1.getTimeStamp()).thenReturn(t1); - when(result1.getData()).thenReturn(lc1); - result2 = mock(TestPojo.class); - when(result2.getTimeStamp()).thenReturn(t2); - when(result2.getData()).thenReturn(lc2); - } - - @Test - public void verifyLatestQueryDescriptorFormat() { - String newestExpected = "QUERY %s WHERE 'agentId' = ?s SORT 'timeStamp' DSC LIMIT 1"; - assertEquals(newestExpected, HostBoundaryPojoGetter.DESC_NEWEST_HOST_STAT); - } - - @Test - public void verifyOldestQueryDescriptorFormat() { - String oldestExpected = "QUERY %s WHERE 'agentId' = ?s SORT 'timeStamp' ASC LIMIT 1"; - assertEquals(oldestExpected, HostBoundaryPojoGetter.DESC_OLDEST_HOST_STAT); - } - - @Test - public void verifyLatestQueryDescriptorIsSane() { - Storage storage = mock(Storage.class); - HostBoundaryPojoGetter<TestPojo> getter = new HostBoundaryPojoGetter<>(storage, cat); - - String actualLatestDesc = getter.getNewestQueryDesc(); - String latestExpected = "QUERY host-boundary-category WHERE 'agentId' = ?s SORT 'timeStamp' DSC LIMIT 1"; - assertEquals(latestExpected, actualLatestDesc); - } - - @Test - public void verifyOldestQueryDescriptorIsSane() { - Storage storage = mock(Storage.class); - HostBoundaryPojoGetter<TestPojo> getter = new HostBoundaryPojoGetter<>(storage, cat); - - String actualOldestDesc = getter.getOldestQueryDesc(); - String oldestExpected = "QUERY host-boundary-category WHERE 'agentId' = ?s SORT 'timeStamp' ASC LIMIT 1"; - - assertEquals(oldestExpected, actualOldestDesc); - } - - @Test - public void testHostRefGetOldest() throws DescriptorParsingException, StatementExecutionException { - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(null); - - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(query.executeQuery()).thenReturn(cursor); - - Storage storage = mock(Storage.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - - HostBoundaryPojoGetter<TestPojo> getter = new HostBoundaryPojoGetter<>(storage, cat); - - TestPojo oldest = getter.getOldestStat(hostRef); - - assertEquals(t1, oldest.getTimeStamp()); - assertEquals(lc1, oldest.getData()); - } - - @Test - public void testGetOldest() throws DescriptorParsingException, StatementExecutionException { - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(null); - - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(query.executeQuery()).thenReturn(cursor); - - Storage storage = mock(Storage.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - - HostBoundaryPojoGetter<TestPojo> getter = new HostBoundaryPojoGetter<>(storage, cat); - - TestPojo oldest = getter.getOldestStat(agentId); - - assertEquals(t1, oldest.getTimeStamp()); - assertEquals(lc1, oldest.getData()); - } - - @Test - public void testHostRefGetLatest() throws DescriptorParsingException, StatementExecutionException { - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result2).thenReturn(null); - - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(query.executeQuery()).thenReturn(cursor); - - Storage storage = mock(Storage.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - - HostBoundaryPojoGetter<TestPojo> getter = new HostBoundaryPojoGetter<>(storage, cat); - - TestPojo newest = getter.getNewestStat(hostRef); - - assertEquals(t2, newest.getTimeStamp()); - assertEquals(lc2, newest.getData()); - } - - @Test - public void testGetLatest() throws DescriptorParsingException, StatementExecutionException { - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result2).thenReturn(null); - - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(query.executeQuery()).thenReturn(cursor); - - Storage storage = mock(Storage.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - - HostBoundaryPojoGetter<TestPojo> getter = new HostBoundaryPojoGetter<>(storage, cat); - - TestPojo newest = getter.getNewestStat(agentId); - - assertEquals(t2, newest.getTimeStamp()); - assertEquals(lc2, newest.getData()); - } - - @SuppressWarnings("unchecked") - private StatementDescriptor<TestPojo> anyDescriptor() { - return (StatementDescriptor<TestPojo>) any(StatementDescriptor.class); - } - - private static interface TestPojo extends TimeStampedPojo { - long getData(); - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/HostLatestPojoListGetterTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import java.util.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.model.TimeStampedPojo; - -public class HostLatestPojoListGetterTest { - private static final String AGENT_ID = "agentid"; - private static final String HOSTNAME = "host.example.com"; - private static final String CATEGORY_NAME = "hostcategory"; - // Make this one static so we don't get IllegalStateException from trying - // to make category of same name while running tests in same classloader. - private static final Category<TestPojo> cat = new Category<>(CATEGORY_NAME, TestPojo.class); - - private static long t1 = 1; - private static long t2 = 5; - private static long t3 = 10; - - private static Double load5_1 = 2.0; - private static Double load5_2 = 6.0; - private static Double load5_3 = 11.0; - - private static Double load10_1 = 3.0; - private static Double load10_2 = 7.0; - private static Double load10_3 = 12.0; - - private static Double load15_1 = 4.0; - private static Double load15_2 = 8.0; - private static Double load15_3 = 13.0; - - private HostRef ref; - private AgentId agentId; - private TestPojo result1, result2, result3; - - @Before - public void setUp() { - final double[] d1 = new double[]{load5_1, load10_1, load15_1}; - final double[] d2 = new double[]{load5_2, load10_2, load15_2}; - final double[] d3 = new double[]{load5_3, load10_3, load15_3}; - ref = new HostRef(AGENT_ID, HOSTNAME); - agentId = new AgentId(AGENT_ID); - result1 = mock(TestPojo.class); - when(result1.getTimeStamp()).thenReturn(t1); - when(result1.getData()).thenReturn(d1); - result2 = mock(TestPojo.class); - when(result2.getTimeStamp()).thenReturn(t2); - when(result2.getData()).thenReturn(d2); - result3 = mock(TestPojo.class); - when(result3.getTimeStamp()).thenReturn(t3); - when(result3.getData()).thenReturn(d3); - } - - @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); - String actualDesc = getter.getQueryLatestDesc(); - String expected = "QUERY hostcategory WHERE 'agentId' = ?s AND " + - "'timeStamp' > ?l SORT 'timeStamp' DSC"; - assertEquals(expected, actualDesc); - } - - @SuppressWarnings("unchecked") - private StatementDescriptor<TestPojo> anyDescriptor() { - return (StatementDescriptor<TestPojo>) any(StatementDescriptor.class); - } - - @Test - public void testHostRefGetLatest() throws DescriptorParsingException, StatementExecutionException { - @SuppressWarnings("unchecked") - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null); - - Storage storage = mock(Storage.class); - @SuppressWarnings("unchecked") - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - when(query.executeQuery()).thenReturn(cursor); - - HostLatestPojoListGetter<TestPojo> getter = new HostLatestPojoListGetter<>(storage, cat); - - List<TestPojo> stats = getter.getLatest(ref, Long.MIN_VALUE); - - assertNotNull(stats); - assertEquals(2, stats.size()); - TestPojo stat1 = stats.get(0); - assertEquals(t1, stat1.getTimeStamp()); - assertArrayEquals(new double[]{load5_1, load10_1, load15_1}, stat1.getData(), 0.001); - TestPojo stat2 = stats.get(1); - assertEquals(t2, stat2.getTimeStamp()); - assertArrayEquals(new double[]{load5_2, load10_2, load15_2}, stat2.getData(), 0.001); - } - - @Test - public void testGetLatest() throws DescriptorParsingException, StatementExecutionException { - @SuppressWarnings("unchecked") - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null); - - Storage storage = mock(Storage.class); - @SuppressWarnings("unchecked") - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - when(query.executeQuery()).thenReturn(cursor); - - HostLatestPojoListGetter<TestPojo> getter = new HostLatestPojoListGetter<>(storage, cat); - - List<TestPojo> stats = getter.getLatest(agentId, Long.MIN_VALUE); - - assertNotNull(stats); - assertEquals(2, stats.size()); - TestPojo stat1 = stats.get(0); - assertEquals(t1, stat1.getTimeStamp()); - assertArrayEquals(new double[]{load5_1, load10_1, load15_1}, stat1.getData(), 0.001); - TestPojo stat2 = stats.get(1); - assertEquals(t2, stat2.getTimeStamp()); - assertArrayEquals(new double[]{load5_2, load10_2, load15_2}, stat2.getData(), 0.001); - } - - @After - public void tearDown() { - ref = null; - result1 = null; - result2 = null; - result3 = null; - } - - private static interface TestPojo extends TimeStampedPojo { - - double[] getData(); - - } - -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/PreparedParamentersTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import org.junit.Test; - -import com.redhat.thermostat.storage.model.AgentInformation; - -public class PreparedParamentersTest { - - @Test - public void cannotSetNullPojo() { - PreparedParameters params = new PreparedParameters(1); - try { - params.setPojo(0, null); - fail("should not be able to set null Pojo"); - } catch (NullPointerException e) { - // passs - } - } - - @Test - public void cannotSetNullPojoList() { - PreparedParameters params = new PreparedParameters(1); - try { - params.setPojoList(0, null); - fail("should not be able to set null Pojo list"); - } catch (NullPointerException e) { - // passs - } - } - - @Test - public void canSetPojoType() { - PreparedParameters params = new PreparedParameters(1); - AgentInformation info = new AgentInformation(); - params.setPojo(0, info); - assertEquals(AgentInformation.class, params.getParams()[0].getType()); - assertEquals(info, params.getParams()[0].getValue()); - } - - @Test - public void canSetPojoListType() { - PreparedParameters params = new PreparedParameters(1); - AgentInformation info = new AgentInformation(); - params.setPojoList(0, new AgentInformation[] { info }); - PreparedParameter p = params.getParams()[0]; - assertEquals("Type should be component type", AgentInformation.class, p.getType()); - assertEquals(info, ((AgentInformation[])p.getValue())[0]); - } - - @Test - public void testTypeInt() { - PreparedParameters params = new PreparedParameters(1); - params.setInt(0, -1); - assertEquals(int.class, params.getParams()[0].getType()); - } - - @Test - public void testTypeIntList() { - PreparedParameters params = new PreparedParameters(1); - params.setIntList(0, new int[] { -1 }); - assertEquals(int[].class, params.getParams()[0].getType()); - } - - @Test - public void testTypeLong() { - PreparedParameters params = new PreparedParameters(1); - params.setLong(0, -1); - assertEquals(long.class, params.getParams()[0].getType()); - } - - @Test - public void testTypeLongList() { - PreparedParameters params = new PreparedParameters(1); - params.setLongList(0, new long[] { -1 }); - assertEquals(long[].class, params.getParams()[0].getType()); - } - - @Test - public void testTypeBoolList() { - PreparedParameters params = new PreparedParameters(1); - params.setBooleanList(0, new boolean[] { true } ); - assertEquals(boolean[].class, params.getParams()[0].getType()); - } - - @Test - public void testTypeDouble() { - PreparedParameters params = new PreparedParameters(1); - params.setDouble(0, Math.E); - assertEquals(double.class, params.getParams()[0].getType()); - } - - @Test - public void testTypeDoubleList() { - PreparedParameters params = new PreparedParameters(1); - params.setDoubleList(0, new double[] { Math.E }); - assertEquals(double[].class, params.getParams()[0].getType()); - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/QueuedStorageTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,641 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isA; -import static org.mockito.Matchers.same; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -import java.io.InputStream; -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 org.mockito.Mockito; - -import com.redhat.thermostat.common.Constants; -import com.redhat.thermostat.storage.core.QueuedStorage.QueuedParsedStatement; -import com.redhat.thermostat.storage.core.QueuedStorage.QueuedPreparedStatement; -import com.redhat.thermostat.storage.core.QueuedStorage.QueuedWrite; -import com.redhat.thermostat.storage.model.Pojo; - - -public class QueuedStorageTest { - - private static class TestExecutor implements ExecutorService { - - private Runnable task; - private boolean shutdown; - private long awaitTerminationTimeout; - private TimeUnit awaitTerminationTimeUnit; - - @Override - public void execute(Runnable task) { - this.task = task; - } - - Runnable getTask() { - return task; - } - - @Override - public void shutdown() { - shutdown = true; - } - - @Override - public List<Runnable> 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 { - awaitTerminationTimeout = timeout; - awaitTerminationTimeUnit = unit; - return true; - } - - long getAwaitTerminationTimeout() { - return awaitTerminationTimeout; - } - - TimeUnit getAwaitTerminationTimeUnit() { - return awaitTerminationTimeUnit; - } - - @Override - public <T> Future<T> submit(Callable<T> task) { - // Not used. - return null; - } - - @Override - public <T> Future<T> submit(Runnable task, T result) { - // Not used. - return null; - } - - @Override - public Future<?> submit(Runnable task) { - // Not used. - return null; - } - - @Override - public <T> List<Future<T>> invokeAll( - Collection<? extends Callable<T>> tasks) - throws InterruptedException { - // Not used. - return null; - } - - @Override - public <T> List<Future<T>> invokeAll( - Collection<? extends Callable<T>> tasks, long timeout, - TimeUnit unit) throws InterruptedException { - // Not used. - return null; - } - - @Override - public <T> T invokeAny(Collection<? extends Callable<T>> tasks) - throws InterruptedException, ExecutionException { - // Not used. - return null; - } - - @Override - public <T> T invokeAny(Collection<? extends Callable<T>> tasks, - long timeout, TimeUnit unit) throws InterruptedException, - ExecutionException, TimeoutException { - // Not used. - return null; - } - - } - - private static class TestShutdownExecutor extends TestExecutor { - long executorShutDownTime = -1; - - @Override - public void shutdown() { - super.shutdown(); - executorShutDownTime = System.currentTimeMillis(); - // delay shutdown just a little - try { - Thread.sleep(10); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } - - private static final Category<FooPojo> TEST_CATEGORY = new Category<>("foo-table", FooPojo.class); - - private QueuedStorage queuedStorage; - private Storage delegateStorage; - - private TestExecutor executor; - private TestExecutor fileExecutor; - - private InputStream expectedFile; - - @Before - public void setUp() { - executor = new TestExecutor(); - fileExecutor = new TestExecutor(); - delegateStorage = mock(Storage.class); - - expectedFile = mock(InputStream.class); - when(delegateStorage.loadFile(anyString())).thenReturn(expectedFile); - queuedStorage = new QueuedStorage(delegateStorage, executor, fileExecutor, null); - } - - @After - public void tearDown() { - System.clearProperty(Constants.IS_PROXIED_STORAGE); - expectedFile = null; - queuedStorage = null; - delegateStorage = null; - fileExecutor = null; - executor = null; - } - - @Test - public void testPurge() { - - queuedStorage.purge("fluff"); - - Runnable r = executor.getTask(); - assertNotNull(r); - verifyZeroInteractions(delegateStorage); - r.run(); - verify(delegateStorage, times(1)).purge("fluff"); - verifyNoMoreInteractions(delegateStorage); - - assertNull(fileExecutor.getTask()); - } - - @Test - public void testSaveFile() { - InputStream stream = mock(InputStream.class); - SaveFileListener listener = mock(SaveFileListener.class); - - queuedStorage.saveFile("fluff", stream, listener); - - Runnable task = fileExecutor.getTask(); - assertNotNull(task); - verifyZeroInteractions(delegateStorage); - task.run(); - verify(delegateStorage).saveFile(eq("fluff"), same(stream), same(listener)); - - assertNull(executor.getTask()); - } - - @Test - public void testLoadFile() { - - InputStream stream = queuedStorage.loadFile("fluff"); - - assertSame(expectedFile, stream); - - assertNull(executor.getTask()); - assertNull(fileExecutor.getTask()); - } - - /* - * For backing storage (i.e. a mongo delegate) and a proxy in front - * we should decorate PreparedStatement.execute(), - * PreparedStatement.executeQuery() and PreparedStatement.getParsedStatement(). - * However, execute() and executeQuery() must not be called and it is not - * called. In that case the queueing is achieved via the decoration of - * PreparedStatement.getParsedStatement(). - */ - @Test - public void testPrepareStatementBackingNotProxied() throws DescriptorParsingException, StatementExecutionException, IllegalPatchException { - assertFalse("Precondition not secure storage FAILED!", delegateStorage instanceof SecureStorage); - System.setProperty(Constants.IS_PROXIED_STORAGE, Boolean.TRUE.toString()); - queuedStorage = new QueuedStorage(delegateStorage, executor, fileExecutor); - - @SuppressWarnings("unchecked") - PreparedStatement<Pojo> statement = (PreparedStatement<Pojo>)mock(PreparedStatement.class); - when(delegateStorage.prepareStatement(anyStatementDescriptor())).thenReturn(statement); - @SuppressWarnings("unchecked") - ParsedStatement<Pojo> mockParsedStatement = (ParsedStatement<Pojo>)mock(ParsedStatement.class); - when(statement.getParsedStatement()).thenReturn(mockParsedStatement); - @SuppressWarnings("unchecked") - DataModifyingStatement<Pojo> mockDms = (DataModifyingStatement<Pojo>)mock(DataModifyingStatement.class); - @SuppressWarnings("unchecked") - Query<Pojo> mockQuery = (Query<Pojo>)mock(Query.class); - // First return a write then a query - when(mockParsedStatement.patchStatement(any(PreparedParameter[].class))).thenReturn(mockDms).thenReturn(mockQuery); - - - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(TEST_CATEGORY, "QUERY foo-table"); - PreparedStatement<FooPojo> decorated = queuedStorage.prepareStatement(desc); - assertNotNull(decorated); - assertTrue(decorated instanceof QueuedPreparedStatement); - assertNotSame(decorated, statement); - assertNull(executor.getTask()); - QueuedPreparedStatement<FooPojo> stmt = (QueuedPreparedStatement<FooPojo>)decorated; - - // make sure execution of PreparedStatement.execute() and - // PreparedStatement.executeQuery() throws assertionError. - verifyAssertionError(stmt); - - // be sure that getParsedStatement returns a QueuedParsedStatement - ParsedStatement<FooPojo> parsed = stmt.getParsedStatement(); - assertNotNull(parsed); - assertTrue(parsed instanceof QueuedParsedStatement); - QueuedParsedStatement<FooPojo> qParsed = (QueuedParsedStatement<FooPojo>)parsed; - // we should get a write first - Statement<FooPojo> patched = qParsed.patchStatement(new PreparedParameter[]{}); - assertTrue(patched instanceof QueuedWrite); - QueuedWrite<FooPojo> qWrite = (QueuedWrite<FooPojo>)patched; - assertNull(executor.getTask()); - qWrite.apply(); - assertNotNull(executor.getTask()); - // run the task - executor.getTask().run(); - verify(mockDms).apply(); - verifyNoMoreInteractions(mockDms); - // reset - executor.execute(null); - - // now do it again with a query - patched = qParsed.patchStatement(new PreparedParameter[]{}); - assertTrue(patched instanceof Query); - Query<FooPojo> query = (Query<FooPojo>)patched; - assertNull(executor.getTask()); - assertSame("Didn't expect query to get decorated", mockQuery, query); - query.execute(); - assertNull("should not have submited to executor", executor.getTask()); - verify(mockQuery).execute(); - verifyNoMoreInteractions(mockQuery); - } - - private <T extends Pojo> void verifyAssertionError(QueuedPreparedStatement<T> decorated) throws StatementExecutionException { - try { - decorated.execute(); - // throw something not an assertion error - throw new IllegalStateException("test failed"); - } catch (AssertionError e) { - assertTrue(e.getMessage().contains("backing storage")); - } - try { - decorated.executeQuery(); - // throw something not an assertion error - throw new IllegalStateException("test failed"); - } catch (AssertionError e) { - assertTrue(e.getMessage().contains("backing storage")); - } - } - - /* - * For proxied storage (i.e. a web delegate) we should only decorate - * PreparedStatement.execute() and PreparedStatement.executeQuery() rather - * than also decorating PreparedStatement.getParsedStatement(). If we did - * both, we'd queue things twice. - */ - @Test - public void testPrepareStatementProxied() throws DescriptorParsingException, StatementExecutionException, IllegalPatchException { - assertFalse(delegateStorage instanceof SecureStorage); - delegateStorage = mock(SecureStorage.class); - System.setProperty(Constants.IS_PROXIED_STORAGE, Boolean.TRUE.toString()); - assertTrue("Precondition secure storage FAILED!", delegateStorage instanceof SecureStorage); - queuedStorage = new QueuedStorage(delegateStorage, executor, fileExecutor); - - verifyDirectStorage(); - } - - /* - * For backing storage used directly (i.e. a mongo delegate with *no* proxy storage in front) we should only decorate - * PreparedStatement.execute() and PreparedStatement.executeQuery() rather - * than also decorating PreparedStatement.getParsedStatement(). If we did - * both, we'd queue things twice. - */ - @Test - public void testPrepareStatementBackingNoProxy() throws DescriptorParsingException, StatementExecutionException, IllegalPatchException { - assertFalse(delegateStorage instanceof SecureStorage); - System.setProperty(Constants.IS_PROXIED_STORAGE, Boolean.FALSE.toString()); - queuedStorage = new QueuedStorage(delegateStorage, executor, fileExecutor); - - verifyDirectStorage(); - } - - private void verifyDirectStorage() throws DescriptorParsingException, StatementExecutionException, IllegalPatchException { - @SuppressWarnings("unchecked") - PreparedStatement<Pojo> statement = (PreparedStatement<Pojo>)mock(PreparedStatement.class); - when(delegateStorage.prepareStatement(anyStatementDescriptor())).thenReturn(statement); - @SuppressWarnings("unchecked") - ParsedStatement<Pojo> mockParsedStatement = (ParsedStatement<Pojo>)mock(ParsedStatement.class); - when(statement.getParsedStatement()).thenReturn(mockParsedStatement); - @SuppressWarnings("unchecked") - DataModifyingStatement<Pojo> mockDms = (DataModifyingStatement<Pojo>)mock(DataModifyingStatement.class); - @SuppressWarnings("unchecked") - Query<Pojo> mockQuery = (Query<Pojo>)mock(Query.class); - // First return a write then a query - when(mockParsedStatement.patchStatement(any(PreparedParameter[].class))).thenReturn(mockDms).thenReturn(mockQuery); - - - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(TEST_CATEGORY, "QUERY foo-table"); - PreparedStatement<FooPojo> decorated = queuedStorage.prepareStatement(desc); - assertNotNull(decorated); - assertTrue(decorated instanceof QueuedPreparedStatement); - assertNotSame(decorated, statement); - assertNull(executor.getTask()); - - // make sure execution queues a runnable - decorated.execute(); - assertNotNull(executor.getTask()); - // reset - executor.execute(null); - assertNull(executor.getTask()); - decorated.executeQuery(); - assertNull("queries are not queued", executor.getTask()); - - QueuedPreparedStatement<FooPojo> stmt = (QueuedPreparedStatement<FooPojo>)decorated; - ParsedStatement<FooPojo> parsed = stmt.getParsedStatement(); - assertNotNull(parsed); - // Be sure that getParsedStatement returns simple (non-queued version). - // If true, we'd be queueing things twice: via execute() then via - // getParsedStatement(). - assertFalse("Do not want parsed statement decoration for web", parsed instanceof QueuedParsedStatement); - Statement<FooPojo> patched = parsed.patchStatement(new PreparedParameter[]{}); - assertFalse("Do not want parsed statement decoration for web", patched instanceof QueuedWrite); - assertNull(executor.getTask()); - assertTrue(patched instanceof DataModifyingStatement); - DataModifyingStatement<FooPojo> write = (DataModifyingStatement<FooPojo>)patched; - write.apply(); - assertNull(executor.getTask()); - verify(mockDms).apply(); - verifyNoMoreInteractions(mockDms); - // reset - executor.execute(null); - - // now do it again with a query - patched = parsed.patchStatement(new PreparedParameter[]{}); - assertTrue(patched instanceof Query); - Query<FooPojo> query = (Query<FooPojo>)patched; - assertNull(executor.getTask()); - assertSame("Didn't expect query to get decorated", mockQuery, query); - query.execute(); - assertNull("should not have submited to executor", executor.getTask()); - verify(mockQuery).execute(); - verifyNoMoreInteractions(mockQuery); - } - - /* - * QueuedStorage decorates PreparedStatement, which may throw a - * StatementExecution exception on stmt.execute(). All the decorator can do - * is to log the exception and continue. As such, the decorated - * PreparedStatement should never throw that exception. It can't since it - * solely submits a runnable for execution. - */ - @Test - public void testExecutePreparedStatementFails() - throws DescriptorParsingException, StatementExecutionException { - assertFalse(delegateStorage instanceof SecureStorage); - delegateStorage = mock(SecureStorage.class); - queuedStorage = new QueuedStorage(delegateStorage, executor, fileExecutor); - assertFalse(Boolean.getBoolean(Constants.IS_PROXIED_STORAGE)); - - assertTrue("Precondition secure storage FAILED!", delegateStorage instanceof SecureStorage); - @SuppressWarnings("unchecked") - PreparedStatement<Pojo> statement = (PreparedStatement<Pojo>)mock(PreparedStatement.class); - - // make sure the delegate throws a StatementExecutionException - Mockito.doThrow(StatementExecutionException.class).when(statement).execute(); - when(delegateStorage.prepareStatement(anyStatementDescriptor())).thenReturn(statement); - - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(TEST_CATEGORY, "QUERY foo-table"); - PreparedStatement<FooPojo> decorated = queuedStorage.prepareStatement(desc); - assertNotNull(decorated); - assertTrue(decorated instanceof QueuedPreparedStatement); - assertNotSame(decorated, statement); - assertNull(executor.getTask()); - - // this should not throw the exception the decoratee throws. - try { - decorated.execute(); - // pass - } catch (StatementExecutionException e) { - fail("decorator should only submit task and continue"); - } - assertNotNull(executor.getTask()); - try { - executor.getTask().run(); - // pass - } catch (Exception e) { - fail("delegate's StatementExecutionException should have been caught"); - } - } - - @Test - public void testPrepareStatementDescriptorParseFailure() throws DescriptorParsingException, StatementExecutionException { - - Mockito.doThrow(DescriptorParsingException.class).when(delegateStorage).prepareStatement(anyStatementDescriptor()); - - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(TEST_CATEGORY, "QUERY foo-table"); - - try { - queuedStorage.prepareStatement(desc); - fail("should have thrown descptor parsing exception!"); - } catch (DescriptorParsingException e) { - // pass - } - } - - @SuppressWarnings("unchecked") - private <T extends Pojo> StatementDescriptor<T> anyStatementDescriptor() { - return any(StatementDescriptor.class); - } - - @Test - public void testRegisterCategory() { - - Category<?> category = mock(Category.class); - - queuedStorage.registerCategory(category); - - verify(delegateStorage).registerCategory(category); - - assertNull(executor.getTask()); - assertNull(fileExecutor.getTask()); - } - - @Test - public void testGetConnection() { - Connection connection = mock(Connection.class); - when(delegateStorage.getConnection()).thenReturn(connection); - - Connection conn = queuedStorage.getConnection(); - - verify(delegateStorage).getConnection(); - - assertSame(conn, connection); - - assertNull(executor.getTask()); - assertNull(fileExecutor.getTask()); - } - - @Test - public void testShutdown() { - queuedStorage.shutdown(); - verify(delegateStorage).shutdown(); - assertTrue(executor.isShutdown()); - assertEquals(3, executor.getAwaitTerminationTimeout()); - assertEquals(TimeUnit.SECONDS, executor.getAwaitTerminationTimeUnit()); - assertTrue(fileExecutor.isShutdown()); - assertEquals(3, fileExecutor.getAwaitTerminationTimeout()); - assertEquals(TimeUnit.SECONDS, fileExecutor.getAwaitTerminationTimeUnit()); - } - - @Test - public void executorsShutdownBeforeDelegate() { - StubStorage delegate = new StubStorage(); - TestShutdownExecutor executor = new TestShutdownExecutor(); - TestShutdownExecutor fileExecutor = new TestShutdownExecutor(); - queuedStorage = new QueuedStorage(delegate, executor, fileExecutor); - queuedStorage.shutdown(); - - // all shutdown methods should have been called - assertTrue(-1 != delegate.shutDownTime); - assertTrue(-1 != executor.executorShutDownTime); - assertTrue(-1 != fileExecutor.executorShutDownTime); - // delegate should have shut down last - assertTrue(delegate.shutDownTime > executor.executorShutDownTime); - assertTrue(delegate.shutDownTime > fileExecutor.executorShutDownTime); - } - - private static class StubStorage implements Storage { - - long shutDownTime = -1; - - @Override - public void registerCategory(Category<?> category) { - // not implemented - throw new AssertionError(); - } - - @Override - public Connection getConnection() { - // not implemented - throw new AssertionError(); - } - - @Override - public void purge(String agentId) { - // not implemented - throw new AssertionError(); - } - - @Override - public void saveFile(String filename, InputStream data, SaveFileListener listener) { - // not implemented - throw new AssertionError(); - } - - @Override - public InputStream loadFile(String filename) { - // not implemented - throw new AssertionError(); - } - - @Override - public void shutdown() { - shutDownTime = System.currentTimeMillis(); - // delay shutdown just a little - try { - Thread.sleep(10); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - @Override - public <T extends Pojo> PreparedStatement<T> prepareStatement(StatementDescriptor<T> desc) - throws DescriptorParsingException { - // not implemented - return null; - } - - } - - private static class FooPojo implements Pojo { - // Dummy class for testing - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/StatementDescriptorTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; - -import org.junit.Test; - -import com.redhat.thermostat.storage.dao.AgentInfoDAO; -import com.redhat.thermostat.storage.dao.VmInfoDAO; -import com.redhat.thermostat.storage.model.AgentInformation; -import com.redhat.thermostat.storage.model.AggregateCount; -import com.redhat.thermostat.storage.model.VmInfo; - -public class StatementDescriptorTest { - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Test - public void testToString() { - String desc = "QUERY agent-config WHERE 'agentId' = ?s"; - Category cat = mock(Category.class); - StatementDescriptor stmtDesc = new StatementDescriptor(cat, desc); - // toString is used extensively for logging. - assertEquals(desc, stmtDesc.toString()); - } - - @Test - public void testHashCode() { - String strDesc = "QUERY agent-config"; - StatementDescriptor<AgentInformation> desc1 = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - CategoryAdapter<AgentInformation, AggregateCount> adapter = new CategoryAdapter<>(AgentInfoDAO.CATEGORY); - Category<AggregateCount> aggregateCat = adapter.getAdapted(AggregateCount.class); - StatementDescriptor<AggregateCount> desc2 = new StatementDescriptor<>(aggregateCat, strDesc); - assertTrue("regular and aggregate category should have different hashcode", - desc1.hashCode() != desc2.hashCode()); - - System.out.println("desc1 = " + desc1.hashCode()); - assertEquals("same descriptors should have same hash code", desc1.hashCode(), desc1.hashCode()); - assertEquals("same descriptors should have same hash code", desc2.hashCode(), desc2.hashCode()); - StatementDescriptor<AgentInformation> desc1Dupl = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - assertEquals("same descriptors should have same hash code", desc1.hashCode(), desc1Dupl.hashCode()); - - strDesc = "QUERY " + VmInfoDAO.vmInfoCategory.getName(); - StatementDescriptor<VmInfo> desc3 = new StatementDescriptor<>(VmInfoDAO.vmInfoCategory, strDesc); - assertTrue("*very* different descriptors should have different hash code", - desc1.hashCode() != desc3.hashCode()); - - strDesc = "QUERY " + VmInfoDAO.vmInfoCategory.getName() + " WHERE 'a' = ?s"; - StatementDescriptor<VmInfo> desc4 = new StatementDescriptor<>(VmInfoDAO.vmInfoCategory, strDesc); - assertTrue("different descriptors, but same category should have different hash code", - desc3.hashCode() != desc4.hashCode()); - - strDesc = "QUERY agent-config"; - // doesn't really make sense (would not parse), but this is a hash code test - StatementDescriptor<VmInfo> desc5 = new StatementDescriptor<>(VmInfoDAO.vmInfoCategory, strDesc); - assertTrue("same string desc, but different category should be different hash code", - desc5.hashCode() != desc4.hashCode()); - } - - @Test - public void testEquals() { - String strDesc = "QUERY agent-config"; - StatementDescriptor<AgentInformation> desc1 = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - CategoryAdapter<AgentInformation, AggregateCount> adapter = new CategoryAdapter<>(AgentInfoDAO.CATEGORY); - Category<AggregateCount> aggregateCat = adapter.getAdapted(AggregateCount.class); - StatementDescriptor<AggregateCount> desc2 = new StatementDescriptor<>(aggregateCat, strDesc); - assertFalse("regular and aggregate category should not be equal", - desc1.equals(desc2)); - assertFalse("null not equal non-null desc", desc1.equals(null)); - assertTrue("self-equals test", desc1.equals(desc1)); - - assertEquals("same descriptors should be equal", desc1, desc1); - assertEquals("same descriptors should be equal", desc2, desc2); - StatementDescriptor<AgentInformation> desc1Dupl = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - assertEquals("same descriptors should be equal", desc1, desc1Dupl); - - strDesc = "QUERY " + VmInfoDAO.vmInfoCategory.getName(); - StatementDescriptor<VmInfo> desc3 = new StatementDescriptor<>(VmInfoDAO.vmInfoCategory, strDesc); - assertFalse("*very* different descriptors should not be equal", - desc1.equals(desc3)); - - strDesc = "QUERY " + VmInfoDAO.vmInfoCategory.getName() + " WHERE 'a' = ?s"; - StatementDescriptor<VmInfo> desc4 = new StatementDescriptor<>(VmInfoDAO.vmInfoCategory, strDesc); - assertFalse("different descriptors, but same category should not be equal", - desc3.equals(desc4)); - - strDesc = "QUERY agent-config"; - // doesn't really make sense (would not parse), but will do for this test - StatementDescriptor<VmInfo> desc5 = new StatementDescriptor<>(VmInfoDAO.vmInfoCategory, strDesc); - assertFalse("same string desc, but different category should not be equal", - desc5.equals(desc4)); - } - -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/VmBoundaryPojoGetterTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.model.TimeStampedPojo; - -public class VmBoundaryPojoGetterTest { - private static final String AGENT_ID = "agentid"; - private static final String HOSTNAME = "host.example.com"; - private static final String VM_ID = "vmId"; - private static final int VM_PID = 123; - private static final String MAIN_CLASS = "Foo.class"; - private static final String CATEGORY_NAME = "vm-boundary-category"; - // Make this one static so we don't get IllegalStateException from trying - // to make category of same name while running tests in same classloader. - private static final Category<TestPojo> cat = new Category<>(CATEGORY_NAME, TestPojo.class); - - private static long t1 = 1; - private static long t2 = 5; - - private static long lc1 = 10; - private static long lc2 = 20; - - private HostRef hostRef; - private VmRef vmRef; - private AgentId agentId; - private VmId vmId; - private TestPojo result1, result2; - - @Before - public void setUp() { - hostRef = new HostRef(AGENT_ID, HOSTNAME); - vmRef = new VmRef(hostRef, VM_ID, VM_PID, MAIN_CLASS); - agentId = new AgentId(AGENT_ID); - vmId = new VmId(VM_ID); - result1 = mock(TestPojo.class); - when(result1.getTimeStamp()).thenReturn(t1); - when(result1.getData()).thenReturn(lc1); - result2 = mock(TestPojo.class); - when(result2.getTimeStamp()).thenReturn(t2); - when(result2.getData()).thenReturn(lc2); - } - - @Test - public void verifyLatestQueryDescriptorFormat() { - String newestExpected = "QUERY %s WHERE 'agentId' = ?s AND " + - "'vmId' = ?s SORT 'timeStamp' DSC LIMIT 1"; - assertEquals(newestExpected, VmBoundaryPojoGetter.DESC_NEWEST_VM_STAT); - } - - @Test - public void verifyOldestQueryDescriptorFormat() { - String oldestExpected = "QUERY %s WHERE 'agentId' = ?s AND " + - "'vmId' = ?s SORT 'timeStamp' ASC LIMIT 1"; - assertEquals(oldestExpected, VmBoundaryPojoGetter.DESC_OLDEST_VM_STAT); - } - - @Test - public void verifyLatestQueryDescriptorIsSane() { - Storage storage = mock(Storage.class); - VmBoundaryPojoGetter<TestPojo> getter = new VmBoundaryPojoGetter<>(storage, cat); - - String actualLatestDesc = getter.getNewestQueryDesc(); - String newestExpected = "QUERY vm-boundary-category WHERE 'agentId' = ?s AND " + - "'vmId' = ?s SORT 'timeStamp' DSC LIMIT 1"; - assertEquals(newestExpected, actualLatestDesc); - } - - @Test - public void verifyOldestQueryDescriptorIsSane() { - Storage storage = mock(Storage.class); - VmBoundaryPojoGetter<TestPojo> getter = new VmBoundaryPojoGetter<>(storage, cat); - - String actualOldestDesc = getter.getOldestQueryDesc(); - String oldestExpected = "QUERY vm-boundary-category WHERE 'agentId' = ?s AND " + - "'vmId' = ?s SORT 'timeStamp' ASC LIMIT 1"; - - assertEquals(oldestExpected, actualOldestDesc); - } - - @Test - public void testVmRefGetOldest() throws DescriptorParsingException, StatementExecutionException { - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(null); - - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(query.executeQuery()).thenReturn(cursor); - - Storage storage = mock(Storage.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - - VmBoundaryPojoGetter<TestPojo> getter = new VmBoundaryPojoGetter<>(storage, cat); - - TestPojo oldest = getter.getOldestStat(vmRef); - - assertEquals(t1, oldest.getTimeStamp()); - assertEquals(lc1, oldest.getData()); - } - - @Test - public void testGetOldest() throws DescriptorParsingException, StatementExecutionException { - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(null); - - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(query.executeQuery()).thenReturn(cursor); - - Storage storage = mock(Storage.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - - VmBoundaryPojoGetter<TestPojo> getter = new VmBoundaryPojoGetter<>(storage, cat); - - TestPojo oldest = getter.getOldestStat(vmId, agentId); - - assertEquals(t1, oldest.getTimeStamp()); - assertEquals(lc1, oldest.getData()); - } - - @Test - public void testVmRefGetLatest() throws DescriptorParsingException, StatementExecutionException { - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result2).thenReturn(null); - - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(query.executeQuery()).thenReturn(cursor); - - Storage storage = mock(Storage.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - - VmBoundaryPojoGetter<TestPojo> getter = new VmBoundaryPojoGetter<>(storage, cat); - - TestPojo newest = getter.getNewestStat(vmRef); - - assertEquals(t2, newest.getTimeStamp()); - assertEquals(lc2, newest.getData()); - } - - @Test - public void testGetLatest() throws DescriptorParsingException, StatementExecutionException { - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result2).thenReturn(null); - - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(query.executeQuery()).thenReturn(cursor); - - Storage storage = mock(Storage.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - - VmBoundaryPojoGetter<TestPojo> getter = new VmBoundaryPojoGetter<>(storage, cat); - - TestPojo newest = getter.getNewestStat(vmId, agentId); - - assertEquals(t2, newest.getTimeStamp()); - assertEquals(lc2, newest.getData()); - } - - @SuppressWarnings("unchecked") - private StatementDescriptor<TestPojo> anyDescriptor() { - return (StatementDescriptor<TestPojo>) any(StatementDescriptor.class); - } - - private static interface TestPojo extends TimeStampedPojo { - long getData(); - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/VmLatestPojoListGetterTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,196 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.common.Pair; -import com.redhat.thermostat.storage.model.TimeStampedPojo; - -public class VmLatestPojoListGetterTest { - private static final String AGENT_ID = "agentid"; - private static final String HOSTNAME = "host.example.com"; - private static final String VM_ID = "vmId"; - private static final int VM_PID = 123; - private static final String MAIN_CLASS = "Foo.class"; - private static final String CATEGORY_NAME = "vmcategory"; - // Make this one static so we don't get IllegalStateException from trying - // to make category of same name while running tests in same classloader. - private static final Category<TestPojo> cat = new Category<>(CATEGORY_NAME, TestPojo.class); - - private static long t1 = 1; - private static long t2 = 5; - private static long t3 = 10; - - private static long lc1 = 10; - private static long lc2 = 20; - private static long lc3 = 30; - - private HostRef hostRef; - private VmRef vmRef; - private AgentId agentId; - private VmId vmId; - private TestPojo result1, result2, result3; - - @Before - public void setUp() { - hostRef = new HostRef(AGENT_ID, HOSTNAME); - vmRef = new VmRef(hostRef, VM_ID, VM_PID, MAIN_CLASS); - agentId = new AgentId(AGENT_ID); - vmId = new VmId(VM_ID); - result1 = mock(TestPojo.class); - when(result1.getTimeStamp()).thenReturn(t1); - when(result1.getData()).thenReturn(lc1); - result2 = mock(TestPojo.class); - when(result2.getTimeStamp()).thenReturn(t2); - when(result2.getData()).thenReturn(lc2); - result3 = mock(TestPojo.class); - when(result3.getTimeStamp()).thenReturn(t3); - when(result3.getData()).thenReturn(lc3); - } - - @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); - String actualDesc = getter.getQueryLatestDesc(); - String expected = "QUERY vmcategory WHERE 'agentId' = ?s AND " + - "'vmId' = ?s AND 'timeStamp' > ?l SORT 'timeStamp' DSC"; - assertEquals(expected, actualDesc); - } - - @SuppressWarnings("unchecked") - private StatementDescriptor<TestPojo> anyDescriptor() { - return (StatementDescriptor<TestPojo>) any(StatementDescriptor.class); - } - - @Test - public void testVmRefGetLatest() throws DescriptorParsingException, StatementExecutionException { - Pair<Storage, PreparedStatement<TestPojo>> setup = setupGetLatest(); - Storage storage = setup.getFirst(); - PreparedStatement<TestPojo> query = setup.getSecond(); - - VmLatestPojoListGetter<TestPojo> getter = new VmLatestPojoListGetter<>(storage, cat); - List<TestPojo> stats = getter.getLatest(vmRef, t2); - - verify(storage).prepareStatement(anyDescriptor()); - verify(query).setString(0, AGENT_ID); - verify(query).setString(1, VM_ID); - verify(query).setLong(2, t2); - verify(query).executeQuery(); - verifyNoMoreInteractions(query); - - assertNotNull(stats); - assertEquals(2, stats.size()); - TestPojo stat1 = stats.get(0); - assertEquals(t1, stat1.getTimeStamp()); - assertEquals(lc1, stat1.getData()); - TestPojo stat2 = stats.get(1); - assertEquals(t2, stat2.getTimeStamp()); - assertEquals(lc2, stat2.getData()); - } - - @Test - public void testGetLatest() throws DescriptorParsingException, StatementExecutionException { - Pair<Storage, PreparedStatement<TestPojo>> setup = setupGetLatest(); - Storage storage = setup.getFirst(); - PreparedStatement<TestPojo> query = setup.getSecond(); - - VmLatestPojoListGetter<TestPojo> getter = new VmLatestPojoListGetter<>(storage, cat); - List<TestPojo> stats = getter.getLatest(agentId, vmId, t2); - - verify(storage).prepareStatement(anyDescriptor()); - verify(query).setString(0, AGENT_ID); - verify(query).setString(1, VM_ID); - verify(query).setLong(2, t2); - verify(query).executeQuery(); - verifyNoMoreInteractions(query); - - assertNotNull(stats); - assertEquals(2, stats.size()); - TestPojo stat1 = stats.get(0); - assertEquals(t1, stat1.getTimeStamp()); - assertEquals(lc1, stat1.getData()); - TestPojo stat2 = stats.get(1); - assertEquals(t2, stat2.getTimeStamp()); - assertEquals(lc2, stat2.getData()); - } - - private Pair<Storage, PreparedStatement<TestPojo>> setupGetLatest() throws - DescriptorParsingException, StatementExecutionException { - - @SuppressWarnings("unchecked") - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null); - - Storage storage = mock(Storage.class); - @SuppressWarnings("unchecked") - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - when(query.executeQuery()).thenReturn(cursor); - - return new Pair<>(storage, query); - } - - private static interface TestPojo extends TimeStampedPojo { - - long getData(); - - } - -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/core/VmTimeIntervalPojoListGetterTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,192 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.model.TimeStampedPojo; - -public class VmTimeIntervalPojoListGetterTest { - private static final String AGENT_ID = "agentid"; - private static final String HOSTNAME = "host.example.com"; - private static final String VM_ID = "vmId"; - private static final int VM_PID = 123; - private static final String MAIN_CLASS = "Foo.class"; - private static final String CATEGORY_NAME = "vm-timeinterval-category"; - // Make this one static so we don't get IllegalStateException from trying - // to make category of same name while running tests in same classloader. - private static final Category<TestPojo> cat = new Category<>(CATEGORY_NAME, TestPojo.class); - - private static long t1 = 1; - private static long t2 = 5; - private static long t3 = 10; - - private static long lc1 = 10; - private static long lc2 = 20; - private static long lc3 = 30; - - private HostRef hostRef; - private VmRef vmRef; - private AgentId agentId; - private VmId vmId; - private TestPojo result1, result2, result3; - - @Before - public void setUp() { - hostRef = new HostRef(AGENT_ID, HOSTNAME); - vmRef = new VmRef(hostRef, VM_ID, VM_PID, MAIN_CLASS); - agentId = new AgentId(AGENT_ID); - vmId = new VmId(VM_ID); - result1 = mock(TestPojo.class); - when(result1.getTimeStamp()).thenReturn(t1); - when(result1.getData()).thenReturn(lc1); - result2 = mock(TestPojo.class); - when(result2.getTimeStamp()).thenReturn(t2); - when(result2.getData()).thenReturn(lc2); - result3 = mock(TestPojo.class); - when(result3.getTimeStamp()).thenReturn(t3); - when(result3.getData()).thenReturn(lc3); - } - - @Test - public void verifyQueryDescriptorFormat() { - String expected = "QUERY %s WHERE 'agentId' = ?s AND " + - "'vmId' = ?s AND 'timeStamp' >= ?l AND 'timeStamp' < ?l SORT 'timeStamp' DSC"; - assertEquals(expected, VmTimeIntervalPojoListGetter.VM_INTERVAL_QUERY_FORMAT); - } - - @Test - public void verifyQueryDescriptorIsSane() { - Storage storage = mock(Storage.class); - VmTimeIntervalPojoListGetter<TestPojo> getter = new VmTimeIntervalPojoListGetter<>(storage, cat); - String actualDesc = getter.getQueryLatestDesc(); - String expected = "QUERY " + CATEGORY_NAME + " WHERE 'agentId' = ?s AND " + - "'vmId' = ?s AND 'timeStamp' >= ?l AND 'timeStamp' < ?l SORT 'timeStamp' DSC"; - assertEquals(expected, actualDesc); - } - - @SuppressWarnings("unchecked") - private StatementDescriptor<TestPojo> anyDescriptor() { - return (StatementDescriptor<TestPojo>) any(StatementDescriptor.class); - } - - @Test - public void testVmRefGetInterval() throws DescriptorParsingException, StatementExecutionException { - @SuppressWarnings("unchecked") - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null); - - Storage storage = mock(Storage.class); - @SuppressWarnings("unchecked") - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - when(query.executeQuery()).thenReturn(cursor); - - VmTimeIntervalPojoListGetter<TestPojo> getter = new VmTimeIntervalPojoListGetter<>(storage, cat); - - List<TestPojo> stats = getter.getLatest(vmRef, t1, t2); - - verify(storage).prepareStatement(anyDescriptor()); - verify(query).setString(0, AGENT_ID); - verify(query).setString(1, VM_ID); - verify(query).setLong(2, t1); - verify(query).setLong(3, t2); - verify(query).executeQuery(); - verifyNoMoreInteractions(query); - - assertNotNull(stats); - assertEquals(2, stats.size()); - TestPojo stat1 = stats.get(0); - assertEquals(t1, stat1.getTimeStamp()); - assertEquals(lc1, stat1.getData()); - TestPojo stat2 = stats.get(1); - assertEquals(t2, stat2.getTimeStamp()); - assertEquals(lc2, stat2.getData()); - } - - @Test - public void testGetInterval() throws DescriptorParsingException, StatementExecutionException { - @SuppressWarnings("unchecked") - Cursor<TestPojo> cursor = mock(Cursor.class); - when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); - when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null); - - Storage storage = mock(Storage.class); - @SuppressWarnings("unchecked") - PreparedStatement<TestPojo> query = (PreparedStatement<TestPojo>) mock(PreparedStatement.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(query); - when(query.executeQuery()).thenReturn(cursor); - - VmTimeIntervalPojoListGetter<TestPojo> getter = new VmTimeIntervalPojoListGetter<>(storage, cat); - - List<TestPojo> stats = getter.getLatest(agentId, vmId, t1, t2); - - verify(storage).prepareStatement(anyDescriptor()); - verify(query).setString(0, AGENT_ID); - verify(query).setString(1, VM_ID); - verify(query).setLong(2, t1); - verify(query).setLong(3, t2); - verify(query).executeQuery(); - verifyNoMoreInteractions(query); - - assertNotNull(stats); - assertEquals(2, stats.size()); - TestPojo stat1 = stats.get(0); - assertEquals(t1, stat1.getTimeStamp()); - assertEquals(lc1, stat1.getData()); - TestPojo stat2 = stats.get(1); - assertEquals(t2, stat2.getTimeStamp()); - assertEquals(lc2, stat2.getData()); - } - - private static interface TestPojo extends TimeStampedPojo { - long getData(); - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoOperationResultTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; - -public class AbstractDaoOperationResultTest { - - @Test - public void testHasExceptions() { - AbstractDaoOperationResult<VmInfo> abstractDaoOperationResult = getAbstractDaoOperationResult(); - assertFalse(abstractDaoOperationResult.hasExceptions()); - Exception e = new Exception(); - abstractDaoOperationResult.addException(e); - assertTrue(abstractDaoOperationResult.hasExceptions()); - } - - @Test - public void testAddException() { - AbstractDaoOperationResult<VmInfo> abstractDaoOperationResult = getAbstractDaoOperationResult(); - Exception e1 = new Exception(); - abstractDaoOperationResult.addException(e1); - assertFalse(abstractDaoOperationResult.getExceptions().isEmpty()); - assertThat(abstractDaoOperationResult.getExceptions(), is(equalTo(Collections.singletonList(e1)))); - } - - @Test - public void testAddExceptions() { - AbstractDaoOperationResult<VmInfo> abstractDaoOperationResult = getAbstractDaoOperationResult(); - Exception e1 = new Exception("foo"); - Exception e2 = new Exception("bar"); - List<Exception> exceptions = new ArrayList<>(); - exceptions.add(e1); - exceptions.add(e2); - abstractDaoOperationResult.addExceptions(exceptions); - assertFalse(abstractDaoOperationResult.getExceptions().isEmpty()); - assertThat(abstractDaoOperationResult.getExceptions(), is(equalTo(exceptions))); - } - - @Test - public void testAddExceptionsIsDefensive() { - // test that addExceptions makes a defensive copy, so that client code which bulk adds exceptions - // is not able to add further exceptions to the AbstractDaoOperationResult by simply adding exceptions - // to its own reference to the exceptions collection, rather than having to call through addException - // or addExceptions again - AbstractDaoOperationResult<VmInfo> abstractDaoOperationResult = getAbstractDaoOperationResult(); - Exception e1 = new Exception("foo"); - Exception e2 = new Exception("bar"); - List<Exception> exceptions = new ArrayList<>(); - exceptions.add(e1); - exceptions.add(e2); - abstractDaoOperationResult.addExceptions(exceptions); - assertFalse(abstractDaoOperationResult.getExceptions().isEmpty()); - assertThat(abstractDaoOperationResult.getExceptions(), is(equalTo(exceptions))); - Exception e3 = new Exception("baz"); - exceptions.add(e3); - assertFalse(abstractDaoOperationResult.getExceptions().contains(e3)); - } - - @Test - public void testGetExceptions() { - AbstractDaoOperationResult<VmInfo> abstractDaoOperationResult = getAbstractDaoOperationResult(); - Exception e1 = new Exception("foo"); - Exception e2 = new Exception("bar"); - Collection<Exception> exceptions = new HashSet<>(); - exceptions.add(e1); - exceptions.add(e2); - abstractDaoOperationResult.addExceptions(exceptions); - assertFalse(abstractDaoOperationResult.getExceptions().isEmpty()); - assertEquals(exceptions.size(), abstractDaoOperationResult.getExceptions().size()); - for (Exception e : exceptions) { - assertTrue(abstractDaoOperationResult.getExceptions().contains(e)); - } - } - - @Test(expected = UnsupportedOperationException.class) - public void testGetExceptionsImmutable() { - getAbstractDaoOperationResult().getExceptions().add(new Exception()); - } - - private AbstractDaoOperationResult<VmInfo> getAbstractDaoOperationResult() { - return new AbstractDaoOperationResult<VmInfo>() { - @Override - public Iterator<VmInfo> iterator() { - VmInfo vmInfo1 = mock(VmInfo.class); - VmInfo vmInfo2 = mock(VmInfo.class); - return Arrays.asList(vmInfo1, vmInfo2).iterator(); - } - }; - } - -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoOperationTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.dao.AbstractDaoOperation; -import com.redhat.thermostat.storage.dao.VmInfoDAO; -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; - -public class AbstractDaoOperationTest { - - private Storage storage; - private Category<VmInfo> category = VmInfoDAO.vmInfoCategory; - private String descriptor = "descriptor"; - - @Before - public void setup() { - storage = mock(Storage.class); - } - - @Test - public void testGetStorage() { - AbstractDaoOperation<VmInfo> abstractDaoOperation = getAbstractDaoOperation(); - Storage s = abstractDaoOperation.getStorage(); - assertThat(s, is(storage)); - } - - @Test - public void testGetStatementDescriptor() { - AbstractDaoOperation<VmInfo> abstractDaoOperation = getAbstractDaoOperation(); - StatementDescriptor<VmInfo> statementDescriptor = abstractDaoOperation.getStatementDescriptor(); - StatementDescriptor<VmInfo> expected = new StatementDescriptor<>(category, descriptor); - assertThat(statementDescriptor, is(equalTo(expected))); - } - - private AbstractDaoOperation<VmInfo> getAbstractDaoOperation() { - return new AbstractDaoOperation<VmInfo>(storage, category, descriptor) { - @Override - public PreparedStatement<VmInfo> customize(PreparedStatement<VmInfo> preparedStatement) { - return preparedStatement; - } - }; - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoQueryTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class AbstractDaoQueryTest { - - @Test @SuppressWarnings("unchecked") - public void testExecute() throws StatementExecutionException, DescriptorParsingException { - PreparedStatement<VmInfo> preparedStatement = (PreparedStatement<VmInfo>) mock(PreparedStatement.class); - Storage storage = mock(Storage.class); - Category<VmInfo> category = VmInfoDAO.vmInfoCategory; - String descriptor = "descriptor"; - Cursor<VmInfo> cursor = (Cursor<VmInfo>) mock(Cursor.class); - when(preparedStatement.executeQuery()).thenReturn(cursor); - AbstractDaoQuery<VmInfo> abstractDaoQuery = new AbstractDaoQuery<VmInfo>(storage, category, descriptor) { - @Override - public PreparedStatement<VmInfo> customize(PreparedStatement<VmInfo> preparedStatement) { - return preparedStatement; - } - }; - Cursor<VmInfo> c = abstractDaoQuery.execute(preparedStatement); - assertThat(c, is(cursor)); - verify(preparedStatement).executeQuery(); - verify(preparedStatement, never()).execute(); - } -} \ No newline at end of file
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoStatementTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class AbstractDaoStatementTest { - - @Test - @SuppressWarnings("unchecked") - public void testExecute() throws StatementExecutionException, DescriptorParsingException { - PreparedStatement<VmInfo> preparedStatement = (PreparedStatement<VmInfo>) mock(PreparedStatement.class); - Storage storage = mock(Storage.class); - Category<VmInfo> category = VmInfoDAO.vmInfoCategory; - String descriptor = "descriptor"; - Cursor<VmInfo> cursor = (Cursor<VmInfo>) mock(Cursor.class); - when(preparedStatement.executeQuery()).thenReturn(cursor); - DaoStatement<VmInfo> abstractDaoQuery = new SimpleDaoStatement<>(storage, category, descriptor); - abstractDaoQuery.execute(preparedStatement); - verify(preparedStatement).execute(); - verify(preparedStatement, never()).executeQuery(); - } - -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/AbstractDaoTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.logging.Logger; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class AbstractDaoTest { - - private static final List<VmInfo> MOCK_RESULTS = Arrays.asList(mock(VmInfo.class), mock(VmInfo.class)); - - @Test - public void testGetEmptyResultCursor() { - Cursor<VmInfo> cursor = AbstractDao.getEmptyResultCursor(); - assertThat(cursor.hasNext(), is(false)); - assertThat(cursor.next(), is(equalTo(null))); - assertThat(cursor.getBatchSize(), is(0)); - } - - @Test - public void testGetCustomizedPreparedStatement() throws DescriptorParsingException { - Storage storage = mock(Storage.class); - Category<VmInfo> category = VmInfoDAO.vmInfoCategory; - String descriptor = "descriptor"; - @SuppressWarnings("unchecked") - final PreparedStatement<VmInfo> DUMMY_STATEMENT = (PreparedStatement<VmInfo>) mock(PreparedStatement.class); - DaoOperation<VmInfo> daoOperation = new AbstractDaoStatement<VmInfo>(storage, category, descriptor) { - @Override - public PreparedStatement<VmInfo> customize(PreparedStatement<VmInfo> preparedStatement) { - return DUMMY_STATEMENT; - } - }; - AbstractDao abstractDao = getAbstractDao(); - - assertThat(abstractDao.getCustomizedPreparedStatement(daoOperation), is(equalTo(DUMMY_STATEMENT))); - } - - @Test @SuppressWarnings("unchecked") - public void testExecuteStatement() throws DescriptorParsingException, StatementExecutionException { - Storage storage = mock(Storage.class); - PreparedStatement<VmInfo> statement = (PreparedStatement<VmInfo>) mock(PreparedStatement.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(statement); - Cursor<VmInfo> sentinelCursor = getSentinelCursor(); - when(statement.executeQuery()).thenReturn(sentinelCursor); - - Category<VmInfo> category = VmInfoDAO.vmInfoCategory; - String descriptor = "descriptor"; - DaoStatement<VmInfo> daoOperation = new SimpleDaoStatement<>(storage, category, descriptor); - AbstractDao abstractDao = getAbstractDao(); - StatementResult<VmInfo> statementResult = abstractDao.executeStatement(daoOperation); - assertThat(statementResult.hasExceptions(), is(false)); - } - - @Test @SuppressWarnings("unchecked") - public void testExecuteQuery() throws DescriptorParsingException, StatementExecutionException { - Storage storage = mock(Storage.class); - PreparedStatement<VmInfo> statement = (PreparedStatement<VmInfo>) mock(PreparedStatement.class); - when(storage.prepareStatement(anyDescriptor())).thenReturn(statement); - Cursor<VmInfo> sentinelCursor = getSentinelCursor(); - when(statement.executeQuery()).thenReturn(sentinelCursor); - - Category<VmInfo> category = VmInfoDAO.vmInfoCategory; - String descriptor = "descriptor"; - DaoQuery<VmInfo> daoOperation = new SimpleDaoQuery<>(storage, category, descriptor); - AbstractDao abstractDao = getAbstractDao(); - QueryResult<VmInfo> queryResult = abstractDao.executeQuery(daoOperation); - assertThat(queryResult.hasExceptions(), is(false)); - assertEquals(MOCK_RESULTS, queryResult.asList()); - } - - private Cursor<VmInfo> getSentinelCursor() { - return new Cursor<VmInfo>() { - - private final Iterator<VmInfo> iterator = MOCK_RESULTS.iterator(); - - @Override - public void setBatchSize(int n) throws IllegalArgumentException { - } - - @Override - public int getBatchSize() { - return 0; - } - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public VmInfo next() { - return iterator.next(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - private AbstractDao getAbstractDao() { - return new AbstractDao() { - @Override - protected Logger getLogger() { - return LoggingUtils.getLogger(AbstractDaoTest.this.getClass()); - } - }; - } - - @SuppressWarnings("unchecked") - private StatementDescriptor<VmInfo> anyDescriptor() { - return (StatementDescriptor<VmInfo>) any(StatementDescriptor.class); - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/BaseCountableTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.Test; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.model.AggregateCount; - -public class BaseCountableTest { - - @Test - public void testGetCountSuccessful() throws DescriptorParsingException, StatementExecutionException { - Storage storage = mock(Storage.class); - @SuppressWarnings("unchecked") - Category<AggregateCount> mockCategory = (Category<AggregateCount>)mock(Category.class); - BaseCountable countable = new BaseCountable(); - String strDesc = "QUERY-COUNT vm-info"; - StatementDescriptor<AggregateCount> desc = new StatementDescriptor<>(mockCategory, strDesc); - @SuppressWarnings("unchecked") - PreparedStatement<AggregateCount> prepared = (PreparedStatement<AggregateCount>)mock(PreparedStatement.class); - when(storage.prepareStatement(eq(desc))).thenReturn(prepared); - AggregateCount c = new AggregateCount(); - c.setCount(3); - Cursor<AggregateCount> cursor = c.getCursor(); - when(prepared.executeQuery()).thenReturn(cursor); - long count = countable.getCount(storage, mockCategory, strDesc); - assertEquals(3, count); - } - - @Test - public void testGetCountError() throws DescriptorParsingException, StatementExecutionException { - Storage storage = mock(Storage.class); - @SuppressWarnings("unchecked") - Category<AggregateCount> mockCategory = (Category<AggregateCount>)mock(Category.class); - BaseCountable countable = new BaseCountable(); - String strDesc = "QUERY-COUNT vm-info"; - StatementDescriptor<AggregateCount> desc = new StatementDescriptor<>(mockCategory, strDesc); - doThrow(DescriptorParsingException.class).when(storage).prepareStatement(eq(desc)); - long count = countable.getCount(storage, mockCategory, strDesc); - assertEquals(-1, count); - } - - @Test - public void testGetCountError2() throws DescriptorParsingException, StatementExecutionException { - Storage storage = mock(Storage.class); - @SuppressWarnings("unchecked") - Category<AggregateCount> mockCategory = (Category<AggregateCount>)mock(Category.class); - BaseCountable countable = new BaseCountable(); - String strDesc = "QUERY-COUNT vm-info"; - StatementDescriptor<AggregateCount> desc = new StatementDescriptor<>(mockCategory, strDesc); - @SuppressWarnings("unchecked") - PreparedStatement<AggregateCount> prepared = (PreparedStatement<AggregateCount>)mock(PreparedStatement.class); - when(storage.prepareStatement(eq(desc))).thenReturn(prepared); - doThrow(StatementExecutionException.class).when(prepared).executeQuery(); - long count = countable.getCount(storage, mockCategory, strDesc); - assertEquals(-1, count); - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/QueryResultTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; - -public class QueryResultTest { - - private static final List<VmInfo> MOCK_RESULTS = Collections.unmodifiableList(Arrays.asList(mock(VmInfo.class), mock(VmInfo.class))); - - @Test - public void testAsListContents() { - QueryResult<VmInfo> queryResult = getQueryResult(MOCK_RESULTS); - List<VmInfo> list = queryResult.asList(); - assertThat(list, is(equalTo(MOCK_RESULTS))); - } - - @Test - public void testAsListAllowsInPlaceModification() { - QueryResult<VmInfo> queryResult = getQueryResult(MOCK_RESULTS); - List<VmInfo> list = queryResult.asList(); - VmInfo foo = mock(VmInfo.class); - list.add(foo); - assertThat(queryResult.asList().contains(foo), is(true)); - list.clear(); - assertThat(queryResult.asList().isEmpty(), is(true)); - } - - @Test - public void testHeadEmpty() { - QueryResult<VmInfo> queryResult = getQueryResult(Collections.<VmInfo>emptyList()); - VmInfo head = queryResult.head(); - assertThat(head, is(equalTo(null))); - } - - @Test - public void testHeadNonEmpty() { - QueryResult<VmInfo> queryResult = getQueryResult(MOCK_RESULTS); - VmInfo head = queryResult.head(); - assertThat(head, is(MOCK_RESULTS.get(0))); - } - - @Test - public void testIterator() { - QueryResult<VmInfo> queryResult = getQueryResult(MOCK_RESULTS); - Iterator<VmInfo> iterator = queryResult.iterator(); - List<VmInfo> list = new ArrayList<>(); - while (iterator.hasNext()) { - list.add(iterator.next()); - } - assertThat(list, is(equalTo(MOCK_RESULTS))); - } - - @Test - public void testIteratorCanRemove() { - List<VmInfo> list = new ArrayList<>(); - list.addAll(MOCK_RESULTS); - VmInfo foo = MOCK_RESULTS.get(0); - QueryResult<VmInfo> queryResult = getQueryResult(list); - assertThat(queryResult.asList().size(), is(equalTo(2))); - assertThat(queryResult.asList().contains(foo), is(true)); - Iterator<VmInfo> iterator = queryResult.iterator(); - iterator.next(); - iterator.remove(); - assertThat(queryResult.asList().size(), is(equalTo(1))); - assertThat(queryResult.asList().contains(foo), is(false)); - } - - private QueryResult<VmInfo> getQueryResult(final List<VmInfo> list) { - Cursor<VmInfo> cursor = new Cursor<VmInfo>() { - - private final Iterator<VmInfo> it = list.iterator(); - - @Override - public void setBatchSize(int n) throws IllegalArgumentException { - } - - @Override - public int getBatchSize() { - return 0; - } - - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public VmInfo next() { - return it.next(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - return new QueryResult<>(cursor); - } - -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/SimpleDaoQueryTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.dao.SimpleDaoQuery; -import com.redhat.thermostat.storage.dao.VmInfoDAO; -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyZeroInteractions; - -public class SimpleDaoQueryTest { - - @Test - public void testNoCustomizationDone() { - Storage storage = mock(Storage.class); - Category<VmInfo> category = VmInfoDAO.vmInfoCategory; - String descriptor = "descriptor"; - SimpleDaoQuery<VmInfo> simpleDaoQuery = new SimpleDaoQuery<>(storage, category, descriptor); - @SuppressWarnings("unchecked") - PreparedStatement<VmInfo> preparedStatement = (PreparedStatement<VmInfo>) mock(PreparedStatement.class); - PreparedStatement<VmInfo> customized = simpleDaoQuery.customize(preparedStatement); - assertThat(customized, is(equalTo(preparedStatement))); - verifyZeroInteractions(preparedStatement); - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/SimpleDaoStatementTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.dao.SimpleDaoStatement; -import com.redhat.thermostat.storage.dao.VmInfoDAO; -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyZeroInteractions; - -public class SimpleDaoStatementTest { - - @Test - public void testNoCustomizationDone() { - Storage storage = mock(Storage.class); - Category<VmInfo> category = VmInfoDAO.vmInfoCategory; - String descriptor = "descriptor"; - SimpleDaoStatement<VmInfo> simpleDaoStatement = new SimpleDaoStatement<>(storage, category, descriptor); - @SuppressWarnings("unchecked") - PreparedStatement<VmInfo> preparedStatement = (PreparedStatement<VmInfo>) mock(PreparedStatement.class); - PreparedStatement<VmInfo> customized = simpleDaoStatement.customize(preparedStatement); - assertThat(customized, is(equalTo(preparedStatement))); - verifyZeroInteractions(preparedStatement); - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/dao/StatementResultTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.dao; - -import com.redhat.thermostat.storage.model.VmInfo; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -public class StatementResultTest { - - @Test - public void testIteratorIsEmpty() { - StatementResult<VmInfo> statementResult = new StatementResult<>(); - assertThat(statementResult.iterator().hasNext(), is(false)); - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/ActivatorTest.java Fri May 19 11:37:45 2017 +0200 +++ b/storage/core/src/test/java/com/redhat/thermostat/storage/internal/ActivatorTest.java Fri May 19 11:58:05 2017 +0200 @@ -47,7 +47,6 @@ import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.Timer; import com.redhat.thermostat.common.TimerFactory; -import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.storage.dao.AgentInfoDAO; import com.redhat.thermostat.storage.dao.BackendInfoDAO; @@ -103,15 +102,11 @@ @Test public void verifyActivatorRegistersServicesMultipleTimes() throws Exception { StubBundleContext context = new StubBundleContext(); - Storage storage = mock(Storage.class); - ApplicationService appService = mock(ApplicationService.class); TimerFactory timerFactory = mock(TimerFactory.class); when(appService.getTimerFactory()).thenReturn(timerFactory); Timer timer = mock(Timer.class); when(timerFactory.createTimer()).thenReturn(timer); - - context.registerService(Storage.class, storage, null); context.registerService(ApplicationService.class, appService, null); Activator activator = new Activator(); @@ -127,7 +122,7 @@ activator.stop(context); assertEquals(0, context.getServiceListeners().size()); - assertEquals(2, context.getAllServices().size()); + assertEquals(1, context.getAllServices().size()); activator.start(context); @@ -140,7 +135,7 @@ activator.stop(context); assertEquals(0, context.getServiceListeners().size()); - assertEquals(2, context.getAllServices().size()); + assertEquals(1, context.getAllServices().size()); } }
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/DbServiceImplTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,506 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.junit.Before; -import org.junit.Test; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; - -import com.redhat.thermostat.shared.config.SSLConfiguration; -import com.redhat.thermostat.storage.core.Connection; -import com.redhat.thermostat.storage.core.Connection.ConnectionListener; -import com.redhat.thermostat.storage.core.Connection.ConnectionStatus; -import com.redhat.thermostat.storage.core.ConnectionException; -import com.redhat.thermostat.storage.core.DbService; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.core.StorageCredentials; -import com.redhat.thermostat.storage.core.StorageException; -import com.redhat.thermostat.storage.core.StorageProvider; -import com.redhat.thermostat.testutils.StubBundleContext; - -public class DbServiceImplTest { - - // Stub connection which is always successful and - // firesChanged immediately. - private ImmediateConnection connection = new ImmediateConnection(); - private StorageProvider storageProvider; - private Storage storage; - private StubBundleContext context; - private StorageCredentials creds; - private SSLConfiguration sslConf; - - @Before - public void setup() { - context = new StubBundleContext(); - sslConf = mock(SSLConfiguration.class); - - storage = mock(Storage.class); - when(storage.getConnection()).thenReturn(connection); - - storageProvider = mock(StorageProvider.class); - when(storageProvider.canHandleProtocol()).thenReturn(true); - when(storageProvider.createStorage()).thenReturn(storage); - context.registerService(StorageProvider.class, storageProvider, null); - - creds = mock(StorageCredentials.class); - } - - @Test - public void testNoStorageProvider() { - context = new StubBundleContext(); - - try { - new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - fail("exception expected"); - } catch (StorageException se) { - assertEquals("No storage provider available", se.getMessage()); - } - } - - @Test - public void testNoStorageProviderCanHandleStorageUrl() { - when(storageProvider.canHandleProtocol()).thenReturn(false); - - try { - new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - fail("exception expected"); - } catch (StorageException se) { - assertEquals("No storage found for URL http://ignored.example.com", se.getMessage()); - } - } - - @Test - public void testConnect() { - DbService dbService = new DbServiceImpl(context, storage, creds, sslConf); - try { - dbService.connect(); - // pass - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.connectCalled); - } - - @Test - public void connectEnsuresPostConditionOnDelayedException() { - Storage mockStorage = mock(Storage.class); - DelayedConnection connection = new DelayedConnection(); - when(mockStorage.getConnection()).thenReturn(connection); - DbService dbService = new DbServiceImpl(context, mockStorage, creds, sslConf); - - try { - dbService.connect(); - fail("Should have thrown ConnectionException!"); - } catch (ConnectionException e) { - // pass - } - assertTrue(connection.connectCalled); - assertTrue(connection.delayAwaited); - assertFalse(context.isServiceRegistered(Storage.class.getName(), mockStorage.getClass())); - assertFalse(context.isServiceRegistered(DbService.class.getName(), DbServiceImpl.class)); - } - - @Test - public void disconnectAwaitsConnectionDisconnect() { - Storage mockStorage = mock(Storage.class); - DelayedConnection connection = new DelayedConnection() { - @Override - public void connect() { - fireChanged(ConnectionStatus.CONNECTED); - connectCalled = true; - } - }; - when(mockStorage.getConnection()).thenReturn(connection); - DbService dbService = new DbServiceImpl(context, mockStorage, creds, sslConf); - - try { - dbService.connect(); - // pass - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.connectCalled); - connection.connectCalled = false; - assertFalse(connection.delayAwaited); - assertFalse(connection.disconnectCalled); - assertNotNull(context.getServiceReference(DbService.class)); - assertNotNull(context.getServiceReference(Storage.class)); - - try { - dbService.disconnect(); - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.disconnectCalled); - assertFalse(connection.connectCalled); - assertTrue(connection.delayAwaited); - assertNull(context.getServiceReference(DbService.class)); - assertNull(context.getServiceReference(Storage.class)); - } - - @Test - public void testConnectRegistersDbService() { - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - try { - dbService.connect(); - // pass - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.connectCalled); - @SuppressWarnings("rawtypes") - ServiceReference dbServiceRef = context.getServiceReference(DbService.class); - // connect registers DbService - assertNotNull(dbServiceRef); - // make sure we really get the same instance - assertTrue(dbService.equals(context.getService(dbServiceRef))); - } - - @Test - public void testConnectRegistersStorage() { - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - try { - dbService.connect(); - // pass - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.connectCalled); - @SuppressWarnings("rawtypes") - ServiceReference storageRef = context.getServiceReference(Storage.class); - // connect registers DbService - assertNotNull(storageRef); - // make sure we really get the same instance - assertTrue(storage.equals(context.getService(storageRef))); - } - - @SuppressWarnings("rawtypes") - @Test - public void testConnectEnforcesPreCond() { - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - ServiceRegistration reg = context.registerService(DbService.class, dbService, null); - try { - dbService.connect(); - fail("connect should check if db service is already registered"); - } catch (IllegalStateException e) { - // pass - reg.unregister(); - } - reg = context.registerService(Storage.class, storage, null); - try { - dbService.connect(); - fail("connect should check if storage service is already registered"); - } catch (IllegalStateException e) { - // pass - reg.unregister(); - } - } - - @SuppressWarnings("rawtypes") - @Test - public void testDisConnectEnforcesPreCond() { - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - ServiceRegistration reg = context.registerService(DbService.class, dbService, null); - try { - // Storage == null - dbService.disconnect(); - fail("disconnect should check if storage service is already registered"); - } catch (IllegalStateException e) { - // pass - reg.unregister(); - } - reg = context.registerService(Storage.class, storage, null); - try { - // DbService == null - dbService.disconnect(); - fail("disconnect should check if db service is already registered"); - } catch (IllegalStateException e) { - // pass - reg.unregister(); - } - } - - @Test - public void testDisconnect() { - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - try { - dbService.connect(); - // pass - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.connectCalled); - assertNotNull(context.getServiceReference(DbService.class)); - - dbService.disconnect(); - - assertTrue(connection.disconnectCalled); - } - - @Test - public void testDisconnectUnregistersDbService() { - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - try { - dbService.connect(); - // pass - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.connectCalled); - assertNotNull(context.getServiceReference(DbService.class)); - - dbService.disconnect(); - - assertTrue(connection.disconnectCalled); - // disconnect unregisters DbService - assertNull(context.getServiceReference(DbService.class)); - } - - @Test - public void testDisconnectUnregistersStorage() { - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - try { - dbService.connect(); - // pass - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.connectCalled); - assertNotNull(context.getServiceReference(Storage.class)); - - dbService.disconnect(); - - assertTrue(connection.disconnectCalled); - - // disconnect unregisters Storage - assertNull(context.getServiceReference(Storage.class)); - } - - @Test - public void canGetStorageUrl() { - String connectionURL = "http://test.example.com:8082"; - - DbService dbService = new DbServiceImpl(context, connectionURL, creds, sslConf); - assertEquals(connectionURL, dbService.getConnectionUrl()); - } - - @Test - public void canGetUsername() { - String connectionURL = "http://test.example.com:8082"; - - DbService dbService = new DbServiceImpl(context, connectionURL, creds, sslConf); - dbService.connect(); - - assertEquals(ImmediateConnection.USERNAME, dbService.getUserName()); - } - - @Test - public void testDisconnectUnsetsUsername() { - String connectionURL = "http://test.example.com:8082"; - - DbService dbService = new DbServiceImpl(context, connectionURL, creds, sslConf); - dbService.connect(); - - assertEquals(ImmediateConnection.USERNAME, dbService.getUserName()); - - dbService.disconnect(); - - assertEquals(Connection.UNSET_USERNAME, dbService.getUserName()); - } - - @Test - public void testAddListener() { - ConnectionListener listener = mock(ConnectionListener.class); - Connection connection = mock(Connection.class); - when(storage.getConnection()).thenReturn(connection); - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - dbService.addConnectionListener(listener); - verify(connection).addListener(listener); - } - - @Test - public void testListenerGetsEvent() { - ConnectingConnectionListener listener = new ConnectingConnectionListener(); - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - - ConnectingConnection connection = new ConnectingConnection(); - when(storage.getConnection()).thenReturn(connection); - dbService.addConnectionListener(listener); - assertFalse(listener.eventReceived); - try { - dbService.connect(); - } catch (ConnectionException e) { - fail(); - } - assertTrue(connection.connectCalled); - assertTrue(listener.eventReceived); - listener.eventReceived = false; - dbService.removeConnectionListener(listener); - try { - dbService.disconnect(); - dbService.connect(); - } catch (ConnectionException e) { - fail(); - } - assertFalse(listener.eventReceived); - } - - @Test - public void testRemoveListener() { - // Remove called regardless of listener actually being added - ConnectionListener listener = mock(ConnectionListener.class); - Connection connection = mock(Connection.class); - when(storage.getConnection()).thenReturn(connection); - DbService dbService = new DbServiceImpl(context, "http://ignored.example.com", creds, sslConf); - dbService.removeConnectionListener(listener); - verify(connection).removeListener(listener); - } - - static class DelayedConnection extends Connection { - - boolean connectCalled = false; - boolean disconnectCalled = false; - private Thread thread; - boolean delayAwaited = false; - - @Override - public void connect() { - // delay connection and then fail - Runnable runnable = new Runnable() { - - @Override - public void run() { - try { - Thread.sleep(100); - // This makes the connection fail (although delayed). - delayAwaited = true; - fireChanged(ConnectionStatus.FAILED_TO_CONNECT); - } catch (InterruptedException e) { - // ignore - } - } - }; - thread = new Thread(runnable); - thread.start(); - connectCalled = true; - } - - @Override - public void disconnect() { - Runnable runnable = new Runnable() { - - @Override - public void run() { - try { - Thread.sleep(100); - delayAwaited = true; - fireChanged(ConnectionStatus.DISCONNECTED); - } catch (InterruptedException e) { - // ignore - } - } - }; - thread = new Thread(runnable); - thread.start(); - disconnectCalled = true; - } - - } - - static class ImmediateConnection extends Connection { - - private static final String USERNAME = "username"; - - boolean connectCalled = false; - boolean disconnectCalled = false; - - @Override - public void connect() { - connectCalled = true; - setUsername(USERNAME); - fireChanged(ConnectionStatus.CONNECTED); - } - - @Override - public void disconnect() { - disconnectCalled = true; - fireChanged(ConnectionStatus.DISCONNECTED); - } - - } - - static class ConnectingConnectionListener implements ConnectionListener { - - boolean eventReceived = false; - - @Override - public void changed(ConnectionStatus newStatus) { - if (newStatus == ConnectionStatus.CONNECTING) { - eventReceived = true; - } - } - - } - - static class ConnectingConnection extends ImmediateConnection { - @Override - public void connect() { - fireChanged(ConnectionStatus.CONNECTING); - super.connect(); - } - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/BasicDescriptorParserTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2043 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.any; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import com.redhat.thermostat.storage.core.Add; -import com.redhat.thermostat.storage.core.AggregateQuery; -import com.redhat.thermostat.storage.core.AggregateQuery.AggregateFunction; -import com.redhat.thermostat.storage.core.BackingStorage; -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.CategoryAdapter; -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.Remove; -import com.redhat.thermostat.storage.core.Replace; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.Update; -import com.redhat.thermostat.storage.dao.AgentInfoDAO; -import com.redhat.thermostat.storage.model.AgentInformation; -import com.redhat.thermostat.storage.model.AggregateCount; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.BinaryComparisonOperator; -import com.redhat.thermostat.storage.query.BinaryLogicalOperator; - -public class BasicDescriptorParserTest { - - private BackingStorage storage; - private Query<AgentInformation> mockQuery; - private BasicDescriptorParser<AgentInformation> parser; - private Add<AgentInformation> mockAdd; - private Update<AgentInformation> mockUpdate; - private Replace<AgentInformation> mockReplace; - private Remove<AgentInformation> mockRemove; - - @SuppressWarnings("unchecked") - @Before - public void setup() { - storage = mock(BackingStorage.class); - mockQuery = mock(Query.class); - when(storage.createQuery(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockQuery); - // setup for ADD - mockAdd = mock(Add.class); - when(storage.createAdd(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockAdd); - // setup for UPDATE - mockUpdate = mock(Update.class); - when(storage.createUpdate(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockUpdate); - // setup for REMOVE - mockRemove = mock(Remove.class); - when(storage.createRemove(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockRemove); - // setup for REPLACE - mockReplace = mock(Replace.class); - when(storage.createReplace(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockReplace); - } - - @Test - public void verifyMatchingAggregateCountParamRegexp() { - Pattern p = Pattern.compile(BasicDescriptorParser.AGGREGATE_PARAM_REGEXP); - String empty = ""; - Matcher matcher = p.matcher(empty); - assertTrue("Should match empty == no params", matcher.matches()); - assertEquals(1, matcher.groupCount()); - assertNull(matcher.group(1)); - String parensWithName = "(foo)"; - matcher = p.matcher(parensWithName); - assertTrue("Should match for a parameter name: " + parensWithName, matcher.matches()); - assertEquals(1, matcher.groupCount()); - assertEquals("foo", matcher.group(1)); - String upLowUnderscore = "(Foo_Bar)"; - matcher = p.matcher(upLowUnderscore); - assertTrue("Should match for a parameter name with upper/lowercase and underscore: " - + upLowUnderscore, matcher.matches()); - assertEquals(1, matcher.groupCount()); - assertEquals("Foo_Bar", matcher.group(1)); - } - - @Test - public void verifyRejectingAggregateCountParamRegexp() { - Pattern p = Pattern.compile(BasicDescriptorParser.AGGREGATE_PARAM_REGEXP); - String parensOnly = "()"; - Matcher matcher = p.matcher(parensOnly); - assertFalse(parensOnly + " should not match", matcher.matches()); - String spaceString = "( foo )"; - matcher = p.matcher(spaceString); - assertFalse(spaceString + " should not match because it has spaces", matcher.matches()); - } - - /* - * We allow QUERY-COUNT without any parameter for backwards compatibility - * Contrast this with QUERY-COUNT(foo). - */ - @Test - public void testParseAggregateCount() throws DescriptorParsingException { - String descFormat = "QUERY-COUNT %s WHERE 'a' = 'b'"; - runAggregateCountTest(descFormat, AggregateFunction.COUNT); - } - - /* - * Query count with a specific optional key. Tests basic parsing. - */ - @Test - public void testParseAggregateCountWithParam() throws DescriptorParsingException { - String descrString = "QUERY-COUNT(a) %s WHERE 'a' = 'b'"; - runAggregateCountTest(descrString, AggregateFunction.COUNT); - } - - /* - * Distinct with a specific optional key. Tests basic parsing. - */ - @Test - public void testParseAggregateDistinctWithParam() throws DescriptorParsingException { - String descrString = "QUERY-DISTINCT(a) %s WHERE 'a' = 'b'"; - runAggregateCountTest(descrString, AggregateFunction.DISTINCT); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Test - public void testParseAggregateCountNoWhereClause() throws DescriptorParsingException { - AggregateQuery<AggregateCount> query = mock(AggregateQuery.class); - ArgumentCaptor<Category> captor = ArgumentCaptor.forClass(Category.class); - when(storage.createAggregateQuery(eq(AggregateFunction.COUNT), captor.capture())).thenReturn(query); - // first adapt from the target category in order to be able to produce the - // right aggregate query with a different result type. - CategoryAdapter<AgentInformation, AggregateCount> adapter = new CategoryAdapter<>(AgentInfoDAO.CATEGORY); - Category<AggregateCount> aggregateCategory = adapter.getAdapted(AggregateCount.class); - String descrString = "QUERY-COUNT " + aggregateCategory.getName(); - StatementDescriptor<AggregateCount> desc = new StatementDescriptor<>(aggregateCategory, descrString); - BasicDescriptorParser<AggregateCount> parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AggregateCount> statement = (ParsedStatementImpl<AggregateCount>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertTrue(statement.getRawStatement() instanceof AggregateQuery); - Category<AggregateCount> capturedCategory = captor.getValue(); - assertEquals(aggregateCategory, capturedCategory); - SuffixExpression expn = statement.getSuffixExpression(); - assertNotNull(expn); - assertNull(expn.getWhereExpn()); - assertNull(expn.getSortExpn()); - assertNull(expn.getLimitExpn()); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void runAggregateCountTest(String descriptorFormat, AggregateFunction function) throws DescriptorParsingException { - AggregateQuery<AggregateCount> query = mock(AggregateQuery.class); - ArgumentCaptor<Category> captor = ArgumentCaptor.forClass(Category.class); - when(storage.createAggregateQuery(eq(function), captor.capture())).thenReturn(query); - // first adapt from the target category in order to be able to produce the - // right aggregate query with a different result type. - CategoryAdapter<AgentInformation, AggregateCount> adapter = new CategoryAdapter<>(AgentInfoDAO.CATEGORY); - Category<AggregateCount> aggregateCategory = adapter.getAdapted(AggregateCount.class); - String descrString = String.format(descriptorFormat, aggregateCategory.getName()); - StatementDescriptor<AggregateCount> desc = new StatementDescriptor<>(aggregateCategory, descrString); - BasicDescriptorParser<AggregateCount> parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AggregateCount> statement = (ParsedStatementImpl<AggregateCount>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertTrue(statement.getRawStatement() instanceof AggregateQuery); - Category<AggregateCount> capturedCategory = captor.getValue(); - assertEquals(aggregateCategory, capturedCategory); - SuffixExpression expn = statement.getSuffixExpression(); - assertNotNull(expn); - WhereExpression where = expn.getWhereExpn(); - assertNotNull(where); - assertNull(expn.getSortExpn()); - assertNull(expn.getLimitExpn()); - } - - @Test - public void testParseQueryCountWithAssertedParamValue() throws DescriptorParsingException { - String formatedDesc = "QUERY-COUNT(a) %s"; - runParamAggregateAssertedValueTest(formatedDesc, AggregateFunction.COUNT); - } - - @Test - public void testParseQueryDistinctWithAssertedParamValue() throws DescriptorParsingException { - String formatedDesc = "QUERY-DISTINCT(a) %s"; - runParamAggregateAssertedValueTest(formatedDesc, AggregateFunction.DISTINCT); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void runParamAggregateAssertedValueTest(String aggregateDescFormat, AggregateFunction function) throws DescriptorParsingException { - AggregateQuery<AggregateCount> query = mock(AggregateQuery.class); - ArgumentCaptor<Category> captor = ArgumentCaptor.forClass(Category.class); - when(storage.createAggregateQuery(eq(function), captor.capture())).thenReturn(query); - // first adapt from the target category in order to be able to produce the - // right aggregate query with a different result type. - CategoryAdapter<AgentInformation, AggregateCount> adapter = new CategoryAdapter<>(AgentInfoDAO.CATEGORY); - Category<AggregateCount> aggregateCategory = adapter.getAdapted(AggregateCount.class); - String descrString = String.format(aggregateDescFormat, aggregateCategory.getName()); - StatementDescriptor<AggregateCount> desc = new StatementDescriptor<>(aggregateCategory, descrString); - BasicDescriptorParser<AggregateCount> parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AggregateCount> statement = (ParsedStatementImpl<AggregateCount>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertTrue(statement.getRawStatement() instanceof AggregateQuery); - Key<?> aKey = new Key<>("a"); - // Make sure the optional key is set - verify(query).setAggregateKey(eq(aKey)); - Category<AggregateCount> capturedCategory = captor.getValue(); - assertEquals(aggregateCategory, capturedCategory); - SuffixExpression expn = statement.getSuffixExpression(); - assertNotNull(expn); - assertNull("No where expression expected", expn.getWhereExpn()); - assertNull(expn.getSortExpn()); - assertNull(expn.getLimitExpn()); - } - - @Test - public void testParseQuerySimple() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName(); - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression tree = statement.getSuffixExpression(); - assertNull(tree.getLimitExpn()); - assertNull(tree.getSortExpn()); - assertNull(tree.getWhereExpn()); - } - - @Test - public void testParseLongInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != 30000000003L"; - doTestType(descrString, 30000000003L, 0); - } - - @Test - public void testParseLongInWhere2() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != 30000000003l"; - doTestType(descrString, 30000000003L, 0); - } - - @Test - public void testParseLongInWhere3() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != 3l"; - doTestType(descrString, 3L, 0); - } - - @Test - public void testParseLongInWhere4() throws DescriptorParsingException { - long val = Long.MIN_VALUE; - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != " + val + "l"; - doTestType(descrString, val, 0); - } - - @Test - public void testParseIntInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != 30000"; - doTestType(descrString, 30000, 0); - } - - @Test - public void testParseIntInWhere2() throws DescriptorParsingException { - int val = Integer.MAX_VALUE - 1; - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != " + val; - doTestType(descrString, val, 0); - } - - @Test - public void testParseIntInWhere3() throws DescriptorParsingException { - int val = Integer.MIN_VALUE; - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != " + val; - doTestType(descrString, val, 0); - } - - @Test - public void testParseBooleanInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != true"; - doTestType(descrString, true, 0); - } - - @Test - public void testParseBooleanInWhere2() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != false"; - doTestType(descrString, false, 0); - } - - @Test - public void testParseStringInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != 'testing'"; - doTestType(descrString, "testing", 0); - } - - @Test - public void testParseStringTypeFreeVarInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != ?s"; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(String.class); - unfinished.setParameterIndex(0); - doTestType(descrString, unfinished, 1); - } - - @Test - public void testParseDoubleTypeFreeVarInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != ?d"; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(double.class); - unfinished.setParameterIndex(0); - doTestType(descrString, unfinished, 1); - } - - /* - * SET clauses allow for setting list types. Test that it works for a - * String list free variable type in ADD. - */ - @Test - public void testParseStringListTypeFreeVarInSetlist() throws DescriptorParsingException { - // use ADD since WHERE should not support list types. - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?s["; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(String[].class); - unfinished.setParameterIndex(0); - doListTypeTest(descString, unfinished); - } - - /* - * SET clauses allow for setting list types. Test that it works for a - * integer list free variable type in ADD. - */ - @Test - public void testParseDoubleListTypeFreeVarInSetlist() throws DescriptorParsingException { - // use ADD since WHERE should not support list types. - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?d["; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(double[].class); - unfinished.setParameterIndex(0); - doListTypeTest(descString, unfinished); - } - - /* - * SET clauses allow for setting list types. Test that it works for a - * double list free variable type in ADD. - */ - @Test - public void testParseIntListTypeFreeVarInSetlist() throws DescriptorParsingException { - // use ADD since WHERE should not support list types. - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?i["; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(int[].class); - unfinished.setParameterIndex(0); - doListTypeTest(descString, unfinished); - } - - /* - * SET clauses allow for setting list types. Test that it works for a - * boolean list free variable type in ADD. - */ - @Test - public void testParseBooleanListTypeFreeVarInSetlist() throws DescriptorParsingException { - // use ADD since WHERE should not support list types. - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?b["; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(boolean[].class); - unfinished.setParameterIndex(0); - doListTypeTest(descString, unfinished); - } - - /* - * SET clauses allow for setting list types. Test that it works for a - * long list free variable type in ADD. - */ - @Test - public void testParseLongListTypeFreeVarInSetlist() throws DescriptorParsingException { - // use ADD since WHERE should not support list types. - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?l["; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(long[].class); - unfinished.setParameterIndex(0); - doListTypeTest(descString, unfinished); - } - - /* - * SET clauses allow for setting list types. Test that it works for a - * long list free variable type in ADD. - */ - @Test - public void testParsePojoTypeFreeVarInSetlist() throws DescriptorParsingException { - // use ADD since WHERE should not support pojo type. - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?p"; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(Pojo.class); - unfinished.setParameterIndex(0); - doListTypeTest(descString, unfinished); - } - - /* - * SET clauses allow for setting list types. Test that it works for a - * Pojo list free variable type in ADD. - */ - @Test - public void testParsePojoListTypeFreeVarInSetlist() throws DescriptorParsingException { - // use ADD since WHERE should not support list types. - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?p["; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(Pojo[].class); - unfinished.setParameterIndex(0); - doListTypeTest(descString, unfinished); - } - - private void doListTypeTest(String descString, UnfinishedValueNode unfinished) { - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - assertTrue(statement.getRawStatement() instanceof Add); - SuffixExpression suffix = statement.getSuffixExpression(); - assertNotNull(suffix); - assertNull(suffix.getLimitExpn()); - assertNull(suffix.getSortExpn()); - assertNull(suffix.getWhereExpn()); - SetList list = statement.getSetList(); - assertNotNull(list); - List<SetListValue> mems = list.getValues(); - assertEquals(1, mems.size()); - SetListValue val = mems.get(0); - TerminalNode aKey = new TerminalNode(null); - aKey.setValue(new Key<>("a")); - assertEquals(aKey, val.getKey()); - TerminalNode aVal = new TerminalNode(null); - aVal.setValue(unfinished); - assertEquals(aVal, val.getValue()); - } - - @Test - public void testParseIntTypeFreeVarInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != ?i"; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(int.class); - unfinished.setParameterIndex(0); - doTestType(descrString, unfinished, 1); - } - - @Test - public void testParseLongTypeFreeVarInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != ?l"; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(long.class); - unfinished.setParameterIndex(0); - doTestType(descrString, unfinished, 1); - } - - @Test - public void testParseBooleanTypeFreeVarInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != ?b"; - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setType(boolean.class); - unfinished.setParameterIndex(0); - doTestType(descrString, unfinished, 1); - } - - private void doTestType(String strDesc, Object bVal, int expNumFreeVars) throws DescriptorParsingException { - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(expNumFreeVars, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression tree = statement.getSuffixExpression(); - assertNull(tree.getLimitExpn()); - assertNull(tree.getSortExpn()); - assertNotNull(tree.getWhereExpn()); - - WhereExpression expected = new WhereExpression(); - BinaryExpressionNode notEquals = new BinaryExpressionNode(expected.getRoot()); - expected.getRoot().setValue(notEquals); - notEquals.setOperator(BinaryComparisonOperator.NOT_EQUAL_TO); - TerminalNode a = new TerminalNode(notEquals); - a.setValue(new Key<String>("a")); - TerminalNode b = new TerminalNode(notEquals); - b.setValue(bVal); - notEquals.setLeftChild(a); - notEquals.setRightChild(b); - - assertTrue(WhereExpressions.equals(expected, tree.getWhereExpn())); - } - - @Test - public void testParseNotEqualComparisonInWhere() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != 'b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression tree = statement.getSuffixExpression(); - assertNull(tree.getLimitExpn()); - assertNull(tree.getSortExpn()); - assertNotNull(tree.getWhereExpn()); - - WhereExpression expected = new WhereExpression(); - BinaryExpressionNode notEquals = new BinaryExpressionNode(expected.getRoot()); - expected.getRoot().setValue(notEquals); - notEquals.setOperator(BinaryComparisonOperator.NOT_EQUAL_TO); - TerminalNode a = new TerminalNode(notEquals); - a.setValue(new Key<String>("a")); - TerminalNode b = new TerminalNode(notEquals); - b.setValue("b"); - notEquals.setLeftChild(a); - notEquals.setRightChild(b); - - assertTrue(WhereExpressions.equals(expected, tree.getWhereExpn())); - } - - @Test - public void testParseQuerySimpleWithLimit() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT ?i"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(1, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression expn = statement.getSuffixExpression(); - assertNotNull(expn.getLimitExpn()); - assertNull(expn.getSortExpn()); - assertNull(expn.getWhereExpn()); - LimitExpression limitExp = expn.getLimitExpn(); - assertTrue(limitExp.getValue() instanceof UnfinishedLimitValue); - UnfinishedLimitValue value = (UnfinishedLimitValue)limitExp.getValue(); - assertEquals(0, value.getParameterIndex()); - } - - @Test - public void testParseSortMultiple() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " SORT 'a' ASC , 'b' DSC , 'c' ASC"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - SortExpression sortExpn = suffixExpn.getSortExpn(); - assertNotNull(sortExpn); - assertNull(suffixExpn.getLimitExpn()); - assertNull(suffixExpn.getWhereExpn()); - List<SortMember> list = sortExpn.getMembers(); - assertNotNull(list); - assertEquals(3, list.size()); - assertEquals(SortDirection.ASCENDING, list.get(0).getDirection()); - assertEquals(SortDirection.DESCENDING, list.get(1).getDirection()); - assertEquals(SortDirection.ASCENDING, list.get(2).getDirection()); - assertEquals("a", list.get(0).getSortKey()); - assertEquals("b", list.get(1).getSortKey()); - assertEquals("c", list.get(2).getSortKey()); - } - - @Test - public void testParseQueryWithMultipleConcunctions() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = 'b' AND 'c' = 'd' AND 'e' < ?i"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(1, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression expn = statement.getSuffixExpression(); - assertNull(expn.getLimitExpn()); - assertNull(expn.getSortExpn()); - assertNotNull(expn.getWhereExpn()); - WhereExpression where = expn.getWhereExpn(); - // build the expected expression tree - WhereExpression expected = new WhereExpression(); - BinaryExpressionNode and1 = new BinaryExpressionNode(expected.getRoot()); - expected.getRoot().setValue(and1); - BinaryExpressionNode and2 = new BinaryExpressionNode(and1); - and1.setLeftChild(and2); - and1.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode equality1 = new BinaryExpressionNode(and2); - and2.setOperator(BinaryLogicalOperator.AND); - and2.setLeftChild(equality1); - equality1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality1); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - equality1.setLeftChild(a); - TerminalNode b = new TerminalNode(equality1); - b.setValue("b"); - equality1.setRightChild(b); - BinaryExpressionNode equality2 = new BinaryExpressionNode(and2); - and2.setRightChild(equality2); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality2); - Key<String> cKey = new Key<>("c"); - c.setValue(cKey); - equality2.setLeftChild(c); - TerminalNode d = new TerminalNode(equality2); - d.setValue("d"); - equality2.setRightChild(d); - BinaryExpressionNode lessThan = new BinaryExpressionNode(and1); - lessThan.setOperator(BinaryComparisonOperator.LESS_THAN); - and1.setRightChild(lessThan); - TerminalNode e = new TerminalNode(lessThan); - Key<Integer> eKey = new Key<>("e"); - e.setValue(eKey); - lessThan.setLeftChild(e); - UnfinishedValueNode f = new UnfinishedValueNode(); - f.setParameterIndex(0); - f.setType(int.class); - f.setLHS(false); - TerminalNode fReal = new TerminalNode(lessThan); - fReal.setValue(f); - lessThan.setRightChild(fReal); - - assertTrue( WhereExpressions.equals(expected, where)); - } - - @Test - public void testParseQueryWithMultipleConcunctions2() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = 'b' AND 'c' = 'd' AND 'e' < 'f' AND 'g' >= 'h'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression expn = statement.getSuffixExpression(); - assertNull(expn.getLimitExpn()); - assertNull(expn.getSortExpn()); - assertNotNull(expn.getWhereExpn()); - WhereExpression where = expn.getWhereExpn(); - // build the expected expression tree - WhereExpression expected = new WhereExpression(); - BinaryExpressionNode and1 = new BinaryExpressionNode(expected.getRoot()); - expected.getRoot().setValue(and1); - BinaryExpressionNode and2 = new BinaryExpressionNode(and1); - and1.setLeftChild(and2); - BinaryExpressionNode and3 = new BinaryExpressionNode(and2); - and3.setOperator(BinaryLogicalOperator.AND); - and2.setLeftChild(and3); - and1.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode equality1 = new BinaryExpressionNode(and3); - and2.setOperator(BinaryLogicalOperator.AND); - and3.setLeftChild(equality1); - equality1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality1); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - equality1.setLeftChild(a); - TerminalNode b = new TerminalNode(equality1); - b.setValue("b"); - equality1.setRightChild(b); - BinaryExpressionNode equality2 = new BinaryExpressionNode(and3); - and3.setRightChild(equality2); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality2); - Key<String> cKey = new Key<>("c"); - c.setValue(cKey); - equality2.setLeftChild(c); - TerminalNode d = new TerminalNode(equality2); - d.setValue("d"); - equality2.setRightChild(d); - BinaryExpressionNode lessThan = new BinaryExpressionNode(and2); - lessThan.setOperator(BinaryComparisonOperator.LESS_THAN); - and2.setRightChild(lessThan); - TerminalNode e = new TerminalNode(lessThan); - Key<String> eKey = new Key<>("e"); - e.setValue(eKey); - lessThan.setLeftChild(e); - TerminalNode f = new TerminalNode(lessThan); - f.setValue("f"); - lessThan.setRightChild(f); - BinaryExpressionNode greaterOrEqual = new BinaryExpressionNode(and1); - greaterOrEqual.setOperator(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL_TO); - TerminalNode g = new TerminalNode(greaterOrEqual); - Key<String> gKey = new Key<>("g"); - g.setValue(gKey); - greaterOrEqual.setLeftChild(g); - TerminalNode h = new TerminalNode(greaterOrEqual); - h.setValue("h"); - greaterOrEqual.setRightChild(h); - and1.setRightChild(greaterOrEqual); - - assertTrue( WhereExpressions.equals(expected, where)); - } - - @Test - public void testParseQueryWithMultipleDisjunctions() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = 'b' OR 'c' = 'd' OR 'e' < ?i"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(1, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression expn = statement.getSuffixExpression(); - assertNull(expn.getLimitExpn()); - assertNull(expn.getSortExpn()); - assertNotNull(expn.getWhereExpn()); - - WhereExpression where = expn.getWhereExpn(); - // build the expected expression tree - WhereExpression expected = new WhereExpression(); - BinaryExpressionNode or1 = new BinaryExpressionNode(expected.getRoot()); - expected.getRoot().setValue(or1); - BinaryExpressionNode or2 = new BinaryExpressionNode(or1); - or1.setLeftChild(or2); - or1.setOperator(BinaryLogicalOperator.OR); - BinaryExpressionNode equality1 = new BinaryExpressionNode(or2); - or2.setOperator(BinaryLogicalOperator.OR); - or2.setLeftChild(equality1); - equality1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality1); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - equality1.setLeftChild(a); - TerminalNode b = new TerminalNode(equality1); - b.setValue("b"); - equality1.setRightChild(b); - BinaryExpressionNode equality2 = new BinaryExpressionNode(or2); - or2.setRightChild(equality2); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality2); - Key<String> cKey = new Key<>("c"); - c.setValue(cKey); - equality2.setLeftChild(c); - TerminalNode d = new TerminalNode(equality2); - d.setValue("d"); - equality2.setRightChild(d); - BinaryExpressionNode lessThan = new BinaryExpressionNode(or1); - lessThan.setOperator(BinaryComparisonOperator.LESS_THAN); - or1.setRightChild(lessThan); - TerminalNode e = new TerminalNode(lessThan); - Key<Integer> eKey = new Key<>("e"); - e.setValue(eKey); - lessThan.setLeftChild(e); - UnfinishedValueNode f = new UnfinishedValueNode(); - f.setParameterIndex(0); - f.setType(int.class); - f.setLHS(false); - TerminalNode fReal = new TerminalNode(lessThan); - fReal.setValue(f); - lessThan.setRightChild(fReal); - - assertTrue( WhereExpressions.equals(expected, where)); - } - - @Test - public void testParseQueryWithMultipleDisjunctions2() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = 'b' OR 'c' = 'd' OR 'e' < 'f' OR 'g' >= 'h'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression expn = statement.getSuffixExpression(); - assertNull(expn.getLimitExpn()); - assertNull(expn.getSortExpn()); - assertNotNull(expn.getWhereExpn()); - - WhereExpression where = expn.getWhereExpn(); - // build the expected expression tree - WhereExpression expected = new WhereExpression(); - BinaryExpressionNode or1 = new BinaryExpressionNode(expected.getRoot()); - expected.getRoot().setValue(or1); - BinaryExpressionNode or2 = new BinaryExpressionNode(or1); - or1.setLeftChild(or2); - BinaryExpressionNode or3 = new BinaryExpressionNode(or2); - or3.setOperator(BinaryLogicalOperator.OR); - or2.setLeftChild(or3); - or1.setOperator(BinaryLogicalOperator.OR); - BinaryExpressionNode equality1 = new BinaryExpressionNode(or3); - or2.setOperator(BinaryLogicalOperator.OR); - or3.setLeftChild(equality1); - equality1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality1); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - equality1.setLeftChild(a); - TerminalNode b = new TerminalNode(equality1); - b.setValue("b"); - equality1.setRightChild(b); - BinaryExpressionNode equality2 = new BinaryExpressionNode(or3); - or3.setRightChild(equality2); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality2); - Key<String> cKey = new Key<>("c"); - c.setValue(cKey); - equality2.setLeftChild(c); - TerminalNode d = new TerminalNode(equality2); - d.setValue("d"); - equality2.setRightChild(d); - BinaryExpressionNode lessThan = new BinaryExpressionNode(or2); - lessThan.setOperator(BinaryComparisonOperator.LESS_THAN); - or2.setRightChild(lessThan); - TerminalNode e = new TerminalNode(lessThan); - Key<String> eKey = new Key<>("e"); - e.setValue(eKey); - lessThan.setLeftChild(e); - TerminalNode f = new TerminalNode(lessThan); - f.setValue("f"); - lessThan.setRightChild(f); - BinaryExpressionNode greaterOrEqual = new BinaryExpressionNode(or1); - greaterOrEqual.setOperator(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL_TO); - TerminalNode g = new TerminalNode(greaterOrEqual); - Key<String> gKey = new Key<>("g"); - g.setValue(gKey); - greaterOrEqual.setLeftChild(g); - TerminalNode h = new TerminalNode(greaterOrEqual); - h.setValue("h"); - greaterOrEqual.setRightChild(h); - or1.setRightChild(greaterOrEqual); - - assertTrue( WhereExpressions.equals(expected, where)); - } - - @Test - public void testParseQueryWithMultipleConDisjunctions() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = 'b' OR 'c' = 'd' OR 'e' < 'f' OR 'g' >= 'h' AND 'x' = 'y' AND 'u' = 'w' AND 's' = 't'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>) parser.parse(); - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression expn = statement.getSuffixExpression(); - assertNull(expn.getLimitExpn()); - assertNull(expn.getSortExpn()); - assertNotNull(expn.getWhereExpn()); - - WhereExpression where = expn.getWhereExpn(); - // build the expected expression tree - WhereExpression expected = new WhereExpression(); - BinaryExpressionNode and3 = new BinaryExpressionNode(expected.getRoot()); - expected.getRoot().setValue(and3); - and3.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode and2 = new BinaryExpressionNode(and3); - and2.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode and1 = new BinaryExpressionNode(and2); - and1.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode equality3 = new BinaryExpressionNode(and1); - equality3.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode x = new TerminalNode(equality3); - x.setValue(new Key<>("x")); - TerminalNode y = new TerminalNode(equality3); - y.setValue("y"); - equality3.setLeftChild(x); - equality3.setRightChild(y); - and1.setRightChild(equality3); - and3.setLeftChild(and2); - and2.setLeftChild(and1); - BinaryExpressionNode equality4 = new BinaryExpressionNode(and2); - equality4.setOperator(BinaryComparisonOperator.EQUALS); - and2.setRightChild(equality4); - TerminalNode u = new TerminalNode(equality4); - u.setValue(new Key<>("u")); - equality4.setLeftChild(u); - TerminalNode w = new TerminalNode(equality4); - w.setValue("w"); - equality4.setRightChild(w); - BinaryExpressionNode equality5 = new BinaryExpressionNode(and3); - equality5.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode s = new TerminalNode(equality5); - s.setValue(new Key<>("s")); - TerminalNode t = new TerminalNode(equality5); - t.setValue("t"); - equality5.setLeftChild(s); - equality5.setRightChild(t); - and3.setRightChild(equality5); - BinaryExpressionNode or3 = new BinaryExpressionNode(and1); - BinaryExpressionNode or2 = new BinaryExpressionNode(or3); - BinaryExpressionNode or1 = new BinaryExpressionNode(or2); - or3.setOperator(BinaryLogicalOperator.OR); - or2.setOperator(BinaryLogicalOperator.OR); - or1.setOperator(BinaryLogicalOperator.OR); - or3.setLeftChild(or2); - or2.setLeftChild(or1); - BinaryExpressionNode equality1 = new BinaryExpressionNode(or1); - or1.setLeftChild(equality1); - equality1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality1); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - equality1.setLeftChild(a); - TerminalNode b = new TerminalNode(equality1); - b.setValue("b"); - equality1.setRightChild(b); - BinaryExpressionNode equality2 = new BinaryExpressionNode(or1); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - or1.setRightChild(equality2); - TerminalNode c = new TerminalNode(equality2); - Key<String> cKey = new Key<>("c"); - c.setValue(cKey); - equality2.setLeftChild(c); - TerminalNode d = new TerminalNode(equality2); - d.setValue("d"); - equality2.setRightChild(d); - BinaryExpressionNode lessThan = new BinaryExpressionNode(or2); - lessThan.setOperator(BinaryComparisonOperator.LESS_THAN); - or2.setRightChild(lessThan); - or2.setLeftChild(or1); - TerminalNode e = new TerminalNode(lessThan); - Key<String> eKey = new Key<>("e"); - e.setValue(eKey); - lessThan.setLeftChild(e); - TerminalNode f = new TerminalNode(lessThan); - f.setValue("f"); - lessThan.setRightChild(f); - BinaryExpressionNode greaterOrEqual = new BinaryExpressionNode(or3); - greaterOrEqual.setOperator(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL_TO); - TerminalNode g = new TerminalNode(greaterOrEqual); - Key<String> gKey = new Key<>("g"); - g.setValue(gKey); - greaterOrEqual.setLeftChild(g); - TerminalNode h = new TerminalNode(greaterOrEqual); - h.setValue("h"); - greaterOrEqual.setRightChild(h); - or3.setRightChild(greaterOrEqual); - or3.setLeftChild(or2); - and1.setLeftChild(or3); - - assertTrue(WhereExpressions.equals(expected, where)); - } - - @Test - public void testParseQueryWithMultipleConDisjunctionsNegations() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = 'b' OR NOT 'c' = 'd' OR 'e' < 'f' OR 'g' >= 'h' AND NOT 'x' = 'y' AND 'u' = 'w' AND 's' = 't'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>) parser.parse(); - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression expn = statement.getSuffixExpression(); - assertNull(expn.getLimitExpn()); - assertNull(expn.getSortExpn()); - assertNotNull(expn.getWhereExpn()); - - WhereExpression where = expn.getWhereExpn(); - // build the expected expression tree - WhereExpression expected = new WhereExpression(); - BinaryExpressionNode and3 = new BinaryExpressionNode(expected.getRoot()); - expected.getRoot().setValue(and3); - and3.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode and2 = new BinaryExpressionNode(and3); - and2.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode and1 = new BinaryExpressionNode(and2); - and1.setOperator(BinaryLogicalOperator.AND); - NotBooleanExpressionNode not2 = new NotBooleanExpressionNode(and1); - BinaryExpressionNode equality3 = new BinaryExpressionNode(not2); - not2.setValue(equality3); - equality3.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode x = new TerminalNode(equality3); - x.setValue(new Key<String>("x")); - TerminalNode y = new TerminalNode(equality3); - y.setValue("y"); - equality3.setLeftChild(x); - equality3.setRightChild(y); - and1.setRightChild(not2); - and3.setLeftChild(and2); - and2.setLeftChild(and1); - BinaryExpressionNode equality4 = new BinaryExpressionNode(and2); - equality4.setOperator(BinaryComparisonOperator.EQUALS); - and2.setRightChild(equality4); - TerminalNode u = new TerminalNode(equality4); - u.setValue(new Key<String>("u")); - equality4.setLeftChild(u); - TerminalNode w = new TerminalNode(equality4); - w.setValue("w"); - equality4.setRightChild(w); - BinaryExpressionNode equality5 = new BinaryExpressionNode(and3); - equality5.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode s = new TerminalNode(equality5); - s.setValue(new Key<String>("s")); - TerminalNode t = new TerminalNode(equality5); - t.setValue("t"); - equality5.setLeftChild(s); - equality5.setRightChild(t); - and3.setRightChild(equality5); - BinaryExpressionNode or3 = new BinaryExpressionNode(and1); - BinaryExpressionNode or2 = new BinaryExpressionNode(or3); - BinaryExpressionNode or1 = new BinaryExpressionNode(or2); - or3.setOperator(BinaryLogicalOperator.OR); - or2.setOperator(BinaryLogicalOperator.OR); - or1.setOperator(BinaryLogicalOperator.OR); - or3.setLeftChild(or2); - or2.setLeftChild(or1); - BinaryExpressionNode equality1 = new BinaryExpressionNode(or1); - or1.setLeftChild(equality1); - equality1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality1); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - equality1.setLeftChild(a); - TerminalNode b = new TerminalNode(equality1); - b.setValue("b"); - equality1.setRightChild(b); - BinaryExpressionNode equality2 = new BinaryExpressionNode(or1); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - NotBooleanExpressionNode not1 = new NotBooleanExpressionNode(or1); - not1.setValue(equality2); - or1.setRightChild(not1); - TerminalNode c = new TerminalNode(equality2); - Key<String> cKey = new Key<>("c"); - c.setValue(cKey); - equality2.setLeftChild(c); - TerminalNode d = new TerminalNode(equality2); - d.setValue("d"); - equality2.setRightChild(d); - BinaryExpressionNode lessThan = new BinaryExpressionNode(or2); - lessThan.setOperator(BinaryComparisonOperator.LESS_THAN); - or2.setRightChild(lessThan); - or2.setLeftChild(or1); - TerminalNode e = new TerminalNode(lessThan); - Key<String> eKey = new Key<>("e"); - e.setValue(eKey); - lessThan.setLeftChild(e); - TerminalNode f = new TerminalNode(lessThan); - f.setValue("f"); - lessThan.setRightChild(f); - BinaryExpressionNode greaterOrEqual = new BinaryExpressionNode(or3); - greaterOrEqual.setOperator(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL_TO); - TerminalNode g = new TerminalNode(greaterOrEqual); - Key<String> gKey = new Key<>("g"); - g.setValue(gKey); - greaterOrEqual.setLeftChild(g); - TerminalNode h = new TerminalNode(greaterOrEqual); - h.setValue("h"); - greaterOrEqual.setRightChild(h); - or3.setRightChild(greaterOrEqual); - or3.setLeftChild(or2); - and1.setLeftChild(or3); - - assertTrue(WhereExpressions.equals(expected, where)); - } - - @Test - public void testParseQueryWhereAndSortMultiple() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' < 'b' AND 'c' = ?s OR NOT 'x' >= ?i SORT 'a' ASC , 'b' DSC , 'c' ASC"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>) parser.parse(); - assertEquals(2, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNotNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getLimitExpn()); - assertNotNull(suffixExpn.getWhereExpn()); - List<SortMember> list = suffixExpn.getSortExpn().getMembers(); - assertNotNull(list); - assertEquals(3, list.size()); - assertEquals(SortDirection.ASCENDING, list.get(0).getDirection()); - assertEquals(SortDirection.DESCENDING, list.get(1).getDirection()); - assertEquals(SortDirection.ASCENDING, list.get(2).getDirection()); - assertEquals("a", list.get(0).getSortKey()); - assertEquals("b", list.get(1).getSortKey()); - assertEquals("c", list.get(2).getSortKey()); - // build the expected expression tree - WhereExpression where = new WhereExpression(); - BinaryExpressionNode or = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(or); - or.setOperator(BinaryLogicalOperator.OR); - BinaryExpressionNode and = new BinaryExpressionNode(or); - and.setOperator(BinaryLogicalOperator.AND); - or.setLeftChild(and); - NotBooleanExpressionNode not = new NotBooleanExpressionNode(or); - or.setRightChild(not); - BinaryExpressionNode unequality = new BinaryExpressionNode(and); - unequality.setOperator(BinaryComparisonOperator.LESS_THAN); - TerminalNode a = new TerminalNode(unequality); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - unequality.setLeftChild(a); - TerminalNode b = new TerminalNode(unequality); - b.setValue("b"); - unequality.setRightChild(b); - and.setLeftChild(unequality); - BinaryExpressionNode equality = new BinaryExpressionNode(and); - equality.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality); - Key<String> cKey = new Key<>("c"); - c.setValue(cKey); - equality.setLeftChild(c); - UnfinishedValueNode patch1 = new UnfinishedValueNode(); - patch1.setParameterIndex(0); - patch1.setLHS(false); - patch1.setType(String.class); - TerminalNode d = new TerminalNode(equality); - d.setValue(patch1); - equality.setRightChild(d); - and.setRightChild(equality); - BinaryExpressionNode greaterEqual = new BinaryExpressionNode(not); - not.setValue(greaterEqual); - greaterEqual.setOperator(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL_TO); - TerminalNode x = new TerminalNode(greaterEqual); - Key<Integer> xKey = new Key<>("x"); - x.setValue(xKey); - greaterEqual.setLeftChild(x); - UnfinishedValueNode patch2 = new UnfinishedValueNode(); - patch2.setParameterIndex(1); - patch2.setLHS(false); - patch2.setType(int.class); - TerminalNode y = new TerminalNode(greaterEqual); - y.setValue(patch2); - greaterEqual.setRightChild(y); - // finally assert equality - assertTrue( WhereExpressions.equals(where, suffixExpn.getWhereExpn())); - } - - @Test - public void testParseQueryWhereOrSortMultiple() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' < 'b' OR 'c' = ?s SORT 'a' ASC , ?s DSC , 'c' ASC"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>) parser.parse(); - assertEquals(2, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNotNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getLimitExpn()); - assertNotNull(suffixExpn.getWhereExpn()); - SortExpression sortExp = suffixExpn.getSortExpn(); - List<SortMember> list = sortExp.getMembers(); - assertNotNull(list); - assertEquals(3, list.size()); - assertEquals(SortDirection.ASCENDING, list.get(0).getDirection()); - assertEquals(SortDirection.DESCENDING, list.get(1).getDirection()); - assertEquals(SortDirection.ASCENDING, list.get(2).getDirection()); - assertEquals("a", list.get(0).getSortKey()); - UnfinishedSortKey unfinished = new UnfinishedSortKey(); - unfinished.setParameterIndex(1); - assertEquals(unfinished, list.get(1).getSortKey()); - assertEquals("c", list.get(2).getSortKey()); - // build the expected expression tree - WhereExpression where = new WhereExpression(); - BinaryExpressionNode or = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(or); - or.setOperator(BinaryLogicalOperator.OR); - BinaryExpressionNode unequality = new BinaryExpressionNode(or); - unequality.setOperator(BinaryComparisonOperator.LESS_THAN); - TerminalNode a = new TerminalNode(unequality); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - unequality.setLeftChild(a); - TerminalNode b = new TerminalNode(unequality); - b.setValue("b"); - unequality.setRightChild(b); - or.setLeftChild(unequality); - BinaryExpressionNode equality = new BinaryExpressionNode(or); - equality.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality); - Key<String> cKey = new Key<>("c"); - c.setValue(cKey); - equality.setLeftChild(c); - UnfinishedValueNode patch1 = new UnfinishedValueNode(); - patch1.setParameterIndex(0); - patch1.setLHS(false); - patch1.setType(String.class); - TerminalNode d = new TerminalNode(equality); - d.setValue(patch1); - equality.setRightChild(d); - or.setRightChild(equality); - assertTrue(WhereExpressions.equals(where, suffixExpn.getWhereExpn())); - } - - @Test - public void testParseQuerySimpleWhereAndSimpleSort() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' < 'b' SORT 'a' DSC"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNotNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getLimitExpn()); - assertNotNull(suffixExpn.getWhereExpn()); - SortExpression sortExp = suffixExpn.getSortExpn(); - List<SortMember> list = sortExp.getMembers(); - assertNotNull(list); - assertEquals(1, list.size()); - assertEquals(SortDirection.DESCENDING, list.get(0).getDirection()); - assertEquals("a", list.get(0).getSortKey()); - // build the expected expression tree - WhereExpression where = new WhereExpression(); - BinaryExpressionNode unequality = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(unequality); - unequality.setOperator(BinaryComparisonOperator.LESS_THAN); - TerminalNode a = new TerminalNode(unequality); - @SuppressWarnings("rawtypes") - Key aKey = new Key("a"); - a.setValue(aKey); - unequality.setLeftChild(a); - TerminalNode b = new TerminalNode(unequality); - b.setValue("b"); - unequality.setRightChild(b); - assertTrue(WhereExpressions.equals(where, suffixExpn.getWhereExpn())); - } - - @Test - public void testParseQuerySimpleWithOneWhere() { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE '" + Key.AGENT_ID.getName() + "' = ?s"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - fail(e.getMessage()); - } - assertEquals(1, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getLimitExpn()); - assertNotNull(suffixExpn.getWhereExpn()); - // build the expected expression tree - WhereExpression where = new WhereExpression(); - BinaryExpressionNode equality = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(equality); - equality.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality); - @SuppressWarnings("rawtypes") - Key aKey = new Key(Key.AGENT_ID.getName()); - a.setValue(aKey); - equality.setLeftChild(a); - TerminalNode b = new TerminalNode(equality); - UnfinishedValueNode node = new UnfinishedValueNode(); - node.setParameterIndex(0); - node.setLHS(false); - node.setType(String.class); - b.setValue(node); - equality.setRightChild(b); - assertTrue(WhereExpressions.equals(where, suffixExpn.getWhereExpn())); - } - - @Test - public void testParseSimpleWithAndOr() { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE '" + Key.AGENT_ID.getName() + "' = ?s" + - " AND ?s < ?b OR 'a' = 'b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - assertEquals(3, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getLimitExpn()); - assertNotNull(suffixExpn.getWhereExpn()); - // build the expected expression tree - WhereExpression where = new WhereExpression(); - BinaryExpressionNode or = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(or); - or.setOperator(BinaryLogicalOperator.OR); - BinaryExpressionNode and = new BinaryExpressionNode(or); - and.setOperator(BinaryLogicalOperator.AND); - or.setLeftChild(and); - BinaryExpressionNode equality = new BinaryExpressionNode(and); - equality.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - equality.setLeftChild(a); - TerminalNode b = new TerminalNode(equality); - b.setValue("b"); - equality.setRightChild(b); - or.setRightChild(equality); - BinaryExpressionNode equality2 = new BinaryExpressionNode(and); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality2); - Key<String> cKey = new Key<>(Key.AGENT_ID.getName()); - c.setValue(cKey); - equality2.setLeftChild(c); - UnfinishedValueNode patch1 = new UnfinishedValueNode(); - patch1.setParameterIndex(0); - patch1.setLHS(false); - patch1.setType(String.class); - TerminalNode d = new TerminalNode(equality2); - d.setValue(patch1); - equality2.setRightChild(d); - and.setLeftChild(equality2); - BinaryExpressionNode lessThan = new BinaryExpressionNode(and); - lessThan.setOperator(BinaryComparisonOperator.LESS_THAN); - UnfinishedValueNode patch = new UnfinishedValueNode(); - patch.setParameterIndex(1); - patch.setType(String.class); - patch.setLHS(true); - TerminalNode x = new TerminalNode(lessThan); - x.setValue(patch); - lessThan.setLeftChild(x); - UnfinishedValueNode patch2 = new UnfinishedValueNode(); - patch2.setLHS(false); - patch2.setParameterIndex(2); - patch2.setType(boolean.class); - TerminalNode y = new TerminalNode(lessThan); - y.setValue(patch2); - lessThan.setRightChild(y); - and.setRightChild(lessThan); - assertTrue(WhereExpressions.equals(where, suffixExpn.getWhereExpn())); - } - - @Test - public void testParseSimpleWithAnd() { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = ?s AND ?s = 'd'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - assertEquals(2, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getLimitExpn()); - assertNotNull(suffixExpn.getWhereExpn()); - // build the expected expression tree - WhereExpression where = new WhereExpression(); - BinaryExpressionNode and = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(and); - and.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode equality = new BinaryExpressionNode(and); - equality.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality); - @SuppressWarnings("rawtypes") - Key aKey = new Key("a"); - a.setValue(aKey); - equality.setLeftChild(a); - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setParameterIndex(0); - unfinished.setLHS(false); - unfinished.setType(String.class); - TerminalNode b = new TerminalNode(equality); - b.setValue(unfinished); - equality.setRightChild(b); - and.setLeftChild(equality); - BinaryExpressionNode equality2 = new BinaryExpressionNode(and); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality2); - UnfinishedValueNode patch1 = new UnfinishedValueNode(); - patch1.setParameterIndex(1); - patch1.setType(String.class); - patch1.setLHS(true); - c.setValue(patch1); - equality2.setLeftChild(c); - TerminalNode d = new TerminalNode(equality2); - d.setValue("d"); - equality2.setRightChild(d); - and.setRightChild(equality2); - assertTrue(WhereExpressions.equals(where, suffixExpn.getWhereExpn())); - } - - @Test - public void testParseSimpleWithNotOR() { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE NOT 'a' = ?s OR ?s = 'd'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - assertEquals(2, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getLimitExpn()); - assertNotNull(suffixExpn.getWhereExpn()); - // build the expected parse tree - WhereExpression expn = new WhereExpression(); - BinaryExpressionNode or = new BinaryExpressionNode(expn.getRoot()); - expn.getRoot().setValue(or); - or.setOperator(BinaryLogicalOperator.OR); - NotBooleanExpressionNode notNode = new NotBooleanExpressionNode(or); - BinaryExpressionNode comparison = new BinaryExpressionNode(notNode); - notNode.setValue(comparison); - or.setLeftChild(notNode); - comparison.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode rightCompTerm = new TerminalNode(comparison); - TerminalNode leftCompTerm = new TerminalNode(comparison); - @SuppressWarnings("rawtypes") - Key aKey = new Key("a"); - leftCompTerm.setValue(aKey); - UnfinishedValueNode patch1 = new UnfinishedValueNode(); - patch1.setParameterIndex(0); - patch1.setType(String.class); - patch1.setLHS(false); - rightCompTerm.setValue(patch1); - comparison.setLeftChild(leftCompTerm); - comparison.setRightChild(rightCompTerm); - BinaryExpressionNode otherComparison = new BinaryExpressionNode(or); - otherComparison.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode leftUnfinished = new TerminalNode(otherComparison); - UnfinishedValueNode patch2 = new UnfinishedValueNode(); - patch2.setParameterIndex(1); - patch2.setLHS(true); - patch2.setType(String.class); - leftUnfinished.setValue(patch2); - TerminalNode other = new TerminalNode(otherComparison); - other.setValue("d"); - otherComparison.setLeftChild(leftUnfinished); - otherComparison.setRightChild(other); - or.setRightChild(otherComparison); - assertTrue(WhereExpressions.equals(expn, suffixExpn.getWhereExpn())); - } - - @Test - public void testParseSimpleWithOr() { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = ?s OR ?s = 'd'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - assertEquals(2, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getLimitExpn()); - assertNotNull(suffixExpn.getWhereExpn()); - // build the expected parse tree - WhereExpression where = new WhereExpression(); - BinaryExpressionNode and = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(and); - and.setOperator(BinaryLogicalOperator.OR); - BinaryExpressionNode equality = new BinaryExpressionNode(and); - equality.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(equality); - @SuppressWarnings("rawtypes") - Key aKey = new Key("a"); - a.setValue(aKey); - equality.setLeftChild(a); - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setParameterIndex(0); - unfinished.setType(String.class); - unfinished.setLHS(false); - TerminalNode b = new TerminalNode(equality); - b.setValue(unfinished); - equality.setRightChild(b); - and.setLeftChild(equality); - BinaryExpressionNode equality2 = new BinaryExpressionNode(and); - equality2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode c = new TerminalNode(equality2); - UnfinishedValueNode patch1 = new UnfinishedValueNode(); - patch1.setParameterIndex(1); - patch1.setType(String.class); - patch1.setLHS(true); - c.setValue(patch1); - equality2.setLeftChild(c); - TerminalNode d = new TerminalNode(equality2); - d.setValue("d"); - equality2.setRightChild(d); - and.setRightChild(equality2); - assertTrue(WhereExpressions.equals(where, suffixExpn.getWhereExpn())); - } - - @Test - public void testParseSimpleWithLimit() { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT 1"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - assertEquals(0, statement.getNumParams()); - assertEquals(mockQuery.getClass().getName(), statement.getRawStatement().getClass().getName()); - SuffixExpression suffixExpn = statement.getSuffixExpression(); - assertNull(suffixExpn.getSortExpn()); - assertNull(suffixExpn.getWhereExpn()); - assertNotNull(suffixExpn.getLimitExpn()); - assertEquals(1, suffixExpn.getLimitExpn().getValue()); - } - - @Test - public void testParseAddBasic() throws DescriptorParsingException { - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = 'b' , 'c' = ?s"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - assertTrue(statement.getRawStatement() instanceof Add); - SuffixExpression suffix = statement.getSuffixExpression(); - assertNotNull(suffix); - WhereExpression where = suffix.getWhereExpn(); - LimitExpression limit = suffix.getLimitExpn(); - SortExpression sort = suffix.getSortExpn(); - assertNull(where); - assertNull(limit); - assertNull(sort); - SetList setList = statement.getSetList(); - assertNotNull(setList); - List<SetListValue> valuesList = setList.getValues(); - assertEquals(2, valuesList.size()); - SetListValue first = valuesList.get(0); - SetListValue second = valuesList.get(1); - TerminalNode a = new TerminalNode(null); - a.setValue(new Key<>("a")); - TerminalNode b = new TerminalNode(null); - b.setValue("b"); - SetListValue firstExpected = new SetListValue(); - firstExpected.setKey(a); - firstExpected.setValue(b); - assertEquals(firstExpected, first); - TerminalNode c = new TerminalNode(null); - c.setValue(new Key<>("c")); - UnfinishedValueNode dVal = new UnfinishedValueNode(); - dVal.setType(String.class); - dVal.setLHS(false); - dVal.setParameterIndex(0); - TerminalNode d = new TerminalNode(null); - d.setValue(dVal); - SetListValue secondExpected = new SetListValue(); - secondExpected.setKey(c); - secondExpected.setValue(d); - assertEquals(secondExpected, second); - } - - @Test - public void testParseUpdateBasic() throws DescriptorParsingException { - String descString = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = 'b' , 'c' = ?s WHERE 'foo' != ?i"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - ParsedStatementImpl<AgentInformation> statement = null; - try { - statement = (ParsedStatementImpl<AgentInformation>)parser.parse(); - } catch (DescriptorParsingException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - assertTrue(statement.getRawStatement() instanceof Update); - SuffixExpression suffix = statement.getSuffixExpression(); - assertNotNull(suffix); - WhereExpression where = suffix.getWhereExpn(); - LimitExpression limit = suffix.getLimitExpn(); - SortExpression sort = suffix.getSortExpn(); - assertNotNull(where); - assertNull(limit); - assertNull(sort); - SetList setList = statement.getSetList(); - assertNotNull(setList); - List<SetListValue> valuesList = setList.getValues(); - assertEquals(2, valuesList.size()); - SetListValue first = valuesList.get(0); - SetListValue second = valuesList.get(1); - TerminalNode a = new TerminalNode(null); - a.setValue(new Key<>("a")); - TerminalNode b = new TerminalNode(null); - b.setValue("b"); - SetListValue firstExpected = new SetListValue(); - firstExpected.setKey(a); - firstExpected.setValue(b); - assertEquals(firstExpected, first); - TerminalNode c = new TerminalNode(null); - c.setValue(new Key<>("c")); - UnfinishedValueNode dVal = new UnfinishedValueNode(); - dVal.setType(String.class); - dVal.setLHS(false); - dVal.setParameterIndex(0); - TerminalNode d = new TerminalNode(null); - d.setValue(dVal); - SetListValue secondExpected = new SetListValue(); - secondExpected.setKey(c); - secondExpected.setValue(d); - assertEquals(secondExpected, second); - // Build expected where expn - WhereExpression expectedWhere = new WhereExpression(); - BinaryExpressionNode equality = new BinaryExpressionNode(expectedWhere.getRoot()); - expectedWhere.getRoot().setValue(equality); - equality.setOperator(BinaryComparisonOperator.NOT_EQUAL_TO); - TerminalNode foo = new TerminalNode(equality); - @SuppressWarnings("rawtypes") - Key fooKey = new Key("foo"); - foo.setValue(fooKey); - equality.setLeftChild(foo); - TerminalNode fooVal = new TerminalNode(equality); - UnfinishedValueNode node = new UnfinishedValueNode(); - node.setParameterIndex(1); - node.setLHS(false); - node.setType(int.class); - fooVal.setValue(node); - equality.setRightChild(fooVal); - assertTrue(WhereExpressions.equals(expectedWhere, where)); - } - - // TODO: Add basic parse tests for REMOVE/REPLACE - - @Test - public void rejectLongValAsIntType() throws DescriptorParsingException { - // 30000000003 > Integer.MAX_VALUE; needs to be preceded by 'l/L' - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' != 30000000003"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Illegal terminal type.")); - } - } - - @Test - public void rejectLimitWhichIsNotInt() { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT illegal"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - assertEquals("Invalid limit expression. 'illegal' not an integer", e.getMessage()); - } - } - - @Test - public void rejectLHSnotString() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE a < 1"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Expected string value. Got term ->a<-")); - } - } - - @Test - public void rejectSpaceInQueryCountParam() { - String descFormat = "QUERY-COUNT(' a) %s"; - String expnMsg = "Unknown statement type: 'QUERY-COUNT(''"; - runRejectQueryCountTest(descFormat, expnMsg); - } - - @Test - public void rejectSpaceInQueryCountParam2() { - String descFormat = "QUERY-COUNT(Abc ) %s"; - String expnMsg = "Unknown statement type: 'QUERY-COUNT(Abc'"; - runRejectQueryCountTest(descFormat, expnMsg); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void runRejectQueryCountTest(String descFormat, String expnMsg) { - AggregateQuery<AggregateCount> query = mock(AggregateQuery.class); - ArgumentCaptor<Category> captor = ArgumentCaptor.forClass(Category.class); - when(storage.createAggregateQuery(eq(AggregateFunction.COUNT), captor.capture())).thenReturn(query); - // first adapt from the target category in order to be able to produce the - // right aggregate query with a different result type. - CategoryAdapter<AgentInformation, AggregateCount> adapter = new CategoryAdapter<>(AgentInfoDAO.CATEGORY); - Category<AggregateCount> aggregateCategory = adapter.getAdapted(AggregateCount.class); - String descrString = String.format(descFormat, aggregateCategory.getName()); - StatementDescriptor<AggregateCount> desc = new StatementDescriptor<>(aggregateCategory, descrString); - BasicDescriptorParser<AggregateCount> parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("shouldn't have parsed correctly"); - } catch (DescriptorParsingException e) { - assertTrue(e.getMessage().contains(expnMsg)); - } - } - - - /* - * At this point list types don't make sense in WHERE. - * What should "'a' != [ 'a', 'b' ]" evaluate to? - * How about this? "'key' > [ 1, 2 ]" - * - * The only reasonable use case in WHERE would be 'a' IN [ 'a', 'b' ... ]. - * We don't support this in a prepared context at this point. Should this - * change in future, this test needs to be carefully re-crafted. - */ - @SuppressWarnings("unchecked") - @Test - public void rejectListTypesAsFreeVarInInvalidContext() throws DescriptorParsingException { - List<String> illegalDescs = new ArrayList<>(); - - // Where should not support list types/Pojos. - String[] illegalWheres = new String[] { - " WHERE 'a' = ?s[", - " WHERE 'a' = ?i[", - " WHERE 'a' = ?p[", - " WHERE 'a' = ?d[", - }; - - // Make sure we test for QUERY, QUERY-COUNT, QUERY-DISTINCT, REPLACE, UPDATE, REMOVE - // i.e. all that accept a WHERE. - String basicQuery = "QUERY " + AgentInfoDAO.CATEGORY.getName(); - String basicQueryCount = "QUERY-COUNT " + AgentInfoDAO.CATEGORY.getName(); - String basicQueryDistinct = "QUERY-DISTINCT(foo) " + AgentInfoDAO.CATEGORY.getName(); - when(storage.createAggregateQuery(eq(AggregateFunction.COUNT), eq(AgentInfoDAO.CATEGORY))).thenReturn(mock(AggregateQuery.class)); - when(storage.createAggregateQuery(eq(AggregateFunction.DISTINCT), eq(AgentInfoDAO.CATEGORY))).thenReturn(mock(AggregateQuery.class)); - // note SET clause is legal - String basicUpdate = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?s["; - // note SET clause is legal - String basicReplace = "REPLACE " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = ?i["; - String basicRemove = "REMOVE " + AgentInfoDAO.CATEGORY.getName(); - for (String where: illegalWheres) { - illegalDescs.add(basicQuery + where); - illegalDescs.add(basicQueryCount + where); - illegalDescs.add(basicQueryDistinct + where); - illegalDescs.add(basicUpdate + where); - illegalDescs.add(basicReplace + where); - illegalDescs.add(basicRemove + where); - } - - // Test all illegal descs involving WHERE - doIllegalDescsTest(illegalDescs, "WHERE", "List"); - - // Test limit too - illegalDescs.clear(); - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT ?i["); - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT ?s["); - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT ?p["); - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT ?d["); - - doIllegalDescsTest(illegalDescs, "LIMIT", "List"); - - // Test sort - illegalDescs.clear(); - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " SORT ?i[ ASC"); - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " SORT ?s[ ASC"); - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " SORT ?p[ ASC"); - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " SORT ?d[ ASC"); - - doIllegalDescsTest(illegalDescs, "SORT", "List"); - } - - /* - * Pojos don't make sense in a WHERE, LIMIT and SORT clause. This test makes - * sure we reject this right away. - * - */ - @Test - public void rejectPojoTypesAsFreeVarInInvalidContext() throws DescriptorParsingException { - List<String> illegalDescs = new ArrayList<>(); - - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = ?p"); - doIllegalDescsTest(illegalDescs, "WHERE", "Pojo"); - illegalDescs.clear(); - - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT ?p"); - doIllegalDescsTest(illegalDescs, "LIMIT", "Pojo"); - illegalDescs.clear(); - - illegalDescs.add("QUERY " + AgentInfoDAO.CATEGORY.getName() + " SORT ?p DSC"); - doIllegalDescsTest(illegalDescs, "SORT", "Pojo"); - } - - private void doIllegalDescsTest(List<String> descs, String errorMsgContext, String type) { - for (String strDesc : descs) { - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail(strDesc + " should not parse"); - } catch (DescriptorParsingException e) { - // pass - assertEquals(strDesc + " did not provide correct error message.", - type + " free variable type not allowed in " + errorMsgContext + " context", e.getMessage()); - } - } - } - - @Test - public void rejectIllegalFreeParamType() throws DescriptorParsingException { - // ? should be one of '?i', '?l', '?s', '?b', '?s[' - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE ? < 1"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - assertEquals("Unknown type of free parameter: '?'", e.getMessage()); - } - } - - @Test - public void rejectParseQueryWhereAndSortMultipleIllegalSortModifier() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'somekey' < 2 AND 'c' = ?s OR 'a' >= ?i SORT 'a' ASC , 'b' ILLEGAL , 'c' ASC"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Expected ASC or DSC")); - } - } - - @Test - public void rejectParseQueryWhereBoolTerm() throws DescriptorParsingException { - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE true AND false"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - } - } - - @Test - public void rejectQueryWithParenthesis() throws DescriptorParsingException { - // We don't allow parenthesized expressions. This is due to mongodb not - // allowing this. - String descrString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE NOT ( 'a' = 'b' AND 'c' = 'd' )"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - } - } - - @Test - public void rejectSimpleQueryWithMissingSpaces() throws DescriptorParsingException { - // we require a space before every operator/keyword - String descrString = "QUERY " + AgentInfoDAO.CATEGORY + " WHERE " + "'a'='b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - } - } - - @Test - public void rejectSimpleQueryWithMissingSpaces2() throws DescriptorParsingException { - // we require a space before every operator/keyword - String descrString = "QUERY " + AgentInfoDAO.CATEGORY + " WHERE " + "'a' ='b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - } - } - - @Test - public void rejectSimpleQueryWithInvalidComparison() throws DescriptorParsingException { - // <> is illegal - String descrString = "QUERY " + AgentInfoDAO.CATEGORY + " WHERE " + "'a' <> 'b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descrString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("should not parse"); - } catch (DescriptorParsingException e) { - // pass - } - } - - @Test - public void rejectInvalidDescriptorStringBadWhere() throws DescriptorParsingException { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " where '" + Key.AGENT_ID.getName() + "'= ?s"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("lower case where not allowed in descriptor. Should have rejected."); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Unexpected token: 'where'")); - } - } - - @Test - public void rejectInvalidDescriptorStringBadStatementType() throws DescriptorParsingException { - String descString = "UNKNOWN some-unknown-category WHERE 1 = ?i"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("UNKNOWN not a valid statement type"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Unknown statement type")); - } - } - - @Test - public void rejectInvalidDescriptorStringCategoryMismatch() throws DescriptorParsingException { - String descString = "QUERY some-unknown-category WHERE 1 = ?i"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("category names in descriptor and Category object did not match!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Category mismatch")); - } - } - - @Test - public void rejectInvalidDescriptorStringBadSortNoArg() throws DescriptorParsingException { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE 'a' = ?i SORT"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("category names in descriptor and Category object did not match!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Invalid where clause")); - } - } - - @Test - public void rejectInvalidDescriptorStringBadWhereNoArg() throws DescriptorParsingException { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " WHERE SORT"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("category names in descriptor and Category object did not match!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("SORT")); - assertTrue(e.getMessage().contains("Expected string value")); - } - } - - @Test - public void rejectAddWithInvalidSetList() throws DescriptorParsingException { - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = , 'c' = 'd'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("Invalid SET values list."); - } catch (DescriptorParsingException e) { - // pass - assertEquals("Illegal terminal type. Token was ->,<-", e.getMessage()); - } - } - - @SuppressWarnings("unchecked") - @Test - public void testCompatibilityNonAggregateQuery() throws DescriptorParsingException { - when(storage.createAggregateQuery(any(AggregateFunction.class), any(Category.class))).thenReturn(mock(AggregateQuery.class)); - String descString = "QUERY-COUNT(foo) " + AgentInfoDAO.CATEGORY.getName(); - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new BasicDescriptorParser<>(storage, desc); - try { - parser.parse(); - // pass - } catch (Exception e) { - e.printStackTrace(); - fail("Expected to parse even though createAggregateQuery returned a simple Query instance instead of AggregateQuery"); - } - } - -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/DescriptorParserImplFactory.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.Add; -import com.redhat.thermostat.storage.core.AggregateQuery; -import com.redhat.thermostat.storage.core.AggregateQuery.AggregateFunction; -import com.redhat.thermostat.storage.core.BackingStorage; -import com.redhat.thermostat.storage.core.Category; -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.StatementDescriptor; -import com.redhat.thermostat.storage.core.Update; -import com.redhat.thermostat.storage.model.Pojo; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/* - * NOTE class copied from storage-test-utils for internal testing of Statement - * Adapters - */ -class DescriptorParserImplFactory { - - <T extends Pojo> StatementDescriptorParser<T> getParser(ParserType type, StatementDescriptor<T> desc) { - switch (type) { - case BASIC: - return new BasicDescriptorParser<>(getBasicBackingStorage(), desc); - case SEMANTIC: - return new SemanticsEnabledDescriptorParser<>(getSemanticBackingStorage(), desc); - default: - throw new IllegalStateException("Not implemented"); - } - } - - private BackingStorage getBasicBackingStorage() { - return mock(BackingStorage.class); - } - - @SuppressWarnings("unchecked") - private BackingStorage getSemanticBackingStorage() { - BackingStorage storage = mock(BackingStorage.class); - when(storage.createAdd(any(Category.class))).thenReturn(mock(Add.class)); - when(storage.createUpdate(any(Category.class))).thenReturn(mock(Update.class)); - when(storage.createRemove(any(Category.class))).thenReturn(mock(Remove.class)); - when(storage.createReplace(any(Category.class))).thenReturn(mock(Replace.class)); - when(storage.createQuery(any(Category.class))).thenReturn(mock(Query.class)); - when(storage.createAggregateQuery(any(AggregateFunction.class), any(Category.class))).thenReturn(mock(AggregateQuery.class)); - return storage; - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/LimitExpressionTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -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 org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; - -public class LimitExpressionTest { - - private LimitExpression expn; - - @Before - public void setup() { - expn = new LimitExpression(); - UnfinishedLimitValue unfinished = new UnfinishedLimitValue(); - unfinished.setParameterIndex(0); - expn.setValue(unfinished); - } - - @Test - public void canPatchWithInt() { - PreparedParameter p = new PreparedParameter(); - p.setType(int.class); - p.setValue(3); - - PatchedLimitExpression pLimit = null; - try { - pLimit = expn.patch(new PreparedParameter[] { p }); - // pass - } catch (IllegalPatchException e) { - fail(e.getMessage()); - } - assertNotNull(pLimit); - assertEquals(3, pLimit.getLimitValue()); - } - - @Test - public void rejectPatchWithIntList() { - PreparedParameter p = new PreparedParameter(); - p.setType(int[].class); - p.setValue(new int[] { 3 }); - - try { - expn.patch(new PreparedParameter[] { p }); - fail("Should not be able to patch with int list"); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getMessage().contains("Invalid parameter type for limit expression.")); - } - } - - @Test - public void rejectPatchWithString() { - PreparedParameter p = new PreparedParameter(); - p.setType(String.class); - p.setValue("foo"); - - try { - expn.patch(new PreparedParameter[] { p }); - fail("Should not be able to patch with wrong type"); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getMessage().contains("Invalid parameter type for limit expression.")); - } - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/ParsedStatementImplTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,967 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.common.Pair; -import com.redhat.thermostat.storage.core.Add; -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.DataModifyingStatement; -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.core.Query; -import com.redhat.thermostat.storage.core.Query.SortDirection; -import com.redhat.thermostat.storage.core.Replace; -import com.redhat.thermostat.storage.core.Statement; -import com.redhat.thermostat.storage.core.Update; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.BinaryComparisonExpression; -import com.redhat.thermostat.storage.query.BinaryComparisonOperator; -import com.redhat.thermostat.storage.query.BinaryLogicalExpression; -import com.redhat.thermostat.storage.query.BinaryLogicalOperator; -import com.redhat.thermostat.storage.query.Expression; -import com.redhat.thermostat.storage.query.ExpressionFactory; -import com.redhat.thermostat.storage.query.LiteralExpression; - -public class ParsedStatementImplTest { - - private Query<Pojo> statement; - - @Before - public void setup() { - statement = new TestQuery(); - } - - @After - public void tearDown() { - statement = null; - } - - @Test - public void patchingDuplicatesStatement() throws IllegalPatchException { - @SuppressWarnings("unchecked") - Statement<Pojo> stmt = (Statement<Pojo>)mock(Statement.class); - @SuppressWarnings("unchecked") - Statement<Pojo> mock2 = mock(Statement.class); - when(stmt.getRawDuplicate()).thenReturn(mock2); - ParsedStatementImpl<Pojo> parsedStmt = new ParsedStatementImpl<>(stmt); - SuffixExpression suffixExpn = new SuffixExpression(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - parsedStmt.setSetList(new SetList()); - parsedStmt.setSuffixExpression(suffixExpn); - - Statement<Pojo> result = parsedStmt.patchStatement(new PreparedParameter[] {}); - assertNotSame("Statement should get duplicated on patching", stmt, result); - assertSame(mock2, result); - } - - @Test - public void canPatchWhereAndExpr() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - ParsedStatementImpl<Pojo> parsedStmt = new ParsedStatementImpl<>(statement); - SuffixExpression suffixExpn = new SuffixExpression(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - parsedStmt.setSetList(new SetList()); - // WHERE a = ? AND c = ? - WhereExpression expn = new WhereExpression(); - BinaryExpressionNode and = new BinaryExpressionNode(expn.getRoot()); - expn.getRoot().setValue(and); - and.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode leftEqual = new BinaryExpressionNode(and); - BinaryExpressionNode rightEqual = new BinaryExpressionNode(and); - leftEqual.setOperator(BinaryComparisonOperator.EQUALS); - rightEqual.setOperator(BinaryComparisonOperator.EQUALS); - and.setLeftChild(leftEqual); - and.setRightChild(rightEqual); - TerminalNode a = new TerminalNode(leftEqual); - Key<String> aKey = new Key<>("a"); - a.setValue(aKey); - TerminalNode b = new TerminalNode(leftEqual); - UnfinishedValueNode patchB = new UnfinishedValueNode(); - patchB.setParameterIndex(0); - patchB.setType(String.class); - b.setValue(patchB); - leftEqual.setLeftChild(a); - leftEqual.setRightChild(b); - TerminalNode c = new TerminalNode(rightEqual); - c.setValue("c"); - rightEqual.setLeftChild(c); - TerminalNode d = new TerminalNode(rightEqual); - UnfinishedValueNode dPatch = new UnfinishedValueNode(); - dPatch.setParameterIndex(1); - dPatch.setType(int.class); - d.setValue(dPatch); - rightEqual.setRightChild(d); - suffixExpn.setWhereExpn(expn); - parsedStmt.setNumFreeParams(1); - parsedStmt.setSuffixExpression(suffixExpn); - // next, create the PreparedStatement we are going to use for - // patching. - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(2); - preparedStatement.setString(0, "test1"); - preparedStatement.setInt(1, 2); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Query<Pojo> query = (Query<Pojo>)parsedStmt.patchStatement(params); - assertTrue(query instanceof TestQuery); - TestQuery q = (TestQuery)query; - Expression expectedExpression = q.expr; - assertTrue(expectedExpression instanceof BinaryLogicalExpression); - BinaryLogicalExpression<?, ?> andFinal = (BinaryLogicalExpression<?, ?>) expectedExpression; - assertEquals(BinaryLogicalOperator.AND, andFinal.getOperator()); - assertTrue(andFinal.getLeftOperand() instanceof BinaryComparisonExpression); - assertTrue(andFinal.getRightOperand() instanceof BinaryComparisonExpression); - BinaryComparisonExpression<?> left = (BinaryComparisonExpression<?>)andFinal.getLeftOperand(); - BinaryComparisonExpression<?> right = (BinaryComparisonExpression<?>)andFinal.getRightOperand(); - assertEquals(BinaryComparisonOperator.EQUALS, left.getOperator()); - assertEquals(BinaryComparisonOperator.EQUALS, right.getOperator()); - assertTrue(left.getLeftOperand() instanceof LiteralExpression); - assertTrue(left.getRightOperand() instanceof LiteralExpression); - LiteralExpression<?> leftLiteral1 = (LiteralExpression<?>)left.getLeftOperand(); - LiteralExpression<?> rightLiteral1 = (LiteralExpression<?>)left.getRightOperand(); - assertEquals(aKey, leftLiteral1.getValue()); - assertEquals("test1", rightLiteral1.getValue()); - LiteralExpression<?> leftLiteral2 = (LiteralExpression<?>)right.getLeftOperand(); - LiteralExpression<?> rightLiteral2 = (LiteralExpression<?>)right.getRightOperand(); - assertEquals("c", leftLiteral2.getValue()); - // right literal value should have been patched to a "d" - assertEquals(2, rightLiteral2.getValue()); - } - - @Test - public void canPatchBasicWhereEquals() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - ParsedStatementImpl<Pojo> parsedStmt = new ParsedStatementImpl<>(statement); - SuffixExpression suffixExpn = new SuffixExpression(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - parsedStmt.setSetList(new SetList()); - // WHERE a = ? - WhereExpression expn = new WhereExpression(); - BinaryExpressionNode and = new BinaryExpressionNode(expn.getRoot()); - expn.getRoot().setValue(and); - and.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(and); - a.setValue(new Key<>("a")); - TerminalNode b = new TerminalNode(and); - UnfinishedValueNode bPatch = new UnfinishedValueNode(); - bPatch.setParameterIndex(0); - bPatch.setType(boolean.class); - b.setValue(bPatch); - and.setLeftChild(a); - and.setRightChild(b); - suffixExpn.setWhereExpn(expn); - parsedStmt.setNumFreeParams(1); - parsedStmt.setSuffixExpression(suffixExpn); - // next, create the PreparedStatement we are going to use for - // patching. - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(1); - preparedStatement.setBoolean(0, true); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Query<?> query = (Query<?>)parsedStmt.patchStatement(params); - assertTrue(query instanceof TestQuery); - TestQuery q = (TestQuery)query; - Expression expectedExpression = q.expr; - assertTrue(expectedExpression instanceof BinaryComparisonExpression); - BinaryComparisonExpression<?> root = (BinaryComparisonExpression<?>)expectedExpression; - assertEquals(BinaryComparisonOperator.EQUALS, root.getOperator()); - assertTrue(root.getLeftOperand() instanceof LiteralExpression); - assertTrue(root.getRightOperand() instanceof LiteralExpression); - LiteralExpression<?> leftLiteral1 = (LiteralExpression<?>)root.getLeftOperand(); - LiteralExpression<?> rightLiteral1 = (LiteralExpression<?>)root.getRightOperand(); - assertEquals(new Key<>("a"), leftLiteral1.getValue()); - // this should have gotten patched to a "b" - assertEquals(true, rightLiteral1.getValue()); - // now do it again with a different value - preparedStatement = new PreparedStatementImpl<>(1); - preparedStatement.setBoolean(0, false); - params = preparedStatement.getParams(); - query = (Query<?>)parsedStmt.patchStatement(params); - assertTrue(query instanceof TestQuery); - q = (TestQuery)query; - expectedExpression = q.expr; - assertTrue(expectedExpression instanceof BinaryComparisonExpression); - root = (BinaryComparisonExpression<?>)expectedExpression; - assertEquals(BinaryComparisonOperator.EQUALS, root.getOperator()); - assertTrue(root.getLeftOperand() instanceof LiteralExpression); - assertTrue(root.getRightOperand() instanceof LiteralExpression); - leftLiteral1 = (LiteralExpression<?>)root.getLeftOperand(); - rightLiteral1 = (LiteralExpression<?>)root.getRightOperand(); - assertEquals(new Key<>("a"), leftLiteral1.getValue()); - assertEquals(false, rightLiteral1.getValue()); - } - - @Test - public void canPatchBasicWhereEqualsLHSKeyAndRHSValue() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - ParsedStatementImpl<Pojo> parsedStmt = new ParsedStatementImpl<>(statement); - SuffixExpression suffixExpn = new SuffixExpression(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - parsedStmt.setSetList(new SetList()); - // WHERE ?s = ?b - WhereExpression expn = new WhereExpression(); - BinaryExpressionNode and = new BinaryExpressionNode(expn.getRoot()); - expn.getRoot().setValue(and); - and.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(and); - UnfinishedValueNode aPatch = new UnfinishedValueNode(); - aPatch.setLHS(true); - aPatch.setType(String.class); - aPatch.setParameterIndex(0); - a.setValue(aPatch); - TerminalNode b = new TerminalNode(and); - UnfinishedValueNode bPatch = new UnfinishedValueNode(); - bPatch.setParameterIndex(1); - bPatch.setType(boolean.class); - b.setValue(bPatch); - and.setLeftChild(a); - and.setRightChild(b); - suffixExpn.setWhereExpn(expn); - parsedStmt.setNumFreeParams(1); - parsedStmt.setSuffixExpression(suffixExpn); - // next, create the PreparedStatement we are going to use for - // patching. - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(2); - preparedStatement.setString(0, "a"); - preparedStatement.setBoolean(1, true); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Query<?> query = (Query<?>)parsedStmt.patchStatement(params); - assertTrue(query instanceof TestQuery); - TestQuery q = (TestQuery)query; - Expression expectedExpression = q.expr; - assertTrue(expectedExpression instanceof BinaryComparisonExpression); - BinaryComparisonExpression<?> root = (BinaryComparisonExpression<?>)expectedExpression; - assertEquals(BinaryComparisonOperator.EQUALS, root.getOperator()); - assertTrue(root.getLeftOperand() instanceof LiteralExpression); - assertTrue(root.getRightOperand() instanceof LiteralExpression); - LiteralExpression<?> leftLiteral1 = (LiteralExpression<?>)root.getLeftOperand(); - LiteralExpression<?> rightLiteral1 = (LiteralExpression<?>)root.getRightOperand(); - assertEquals(new Key<>("a"), leftLiteral1.getValue()); - // this should have gotten patched to a "b" - assertEquals(true, rightLiteral1.getValue()); - // now do it again with a different value - preparedStatement = new PreparedStatementImpl<>(2); - preparedStatement.setString(0, "a"); - preparedStatement.setBoolean(1, false); - params = preparedStatement.getParams(); - query = (Query<?>)parsedStmt.patchStatement(params); - assertTrue(query instanceof TestQuery); - q = (TestQuery)query; - expectedExpression = q.expr; - assertTrue(expectedExpression instanceof BinaryComparisonExpression); - root = (BinaryComparisonExpression<?>)expectedExpression; - assertEquals(BinaryComparisonOperator.EQUALS, root.getOperator()); - assertTrue(root.getLeftOperand() instanceof LiteralExpression); - assertTrue(root.getRightOperand() instanceof LiteralExpression); - leftLiteral1 = (LiteralExpression<?>)root.getLeftOperand(); - rightLiteral1 = (LiteralExpression<?>)root.getRightOperand(); - assertEquals(new Key<>("a"), leftLiteral1.getValue()); - assertEquals(false, rightLiteral1.getValue()); - } - - @Test - public void canPatchBasicLimit() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - ParsedStatementImpl<Pojo> parsedStmt = new ParsedStatementImpl<>(statement); - parsedStmt.setSetList(new SetList()); - SuffixExpression suffixExpn = new SuffixExpression(); - LimitExpression limitExpnToPatch = new LimitExpression(); - UnfinishedLimitValue unfinished = new UnfinishedLimitValue(); - unfinished.setParameterIndex(0); - limitExpnToPatch.setValue(unfinished); - suffixExpn.setLimitExpn(limitExpnToPatch); - suffixExpn.setSortExpn(null); - suffixExpn.setWhereExpn(null); - parsedStmt.setSuffixExpression(suffixExpn); - // set the value for the one unfinished param - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(1); - preparedStatement.setInt(0, 3); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Query<?> query = (Query<?>)parsedStmt.patchStatement(params); - assertTrue(query instanceof TestQuery); - TestQuery q = (TestQuery)query; - assertEquals(3, q.limitVal); - } - - private SetList buildSetList() { - // Build this set list, which corresponds to the TestPojo below - // SET 'writerId' = ?s , 'fooTimeStamp' = ?l - SetList setList = new SetList(); - SetListValue writerId = new SetListValue(); - TerminalNode writerKey = new TerminalNode(null); - writerKey.setValue(new Key<>("writerId")); - TerminalNode writerValue = new TerminalNode(null); - UnfinishedValueNode unfinishedWriter = new UnfinishedValueNode(); - unfinishedWriter.setParameterIndex(0); - unfinishedWriter.setType(String.class); - unfinishedWriter.setLHS(false); - writerValue.setValue(unfinishedWriter); - writerId.setKey(writerKey); - writerId.setValue(writerValue); - setList.addValue(writerId); - SetListValue fooTimeStamp = new SetListValue(); - TerminalNode timeStampKey = new TerminalNode(null); - timeStampKey.setValue(new Key<>("fooTimeStamp")); - fooTimeStamp.setKey(timeStampKey); - TerminalNode timeStampVal = new TerminalNode(null); - UnfinishedValueNode timeStampUnfinished = new UnfinishedValueNode(); - timeStampUnfinished.setLHS(false); - timeStampUnfinished.setParameterIndex(1); - timeStampUnfinished.setType(long.class); - timeStampVal.setValue(timeStampUnfinished); - fooTimeStamp.setValue(timeStampVal); - setList.addValue(fooTimeStamp); - return setList; - } - - /* - * Test for patching of: - * "ADD something SET 'writerId' = ?s, 'fooTimeStamp' = ?l" - */ - @Test - public void canPatchBasicSetListAdd() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - DataModifyingStatement<TestPojo> stmt = new TestAdd<>(); - ParsedStatementImpl<TestPojo> parsedStmt = new ParsedStatementImpl<>(stmt); - SuffixExpression suffixExpn = new SuffixExpression(); - SetList setList = buildSetList(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - suffixExpn.setWhereExpn(null); - parsedStmt.setSuffixExpression(suffixExpn); - assertEquals(2, setList.getValues().size()); - parsedStmt.setSetList(setList); - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(2); - preparedStatement.setString(0, "foo-writer"); - preparedStatement.setLong(1, Long.MAX_VALUE); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Add<TestPojo> add = (Add<TestPojo>)parsedStmt.patchStatement(params); - assertTrue(add instanceof TestAdd); - TestAdd<TestPojo> q = (TestAdd<TestPojo>)add; - Map<String, Object> vals = q.values; - assertEquals(2, vals.keySet().size()); - assertEquals("foo-writer", vals.get("writerId")); - assertEquals(Long.MAX_VALUE, vals.get("fooTimeStamp")); - } - - /* - * Test for patching of: - * "ADD something SET 'someList' = ?p[" - */ - @Test - public void canPatchSetListAddWithPojoList() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - DataModifyingStatement<FancyPojo> stmt = new TestAdd<>(); - ParsedStatementImpl<FancyPojo> parsedStmt = new ParsedStatementImpl<>(stmt); - SuffixExpression suffixExpn = new SuffixExpression(); - SetList setList = new SetList(); - parsedStmt.setSetList(setList); - TerminalNode someProperty = new TerminalNode(null); - someProperty.setValue(new Key<>("someList")); - TerminalNode somePropertyVal = new TerminalNode(null); - UnfinishedValueNode unfinishedPojoList = new UnfinishedValueNode(); - unfinishedPojoList.setLHS(false); - unfinishedPojoList.setType(Pojo[].class); - unfinishedPojoList.setParameterIndex(0); - somePropertyVal.setValue(unfinishedPojoList); - SetListValue value = new SetListValue(); - value.setKey(someProperty); - value.setValue(somePropertyVal); - setList.addValue(value); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - suffixExpn.setWhereExpn(null); - parsedStmt.setSuffixExpression(suffixExpn); - assertEquals(1, setList.getValues().size()); - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(1); - TestPojo elem1 = new TestPojo(); - elem1.setFooTimeStamp(-300); - elem1.setWriterId("elem1"); - TestPojo elem2 = new TestPojo(); - elem2.setFooTimeStamp(-301); - elem2.setWriterId("elem2"); - TestPojo[] elems = new TestPojo[] { - elem1, elem2 - }; - preparedStatement.setPojoList(0, elems); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Add<FancyPojo> add = (Add<FancyPojo>)parsedStmt.patchStatement(params); - assertTrue(add instanceof TestAdd); - TestAdd<FancyPojo> q = (TestAdd<FancyPojo>)add; - Map<String, Object> vals = q.values; - assertEquals(1, vals.keySet().size()); - assertEquals(null, vals.get("writerId")); - assertNotNull(vals.get("someList")); - Object someList = vals.get("someList"); - assertTrue(someList instanceof TestPojo[]); - TestPojo[] tPojo = (TestPojo[])someList; - assertEquals(2, tPojo.length); - TestPojo first = tPojo[0]; - TestPojo second = tPojo[1]; - assertEquals(elem1, first); - assertEquals(elem2, second); - assertEquals("elem1", first.getWriterId()); - assertEquals(-300, first.getFooTimeStamp()); - assertEquals("elem2", second.getWriterId()); - assertEquals(-301, second.getFooTimeStamp()); - } - - /* - * Test for patching of: - * "REPLACE something SET ?s = 'foo-bar', 'fooTimeStamp' = ?l WHERE 'foo' = ?i" - */ - @Test - public void canPatchBasicSetListReplace() throws IllegalPatchException { - DataModifyingStatement<TestPojo> stmt = new TestReplace(); - ParsedStatementImpl<TestPojo> parsedStmt = new ParsedStatementImpl<>(stmt); - SuffixExpression suffixExpn = new SuffixExpression(); - - // Build this set list, which corresponds to the TestPojo below - // SET ?s = 'foo-bar' , 'fooTimeStamp' = ?l - SetList setList = new SetList(); - SetListValue writerId = new SetListValue(); - TerminalNode writerKey = new TerminalNode(null); - UnfinishedValueNode unfinishedWriterKey = new UnfinishedValueNode(); - unfinishedWriterKey.setParameterIndex(0); - unfinishedWriterKey.setType(String.class); - unfinishedWriterKey.setLHS(true); - writerKey.setValue(unfinishedWriterKey); - writerId.setKey(writerKey); - TerminalNode writerValue = new TerminalNode(null); - writerValue.setValue("foo-bar"); - writerId.setValue(writerValue); - setList.addValue(writerId); - SetListValue fooTimeStamp = new SetListValue(); - TerminalNode timeStampKey = new TerminalNode(null); - timeStampKey.setValue(new Key<>("fooTimeStamp")); - fooTimeStamp.setKey(timeStampKey); - TerminalNode timeStampVal = new TerminalNode(null); - UnfinishedValueNode timeStampUnfinished = new UnfinishedValueNode(); - timeStampUnfinished.setLHS(false); - timeStampUnfinished.setParameterIndex(1); - timeStampUnfinished.setType(long.class); - timeStampVal.setValue(timeStampUnfinished); - fooTimeStamp.setValue(timeStampVal); - setList.addValue(fooTimeStamp); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - - // WHERE 'foo' = ?i - WhereExpression where = new WhereExpression(); - BinaryExpressionNode equals = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(equals); - equals.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode fooPatch = new TerminalNode(equals); - UnfinishedValueNode patch2 = new UnfinishedValueNode(); - patch2.setLHS(false); - patch2.setType(int.class); - patch2.setParameterIndex(2); - fooPatch.setValue(patch2); - TerminalNode foo = new TerminalNode(equals); - foo.setValue(new Key<>("foo")); - equals.setLeftChild(foo); - equals.setRightChild(fooPatch); - suffixExpn.setWhereExpn(where); - - parsedStmt.setSuffixExpression(suffixExpn); - assertEquals(2, setList.getValues().size()); - parsedStmt.setSetList(setList); - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(3); - preparedStatement.setString(0, "writerId"); - preparedStatement.setLong(1, Long.MAX_VALUE); - preparedStatement.setInt(2, -400); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Replace<TestPojo> replace = (Replace<TestPojo>)parsedStmt.patchStatement(params); - assertTrue(replace instanceof TestReplace); - TestReplace q = (TestReplace)replace; - Map<String, Object> vals = q.values; - assertEquals(2, vals.keySet().size()); - assertEquals("foo-bar", vals.get("writerId")); - assertEquals(Long.MAX_VALUE, vals.get("fooTimeStamp")); - - ExpressionFactory factory = new ExpressionFactory(); - Expression expectedExpression = factory.equalTo(new Key<>("foo"), -400); - assertEquals(expectedExpression, q.where); - } - - /* - * Test for patching of: - * "UPDATE something SET 'writerId' = ?s WHERE 'foo' = ?i" - */ - @Test - public void canPatchBasicSetListUpdate() throws IllegalPatchException { - DataModifyingStatement<TestPojo> stmt = new TestUpdate(); - ParsedStatementImpl<TestPojo> parsedStmt = new ParsedStatementImpl<>(stmt); - SuffixExpression suffixExpn = new SuffixExpression(); - - // Build this set list, which corresponds to the TestPojo below - // SET 'writerId' = ?s - SetList setList = new SetList(); - SetListValue writerId = new SetListValue(); - TerminalNode writerKey = new TerminalNode(null); - writerKey.setValue(new Key<>("writerId")); - TerminalNode writerValue = new TerminalNode(null); - UnfinishedValueNode unfinishedWriterValue = new UnfinishedValueNode(); - unfinishedWriterValue.setParameterIndex(0); - unfinishedWriterValue.setType(String.class); - unfinishedWriterValue.setLHS(false); - writerValue.setValue(unfinishedWriterValue); - writerId.setKey(writerKey); - writerId.setValue(writerValue); - setList.addValue(writerId); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - - // WHERE 'foo' = ?i - WhereExpression where = new WhereExpression(); - BinaryExpressionNode equals = new BinaryExpressionNode(where.getRoot()); - where.getRoot().setValue(equals); - equals.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode fooPatch = new TerminalNode(equals); - UnfinishedValueNode patch2 = new UnfinishedValueNode(); - patch2.setLHS(false); - patch2.setType(int.class); - patch2.setParameterIndex(1); - fooPatch.setValue(patch2); - TerminalNode foo = new TerminalNode(equals); - foo.setValue(new Key<>("foo")); - equals.setLeftChild(foo); - equals.setRightChild(fooPatch); - suffixExpn.setWhereExpn(where); - - parsedStmt.setSuffixExpression(suffixExpn); - assertEquals(1, setList.getValues().size()); - parsedStmt.setSetList(setList); - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(2); - preparedStatement.setString(0, "foobar-writer-id"); - preparedStatement.setInt(1, -400); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Update<TestPojo> replace = (Update<TestPojo>)parsedStmt.patchStatement(params); - assertTrue(replace instanceof TestUpdate); - TestUpdate q = (TestUpdate)replace; - List<Pair<Object, Object>> updates = q.updates; - assertEquals(1, updates.size()); - Pair<Object, Object> update = updates.get(0); - assertEquals("writerId", update.getFirst()); - assertEquals("foobar-writer-id", update.getSecond()); - - ExpressionFactory factory = new ExpressionFactory(); - Expression expectedExpression = factory.equalTo(new Key<>("foo"), -400); - assertEquals(expectedExpression, q.where); - } - - @Test - public void canPatchBasicSort() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - ParsedStatementImpl<Pojo> parsedStmt = new ParsedStatementImpl<>(statement); - parsedStmt.setSetList(new SetList()); - SuffixExpression suffixExpn = new SuffixExpression(); - // SORT ? ASC, b DSC - SortExpression sortExpn = new SortExpression(); - SortMember member = new SortMember(); - member.setDirection(SortDirection.ASCENDING); - UnfinishedSortKey unfinished = new UnfinishedSortKey(); - unfinished.setParameterIndex(0); - member.setSortKey(unfinished); - SortMember member2 = new SortMember(); - member2.setDirection(SortDirection.DESCENDING); - member2.setSortKey("b"); - sortExpn.addMember(member); - sortExpn.addMember(member2); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(sortExpn); - suffixExpn.setWhereExpn(null); - parsedStmt.setSuffixExpression(suffixExpn); - // set the value for the one unfinished param - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(1); - preparedStatement.setString(0, "a"); - PreparedParameter[] params = preparedStatement.getParams(); - // finally test the patching - Query<Pojo> query = (Query<Pojo>)parsedStmt.patchStatement(params); - assertTrue(query instanceof TestQuery); - TestQuery q = (TestQuery)query; - List<Pair<Key<?>, SortDirection>> actualSorts = q.sorts; - assertEquals(2, actualSorts.size()); - Pair<Key<?>, SortDirection> first = actualSorts.get(0); - Key<?> firstKeyActual = (Key<?>)first.getFirst(); - Key<?> expectedFirst = new Key<>("a"); - assertEquals(expectedFirst, firstKeyActual); - assertEquals(SortDirection.ASCENDING, first.getSecond()); - Pair<Key<?>, SortDirection> second = actualSorts.get(1); - Key<?> secondKeyActual = (Key<?>)second.getFirst(); - Key<?> expectedSecond = new Key<>("b"); - assertEquals(expectedSecond, secondKeyActual); - assertEquals(SortDirection.DESCENDING, second.getSecond()); - } - - @Test - public void failPatchSetListAddWrongType() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - DataModifyingStatement<TestPojo> stmt = new TestAdd<>(); - ParsedStatementImpl<TestPojo> parsedStmt = new ParsedStatementImpl<>(stmt); - SuffixExpression suffixExpn = new SuffixExpression(); - SetList setList = buildSetList(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - suffixExpn.setWhereExpn(null); - parsedStmt.setSuffixExpression(suffixExpn); - assertEquals(2, setList.getValues().size()); - parsedStmt.setSetList(setList); - // set the value for the one unfinished param - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(2); - preparedStatement.setLong(0, -1); - preparedStatement.setString(1, "foobar"); - PreparedParameter[] params = preparedStatement.getParams(); - // this should fail since types don't match - try { - parsedStmt.patchStatement(params); - fail("Should have failed to patch, due to type mismatch"); - } catch (IllegalPatchException e) { - assertTrue(e.getMessage().contains("Expected " + String.class.getName())); - // pass - } - } - - @Test - public void failPatchSetListAddInsufficientParams() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - DataModifyingStatement<TestPojo> stmt = new TestAdd<>(); - ParsedStatementImpl<TestPojo> parsedStmt = new ParsedStatementImpl<>(stmt); - SuffixExpression suffixExpn = new SuffixExpression(); - SetList setList = buildSetList(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - suffixExpn.setWhereExpn(null); - parsedStmt.setSuffixExpression(suffixExpn); - assertEquals(2, setList.getValues().size()); - parsedStmt.setSetList(setList); - // set the value for the one unfinished param - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(0); - PreparedParameter[] params = preparedStatement.getParams(); - // this should fail since types don't match - try { - parsedStmt.patchStatement(params); - fail("Should have failed to patch, due to type mismatch"); - } catch (IllegalPatchException e) { - // pass - } - } - - @Test - public void failPatchWithWrongType() throws IllegalPatchException { - // create the parsedStatementImpl we are going to use - ParsedStatementImpl<Pojo> parsedStmt = new ParsedStatementImpl<>(statement); - parsedStmt.setSetList(new SetList()); - SuffixExpression suffixExpn = new SuffixExpression(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - // WHERE 'a' = ?s AND 'c' = ?i - WhereExpression expn = new WhereExpression(); - BinaryExpressionNode and = new BinaryExpressionNode(expn.getRoot()); - expn.getRoot().setValue(and); - and.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode leftEqual = new BinaryExpressionNode(and); - BinaryExpressionNode rightEqual = new BinaryExpressionNode(and); - leftEqual.setOperator(BinaryComparisonOperator.EQUALS); - rightEqual.setOperator(BinaryComparisonOperator.EQUALS); - and.setLeftChild(leftEqual); - and.setRightChild(rightEqual); - TerminalNode a = new TerminalNode(leftEqual); - Key<?> aKey = new Key<>("a"); - a.setValue(aKey); - TerminalNode b = new TerminalNode(leftEqual); - UnfinishedValueNode patchB = new UnfinishedValueNode(); - patchB.setType(String.class); - patchB.setParameterIndex(0); - b.setValue(patchB); - leftEqual.setLeftChild(a); - leftEqual.setRightChild(b); - TerminalNode c = new TerminalNode(rightEqual); - Key<?> cKey = new Key<>("c"); - c.setValue(cKey); - rightEqual.setLeftChild(c); - TerminalNode d = new TerminalNode(rightEqual); - UnfinishedValueNode dPatch = new UnfinishedValueNode(); - dPatch.setParameterIndex(1); - dPatch.setType(Integer.class); - d.setValue(dPatch); - rightEqual.setRightChild(d); - suffixExpn.setWhereExpn(expn); - parsedStmt.setNumFreeParams(1); - parsedStmt.setSuffixExpression(suffixExpn); - // next, create the PreparedStatement we are going to use for - // patching. - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(2); - preparedStatement.setString(0, "test1"); - preparedStatement.setString(1, "foo"); - // finally test the patching - try { - PreparedParameter[] params = preparedStatement.getParams(); - parsedStmt.patchStatement(params); - fail("should have failed to patch param 1 with a string value (expected int)"); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getMessage().contains("invalid type when attempting to patch")); - } - } - - @Test - public void failPatchBasicEqualsIfIndexOutofBounds() { - // create the parsedStatementImpl we are going to use - ParsedStatementImpl<Pojo> parsedStmt = new ParsedStatementImpl<>(statement); - SuffixExpression suffixExpn = new SuffixExpression(); - suffixExpn.setLimitExpn(null); - suffixExpn.setSortExpn(null); - parsedStmt.setSetList(new SetList()); - // WHERE a = ? - WhereExpression expn = new WhereExpression(); - BinaryExpressionNode and = new BinaryExpressionNode(expn.getRoot()); - expn.getRoot().setValue(and); - and.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode a = new TerminalNode(and); - a.setValue("a"); - TerminalNode b = new TerminalNode(and); - UnfinishedValueNode bPatch = new UnfinishedValueNode(); - bPatch.setParameterIndex(1); // out of bounds - b.setValue(bPatch); - and.setLeftChild(a); - and.setRightChild(b); - suffixExpn.setWhereExpn(expn); - parsedStmt.setNumFreeParams(1); - parsedStmt.setSuffixExpression(suffixExpn); - PreparedStatementImpl<Pojo> preparedStatement = new PreparedStatementImpl<>(1); - preparedStatement.setString(0, "b"); - try { - PreparedParameter[] params = preparedStatement.getParams(); - // this should fail - parsedStmt.patchStatement(params); - fail("should not reach here"); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getCause() instanceof ArrayIndexOutOfBoundsException); - } - } - - private static class TestQuery implements Query<Pojo> { - - private Expression expr; - private List<Pair<Key<?>, SortDirection>> sorts; - private int limitVal = -1; - - private TestQuery() { - sorts = new ArrayList<>(); - } - - @Override - public void where(Expression expr) { - this.expr = expr; - } - - @Override - public void sort(Key<?> key, SortDirection direction) { - Pair<Key<?>, SortDirection> sortPair = new Pair<Key<?>, SortDirection>(key, direction); - sorts.add(sortPair); - } - - @Override - public void limit(int n) { - this.limitVal = n; - } - - @Override - public Cursor<Pojo> execute() { - // Not implemented - throw new AssertionError(); - } - - @Override - public Expression getWhereExpression() { - // Not implemented - throw new AssertionError(); - } - - @Override - public Statement<Pojo> getRawDuplicate() { - return new TestQuery(); - } - - } - - private static class TestAdd<T extends Pojo> implements Add<T> { - - private Map<String, Object> values = new HashMap<>(); - - @Override - public void set(String key, Object value) { - values.put(key, value); - } - - @Override - public int apply() { - // not implemented - throw new AssertionError(); - } - - @Override - public Statement<T> getRawDuplicate() { - return new TestAdd<>(); - } - - } - - private static class TestReplace implements Replace<TestPojo> { - - private Expression where; - private Map<String, Object> values = new HashMap<>(); - - @Override - public void set(String key, Object value) { - values.put(key, value); - } - - @Override - public void where(Expression expression) { - where = expression; - } - - @Override - public int apply() { - // not implemented - throw new AssertionError(); - } - - @Override - public Statement<TestPojo> getRawDuplicate() { - return new TestReplace(); - } - - } - - private static class TestUpdate implements Update<TestPojo> { - - private Expression where; - private List<Pair<Object, Object>> updates = new ArrayList<>(); - - @Override - public void where(Expression expr) { - this.where = expr; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public void set(String key, Object value) { - Pair update = new Pair<>(key, value); - updates.add(update); - } - - @Override - public int apply() { - // not implemented - throw new AssertionError(); - } - - @Override - public Statement<TestPojo> getRawDuplicate() { - return new TestUpdate(); - } - - } - - public static class TestPojo implements Pojo { - - private String writerId; - private long fooTimeStamp; - - public String getWriterId() { - return writerId; - } - public void setWriterId(String writerId) { - this.writerId = writerId; - } - public long getFooTimeStamp() { - return fooTimeStamp; - } - public void setFooTimeStamp(long fooTimeStamp) { - this.fooTimeStamp = fooTimeStamp; - } - - } - - public static class FancyPojo extends TestPojo { - - private TestPojo[] someList; - - public TestPojo[] getSomeList() { - return someList; - } - - public void setSomeList(TestPojo[] someList) { - this.someList = someList; - } - - - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/ParserType.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -/* - * NOTE class copied from storage-test-utils for internal testing - */ -public enum ParserType { - BASIC, - SEMANTIC -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/PreparedStatementImplTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,480 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; - -import com.redhat.thermostat.common.Pair; -import com.redhat.thermostat.storage.core.Add; -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.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.Statement; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.core.StatementExecutionException; -import com.redhat.thermostat.storage.core.Update; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.BinaryComparisonExpression; -import com.redhat.thermostat.storage.query.BinaryComparisonOperator; -import com.redhat.thermostat.storage.query.Expression; -import com.redhat.thermostat.storage.query.LiteralExpression; - -public class PreparedStatementImplTest { - - private static int counter = 0; - - /* - * Category names need to be unique. In order to prevent IllegalStateExceptions - * create a new category name each time this is called. - */ - private synchronized String getNextCategoryName() { - String name = "foo-table-" + counter; - counter++; - return name; - } - - @Test - public void failToSetIndexOutOfBounds() { - PreparedStatementImpl<?> preparedStatement = new PreparedStatementImpl<>(2); - preparedStatement.setInt(1, 3); - preparedStatement.setString(0, "testing"); - try { - preparedStatement.setLong(3, 1); - fail("should have thrown exception"); - } catch (IllegalArgumentException e) { - // pass - } - try { - preparedStatement.setInt(4, 1); - fail("should have thrown exception"); - } catch (IllegalArgumentException e) { - // pass - } - try { - preparedStatement.setString(10, "ignored"); - fail("should have thrown exception"); - } catch (IllegalArgumentException e) { - // pass - } - try { - preparedStatement.setStringList(3, new String[] { "ignored" }); - fail("should have thrown exception"); - } catch (IllegalArgumentException e) { - // pass - } - } - - @Test - public void canDoParsingPatchingAndExecutionQuery() throws Exception { - String categoryName = getNextCategoryName(); - String queryString = "QUERY " + categoryName + " WHERE 'a' = ?s"; - Category<FooPojo> fooCategory = new Category<>(categoryName, FooPojo.class, new Key<String>("a")); - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(fooCategory, queryString); - BackingStorage storage = mock(BackingStorage.class); - StubQuery<FooPojo> stmt = new StubQuery<>(); - when(storage.createQuery(fooCategory)).thenReturn(stmt); - PreparedStatementImpl<FooPojo> preparedStatement = new PreparedStatementImpl<>(storage, desc); - preparedStatement.setString(0, "foo"); - preparedStatement.executeQuery(); - assertTrue(stmt.called); - LiteralExpression<Key<String>> o1 = new LiteralExpression<>(new Key<String>("a")); - LiteralExpression<String> o2 = new LiteralExpression<>("foo"); - BinaryComparisonExpression<String> binComp = new BinaryComparisonExpression<>( - o1, BinaryComparisonOperator.EQUALS, o2); - assertEquals(binComp, stmt.expr); - } - - @Test - public void canDoParsingPatchingAndExecutionForAdd() throws Exception { - String categoryName = getNextCategoryName(); - String addString = "ADD " + categoryName +" SET 'foo' = ?s"; - Category<FooPojo> fooCategory = new Category<>(categoryName, FooPojo.class, new Key<String>("foo")); - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(fooCategory, addString); - BackingStorage storage = mock(BackingStorage.class); - TestAdd<FooPojo> add = new TestAdd<>(); - when(storage.createAdd(fooCategory)).thenReturn(add); - PreparedStatement<FooPojo> preparedStatement = new PreparedStatementImpl<FooPojo>(storage, desc); - preparedStatement.setString(0, "foo-val"); - assertFalse(add.executed); - try { - // this should call add.apply(); - preparedStatement.execute(); - } catch (StatementExecutionException e) { - fail(e.getMessage()); - } - assertFalse(add.values.isEmpty()); - assertTrue(add.executed); - assertEquals(1, add.values.keySet().size()); - assertEquals("foo-val", add.values.get("foo")); - } - - @Test - public void canDoParsingPatchingAndExecutionForAddInvolvingFancyPojo() throws Exception { - String categoryName = getNextCategoryName(); - String addString = "ADD " + categoryName + " SET 'fancyFoo' = ?p["; - Category<FancyFoo> fooCategory = new Category<>(categoryName, FancyFoo.class, new Key<String>("fancyFoo")); - StatementDescriptor<FancyFoo> desc = new StatementDescriptor<>(fooCategory, addString); - BackingStorage storage = mock(BackingStorage.class); - TestAdd<FancyFoo> add = new TestAdd<>(); - when(storage.createAdd(fooCategory)).thenReturn(add); - PreparedStatement<FancyFoo> preparedStatement = new PreparedStatementImpl<FancyFoo>(storage, desc); - FooPojo one = new FooPojo(); - one.setFoo("one"); - FooPojo two = new FooPojo(); - two.setFoo("two"); - FooPojo[] list = new FooPojo[] { - one, two - }; - preparedStatement.setPojoList(0, list); - assertFalse(add.executed); - try { - // this should call add.apply(); - preparedStatement.execute(); - } catch (StatementExecutionException e) { - fail(e.getMessage()); - } - assertFalse(add.values.isEmpty()); - assertEquals(1, add.values.keySet().size()); - assertTrue(add.executed); - FooPojo[] fancyFoo = (FooPojo[])add.values.get("fancyFoo"); - assertEquals(2, fancyFoo.length); - FooPojo first = fancyFoo[0]; - FooPojo second = fancyFoo[1]; - assertEquals("one", first.getFoo()); - assertEquals("two", second.getFoo()); - } - - @Test - public void canDoParsingPatchingAndExecutionForUpdate() throws Exception { - String categoryName = getNextCategoryName(); - String addString = "UPDATE " + categoryName + " SET 'foo' = ?s WHERE 'foo' = ?s"; - Category<FooPojo> fooCategory = new Category<>(categoryName, FooPojo.class, new Key<String>("foo")); - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(fooCategory, addString); - BackingStorage storage = mock(BackingStorage.class); - TestUpdate update = new TestUpdate(); - when(storage.createUpdate(fooCategory)).thenReturn(update); - PreparedStatement<FooPojo> preparedStatement = new PreparedStatementImpl<FooPojo>(storage, desc); - preparedStatement.setString(0, "foo-val"); - preparedStatement.setString(1, "nice"); - assertFalse(update.executed); - try { - // this should call apply(); - preparedStatement.execute(); - } catch (StatementExecutionException e) { - fail(e.getMessage()); - } - assertTrue(update.executed); - assertEquals(1, update.updates.size()); - Pair<String, Object> item = update.updates.get(0); - assertEquals("foo", item.getFirst()); - assertEquals("foo-val", item.getSecond()); - LiteralExpression<Key<String>> o1 = new LiteralExpression<>(new Key<String>("foo")); - LiteralExpression<String> o2 = new LiteralExpression<>("nice"); - BinaryComparisonExpression<String> binComp = new BinaryComparisonExpression<>( - o1, BinaryComparisonOperator.EQUALS, o2); - assertEquals(binComp, update.where); - } - - @Test - public void canDoParsingPatchingAndExecutionForReplace() throws Exception { - String categoryName = getNextCategoryName(); - String addString = "REPLACE " + categoryName + " SET 'foo' = ?s WHERE 'foo' = ?s"; - Category<FooPojo> fooCategory = new Category<>(categoryName, FooPojo.class, new Key<String>("foo")); - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(fooCategory, addString); - BackingStorage storage = mock(BackingStorage.class); - TestReplace<FooPojo> replace = new TestReplace<>(); - when(storage.createReplace(fooCategory)).thenReturn(replace); - PreparedStatement<FooPojo> preparedStatement = new PreparedStatementImpl<FooPojo>(storage, desc); - preparedStatement.setString(0, "foo-val"); - preparedStatement.setString(1, "bar"); - assertFalse(replace.executed); - try { - // this should call apply(); - preparedStatement.execute(); - } catch (StatementExecutionException e) { - fail(e.getMessage()); - } - assertFalse(replace.values.isEmpty()); - assertTrue(replace.executed); - assertEquals("foo-val", replace.values.get("foo")); - LiteralExpression<Key<String>> o1 = new LiteralExpression<>(new Key<String>("foo")); - LiteralExpression<String> o2 = new LiteralExpression<>("bar"); - BinaryComparisonExpression<String> binComp = new BinaryComparisonExpression<>( - o1, BinaryComparisonOperator.EQUALS, o2); - assertEquals(binComp, replace.where); - } - - @Test - public void canDoParsingPatchingAndExecutionForRemove() throws Exception { - String categoryName = getNextCategoryName(); - String addString = "REMOVE " + categoryName + " WHERE 'fooRem' = ?s"; - Category<FooPojo> fooCategory = new Category<>(categoryName, FooPojo.class, new Key<String>("foo")); - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(fooCategory, addString); - BackingStorage storage = mock(BackingStorage.class); - TestRemove<FooPojo> remove = new TestRemove<>(); - when(storage.createRemove(fooCategory)).thenReturn(remove); - PreparedStatement<FooPojo> preparedStatement = new PreparedStatementImpl<FooPojo>(storage, desc); - preparedStatement.setString(0, "bar"); - assertFalse(remove.executed); - try { - // this should call apply(); - preparedStatement.execute(); - } catch (StatementExecutionException e) { - fail(e.getMessage()); - } - assertTrue(remove.executed); - LiteralExpression<Key<String>> o1 = new LiteralExpression<>(new Key<String>("fooRem")); - LiteralExpression<String> o2 = new LiteralExpression<>("bar"); - BinaryComparisonExpression<String> binComp = new BinaryComparisonExpression<>( - o1, BinaryComparisonOperator.EQUALS, o2); - assertEquals(binComp, remove.where); - } - - @Test - public void failExecutionWithWronglyTypedParams() throws Exception { - String categoryName = getNextCategoryName(); - String queryString = "QUERY " + categoryName + " WHERE 'a' = ?b"; - Category<FooPojo> fooCategory = new Category<>(categoryName, FooPojo.class, new Key<String>("a")); - StatementDescriptor<FooPojo> desc = new StatementDescriptor<>(fooCategory, queryString); - BackingStorage storage = mock(BackingStorage.class); - StubQuery<FooPojo> stmt = new StubQuery<>(); - when(storage.createQuery(fooCategory)).thenReturn(stmt); - PreparedStatementImpl<FooPojo> preparedStatement = new PreparedStatementImpl<>(storage, desc); - preparedStatement.setString(0, "foo"); - try { - preparedStatement.executeQuery(); - fail("Should have thrown SEE due to type mismatch. boolean vs. string"); - } catch (StatementExecutionException e) { - // pass - assertTrue(e.getMessage().contains("invalid type when attempting to patch")); - } - } - - private static class TestAdd<T extends Pojo> implements Add<T> { - - private Map<String, Object> values = new HashMap<>(); - private boolean executed = false; - - @Override - public void set(String key, Object value) { - values.put(key, value); - } - - @Override - public int apply() { - executed = true; - return 0; - } - - @Override - public Statement<T> getRawDuplicate() { - // we don't duplicate for this test - return this; - } - - } - - private static class TestReplace<T extends Pojo> implements Replace<T> { - - private Map<String, Object> values = new HashMap<>(); - private boolean executed = false; - private Expression where; - - @Override - public void set(String key, Object value) { - values.put(key, value); - } - - @Override - public void where(Expression expression) { - this.where = expression; - } - - @Override - public int apply() { - this.executed = true; - return 0; - } - - @Override - public Statement<T> getRawDuplicate() { - // we don't duplicate for this test - return this; - } - - } - - private static class TestUpdate implements Update<FooPojo> { - - private Expression where; - private List<Pair<String, Object>> updates = new ArrayList<>(); - private boolean executed = false; - - @Override - public void where(Expression expr) { - this.where = expr; - } - - @Override - public void set(String key, Object value) { - Pair<String, Object> item = new Pair<>(key, value); - updates.add(item); - } - - @Override - public int apply() { - this.executed = true; - return 0; - } - - @Override - public Statement<FooPojo> getRawDuplicate() { - // we don't duplicate for this test - return this; - } - - } - - private static class TestRemove<T extends Pojo> implements Remove<T> { - - private Expression where; - private boolean executed = false; - - @Override - public void where(Expression where) { - this.where = where; - } - - @Override - public int apply() { - this.executed = true; - return 0; - } - - @Override - public Statement<T> getRawDuplicate() { - // we don't duplicate for this test - return this; - } - - } - - public static class FooPojo implements Pojo { - - String foo; - - public void setFoo(String foo) { - this.foo = foo; - } - - public String getFoo() { - return this.foo; - } - } - - public static class FancyFoo extends FooPojo { - - private FooPojo[] fancyFoo; - - public FooPojo[] getFancyFoo() { - return fancyFoo; - } - - public void setFancyFoo(FooPojo[] fancyFoo) { - this.fancyFoo = fancyFoo; - } - - } - - private static class StubQuery<T extends Pojo> implements Query<T> { - - private Expression expr; - private boolean called = false; - - @Override - public void where(Expression expr) { - this.expr = expr; - } - - @Override - public void sort(Key<?> key, SortDirection direction) { - // nothing - } - - @Override - public void limit(int n) { - // nothing - } - - @Override - public Cursor<T> execute() { - called = true; - return null; - } - - @Override - public Expression getWhereExpression() { - // not implemented - return null; - } - - @Override - public Statement<T> getRawDuplicate() { - // For this test, we don't duplicate - return this; - } - - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/SemanticsEnabledDescriptorParserTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,506 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.core.Add; -import com.redhat.thermostat.storage.core.AggregateQuery; -import com.redhat.thermostat.storage.core.AggregateQuery.AggregateFunction; -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.ParsedStatement; -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.StatementDescriptor; -import com.redhat.thermostat.storage.core.Update; -import com.redhat.thermostat.storage.dao.AgentInfoDAO; -import com.redhat.thermostat.storage.model.AgentInformation; - -public class SemanticsEnabledDescriptorParserTest { - - private static final String COMPLETE_SET_LIST_AGENT_INFO = "SET " + - "'" + Key.AGENT_ID.getName() + "' = ?s , " + - "'" + AgentInfoDAO.START_TIME_KEY.getName() + "' = ?l , " + - "'" + AgentInfoDAO.STOP_TIME_KEY.getName() + "' = ?l , " + - "'" + AgentInfoDAO.ALIVE_KEY.getName() + "' = ?b , " + - "'" + AgentInfoDAO.CONFIG_LISTEN_ADDRESS.getName() + "' = ?s"; - - private static final String INCOMPLETE_SET_LIST_AGENT_INFO = "SET " + - "'" + Key.AGENT_ID.getName() + "' = ?s , " + - "'" + AgentInfoDAO.START_TIME_KEY.getName() + "' = ?l , " + - // stop-time key missing - "'" + AgentInfoDAO.ALIVE_KEY.getName() + "' = ?b , " + - "'" + AgentInfoDAO.CONFIG_LISTEN_ADDRESS.getName() + "' = ?s"; - - private BackingStorage storage; - private Query<AgentInformation> mockQuery; - private AggregateQuery<AgentInformation> aggQuery; - private SemanticsEnabledDescriptorParser<AgentInformation> parser; - private Add<AgentInformation> mockAdd; - private Update<AgentInformation> mockUpdate; - private Replace<AgentInformation> mockReplace; - private Remove<AgentInformation> mockRemove; - - @SuppressWarnings("unchecked") - @Before - public void setup() { - storage = mock(BackingStorage.class); - mockQuery = mock(Query.class); - aggQuery = mock(AggregateQuery.class); - // setup for QUERY/QUERY-COUNT/QUERY-DISTINCT - when(storage.createQuery(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockQuery); - when(storage.createAggregateQuery(eq(AggregateFunction.COUNT), (eq(AgentInfoDAO.CATEGORY)))).thenReturn(aggQuery); - when(storage.createAggregateQuery(eq(AggregateFunction.DISTINCT), (eq(AgentInfoDAO.CATEGORY)))).thenReturn(aggQuery); - // setup for ADD - mockAdd = mock(Add.class); - when(storage.createAdd(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockAdd); - // setup for UPDATE - mockUpdate = mock(Update.class); - when(storage.createUpdate(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockUpdate); - // setup for REMOVE - mockRemove = mock(Remove.class); - when(storage.createRemove(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockRemove); - // setup for REPLACE - mockReplace = mock(Replace.class); - when(storage.createReplace(eq(AgentInfoDAO.CATEGORY))).thenReturn(mockReplace); - } - - @Test - public void canParseQueryWithLimit() throws DescriptorParsingException { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " LIMIT 1"; - doSemanticsBasicParseTest(descString); - - } - - @Test - public void catParseQueryCountWithLimit() throws DescriptorParsingException { - when(aggQuery.getAggregateFunction()).thenReturn(AggregateFunction.COUNT); - String descString = "QUERY-COUNT " + AgentInfoDAO.CATEGORY.getName() + " LIMIT 1"; - doSemanticsBasicParseTest(descString); - } - - @Test - public void canParseQueryCountWithCorrectKeyParam() throws DescriptorParsingException { - when(aggQuery.getAggregateFunction()).thenReturn(AggregateFunction.COUNT); - String descString = "QUERY-COUNT(" + Key.AGENT_ID.getName() + ") " - + AgentInfoDAO.CATEGORY.getName(); - doSemanticsBasicParseTest(descString); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Test - public void canParseQueryDistinctWithCorrectKeyParam() throws DescriptorParsingException { - when(aggQuery.getAggregateFunction()).thenReturn(AggregateFunction.DISTINCT); - when(aggQuery.getAggregateKey()).thenReturn((Key)Key.AGENT_ID); - String descString = "QUERY-DISTINCT(" + Key.AGENT_ID.getName() + ") " - + AgentInfoDAO.CATEGORY.getName(); - doSemanticsBasicParseTest(descString); - } - - @Test - public void canParseQueryWithSort() throws DescriptorParsingException { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " SORT 'foo' DSC"; - doSemanticsBasicParseTest(descString); - } - - @Test - public void catParseQueryCountWithSort() throws DescriptorParsingException { - when(aggQuery.getAggregateFunction()).thenReturn(AggregateFunction.COUNT); - String descString = "QUERY-COUNT " + AgentInfoDAO.CATEGORY.getName() + " SORT 'foo' DSC"; - doSemanticsBasicParseTest(descString); - } - - /* - * Tests whether parse succeeds if some properties are missing from the - * UPDATE descriptor. Update is the operation to be used in this case. - */ - @Test - public void canParseUpdateWithSomePropertiesMissing() throws DescriptorParsingException { - String descString = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + - " SET '" + Key.AGENT_ID.getName() + "' = 'b' , " + - "'"+ AgentInfoDAO.ALIVE_KEY.getName() + "' = ?b" + - " WHERE '" + Key.AGENT_ID.getName() + "' = ?s"; - doSemanticsBasicParseTest(descString); - } - - /* - * Tests whether parse succeeds if ALL properties are given in the - * ADD descriptor. - */ - @Test - public void canParseAddWithAllPropertiesGiven() throws DescriptorParsingException { - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " " + COMPLETE_SET_LIST_AGENT_INFO; - doSemanticsBasicParseTest(descString); - } - - /* - * Tests whether parse succeeds if ALL properties are given in the - * REPLACE descriptor. - */ - @Test - public void canParseReplaceWithAllPropertiesGiven() throws DescriptorParsingException { - String descString = "REPLACE " + AgentInfoDAO.CATEGORY.getName() + - " " + COMPLETE_SET_LIST_AGENT_INFO + - " WHERE '" + AgentInfoDAO.CONFIG_LISTEN_ADDRESS.getName()+ "' = ?s"; - doSemanticsBasicParseTest(descString); - } - - private void doSemanticsBasicParseTest(String strDesc) throws DescriptorParsingException { - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - ParsedStatement<AgentInformation> p = parser.parse(); - assertNotNull(p); - } - - /* - * Tests whether we appropriately reject a provided key parameter in a - * query-count aggregate for which the key is unknown in the given category. - */ - @Test - public void rejectQueryCountWithUnknownKeyAsParam() throws DescriptorParsingException { - when(aggQuery.getAggregateFunction()).thenReturn(AggregateFunction.COUNT); - doRejectQueryAggregateTestWithParam(AggregateFunction.COUNT); - } - - /* - * Tests whether we appropriately reject a provided key parameter in a - * query-distinct aggregate for which the key is unknown in the given category. - */ - @Test - public void rejectQueryDistinctWithUnknownKeyAsParam() throws DescriptorParsingException { - when(aggQuery.getAggregateFunction()).thenReturn(AggregateFunction.DISTINCT); - doRejectQueryAggregateTestWithParam(AggregateFunction.DISTINCT); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void doRejectQueryAggregateTestWithParam(AggregateFunction function) { - String unknownKeyName = "unknown_key"; - Key unknownKey = new Key(unknownKeyName); - when(aggQuery.getAggregateKey()).thenReturn(unknownKey); - String format = "QUERY-%s(%s) %s"; - String descString = String.format(format, function.name(), unknownKeyName, AgentInfoDAO.CATEGORY.getName()); - assertNull("Precondition failed. unknown_key in AgentInfo category?", - AgentInfoDAO.CATEGORY.getKey(unknownKeyName)); - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail(String.format("QUERY-%s with an unknown key as param should not parse", function.name())); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Unknown aggregate key '" + unknownKeyName + "'")); - } - } - - /* - * Distinct queries aggregate by selecting all distinct values for a - * given key. Not providing a key for which to find distinct values for - * doesn't make sense. - */ - @Test - public void rejectQueryDistinctWithoutKeyParam() throws DescriptorParsingException { - String descString = "QUERY-DISTINCT " + AgentInfoDAO.CATEGORY.getName(); - - when(aggQuery.getAggregateKey()).thenReturn(null); - when(aggQuery.getAggregateFunction()).thenReturn(AggregateFunction.DISTINCT); - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("QUERY-DISTINCT without a key for which to produce distinct values for should not parse"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Aggregate key for DISTINCT must not be null")); - } - } - - @Test - public void rejectAddWithWhere() throws DescriptorParsingException { - String descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " " + COMPLETE_SET_LIST_AGENT_INFO + " WHERE 'a' = 'b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("ADD operation does not support WHERE clauses!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("WHERE clause not allowed for ADD")); - } - } - - @Test - public void rejectReplaceWithoutWhere() throws DescriptorParsingException { - String descString = "REPLACE " + AgentInfoDAO.CATEGORY.getName() + " " + COMPLETE_SET_LIST_AGENT_INFO; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("REPLACE operation requires WHERE clause, and should not parse!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("WHERE clause required for REPLACE")); - } - } - - @Test - public void rejectUpdateWithoutWhere() throws DescriptorParsingException { - String descString = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + - " SET '" + Key.AGENT_ID.getName() + "' = 'b' , 'c' = 'd'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("UPDATE operation requires WHERE clause, and should not parse!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("WHERE clause required for UPDATE")); - } - } - - @Test - public void rejectRemoveWithSetList() throws DescriptorParsingException { - String descString = "REMOVE " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = 'b'" + - " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("REMOVE does not allow SET list, and should not parse!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue("message was: " + e.getMessage(), e.getMessage().contains("SET not allowed for REMOVE")); - } - } - - @Test - public void rejectQueryWithSetList() throws DescriptorParsingException { - String descString = "QUERY " + AgentInfoDAO.CATEGORY.getName() + " SET 'a' = 'b'" + - " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("QUERY does not allow SET list, and should not parse!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("SET not allowed for QUERY")); - } - } - - - private void doRejectWriteSortLimitTest(String descString, String failmsg) { - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail(failmsg); - } catch (DescriptorParsingException e) { - // pass - assertEquals("LIMIT/SORT only allowed for QUERY/QUERY-COUNT", e.getMessage()); - } - } - - @Test - public void rejectWritesWithSortLimit() throws DescriptorParsingException { - // Update rejects - String descString = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + - " SET '" + Key.AGENT_ID.getName() + "' = 'b'" + - " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'" + - " SORT 'a' DSC"; // this is intentionally wrong for this test - String failmsg = "SORT in UPDATE is not allowed, and should not parse!"; - doRejectWriteSortLimitTest(descString, failmsg); - descString = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + - " SET '" + Key.AGENT_ID.getName() + "' = 'b'" + - " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'" + - " LIMIT 1"; // this is intentionally wrong for this test - failmsg = "LIMIT in UPDATE is not allowed, and should not parse!"; - doRejectWriteSortLimitTest(descString, failmsg); - - // Remove rejects - descString = "REMOVE " + AgentInfoDAO.CATEGORY.getName() + - " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'" + - " LIMIT 1"; // this is intentionally wrong for this test - failmsg = "LIMIT in REMOVE is not allowed, and should not parse!"; - doRejectWriteSortLimitTest(descString, failmsg); - descString = "REMOVE " + AgentInfoDAO.CATEGORY.getName() + - " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'" + - " SORT 'a' ASC"; - failmsg = "SORT in REMOVE is not allowed, and should not parse!"; - doRejectWriteSortLimitTest(descString, failmsg); - - // Replace rejects - descString = "REPLACE " + AgentInfoDAO.CATEGORY.getName() + " " + - COMPLETE_SET_LIST_AGENT_INFO + - " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'" + - " LIMIT 1"; - failmsg = "LIMIT in REPLACE is not allowed, and should not parse!"; - doRejectWriteSortLimitTest(descString, failmsg); - descString = "REPLACE " + AgentInfoDAO.CATEGORY.getName() + " " + - COMPLETE_SET_LIST_AGENT_INFO + - " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'" + - " SORT 'a' ASC"; - failmsg = "SORT in REPLACE is not allowed, and should not parse!"; - doRejectWriteSortLimitTest(descString, failmsg); - - // Add rejects - descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " " + COMPLETE_SET_LIST_AGENT_INFO + " LIMIT 1"; - failmsg = "LIMIT in ADD is not allowed, and should not parse!"; - doRejectWriteSortLimitTest(descString, failmsg); - descString = "ADD " + AgentInfoDAO.CATEGORY.getName() + " " + COMPLETE_SET_LIST_AGENT_INFO + " SORT 'a' ASC"; - failmsg = "SORT in ADD is not allowed, and should not parse!"; - doRejectWriteSortLimitTest(descString, failmsg); - } - - @Test - public void rejectUpdateWithoutSet() throws DescriptorParsingException { - String descString = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + " WHERE '" + Key.AGENT_ID.getName() + "' = 'b'"; - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("UPDATE requires SET list, and should not parse!"); - } catch (DescriptorParsingException e) { - // pass - assertEquals("SET list required for UPDATE", e.getMessage()); - } - } - - /* - * Tests whether parser fails if some properties are missing from the - * ADD descriptor, but the category specified as keys. - */ - @Test - public void rejectAddWithSomePropertiesMissing() throws DescriptorParsingException { - String strDesc = "ADD " + AgentInfoDAO.CATEGORY.getName() + " " + INCOMPLETE_SET_LIST_AGENT_INFO; - doRejectIncompleteKeysTest(strDesc); - } - - /* - * Tests whether parser fails if some properties are missing from the - * REPLACE descriptor, but the category specified as keys. - */ - @Test - public void rejectReplaceWithSomePropertiesMissing() throws DescriptorParsingException { - // The following descriptor should be valid except for the one missing key. - String strDesc = "REPLACE " + AgentInfoDAO.CATEGORY.getName() + " " - + INCOMPLETE_SET_LIST_AGENT_INFO + " WHERE 'foo' = ?s"; - doRejectIncompleteKeysTest(strDesc); - } - - private void doRejectIncompleteKeysTest(String strDesc) { - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("stop timestamp key missing. Should not parse!"); - } catch (DescriptorParsingException e) { - // pass - assertTrue(e.getMessage().contains("Keys don't match keys in category.")); - } - } - - /* - * Tests whether parser fails if LHS of any SET pair of ADD/REPLACE is a - * free variable. We disallow this, since key completeness checks don't make - * much sense (prior patching) without this. - */ - @Test - public void rejectAddReplaceWithFreeVarOnLHS() throws DescriptorParsingException { - // second pair has ?s as LHS - String strDesc = "ADD " + AgentInfoDAO.CATEGORY.getName() + " SET " + - "'" + Key.AGENT_ID.getName() + "' = ?s , ?s = ?b"; - doRejectWithFreeVarOnLHS(strDesc); - - // ?b is the offending part - strDesc = "REPLACE " + AgentInfoDAO.CATEGORY.getName() + " SET " + - "?b = ?s WHERE 'foo' = ?s"; - doRejectWithFreeVarOnLHS(strDesc); - } - - private void doRejectWithFreeVarOnLHS(String strDesc) { - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, strDesc); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("SET with free variable on LHS should not parse!"); - } catch (DescriptorParsingException e) { - // pass - assertEquals("LHS of set list pair must not be a free variable.", e.getMessage()); - } - } - - /* - * Tests whether a key set via UPDATE exists in the category. - */ - @Test - public void rejectUpdateWithUnknownKeyInSet() { - String descString = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + " SET 'iDoNotExist' = ?s WHERE 'foo' = 'b'"; - String detail = "'[iDoNotExist]'"; - doRejectUpdateWithUnknownKeyTest(descString, detail); - descString = "UPDATE " + AgentInfoDAO.CATEGORY.getName() + " SET 'iDoNotExist' = ?s , 'notHere' = ?b WHERE 'foo' = 'b'"; - detail = "'[iDoNotExist, notHere]'"; - doRejectUpdateWithUnknownKeyTest(descString, detail); - } - - private void doRejectUpdateWithUnknownKeyTest(String descString, - String detailMsg) { - StatementDescriptor<AgentInformation> desc = new StatementDescriptor<>(AgentInfoDAO.CATEGORY, descString); - parser = new SemanticsEnabledDescriptorParser<>(storage, desc); - try { - parser.parse(); - fail("SET for unknown key in category should not parse"); - } catch (DescriptorParsingException e) { - // pass - assertEquals("Unknown key(s) in SET: " + detailMsg, e.getMessage()); - } - } - -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/SetListValueTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -public class SetListValueTest { - - @Test - public void testEqualsHashCodeEmpty() { - SetListValue value = new SetListValue(); - assertTrue(value.equals(value)); - SetListValue value2 = new SetListValue(); - assertTrue(value.equals(value2)); - assertEquals(value.hashCode(), value2.hashCode()); - } - - @Test - public void testEqualsHashCodeNonEmpty() { - TerminalNode keyNode = new TerminalNode(null); - keyNode.setValue("foo"); - TerminalNode valNode = new TerminalNode(null); - valNode.setValue("bar-val"); - SetListValue value = new SetListValue(); - value.setKey(keyNode); - value.setValue(valNode); - assertTrue(value.equals(value)); - SetListValue value2 = new SetListValue(); - TerminalNode keyNode2 = new TerminalNode(null); - keyNode2.setValue("foo"); - TerminalNode valNode2 = new TerminalNode(null); - valNode2.setValue("bar-val"); - value2.setKey(keyNode2); - value2.setValue(valNode2); - assertEquals(valNode, valNode2); - assertEquals(keyNode, keyNode2); - assertTrue(value.equals(value2)); - assertEquals(value.hashCode(), value2.hashCode()); - assertFalse(value.equals("something-else")); - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/SortMemberTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -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 org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.core.Query.SortDirection; - -public class SortMemberTest { - - private SortMember member; - - @Before - public void setup() { - member = new SortMember(); - member.setDirection(SortDirection.ASCENDING); - UnfinishedSortKey unfinished = new UnfinishedSortKey(); - unfinished.setParameterIndex(0); - member.setSortKey(unfinished); - } - - @Test - public void testPatchWithString() { - PreparedParameter p = new PreparedParameter(); - p.setType(String.class); - p.setValue("foo"); - PatchedSortMemberExpression expn = null; - try { - // test patching - expn = member.patch(new PreparedParameter[] { p }); - // pass - } catch (IllegalPatchException e) { - fail(e.getMessage()); - } - assertNotNull(expn); - assertEquals(new Key<>("foo"), expn.getSortMember().getSortKey()); - } - - @Test - public void rejectPatchWithStringList() { - PreparedParameter p = new PreparedParameter(); - p.setType(String[].class); - p.setValue(new String[] { "foo" }); - try { - member.patch(new PreparedParameter[] { p }); - fail("Patching with string list should not be possible!"); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getMessage().contains("Illegal parameter type")); - } - } - - @Test - public void rejectPatchWithNumber() { - PreparedParameter p = new PreparedParameter(); - p.setType(int.class); - p.setValue(1); - try { - member.patch(new PreparedParameter[] { p }); - fail("Patching with integer should not be possible!"); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getMessage().contains("Illegal parameter type")); - } - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/StatementDescriptorTester.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.model.Pojo; - -/* - * NOTE class copied from storage-test-utils for internal testing of Statement - * Adapters - */ -public final class StatementDescriptorTester<T extends Pojo> { - - public void testParseBasic(StatementDescriptor<T> desc) - throws DescriptorParsingException { - TestParser<T> testParser = new TestParser<>(desc, ParserType.BASIC); - testParser.parse(); - } - - public void testParseSemantic(StatementDescriptor<T> desc) throws DescriptorParsingException { - TestParser<T> testParser = new TestParser<>(desc, ParserType.SEMANTIC); - testParser.parse(); - } -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/TerminalNodeTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -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 org.junit.Test; - -import com.redhat.thermostat.storage.core.IllegalPatchException; -import com.redhat.thermostat.storage.core.PreparedParameter; -import com.redhat.thermostat.storage.model.AgentInformation; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.query.LiteralExpression; - -public class TerminalNodeTest { - - @Test - public void canPatchWithCorrectType() { - TerminalNode node = new TerminalNode(null); - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setParameterIndex(0); - unfinished.setType(String.class); - - node.setValue(unfinished); - - PreparedParameter p = new PreparedParameter(); - p.setType(String.class); - p.setValue("foo-bar"); - - PatchedWhereExpression expn = null; - try { - expn = node.patch(new PreparedParameter[] { p }); - // pass - } catch (IllegalPatchException e) { - fail(e.getMessage()); - } - assertNotNull(expn); - LiteralExpression<?> literal = (LiteralExpression<?>)expn.getExpression(); - assertEquals("foo-bar", literal.getValue()); - } - - @Test - public void canPatchWithPojoType() { - TerminalNode node = new TerminalNode(null); - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setParameterIndex(0); - unfinished.setType(Pojo.class); - - node.setValue(unfinished); - - PreparedParameter p = new PreparedParameter(); - p.setType(AgentInformation.class); - AgentInformation info = new AgentInformation("foo-bar"); - p.setValue(info); - - PatchedWhereExpression expn = null; - try { - expn = node.patch(new PreparedParameter[] { p }); - // pass - } catch (IllegalPatchException e) { - fail(e.getMessage()); - } - assertNotNull(expn); - LiteralExpression<?> literal = (LiteralExpression<?>)expn.getExpression(); - assertEquals(info, literal.getValue()); - } - - @Test - public void rejectPatchingWithIncorrectListType() { - TerminalNode node = new TerminalNode(null); - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setParameterIndex(0); - unfinished.setType(String.class); - - node.setValue(unfinished); - - PreparedParameter p = new PreparedParameter(); - p.setType(String[].class); - p.setValue(new String[] { "foo-bar" }); - - try { - node.patch(new PreparedParameter[] { p }); - fail("Should not be able to patch string with string list."); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getMessage().contains("invalid type when attempting to patch.")); - } - } - - @Test - public void rejectPatchingWithIncorrectPojoListType() { - TerminalNode node = new TerminalNode(null); - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setParameterIndex(0); - unfinished.setType(Pojo.class); - - node.setValue(unfinished); - - PreparedParameter p = new PreparedParameter(); - p.setType(AgentInformation.class); - AgentInformation info = new AgentInformation("testing"); - p.setValue(new AgentInformation[] { info }); - - try { - node.patch(new PreparedParameter[] { p }); - fail("Should not be able to patch string with string list."); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getMessage().contains("invalid type when attempting to patch.")); - } - } - - @Test - public void rejectPatchingWithIncorrectType() { - TerminalNode node = new TerminalNode(null); - UnfinishedValueNode unfinished = new UnfinishedValueNode(); - unfinished.setLHS(false); - unfinished.setParameterIndex(0); - unfinished.setType(int.class); - - node.setValue(unfinished); - - PreparedParameter p = new PreparedParameter(); - p.setType(String[].class); - p.setValue(new String[] { "foo-bar" }); - - try { - node.patch(new PreparedParameter[] { p }); - fail("Should not be able to patch integer with string list."); - } catch (IllegalPatchException e) { - // pass - assertTrue(e.getMessage().contains("invalid type when attempting to patch.")); - } - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/TestParser.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.ParsedStatement; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.model.Pojo; - -/* - * NOTE class copied from storage-test-utils for internal testing - */ -public final class TestParser<T extends Pojo> implements StatementDescriptorParser<T> { - - private final StatementDescriptor<T> desc; - private final DescriptorParserImplFactory factory; - private final ParserType type; - - public TestParser(StatementDescriptor<T> desc, ParserType type) { - this.desc = desc; - this.factory = new DescriptorParserImplFactory(); - this.type = type; - } - - @Override - public ParsedStatement<T> parse() throws DescriptorParsingException { - StatementDescriptorParser<T> actualParser = factory.getParser(type, desc); - actualParser.parse(); - return null; // Always return null. Testing utility only. - } - -}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/WhereExpressions.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.redhat.thermostat.storage.internal.statement.BinaryExpressionNode; -import com.redhat.thermostat.storage.internal.statement.Node; -import com.redhat.thermostat.storage.internal.statement.NotBooleanExpressionNode; -import com.redhat.thermostat.storage.internal.statement.TerminalNode; -import com.redhat.thermostat.storage.internal.statement.WhereExpression; - -/** - * Helper class for comparing where expression trees. - * - * @see BasicDescriptorParserTest - */ -public class WhereExpressions { - - /** - * Compares two where expression parse trees. - * - * @param a - * @param b - * @return true, if all nodes/values were equal. false otherwise. - */ - public static boolean equals(WhereExpression a, WhereExpression b) { - Node aRoot = a.getRoot(); - Node bRoot = b.getRoot(); - return recEquals(aRoot, bRoot); - } - - private static boolean recEquals(Node a, Node b) { - boolean retval = Objects.equals(a, b); - if (!retval) { - return false; - } - Node[] nextNodesA = getNextNodes(a); - Node[] nextNodesB = getNextNodes(b); - if (nextNodesA != null && nextNodesB != null) { - retval = retval && (nextNodesA.length == nextNodesB.length); - if (!retval) { - return false; - } - // verify nodes at this level are equal - for (int i = 0; i < nextNodesA.length; i++) { - retval = retval && Objects.equals(nextNodesA[i], nextNodesB[i]); - if (!retval) { - return false; - } - } - // recursively check child nodes - for (int i = 0; i < nextNodesA.length; i++) { - retval = retval && recEquals(nextNodesA[i], nextNodesB[i]); - if (!retval) { - return false; - } - } - return retval; - } - if (nextNodesA != null || nextNodesB != null) { - return false; - } - // all pass - return true; - } - - private static Node[] getNextNodes(Node node) { - if (node instanceof TerminalNode) { - return null; - } else if (node instanceof BinaryExpressionNode) { - List<Node> nodes = new ArrayList<>(2); - BinaryExpressionNode binNode = (BinaryExpressionNode)node; - if (binNode.getLeftChild() != null) { - nodes.add(binNode.getLeftChild()); - } - if (binNode.getRightChild() != null) { - nodes.add(binNode.getRightChild()); - } - if (nodes.size() == 0) { - return null; - } - return nodes.toArray(new Node[0]); - } else if (node instanceof NotBooleanExpressionNode || node instanceof Node) { - Node next = (Node)node.getValue(); - if (next == null) { - return null; - } - return new Node[] { next }; - } else { - return null; - } - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/statement/WhereExpressionsTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,286 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.redhat.thermostat.storage.internal.statement.BinaryExpressionNode; -import com.redhat.thermostat.storage.internal.statement.NotBooleanExpressionNode; -import com.redhat.thermostat.storage.internal.statement.TerminalNode; -import com.redhat.thermostat.storage.internal.statement.WhereExpression; -import com.redhat.thermostat.storage.query.BinaryComparisonOperator; -import com.redhat.thermostat.storage.query.BinaryLogicalOperator; - -public class WhereExpressionsTest { - - @Test - public void testEqualsSelf() { - WhereExpression expn1 = new WhereExpression(); - assertTrue(WhereExpressions.equals(expn1, expn1)); - } - - @Test - public void testEqualsEmpty() { - WhereExpression expn1 = new WhereExpression(); - WhereExpression expn2 = new WhereExpression(); - assertTrue(WhereExpressions.equals(expn1, expn2)); - } - - @Test - public void testEqualsSimpleTerminal() { - WhereExpression expn1 = new WhereExpression(); - WhereExpression expn2 = new WhereExpression(); - TerminalNode node = new TerminalNode(expn1.getRoot()); - node.setValue("testing"); - TerminalNode node2 = new TerminalNode(expn2.getRoot()); - node2.setValue("testing"); - expn1.getRoot().setValue(node); - expn2.getRoot().setValue(node2); - assertTrue(WhereExpressions.equals(expn1, expn2)); - } - - @Test - public void testEqualsSimpleTerminalWithDifferentValues() { - WhereExpression expn1 = new WhereExpression(); - WhereExpression expn2 = new WhereExpression(); - TerminalNode node = new TerminalNode(expn1.getRoot()); - node.setValue("test"); - TerminalNode node2 = new TerminalNode(expn2.getRoot()); - node2.setValue("other"); - expn1.getRoot().setValue(node); - expn2.getRoot().setValue(node2); - assertFalse(WhereExpressions.equals(expn1, expn2)); - } - - @Test - public void testEqualsComplexish() { - WhereExpression expn1 = new WhereExpression(); - BinaryExpressionNode binNode1 = new BinaryExpressionNode(expn1.getRoot()); - expn1.getRoot().setValue(binNode1); - binNode1.setOperator(BinaryLogicalOperator.OR); - NotBooleanExpressionNode notNode1 = new NotBooleanExpressionNode(binNode1); - TerminalNode termNode1 = new TerminalNode(notNode1); - termNode1.setValue("testing"); - notNode1.setValue(termNode1); - binNode1.setLeftChild(notNode1); - BinaryExpressionNode and1 = new BinaryExpressionNode(binNode1); - binNode1.setRightChild(and1); - and1.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode left1 = new BinaryExpressionNode(and1); - left1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode termNode1Equal = new TerminalNode(left1); - termNode1Equal.setValue("a"); - TerminalNode termNode1EqualOther = new TerminalNode(left1); - termNode1EqualOther.setValue("b"); - left1.setLeftChild(termNode1Equal); - left1.setRightChild(termNode1EqualOther); - and1.setLeftChild(left1); - BinaryExpressionNode right1 = new BinaryExpressionNode(and1); - right1.setOperator(BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO); - TerminalNode termNode1LessEqual = new TerminalNode(right1); - termNode1LessEqual.setValue("x"); - TerminalNode termNode1LessEqualOther = new TerminalNode(right1); - termNode1LessEqualOther.setValue("y"); - right1.setLeftChild(termNode1LessEqual); - right1.setRightChild(termNode1LessEqualOther); - and1.setRightChild(right1); - - // now build the second and equal where expn - WhereExpression expn2 = new WhereExpression(); - BinaryExpressionNode binNode2 = new BinaryExpressionNode(expn2.getRoot()); - expn2.getRoot().setValue(binNode2); - binNode2.setOperator(BinaryLogicalOperator.OR); - NotBooleanExpressionNode notNode2 = new NotBooleanExpressionNode(binNode2); - TerminalNode termNode2 = new TerminalNode(notNode2); - termNode2.setValue("testing"); - notNode2.setValue(termNode2); - binNode2.setLeftChild(notNode2); - BinaryExpressionNode and2 = new BinaryExpressionNode(binNode2); - binNode2.setRightChild(and2); - and2.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode left2 = new BinaryExpressionNode(and2); - left2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode termNode2Equal = new TerminalNode(left2); - termNode2Equal.setValue("a"); - TerminalNode termNode2EqualOther = new TerminalNode(left2); - termNode2EqualOther.setValue("b"); - left2.setLeftChild(termNode2Equal); - left2.setRightChild(termNode2EqualOther); - and2.setLeftChild(left2); - BinaryExpressionNode right2 = new BinaryExpressionNode(and2); - right2.setOperator(BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO); - TerminalNode termNode2LessEqual = new TerminalNode(right2); - termNode2LessEqual.setValue("x"); - TerminalNode termNode2LessEqualOther = new TerminalNode(right2); - termNode2LessEqualOther.setValue("y"); - right2.setLeftChild(termNode2LessEqual); - right2.setRightChild(termNode2LessEqualOther); - and2.setRightChild(right2); - assertTrue(WhereExpressions.equals(expn1, expn2)); - } - - @Test - public void testNotEqualsComplexish() { - WhereExpression expn1 = new WhereExpression(); - BinaryExpressionNode binNode1 = new BinaryExpressionNode(expn1.getRoot()); - expn1.getRoot().setValue(binNode1); - binNode1.setOperator(BinaryLogicalOperator.OR); - NotBooleanExpressionNode notNode1 = new NotBooleanExpressionNode(binNode1); - TerminalNode termNode1 = new TerminalNode(notNode1); - termNode1.setValue("testing"); - notNode1.setValue(termNode1); - binNode1.setLeftChild(notNode1); - BinaryExpressionNode and1 = new BinaryExpressionNode(binNode1); - binNode1.setRightChild(and1); - and1.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode left1 = new BinaryExpressionNode(and1); - left1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode termNode1Equal = new TerminalNode(left1); - termNode1Equal.setValue("d"); // should be "a" to make it equal - TerminalNode termNode1EqualOther = new TerminalNode(left1); - termNode1EqualOther.setValue("b"); - left1.setLeftChild(termNode1Equal); - left1.setRightChild(termNode1EqualOther); - and1.setLeftChild(left1); - BinaryExpressionNode right1 = new BinaryExpressionNode(and1); - right1.setOperator(BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO); - TerminalNode termNode1LessEqual = new TerminalNode(right1); - termNode1LessEqual.setValue("x"); - TerminalNode termNode1LessEqualOther = new TerminalNode(right1); - termNode1LessEqualOther.setValue("y"); - right1.setLeftChild(termNode1LessEqual); - right1.setRightChild(termNode1LessEqualOther); - and1.setRightChild(right1); - - // now build the second and equal where expn - WhereExpression expn2 = new WhereExpression(); - BinaryExpressionNode binNode2 = new BinaryExpressionNode(expn2.getRoot()); - expn2.getRoot().setValue(binNode2); - binNode2.setOperator(BinaryLogicalOperator.OR); - NotBooleanExpressionNode notNode2 = new NotBooleanExpressionNode(binNode2); - TerminalNode termNode2 = new TerminalNode(notNode2); - termNode2.setValue("testing"); - notNode2.setValue(termNode2); - binNode2.setLeftChild(notNode2); - BinaryExpressionNode and2 = new BinaryExpressionNode(binNode2); - binNode2.setRightChild(and2); - and2.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode left2 = new BinaryExpressionNode(and2); - left2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode termNode2Equal = new TerminalNode(left2); - termNode2Equal.setValue("a"); - TerminalNode termNode2EqualOther = new TerminalNode(left2); - termNode2EqualOther.setValue("b"); - left2.setLeftChild(termNode2Equal); - left2.setRightChild(termNode2EqualOther); - and2.setLeftChild(left2); - BinaryExpressionNode right2 = new BinaryExpressionNode(and2); - right2.setOperator(BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO); - TerminalNode termNode2LessEqual = new TerminalNode(right2); - termNode2LessEqual.setValue("x"); - TerminalNode termNode2LessEqualOther = new TerminalNode(right2); - termNode2LessEqualOther.setValue("y"); - right2.setLeftChild(termNode2LessEqual); - right2.setRightChild(termNode2LessEqualOther); - and2.setRightChild(right2); - assertFalse(WhereExpressions.equals(expn1, expn2)); - } - - @Test - public void testNotEqualsNotSameTreeAtAll() { - WhereExpression expn1 = new WhereExpression(); - BinaryExpressionNode binNode1 = new BinaryExpressionNode(expn1.getRoot()); - expn1.getRoot().setValue(binNode1); - binNode1.setOperator(BinaryLogicalOperator.OR); - NotBooleanExpressionNode notNode1 = new NotBooleanExpressionNode(binNode1); - TerminalNode termNode1 = new TerminalNode(notNode1); - termNode1.setValue("testing"); - notNode1.setValue(termNode1); - binNode1.setLeftChild(notNode1); - BinaryExpressionNode and1 = new BinaryExpressionNode(binNode1); - binNode1.setRightChild(and1); - and1.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode left1 = new BinaryExpressionNode(and1); - left1.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode termNode1Equal = new TerminalNode(left1); - termNode1Equal.setValue("d"); // should be "a" to make it equal - TerminalNode termNode1EqualOther = new TerminalNode(left1); - termNode1EqualOther.setValue("b"); - left1.setLeftChild(termNode1Equal); - left1.setRightChild(termNode1EqualOther); - and1.setLeftChild(left1); - BinaryExpressionNode right1 = new BinaryExpressionNode(and1); - right1.setOperator(BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO); - TerminalNode termNode1LessEqual = new TerminalNode(right1); - termNode1LessEqual.setValue("x"); - TerminalNode termNode1LessEqualOther = new TerminalNode(right1); - termNode1LessEqualOther.setValue("y"); - right1.setLeftChild(termNode1LessEqual); - right1.setRightChild(termNode1LessEqualOther); - and1.setRightChild(right1); - - // now build the second fairly different tree - WhereExpression expn2 = new WhereExpression(); - NotBooleanExpressionNode notNode2 = new NotBooleanExpressionNode(expn2.getRoot()); - BinaryExpressionNode and2 = new BinaryExpressionNode(notNode2); - notNode2.setValue(and2); - and2.setOperator(BinaryLogicalOperator.AND); - BinaryExpressionNode left2 = new BinaryExpressionNode(and2); - left2.setOperator(BinaryComparisonOperator.EQUALS); - TerminalNode termNode2Equal = new TerminalNode(left2); - termNode2Equal.setValue("a"); - TerminalNode termNode2EqualOther = new TerminalNode(left2); - termNode2EqualOther.setValue("b"); - left2.setLeftChild(termNode2Equal); - left2.setRightChild(termNode2EqualOther); - and2.setLeftChild(left2); - BinaryExpressionNode right2 = new BinaryExpressionNode(and2); - right2.setOperator(BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO); - TerminalNode termNode2LessEqual = new TerminalNode(right2); - termNode2LessEqual.setValue("x"); - TerminalNode termNode2LessEqualOther = new TerminalNode(right2); - termNode2LessEqualOther.setValue("y"); - right2.setLeftChild(termNode2LessEqual); - right2.setRightChild(termNode2LessEqualOther); - and2.setRightChild(right2); - assertFalse(WhereExpressions.equals(expn1, expn2)); - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/query/BinaryExpressionTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.mockito.Mockito.mock; - -import org.junit.Before; -import org.junit.Test; - - -public class BinaryExpressionTest { - - private Expression left; - private Expression right; - private BinaryOperator op; - private BinaryExpression<Expression, Expression, BinaryOperator> expr; - - @Before - public void setup() { - left = mock(Expression.class); - right = mock(Expression.class); - op = mock(BinaryOperator.class); - expr = new BinaryExpression<Expression, Expression, BinaryOperator>( - left, op, right) { - }; - } - - @Test - public void testGetLeftOperand() { - assertEquals(left, expr.getLeftOperand()); - } - - @Test - public void testGetRightOperand() { - assertEquals(right, expr.getRightOperand()); - } - - @Test - public void testGetOperator() { - assertEquals(op, expr.getOperator()); - } - - @Test - public void testEquals() { - BinaryExpression<Expression, Expression, BinaryOperator> otherExpr = new BinaryExpression<Expression, Expression, BinaryOperator>( - left, op, right) { - }; - assertEquals(expr, otherExpr); - } - - @Test - public void testNotEquals() { - Expression otherLeft = mock(Expression.class); - BinaryExpression<Expression, Expression, BinaryOperator> otherExpr = new BinaryExpression<Expression, Expression, BinaryOperator>( - otherLeft, op, right) { - }; - - assertFalse(expr.equals(otherExpr)); - } - - @Test - public void testNotEqualsWrongClass() { - assertFalse(expr.equals(new Object())); - } - - @Test - public void testNotEqualsNull() { - assertFalse(expr.equals(null)); - } - - @Test - public void testHashCode() { - int hashCode = left.hashCode() + right.hashCode() + op.hashCode(); - assertEquals(hashCode, expr.hashCode()); - } - -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/query/ExpressionFactoryTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.core.Key; - -public class ExpressionFactoryTest { - - private static final Key<String> key = new Key<>("hello"); - private static final String VALUE = "world"; - private static final Set<String> VALUES = new HashSet<>(Arrays.asList("world", "worlds")); - ExpressionFactory factory; - - @Before - public void setUp() throws Exception { - factory = new ExpressionFactory(); - } - - @Test - public void testEqualTo() { - Expression expr = new BinaryComparisonExpression<>( - new LiteralExpression<>(key), BinaryComparisonOperator.EQUALS, - new LiteralExpression<>(VALUE)); - assertEquals(expr, factory.equalTo(key, VALUE)); - } - - @Test - public void testNotEqualTo() { - Expression expr = new BinaryComparisonExpression<>( - new LiteralExpression<>(key), BinaryComparisonOperator.NOT_EQUAL_TO, - new LiteralExpression<>(VALUE)); - assertEquals(expr, factory.notEqualTo(key, VALUE)); - } - - @Test - public void testGreaterThan() { - Expression expr = new BinaryComparisonExpression<>( - new LiteralExpression<>(key), BinaryComparisonOperator.GREATER_THAN, - new LiteralExpression<>(VALUE)); - assertEquals(expr, factory.greaterThan(key, VALUE)); - } - - @Test - public void testLessThan() { - Expression expr = new BinaryComparisonExpression<>( - new LiteralExpression<>(key), BinaryComparisonOperator.LESS_THAN, - new LiteralExpression<>(VALUE)); - assertEquals(expr, factory.lessThan(key, VALUE)); - } - - @Test - public void testGreaterThanOrEqualTo() { - Expression expr = new BinaryComparisonExpression<>( - new LiteralExpression<>(key), BinaryComparisonOperator.GREATER_THAN_OR_EQUAL_TO, - new LiteralExpression<>(VALUE)); - assertEquals(expr, factory.greaterThanOrEqualTo(key, VALUE)); - } - - @Test - public void testLessThanOrEqualTo() { - Expression expr = new BinaryComparisonExpression<>( - new LiteralExpression<>(key), BinaryComparisonOperator.LESS_THAN_OR_EQUAL_TO, - new LiteralExpression<>(VALUE)); - assertEquals(expr, factory.lessThanOrEqualTo(key, VALUE)); - } - - @Test - public void testIn() { - Expression expr = new BinarySetMembershipExpression<>( - new LiteralExpression<>(key), BinarySetMembershipOperator.IN, - new LiteralSetExpression<>(VALUES, String.class)); - assertEquals(expr, factory.in(key, VALUES, String.class)); - } - - @Test - public void testNotIn() { - Expression expr = new BinarySetMembershipExpression<>( - new LiteralExpression<>(key), BinarySetMembershipOperator.NOT_IN, - new LiteralSetExpression<>(VALUES, String.class)); - assertEquals(expr, factory.notIn(key, VALUES, String.class)); - } - - @Test - public void testNot() { - ComparisonExpression operand = mock(ComparisonExpression.class); - Expression expr = new UnaryLogicalExpression<ComparisonExpression>(operand, UnaryLogicalOperator.NOT); - assertEquals(expr, factory.not(operand)); - } - - @Test - public void testAnd() { - Expression left = mock(Expression.class); - Expression right = mock(Expression.class); - Expression expr = new BinaryLogicalExpression<>(left, BinaryLogicalOperator.AND, right); - assertEquals(expr, factory.and(left, right)); - } - - @Test - public void testOr() { - Expression left = mock(Expression.class); - Expression right = mock(Expression.class); - Expression expr = new BinaryLogicalExpression<>(left, BinaryLogicalOperator.OR, right); - assertEquals(expr, factory.or(left, right)); - } - -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/query/LiteralExpressionTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.junit.Before; -import org.junit.Test; - -public class LiteralExpressionTest { - - private Object value; - private LiteralExpression<Object> expr; - - @Before - public void setup() { - value = new Object(); - expr = new LiteralExpression<Object>(value); - } - - @Test - public void testGetValue() { - assertEquals(value, expr.getValue()); - } - - @Test - public void testEquals() { - LiteralExpression<Object> otherExpr = new LiteralExpression<Object>(value); - assertEquals(expr, otherExpr); - } - - @Test - public void testNotEquals() { - Object otherValue = new Object(); - LiteralExpression<Object> otherExpr = new LiteralExpression<Object>(otherValue); - - assertFalse(expr.equals(otherExpr)); - } - - @Test - public void testNotEqualsWrongClass() { - assertFalse(expr.equals(new Object())); - } - - @Test - public void testNotEqualsNull() { - assertFalse(expr.equals(null)); - } - - @Test - public void testHashCode() { - assertEquals(value.hashCode(), expr.hashCode()); - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/query/LiteralSetExpressionTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; - -public class LiteralSetExpressionTest { - - private static final Set<Object> VALUES = new HashSet<>(Arrays.asList(new Object(), new Object(), new Object())); - private LiteralSetExpression<Object> expr; - - @Before - public void setup() { - expr = new LiteralSetExpression<Object>(VALUES, Object.class); - } - - @Test - public void testGetValues() { - assertEquals(VALUES, expr.getValues()); - } - - @Test(expected=UnsupportedOperationException.class) - public void testGetValuesImmutable() { - Set<Object> values = expr.getValues(); - values.add(new Object()); - } - - @Test - public void testEquals() { - LiteralSetExpression<Object> otherExpr = new LiteralSetExpression<Object>(VALUES, Object.class); - assertEquals(expr, otherExpr); - } - - @Test - public void testDeepEquals() { - Set<Object> otherValues = new HashSet<>(VALUES); - LiteralSetExpression<Object> otherExpr = new LiteralSetExpression<Object>(otherValues, Object.class); - assertEquals(expr, otherExpr); - } - - @Test - public void testNotEquals() { - Set<Object> otherValue = new HashSet<>(Arrays.asList(new Object(), new Object(), new Object())); - LiteralSetExpression<Object> otherExpr = new LiteralSetExpression<Object>(otherValue, Object.class); - - assertFalse(expr.equals(otherExpr)); - } - - @Test - public void testNotEqualsWrongClass() { - assertFalse(expr.equals(new Object())); - } - - @Test - public void testNotEqualsNull() { - assertFalse(expr.equals(null)); - } - - @Test - public void testHashCode() { - assertEquals(VALUES.hashCode() + Object.class.hashCode(), expr.hashCode()); - } -} -
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/query/UnaryExpressionTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.mockito.Mockito.mock; - -import org.junit.Before; -import org.junit.Test; - - -public class UnaryExpressionTest { - - private Expression operand; - private UnaryOperator operator; - private UnaryExpression<Expression, UnaryOperator> expr; - - @Before - public void setup() { - operand = mock(Expression.class); - operator = mock(UnaryOperator.class); - expr = new UnaryExpression<Expression, UnaryOperator>( - operand, operator) { - }; - } - - @Test - public void testGetOperand() { - assertEquals(operand, expr.getOperand()); - } - - @Test - public void testGetOperator() { - assertEquals(operator, expr.getOperator()); - } - - @Test - public void testEquals() { - UnaryExpression<Expression, UnaryOperator> otherExpr = new UnaryExpression<Expression, UnaryOperator>( - operand, operator) { - }; - assertEquals(expr, otherExpr); - } - - @Test - public void testNotEquals() { - Expression otherOperand = mock(Expression.class); - UnaryExpression<Expression, UnaryOperator> otherExpr = new UnaryExpression<Expression, UnaryOperator>( - otherOperand, operator) { - }; - - assertFalse(expr.equals(otherExpr)); - } - - @Test - public void testNotEqualsWrongClass() { - assertFalse(expr.equals(new Object())); - } - - @Test - public void testNotEqualsNull() { - assertFalse(expr.equals(null)); - } - - @Test - public void testHashCode() { - int hashCode = operator.hashCode() + operand.hashCode(); - assertEquals(hashCode, expr.hashCode()); - } - -} -
--- a/storage/pom.xml Fri May 19 11:37:45 2017 +0200 +++ b/storage/pom.xml Fri May 19 11:58:05 2017 +0200 @@ -60,7 +60,6 @@ <modules> <module>core</module> - <module>testutils</module> </modules> </project>
--- a/storage/testutils/pom.xml Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - - Copyright 2012-2017 Red Hat, Inc. - - This file is part of Thermostat. - - Thermostat is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your - option) any later version. - - Thermostat is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Thermostat; see the file COPYING. If not see - <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. - ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>com.redhat.thermostat</groupId> - <artifactId>thermostat-storage</artifactId> - <version>1.99.12-SNAPSHOT</version> - </parent> - - <artifactId>thermostat-storage-testutils</artifactId> - <!-- Intentionally not a bundle. This module - provides utilities for testing statement - descriptors outside of storage-core --> - <packaging>jar</packaging> - - <name>Thermostat Storage Test Utils</name> - - <dependencies> - <!-- Uses classes from storage-core --> - <dependency> - <groupId>com.redhat.thermostat</groupId> - <artifactId>thermostat-storage-core</artifactId> - <version>${project.version}</version> - </dependency> - <!-- Intentionally not scope "test" since this utility uses mockito for - stubbing in src/main/java. However, this test utility - should only be used as a dep with scope "test". --> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-core</artifactId> - </dependency> - </dependencies> - -</project> -
--- a/storage/testutils/src/main/java/com/redhat/thermostat/storage/internal/statement/DescriptorParserImplFactory.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.redhat.thermostat.storage.core.Add; -import com.redhat.thermostat.storage.core.AggregateQuery; -import com.redhat.thermostat.storage.core.AggregateQuery.AggregateFunction; -import com.redhat.thermostat.storage.core.BackingStorage; -import com.redhat.thermostat.storage.core.Category; -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.StatementDescriptor; -import com.redhat.thermostat.storage.core.Update; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.testutils.ParserType; - -class DescriptorParserImplFactory { - - <T extends Pojo> StatementDescriptorParser<T> getParser(ParserType type, StatementDescriptor<T> desc) { - switch (type) { - case BASIC: - return new BasicDescriptorParser<>(getBasicBackingStorage(), desc); - case SEMANTIC: - return new SemanticsEnabledDescriptorParser<>(getSemanticBackingStorage(desc.getDescriptor()), desc); - default: - throw new IllegalStateException("Not implemented"); - } - } - - private BackingStorage getBasicBackingStorage() { - return mock(BackingStorage.class); - } - - @SuppressWarnings("unchecked") - private BackingStorage getSemanticBackingStorage(String desc) { - BackingStorage storage = mock(BackingStorage.class); - when(storage.createAdd(any(Category.class))).thenReturn(mock(Add.class)); - when(storage.createUpdate(any(Category.class))).thenReturn(mock(Update.class)); - when(storage.createRemove(any(Category.class))).thenReturn(mock(Remove.class)); - when(storage.createReplace(any(Category.class))).thenReturn(mock(Replace.class)); - when(storage.createQuery(any(Category.class))).thenReturn(mock(Query.class)); - - AggregateQuery aggregateQuery = mock(AggregateQuery.class); - if (desc.contains("QUERY-COUNT")) { - when(aggregateQuery.getAggregateFunction()).thenReturn(AggregateFunction.COUNT); - } else { - when(aggregateQuery.getAggregateFunction()).thenReturn(AggregateFunction.DISTINCT); - } - when(storage.createAggregateQuery(any(AggregateFunction.class), any(Category.class))).thenReturn(aggregateQuery); - return storage; - } -}
--- a/storage/testutils/src/main/java/com/redhat/thermostat/storage/internal/statement/TestParser.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.statement; - -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.ParsedStatement; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.model.Pojo; -import com.redhat.thermostat.storage.testutils.ParserType; -import com.redhat.thermostat.storage.testutils.StatementDescriptorTester; - -/** - * Do NOT use this class directly. Use {@link StatementDescriptorTester} instead. - */ -public final class TestParser<T extends Pojo> implements StatementDescriptorParser<T> { - - private final StatementDescriptor<T> desc; - private final DescriptorParserImplFactory factory; - private final ParserType type; - - public TestParser(StatementDescriptor<T> desc, ParserType type) { - this.desc = desc; - this.factory = new DescriptorParserImplFactory(); - this.type = type; - } - - @Override - public ParsedStatement<T> parse() throws DescriptorParsingException { - StatementDescriptorParser<T> actualParser = factory.getParser(type, desc); - actualParser.parse(); - return null; // Always return null. Testing utility only. - } - -}
--- a/storage/testutils/src/main/java/com/redhat/thermostat/storage/testutils/ParserType.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.testutils; - -public enum ParserType { - BASIC, - SEMANTIC -} \ No newline at end of file
--- a/storage/testutils/src/main/java/com/redhat/thermostat/storage/testutils/StatementDescriptorTester.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.testutils; - -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.internal.statement.TestParser; -import com.redhat.thermostat.storage.model.Pojo; - -/** - * Unit test utility which is useful for verifying statement descriptors parse - * correctly. - * - * @param <T> The underlying {@link Pojo} implementation type. - */ -public final class StatementDescriptorTester<T extends Pojo> { - - public void testParseBasic(StatementDescriptor<T> desc) - throws DescriptorParsingException { - TestParser<T> testParser = new TestParser<>(desc, ParserType.BASIC); - testParser.parse(); - } - - public void testParseSemantic(StatementDescriptor<T> desc) throws DescriptorParsingException { - TestParser<T> testParser = new TestParser<>(desc, ParserType.SEMANTIC); - testParser.parse(); - } -}
--- a/storage/testutils/src/main/java/com/redhat/thermostat/storage/testutils/package-info.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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. - */ - - -/** - * Helpers for writing unit tests for storage-related classes. - * <p> - * This is for building only, not at run-time. - */ -package com.redhat.thermostat.storage.testutils;
--- a/storage/testutils/src/test/java/com/redhat/thermostat/storage/testutils/StatementDescriptorTesterTest.java Fri May 19 11:37:45 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.testutils; - -import org.junit.Test; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.DescriptorParsingException; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.StatementDescriptor; -import com.redhat.thermostat.storage.model.Pojo; - -public class StatementDescriptorTesterTest { - - private static final Key<String> barKey = new Key<>("bar"); - private static final Category<TestPojo> testCategory = new Category<>("desc-tester-category", TestPojo.class, barKey); - - @Test(expected = DescriptorParsingException.class) - public void canDetermineBadDescriptorBasic() throws DescriptorParsingException { - String brokenDesc = "foo"; - StatementDescriptor<TestPojo> desc = new StatementDescriptor<>(testCategory, brokenDesc); - StatementDescriptorTester<TestPojo> tester = new StatementDescriptorTester<>(); - tester.testParseBasic(desc); // should throw exception - } - - public void canDetermineGoodDescriptorBasic() throws DescriptorParsingException { - // This desc has correct syntax, but is semantically incorrect. The - // basic parser does not check this though. - String goodDesc = "QUERY desc-tester-category WHERE 'foo' = ?l"; - StatementDescriptor<TestPojo> desc = new StatementDescriptor<>(testCategory, goodDesc); - StatementDescriptorTester<TestPojo> tester = new StatementDescriptorTester<>(); - tester.testParseBasic(desc); // must not throw exception - } - - @Test(expected = DescriptorParsingException.class) - public void canDetermineBadDescriptorSemantic() throws DescriptorParsingException { - // No such key 'foo' in category. Thus, DPE on parse() - String brokenDesc = "ADD desc-tester-category SET 'foo' = ?l"; - StatementDescriptor<TestPojo> desc = new StatementDescriptor<>(testCategory, brokenDesc); - StatementDescriptorTester<TestPojo> tester = new StatementDescriptorTester<>(); - tester.testParseSemantic(desc); // should throw exception - } - - @Test - public void canDetermineGoodDescriptorSemantic() throws DescriptorParsingException { - String goodDesc = "ADD desc-tester-category SET 'bar' = ?l"; - StatementDescriptor<TestPojo> desc = new StatementDescriptor<>(testCategory, goodDesc); - StatementDescriptorTester<TestPojo> tester = new StatementDescriptorTester<>(); - tester.testParseSemantic(desc); // must not throw exception - } - - static class TestPojo implements Pojo { - // empty - } -}