JAMES-2133 Switch from cassandraunit to cassandra in docker It allows to switch between versions easily. Most of the commit is actually fixing James Resource lifecycle
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a18a4488 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a18a4488 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a18a4488 Branch: refs/heads/master Commit: a18a44882d0bbb5766556771710dfa1893b997a0 Parents: 0efe1e3 Author: Matthieu Baechler <matth...@apache.org> Authored: Thu Jun 29 11:27:04 2017 +0200 Committer: Matthieu Baechler <matth...@apache.org> Committed: Sat Sep 2 07:58:48 2017 +0200 ---------------------------------------------------------------------- backends-common/cassandra/pom.xml | 23 +- .../cassandra/CassandraConfiguration.java | 292 ------------------- .../cassandra/init/CassandraConfiguration.java | 292 +++++++++++++++++++ .../init/CassandraSessionConfiguration.java | 29 ++ .../cassandra/init/CassandraTableManager.java | 1 + .../cassandra/init/CassandraTypesCreator.java | 2 +- .../SessionWithInitializedTablesFactory.java | 43 ++- .../cassandra/utils/CassandraUtils.java | 2 +- .../backends/cassandra/CassandraCluster.java | 52 ++-- .../cassandra/CassandraConfigurationTest.java | 232 --------------- .../cassandra/CassandraWaitStrategy.java | 64 ++++ .../backends/cassandra/DockerCassandraRule.java | 147 ++++++++++ .../backends/cassandra/EmbeddedCassandra.java | 50 ---- .../init/CassandraConfigurationTest.java | 233 +++++++++++++++ .../init/CassandraTypeProviderTest.java | 19 +- .../backends/cassandra/utils/PaggingTest.java | 13 +- .../versions/CassandraSchemaVersionDAOTest.java | 8 +- .../src/test/resources/logback-test.xml | 24 ++ .../es/ClientProviderImplConnectionTest.java | 10 +- .../AbstractSubscriptionManagerTest.java | 4 - .../james/mailbox/MailboxManagerStressTest.java | 5 +- .../james/mailbox/MailboxManagerTest.java | 6 +- mailbox/cassandra/pom.xml | 10 +- .../CassandraMailboxSessionMapperFactory.java | 2 +- .../cassandra/mail/CassandraACLMapper.java | 2 +- .../cassandra/mail/CassandraBlobsDAO.java | 4 +- .../cassandra/mail/CassandraMailboxDAO.java | 2 +- .../cassandra/mail/CassandraMailboxMapper.java | 8 +- .../cassandra/mail/CassandraMessageDAO.java | 6 +- .../mail/CassandraMessageIdMapper.java | 2 +- .../cassandra/mail/CassandraMessageMapper.java | 2 +- .../cassandra/mail/CassandraModSeqProvider.java | 2 +- .../cassandra/mail/CassandraUidProvider.java | 2 +- .../CassandraCombinationManagerTest.java | 59 +++- .../CassandraCombinationManagerTestSystem.java | 17 +- .../CassandraMailboxManagerStressTest.java | 49 ++-- .../cassandra/CassandraMailboxManagerTest.java | 54 ++-- .../CassandraMessageIdManagerQuotaTest.java | 62 +++- ...CassandraMessageIdManagerSideEffectTest.java | 56 +++- .../CassandraMessageIdManagerStorageTest.java | 58 +++- .../CassandraMessageIdManagerTestSystem.java | 26 +- .../CassandraSubscriptionManagerTest.java | 33 ++- .../cassandra/CassandraTestSystemFixture.java | 60 +--- ...istributedMailboxDelegatingListenerTest.java | 6 +- ...CassandraMailboxPathRegistrerMapperTest.java | 20 +- .../cassandra/mail/CassandraACLMapperTest.java | 10 +- .../mail/CassandraAnnotationMapperTest.java | 51 +++- .../mail/CassandraApplicableFlagDAOTest.java | 9 +- .../mail/CassandraAttachmentMapperTest.java | 52 +++- .../cassandra/mail/CassandraBlobsDAOTest.java | 22 +- .../mail/CassandraDeletedMessageDAOTest.java | 19 +- .../mail/CassandraFirstUnseenDAOTest.java | 9 +- .../mail/CassandraGenericMailboxMapperTest.java | 51 +++- .../mail/CassandraIndexTableHandlerTest.java | 9 +- .../mail/CassandraMailboxCounterDAOTest.java | 8 +- .../cassandra/mail/CassandraMailboxDAOTest.java | 11 +- .../CassandraMailboxManagerAttachmentTest.java | 41 +-- .../CassandraMailboxMapperConcurrencyTest.java | 21 +- .../mail/CassandraMailboxMapperTest.java | 17 +- .../mail/CassandraMailboxPathDAOTest.java | 9 +- .../mail/CassandraMailboxRecentDAOTest.java | 9 +- .../cassandra/mail/CassandraMapperProvider.java | 41 +-- .../cassandra/mail/CassandraMessageDAOTest.java | 10 +- .../mail/CassandraMessageIdDAOTest.java | 9 +- .../mail/CassandraMessageIdMapperTest.java | 52 +++- .../CassandraMessageIdToImapUidDAOTest.java | 9 +- .../mail/CassandraMessageMapperTest.java | 51 +++- .../mail/CassandraMessageMoveTest.java | 51 +++- ...assandraMessageWithAttachmentMapperTest.java | 51 +++- .../mail/CassandraModSeqProviderTest.java | 15 +- .../mail/CassandraUidProviderTest.java | 19 +- .../quota/CassandraCurrentQuotaManagerTest.java | 13 +- .../CassandraPerUserMaxQuotaManagerTest.java | 8 +- .../user/CassandraSubscriptionMapperTest.java | 14 +- .../src/test/resources/logback-test.xml | 19 ++ .../jcr/JCRMailboxManagerStressTest.java | 6 + .../mailbox/jcr/JCRMailboxManagerTest.java | 6 + .../mailbox/jcr/JCRSubscriptionManagerTest.java | 13 + .../mailbox/jpa/JPAMailboxManagerTest.java | 6 + .../mailbox/jpa/JPASubscriptionManagerTest.java | 6 + .../jpa/JpaMailboxManagerStressTest.java | 6 + .../mailbox/jpa/mail/JPAMapperProvider.java | 10 - .../jpa/mail/JpaAnnotationMapperTest.java | 6 + .../mailbox/jpa/mail/JpaMailboxMapperTest.java | 12 + .../mailbox/jpa/mail/JpaMessageMapperTest.java | 12 + ...mainUserMaildirMailboxManagerStressTest.java | 6 + .../DomainUserMaildirMailboxManagerTest.java | 6 + ...FullUserMaildirMailboxManagerStressTest.java | 6 + .../FullUserMaildirMailboxManagerTest.java | 6 + .../maildir/MaildirSubscriptionManagerTest.java | 13 +- .../UserMaildirMailboxManagerStressTest.java | 6 + .../InMemoryCombinationManagerTest.java | 6 + .../InMemoryCombinationManagerTestSystem.java | 6 - .../InMemoryMessageIdManagerStorageTest.java | 6 + .../InMemoryMessageIdManagerTestSystem.java | 5 - .../MemoryMailboxManagerStressTest.java | 7 + .../inmemory/MemoryMailboxManagerTest.java | 7 + .../InMemoryMailboxManagerAttachmentTest.java | 6 +- .../inmemory/mail/InMemoryMapperProvider.java | 10 - .../mail/MemoryAnnotationMapperTest.java | 7 + .../mail/MemoryAttachmentMapperTest.java | 8 + .../inmemory/mail/MemoryMailboxMapperTest.java | 7 + .../inmemory/mail/MemoryMessageMapperTest.java | 7 + .../inmemory/mail/MemoryMessageMoveTest.java | 6 + .../MemoryMessageWithAttachmentMapperTest.java | 7 + .../store/AbstractCombinationManagerTest.java | 8 +- .../AbstractMailboxManagerAttachmentTest.java | 11 - .../AbstractMessageIdManagerQuotaTest.java | 6 - .../AbstractMessageIdManagerSideEffectTest.java | 7 - .../AbstractMessageIdManagerStorageTest.java | 8 - .../store/CombinationManagerTestSystem.java | 1 - .../store/MessageIdManagerTestSystem.java | 2 - .../StoreMessageIdManagerSideEffectTest.java | 5 + .../store/StoreMessageIdManagerTestSystem.java | 5 - .../store/mail/model/AnnotationMapperTest.java | 12 +- .../store/mail/model/AttachmentMapperTest.java | 11 +- .../store/mail/model/MailboxMapperTest.java | 11 +- .../store/mail/model/MapperProvider.java | 5 +- .../store/mail/model/MessageIdMapperTest.java | 12 +- .../store/mail/model/MessageMapperTest.java | 12 +- .../store/mail/model/MessageMoveTest.java | 12 +- .../model/MessageWithAttachmentMapperTest.java | 12 +- .../james/mailbox/tika/TikaContainer.java | 4 +- .../org/apache/james/mpt/api/HostSystem.java | 4 - .../mpt/script/SimpleScriptedTestProtocol.java | 2 +- mpt/impl/imap-mailbox/cassandra/pom.xml | 5 - .../cassandra/CassandraAuthenticatePlain.java | 9 +- .../cassandra/CassandraAuthenticatedState.java | 9 +- .../cassandra/CassandraConcurrentSessions.java | 9 +- .../cassandra/CassandraCondstore.java | 9 +- .../imapmailbox/cassandra/CassandraCopy.java | 9 +- .../imapmailbox/cassandra/CassandraEvents.java | 9 +- .../imapmailbox/cassandra/CassandraExpunge.java | 9 +- .../imapmailbox/cassandra/CassandraFetch.java | 9 +- .../cassandra/CassandraFetchBodySection.java | 9 +- .../cassandra/CassandraFetchBodyStructure.java | 9 +- .../cassandra/CassandraFetchHeaders.java | 9 +- .../imapmailbox/cassandra/CassandraListing.java | 9 +- .../cassandra/CassandraMailboxAnnotation.java | 9 +- .../cassandra/CassandraMailboxTestModule.java | 10 +- .../CassandraMailboxWithLongNameError.java | 9 +- .../imapmailbox/cassandra/CassandraMove.java | 9 +- .../CassandraNonAuthenticatedState.java | 9 +- .../cassandra/CassandraPartialFetch.java | 9 +- .../cassandra/CassandraQuotaTest.java | 9 +- .../imapmailbox/cassandra/CassandraRename.java | 9 +- .../imapmailbox/cassandra/CassandraSearch.java | 9 +- .../cassandra/CassandraSecurity.java | 9 +- .../imapmailbox/cassandra/CassandraSelect.java | 9 +- .../cassandra/CassandraSelectedInbox.java | 9 +- .../cassandra/CassandraSelectedState.java | 9 +- .../cassandra/CassandraUidSearch.java | 9 +- .../cassandra/CassandraUidSearchOnIndex.java | 9 +- .../cassandra/CassandraUserFlagsSupport.java | 9 +- .../cassandra/host/CassandraHostSystem.java | 30 +- .../james/mpt/host/JamesImapHostSystem.java | 41 +-- .../mpt/imapmailbox/suite/UidSearchOnIndex.java | 2 - .../imap/scripts/CreateErrorWithLongName.test | 2 +- .../host/ElasticSearchHostSystem.java | 6 +- .../hbase/HBaseAuthenticatePlain.java | 1 + .../hbase/HBaseAuthenticatedState.java | 1 + .../hbase/HBaseConcurrentSessions.java | 1 + .../mpt/imapmailbox/hbase/HBaseCondstore.java | 1 + .../james/mpt/imapmailbox/hbase/HBaseCopy.java | 1 + .../mpt/imapmailbox/hbase/HBaseEvents.java | 1 + .../mpt/imapmailbox/hbase/HBaseExpunge.java | 1 + .../james/mpt/imapmailbox/hbase/HBaseFetch.java | 1 + .../hbase/HBaseFetchBodySection.java | 1 + .../hbase/HBaseFetchBodyStructure.java | 1 + .../imapmailbox/hbase/HBaseFetchHeaders.java | 1 + .../mpt/imapmailbox/hbase/HBaseListing.java | 1 + .../hbase/HBaseMailboxAnnotation.java | 1 + .../hbase/HBaseMailboxWithLongNameError.java | 1 + .../hbase/HBaseNonAuthenticatedState.java | 1 + .../imapmailbox/hbase/HBasePartialFetch.java | 1 + .../mpt/imapmailbox/hbase/HBaseQuotaTest.java | 1 + .../mpt/imapmailbox/hbase/HBaseRename.java | 1 + .../mpt/imapmailbox/hbase/HBaseSearch.java | 1 + .../mpt/imapmailbox/hbase/HBaseSecurity.java | 1 + .../mpt/imapmailbox/hbase/HBaseSelect.java | 1 + .../imapmailbox/hbase/HBaseSelectedInbox.java | 1 + .../imapmailbox/hbase/HBaseSelectedState.java | 1 + .../mpt/imapmailbox/hbase/HBaseUidSearch.java | 1 + .../hbase/HBaseUidSearchOnIndex.java | 1 + .../hbase/HBaseUserFlagsSupport.java | 1 + .../imapmailbox/hbase/host/HBaseHostSystem.java | 29 +- .../hbase/src/test/resources/logback-test.xml | 22 ++ .../inmemory/InMemoryAuthenticatePlain.java | 1 + .../inmemory/InMemoryAuthenticatedState.java | 1 + .../inmemory/InMemoryConcurrentSessions.java | 1 + .../imapmailbox/inmemory/InMemoryCondstore.java | 1 + .../mpt/imapmailbox/inmemory/InMemoryCopy.java | 1 + .../imapmailbox/inmemory/InMemoryEvents.java | 1 + .../imapmailbox/inmemory/InMemoryExpunge.java | 1 + .../mpt/imapmailbox/inmemory/InMemoryFetch.java | 1 + .../inmemory/InMemoryFetchBodySection.java | 1 + .../inmemory/InMemoryFetchBodyStructure.java | 1 + .../inmemory/InMemoryFetchHeaders.java | 1 + .../imapmailbox/inmemory/InMemoryListing.java | 1 + .../inmemory/InMemoryMailboxAnnotation.java | 1 + .../InMemoryMailboxWithLongNameSuccess.java | 1 + .../mpt/imapmailbox/inmemory/InMemoryMove.java | 1 + .../inmemory/InMemoryNonAuthenticatedState.java | 1 + .../inmemory/InMemoryPartialFetch.java | 1 + .../imapmailbox/inmemory/InMemoryQuotaTest.java | 1 + .../imapmailbox/inmemory/InMemoryRename.java | 1 + .../imapmailbox/inmemory/InMemorySearch.java | 1 + .../imapmailbox/inmemory/InMemorySecurity.java | 1 + .../imapmailbox/inmemory/InMemorySelect.java | 1 + .../inmemory/InMemorySelectedInbox.java | 1 + .../inmemory/InMemorySelectedState.java | 1 + .../imapmailbox/inmemory/InMemoryUidSearch.java | 1 + .../inmemory/InMemoryUidSearchOnIndex.java | 1 + .../inmemory/InMemoryUserFlagsSupport.java | 1 + .../inmemory/host/InMemoryHostSystem.java | 11 +- .../mpt/imapmailbox/jcr/host/JCRHostSystem.java | 6 +- .../imapmailbox/jpa/JpaAuthenticatePlain.java | 1 + .../imapmailbox/jpa/JpaAuthenticatedState.java | 1 + .../imapmailbox/jpa/JpaConcurrentSessions.java | 1 + .../james/mpt/imapmailbox/jpa/JpaCondstore.java | 1 + .../james/mpt/imapmailbox/jpa/JpaCopy.java | 1 + .../james/mpt/imapmailbox/jpa/JpaEvents.java | 1 + .../james/mpt/imapmailbox/jpa/JpaExpunge.java | 1 + .../james/mpt/imapmailbox/jpa/JpaFetch.java | 1 + .../imapmailbox/jpa/JpaFetchBodySection.java | 1 + .../imapmailbox/jpa/JpaFetchBodyStructure.java | 1 + .../mpt/imapmailbox/jpa/JpaFetchHeaders.java | 1 + .../james/mpt/imapmailbox/jpa/JpaListing.java | 1 + .../imapmailbox/jpa/JpaMailboxAnnotation.java | 1 + .../jpa/JpaNonAuthenticatedState.java | 1 + .../mpt/imapmailbox/jpa/JpaPartialFetch.java | 1 + .../james/mpt/imapmailbox/jpa/JpaQuotaTest.java | 1 + .../james/mpt/imapmailbox/jpa/JpaRename.java | 1 + .../james/mpt/imapmailbox/jpa/JpaSearch.java | 1 + .../james/mpt/imapmailbox/jpa/JpaSecurity.java | 1 + .../james/mpt/imapmailbox/jpa/JpaSelect.java | 1 + .../mpt/imapmailbox/jpa/JpaSelectedInbox.java | 1 + .../mpt/imapmailbox/jpa/JpaSelectedState.java | 1 + .../james/mpt/imapmailbox/jpa/JpaUidSearch.java | 1 + .../imapmailbox/jpa/JpaUidSearchOnIndex.java | 1 + .../imapmailbox/jpa/JpaUserFlagsSupport.java | 1 + .../mpt/imapmailbox/jpa/host/JPAHostSystem.java | 25 +- .../host/LuceneSearchHostSystem.java | 4 +- .../maildir/MaildirAuthenticatePlain.java | 1 + .../maildir/MaildirAuthenticatedState.java | 1 + .../maildir/MaildirConcurrentSessions.java | 1 + .../imapmailbox/maildir/MaildirCondstore.java | 1 + .../mpt/imapmailbox/maildir/MaildirCopy.java | 1 + .../mpt/imapmailbox/maildir/MaildirEvents.java | 1 + .../mpt/imapmailbox/maildir/MaildirExpunge.java | 1 + .../mpt/imapmailbox/maildir/MaildirFetch.java | 1 + .../maildir/MaildirFetchBodySection.java | 1 + .../maildir/MaildirFetchBodyStructure.java | 1 + .../maildir/MaildirFetchHeaders.java | 1 + .../mpt/imapmailbox/maildir/MaildirListing.java | 1 + .../maildir/MaildirNonAuthenticatedState.java | 1 + .../maildir/MaildirPartialFetch.java | 1 + .../mpt/imapmailbox/maildir/MaildirRename.java | 1 + .../mpt/imapmailbox/maildir/MaildirSearch.java | 1 + .../imapmailbox/maildir/MaildirSecurity.java | 1 + .../mpt/imapmailbox/maildir/MaildirSelect.java | 1 + .../maildir/MaildirSelectedInbox.java | 1 + .../maildir/MaildirSelectedState.java | 1 + .../imapmailbox/maildir/MaildirUidSearch.java | 1 + .../maildir/MaildirUidSearchOnIndex.java | 1 + .../maildir/host/MaildirHostSystem.java | 9 +- mpt/impl/managesieve/cassandra/pom.xml | 6 +- .../cassandra/CassandraAuthenticateTest.java | 6 +- .../cassandra/CassandraCapabilityTest.java | 6 +- .../cassandra/CassandraCheckScriptTest.java | 6 +- .../cassandra/CassandraDeleteScriptTest.java | 6 +- .../cassandra/CassandraGetScriptTest.java | 6 +- .../cassandra/CassandraHaveSpaceTest.java | 6 +- .../cassandra/CassandraListScriptsTest.java | 6 +- .../cassandra/CassandraLogoutTest.java | 7 +- .../managesieve/cassandra/CassandraModule.java | 16 +- .../cassandra/CassandraNoopTest.java | 6 +- .../cassandra/CassandraPutScriptTest.java | 6 +- .../cassandra/CassandraRenameScriptTest.java | 6 +- .../cassandra/CassandraSetActiveTest.java | 6 +- .../cassandra/CassandraStartTlsTest.java | 6 +- .../cassandra/CassandraUnauthenticatedTest.java | 6 +- .../cassandra/host/CassandraHostSystem.java | 40 +-- mpt/impl/managesieve/core/pom.xml | 4 + .../mpt/host/JamesManageSieveHostSystem.java | 36 +-- .../managesieve/file/host/FileHostSystem.java | 16 +- mpt/impl/smtp/cassandra/pom.xml | 5 - .../mpt/smtp/CassandraForwardSmtpTest.java | 7 +- .../smtp/CassandraSmtpStarttlsCommandTest.java | 7 +- .../apache/james/mpt/smtp/SmtpTestModule.java | 10 +- .../smtp/host/CassandraJamesSmtpHostSystem.java | 21 +- .../apache/james/mpt/smtp/ForwardSmtpTest.java | 4 +- server/container/guice/cassandra-guice/pom.xml | 6 +- .../mailbox/CassandraSessionConfiguration.java | 29 -- .../modules/mailbox/CassandraSessionModule.java | 147 +--------- .../mailbox/ResilientClusterProvider.java | 178 +++++++++++ .../apache/james/CassandraJamesServerTest.java | 6 +- .../org/apache/james/CassandraJmapTestRule.java | 3 +- .../james/CassandraLogConfigurationTest.java | 8 +- .../CassandraMessageIdManagerInjectionTest.java | 7 +- .../org/apache/james/CassandraNodeConfTest.java | 12 +- .../james/CassandraVersionCheckingTest.java | 10 + .../org/apache/james/CassandraWithTikaTest.java | 2 +- .../james/DefaultCassandraJamesServerTest.java | 6 +- .../org/apache/james/DockerCassandraRule.java | 66 ++--- .../apache/james/DockerElasticSearchRule.java | 14 +- .../java/org/apache/james/ESReporterTest.java | 2 +- .../org/apache/james/EmbeddedCassandraRule.java | 75 ----- .../james/JamesCapabilitiesServerTest.java | 29 +- .../JamesServerWithRetryConnectionTest.java | 21 +- .../modules/CassandraJmapServerModule.java | 17 +- .../mailbox/CassandraSessionModuleTest.java | 2 +- .../guice/cassandra-ldap-guice/pom.xml | 11 +- .../apache/james/CassandraLdapJmapTestRule.java | 2 +- .../apache/james/metric/es/ESReporterTest.java | 4 +- .../util/streams/SwarmGenericContainer.java | 21 +- server/data/data-cassandra/pom.xml | 9 +- .../cassandra/CassandraDomainListTest.java | 18 +- .../CassandraRecipientRewriteTableTest.java | 16 +- .../james/rrt/cassandra/CassandraStepdefs.java | 4 +- .../james/rrt/cassandra/RewriteTablesTest.java | 4 + .../cassandra/CassandraActiveScriptDAOTest.java | 10 +- .../sieve/cassandra/CassandraSieveDAOTest.java | 14 +- .../cassandra/CassandraSieveQuotaDAOTest.java | 12 +- .../cassandra/CassandraSieveRepositoryTest.java | 27 +- .../cassandra/CassandraUsersRepositoryTest.java | 17 +- .../rrt/file/XMLRecipientRewriteTableTest.java | 10 +- .../file/SieveFileRepositoryTest.java | 12 +- .../domainlist/hbase/HBaseDomainListTest.java | 15 + .../hbase/HBaseRecipientRewriteTableTest.java | 11 +- .../jdbc/JDBCMailRepositoryTest.java | 6 - .../rrt/jdbc/JDBCRecipientRewriteTableTest.java | 13 + .../jdbc/DefaultUsersJdbcRepositoryTest.java | 12 + .../user/jdbc/JamesUsersJdbcRepositoryTest.java | 13 + server/data/data-jmap-cassandra/pom.xml | 10 +- .../CassandraAccessTokenRepositoryTest.java | 26 +- .../CassandraNotificationRegistryTest.java | 21 +- .../CassandraVacationRepositoryTest.java | 22 +- .../api/access/AccessTokenRepositoryTest.java | 4 +- .../AbstractVacationRepositoryTest.java | 2 +- .../access/MemoryAccessTokenRepositoryTest.java | 7 + .../james/domainlist/jpa/JPADomainListTest.java | 16 + .../rrt/jpa/JPARecipientRewriteTableTest.java | 12 + .../james/user/jpa/JpaUsersRepositoryTest.java | 9 +- .../james/user/ldap/LdapGenericContainer.java | 10 +- .../ldap/ReadOnlyUsersLDAPRepositoryTest.java | 4 +- .../domainlist/lib/AbstractDomainListTest.java | 25 -- .../lib/AbstractRecipientRewriteTableTest.java | 6 +- .../lib/AbstractSieveRepositoryTest.java | 10 - .../user/lib/AbstractUsersRepositoryTest.java | 4 - .../domainlist/memory/MemoryDomainListTest.java | 6 + .../memory/MemoryRecipientRewriteTableTest.java | 12 + .../user/memory/MemoryUsersRepositoryTest.java | 6 + .../james/transport/mailets/amqp/AmqpRule.java | 2 +- .../cassandra-jmap-integration-testing/pom.xml | 11 +- .../CassandraGetMailboxesMethodTest.java | 7 +- .../CassandraGetMessageListMethodTest.java | 7 +- .../CassandraGetVacationResponseTest.java | 7 +- .../CassandraJmapAuthenticationTest.java | 7 +- .../CassandraSetMailboxesMethodTest.java | 12 +- .../CassandraSetMessagesMethodTest.java | 7 +- .../CassandraSetVacationResponseTest.java | 7 +- ...ssandraUserProvisionningConcurrencyTest.java | 8 +- .../CassandraVacationIntegrationTest.java | 6 +- .../CassandraVacationRelayIntegrationTest.java | 9 +- .../cassandra/cucumber/CassandraStepdefs.java | 10 +- .../org/apache/james/jmap/ContainerTest.java | 4 +- .../jmap/VacationRelayIntegrationTest.java | 3 +- .../protocols/webadmin-integration-test/pom.xml | 11 +- .../integration/JwtFilterIntegrationTest.java | 7 +- .../WebAdminServerIntegrationTest.java | 7 +- 371 files changed, 3265 insertions(+), 1956 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/pom.xml b/backends-common/cassandra/pom.xml index 6b57226..8647f80 100644 --- a/backends-common/cassandra/pom.xml +++ b/backends-common/cassandra/pom.xml @@ -40,6 +40,16 @@ <artifactId>james-server-util-java8</artifactId> </dependency> <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-server-util-java8</artifactId> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-core</artifactId> <version>3.2.0</version> @@ -66,6 +76,11 @@ <artifactId>javax.inject</artifactId> </dependency> <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>net.javacrumbs.future-converter</groupId> <artifactId>future-converter-java8-guava</artifactId> <version>0.3.0</version> @@ -81,13 +96,13 @@ <scope>test</scope> </dependency> <dependency> - <groupId>org.cassandraunit</groupId> - <artifactId>cassandra-unit</artifactId> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency> <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-core</artifactId> + <groupId>org.testcontainers</groupId> + <artifactId>testcontainers</artifactId> <scope>test</scope> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/CassandraConfiguration.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/CassandraConfiguration.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/CassandraConfiguration.java deleted file mode 100644 index f976242..0000000 --- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/CassandraConfiguration.java +++ /dev/null @@ -1,292 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.backends.cassandra; - -import java.util.Objects; -import java.util.Optional; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; - -public class CassandraConfiguration { - public static final CassandraConfiguration DEFAULT_CONFIGURATION = builder().build(); - - public static final int DEFAULT_MESSAGE_CHUNK_SIZE_ON_READ = 100; - public static final int DEFAULT_EXPUNGE_BATCH_SIZE = 100; - public static final int DEFAULT_UPDATE_FLAGS_BATCH_SIZE = 20; - public static final int DEFAULT_FLAGS_UPDATE_MESSAGE_MAX_RETRY = 1000; - public static final int DEFAULT_FLAGS_UPDATE_MESSAGE_ID_MAX_RETRY = 1000; - public static final int DEFAULT_MODSEQ_MAX_RETRY = 100000; - public static final int DEFAULT_UID_MAX_RETRY = 100000; - public static final int DEFAULT_ACL_MAX_RETRY = 1000; - public static final int DEFAULT_FETCH_NEXT_PAGE_ADVANCE_IN_ROW = 100; - public static final int DEFAULT_BLOB_PART_SIZE = 100 * 1024; - - public static class Builder { - private Optional<Integer> messageReadChunkSize = Optional.empty(); - private Optional<Integer> expungeChunkSize = Optional.empty(); - private Optional<Integer> flagsUpdateChunkSize = Optional.empty(); - private Optional<Integer> flagsUpdateMessageIdMaxRetry = Optional.empty(); - private Optional<Integer> flagsUpdateMessageMaxRetry = Optional.empty(); - private Optional<Integer> modSeqMaxRetry = Optional.empty(); - private Optional<Integer> uidMaxRetry = Optional.empty(); - private Optional<Integer> aclMaxRetry = Optional.empty(); - private Optional<Integer> fetchNextPageInAdvanceRow = Optional.empty(); - private Optional<Integer> blobPartSize = Optional.empty(); - - public Builder messageReadChunkSize(int value) { - Preconditions.checkArgument(value > 0, "messageReadChunkSize needs to be strictly positive"); - this.messageReadChunkSize = Optional.of(value); - return this; - } - - public Builder expungeChunkSize(int value) { - Preconditions.checkArgument(value > 0, "expungeChunkSize needs to be strictly positive"); - this.expungeChunkSize = Optional.of(value); - return this; - } - - public Builder flagsUpdateChunkSize(int value) { - Preconditions.checkArgument(value > 0, "flagsUpdateChunkSize needs to be strictly positive"); - this.flagsUpdateChunkSize = Optional.of(value); - return this; - } - - public Builder flagsUpdateMessageIdMaxRetry(int value) { - Preconditions.checkArgument(value > 0, "flagsUpdateMessageIdMaxRetry needs to be strictly positive"); - this.flagsUpdateMessageIdMaxRetry = Optional.of(value); - return this; - } - - public Builder flagsUpdateMessageMaxRetry(int value) { - Preconditions.checkArgument(value > 0, "flagsUpdateMessageMaxRetry needs to be strictly positive"); - this.flagsUpdateMessageMaxRetry = Optional.of(value); - return this; - } - - public Builder modSeqMaxRetry(int value) { - Preconditions.checkArgument(value > 0, "modSeqMaxRetry needs to be strictly positive"); - this.modSeqMaxRetry = Optional.of(value); - return this; - } - - public Builder uidMaxRetry(int value) { - Preconditions.checkArgument(value > 0, "uidMaxRetry needs to be strictly positive"); - this.uidMaxRetry = Optional.of(value); - return this; - } - - public Builder aclMaxRetry(int value) { - Preconditions.checkArgument(value > 0, "aclMaxRetry needs to be strictly positive"); - this.aclMaxRetry = Optional.of(value); - return this; - } - - public Builder fetchNextPageInAdvanceRow(int value) { - Preconditions.checkArgument(value > 0, "fetchNextPageInAdvanceRow needs to be strictly positive"); - this.fetchNextPageInAdvanceRow = Optional.of(value); - return this; - } - - public Builder blobPartSize(int value) { - Preconditions.checkArgument(value > 0, "blobPartSize needs to be strictly positive"); - this.blobPartSize = Optional.of(value); - return this; - } - - public Builder messageReadChunkSize(Optional<Integer> value) { - value.ifPresent(this::messageReadChunkSize); - return this; - } - - public Builder expungeChunkSize(Optional<Integer> value) { - value.ifPresent(this::expungeChunkSize); - return this; - } - - public Builder flagsUpdateChunkSize(Optional<Integer> value) { - value.ifPresent(this::flagsUpdateChunkSize); - return this; - } - - public Builder flagsUpdateMessageIdMaxRetry(Optional<Integer> value) { - value.ifPresent(this::flagsUpdateMessageIdMaxRetry); - return this; - } - - public Builder flagsUpdateMessageMaxRetry(Optional<Integer> value) { - value.ifPresent(this::flagsUpdateMessageMaxRetry); - return this; - } - - public Builder modSeqMaxRetry(Optional<Integer> value) { - value.ifPresent(this::modSeqMaxRetry); - return this; - } - - public Builder uidMaxRetry(Optional<Integer> value) { - value.ifPresent(this::uidMaxRetry); - return this; - } - - public Builder aclMaxRetry(Optional<Integer> value) { - value.ifPresent(this::aclMaxRetry); - return this; - } - - public Builder fetchNextPageInAdvanceRow(Optional<Integer> value) { - value.ifPresent(this::fetchNextPageInAdvanceRow); - return this; - } - - public Builder blobPartSize(Optional<Integer> value) { - value.ifPresent(this::blobPartSize); - return this; - } - - public CassandraConfiguration build() { - return new CassandraConfiguration(aclMaxRetry.orElse(DEFAULT_ACL_MAX_RETRY), - messageReadChunkSize.orElse(DEFAULT_MESSAGE_CHUNK_SIZE_ON_READ), - expungeChunkSize.orElse(DEFAULT_EXPUNGE_BATCH_SIZE), - flagsUpdateChunkSize.orElse(DEFAULT_UPDATE_FLAGS_BATCH_SIZE), - flagsUpdateMessageIdMaxRetry.orElse(DEFAULT_FLAGS_UPDATE_MESSAGE_ID_MAX_RETRY), - flagsUpdateMessageMaxRetry.orElse(DEFAULT_FLAGS_UPDATE_MESSAGE_MAX_RETRY), - modSeqMaxRetry.orElse(DEFAULT_MODSEQ_MAX_RETRY), - uidMaxRetry.orElse(DEFAULT_UID_MAX_RETRY), - fetchNextPageInAdvanceRow.orElse(DEFAULT_FETCH_NEXT_PAGE_ADVANCE_IN_ROW), - blobPartSize.orElse(DEFAULT_BLOB_PART_SIZE)); - } - } - - public static Builder builder() { - return new Builder(); - } - - private final int messageReadChunkSize; - private final int expungeChunkSize; - private final int flagsUpdateChunkSize; - private final int flagsUpdateMessageIdMaxRetry; - private final int flagsUpdateMessageMaxRetry; - private final int modSeqMaxRetry; - private final int uidMaxRetry; - private final int aclMaxRetry; - private final int fetchNextPageInAdvanceRow; - private final int blobPartSize; - - @VisibleForTesting - CassandraConfiguration(int aclMaxRetry, int messageReadChunkSize, int expungeChunkSize, - int flagsUpdateChunkSize, int flagsUpdateMessageIdMaxRetry, int flagsUpdateMessageMaxRetry, - int modSeqMaxRetry, int uidMaxRetry, int fetchNextPageInAdvanceRow, - int blobPartSize) { - this.aclMaxRetry = aclMaxRetry; - this.messageReadChunkSize = messageReadChunkSize; - this.expungeChunkSize = expungeChunkSize; - this.flagsUpdateMessageIdMaxRetry = flagsUpdateMessageIdMaxRetry; - this.flagsUpdateMessageMaxRetry = flagsUpdateMessageMaxRetry; - this.modSeqMaxRetry = modSeqMaxRetry; - this.uidMaxRetry = uidMaxRetry; - this.fetchNextPageInAdvanceRow = fetchNextPageInAdvanceRow; - this.flagsUpdateChunkSize = flagsUpdateChunkSize; - this.blobPartSize = blobPartSize; - } - - public int getBlobPartSize() { - return blobPartSize; - } - - public int getFlagsUpdateChunkSize() { - return flagsUpdateChunkSize; - } - - public int getAclMaxRetry() { - return aclMaxRetry; - } - - public int getMessageReadChunkSize() { - return messageReadChunkSize; - } - - public int getExpungeChunkSize() { - return expungeChunkSize; - } - - public int getFlagsUpdateMessageIdMaxRetry() { - return flagsUpdateMessageIdMaxRetry; - } - - public int getFlagsUpdateMessageMaxRetry() { - return flagsUpdateMessageMaxRetry; - } - - public int getModSeqMaxRetry() { - return modSeqMaxRetry; - } - - public int getUidMaxRetry() { - return uidMaxRetry; - } - - public int getFetchNextPageInAdvanceRow() { - return fetchNextPageInAdvanceRow; - } - - @Override - public final boolean equals(Object o) { - if (o instanceof CassandraConfiguration) { - CassandraConfiguration that = (CassandraConfiguration) o; - - return Objects.equals(this.aclMaxRetry, that.aclMaxRetry) - && Objects.equals(this.messageReadChunkSize, that.messageReadChunkSize) - && Objects.equals(this.expungeChunkSize, that.expungeChunkSize) - && Objects.equals(this.flagsUpdateMessageIdMaxRetry, that.flagsUpdateMessageIdMaxRetry) - && Objects.equals(this.flagsUpdateMessageMaxRetry, that.flagsUpdateMessageMaxRetry) - && Objects.equals(this.modSeqMaxRetry, that.modSeqMaxRetry) - && Objects.equals(this.uidMaxRetry, that.uidMaxRetry) - && Objects.equals(this.flagsUpdateChunkSize, that.flagsUpdateChunkSize) - && Objects.equals(this.fetchNextPageInAdvanceRow, that.fetchNextPageInAdvanceRow) - && Objects.equals(this.blobPartSize, that.blobPartSize); - } - return false; - } - - @Override - public final int hashCode() { - return Objects.hash(aclMaxRetry, messageReadChunkSize, expungeChunkSize, flagsUpdateMessageIdMaxRetry, - flagsUpdateMessageMaxRetry, modSeqMaxRetry, uidMaxRetry, fetchNextPageInAdvanceRow, flagsUpdateChunkSize, - blobPartSize); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("aclMaxRetry", aclMaxRetry) - .add("messageReadChunkSize", messageReadChunkSize) - .add("expungeChunkSize", expungeChunkSize) - .add("flagsUpdateMessageIdMaxRetry", flagsUpdateMessageIdMaxRetry) - .add("flagsUpdateMessageMaxRetry", flagsUpdateMessageMaxRetry) - .add("modSeqMaxRetry", modSeqMaxRetry) - .add("fetchNextPageInAdvanceRow", fetchNextPageInAdvanceRow) - .add("flagsUpdateChunkSize", flagsUpdateChunkSize) - .add("uidMaxRetry", uidMaxRetry) - .add("blobPartSize", blobPartSize) - .toString(); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java new file mode 100644 index 0000000..17945e8 --- /dev/null +++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraConfiguration.java @@ -0,0 +1,292 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.backends.cassandra.init; + +import java.util.Objects; +import java.util.Optional; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; + +public class CassandraConfiguration { + public static final CassandraConfiguration DEFAULT_CONFIGURATION = builder().build(); + + public static final int DEFAULT_MESSAGE_CHUNK_SIZE_ON_READ = 100; + public static final int DEFAULT_EXPUNGE_BATCH_SIZE = 100; + public static final int DEFAULT_UPDATE_FLAGS_BATCH_SIZE = 20; + public static final int DEFAULT_FLAGS_UPDATE_MESSAGE_MAX_RETRY = 1000; + public static final int DEFAULT_FLAGS_UPDATE_MESSAGE_ID_MAX_RETRY = 1000; + public static final int DEFAULT_MODSEQ_MAX_RETRY = 100000; + public static final int DEFAULT_UID_MAX_RETRY = 100000; + public static final int DEFAULT_ACL_MAX_RETRY = 1000; + public static final int DEFAULT_FETCH_NEXT_PAGE_ADVANCE_IN_ROW = 100; + public static final int DEFAULT_BLOB_PART_SIZE = 100 * 1024; + + public static class Builder { + private Optional<Integer> messageReadChunkSize = Optional.empty(); + private Optional<Integer> expungeChunkSize = Optional.empty(); + private Optional<Integer> flagsUpdateChunkSize = Optional.empty(); + private Optional<Integer> flagsUpdateMessageIdMaxRetry = Optional.empty(); + private Optional<Integer> flagsUpdateMessageMaxRetry = Optional.empty(); + private Optional<Integer> modSeqMaxRetry = Optional.empty(); + private Optional<Integer> uidMaxRetry = Optional.empty(); + private Optional<Integer> aclMaxRetry = Optional.empty(); + private Optional<Integer> fetchNextPageInAdvanceRow = Optional.empty(); + private Optional<Integer> blobPartSize = Optional.empty(); + + public Builder messageReadChunkSize(int value) { + Preconditions.checkArgument(value > 0, "messageReadChunkSize needs to be strictly positive"); + this.messageReadChunkSize = Optional.of(value); + return this; + } + + public Builder expungeChunkSize(int value) { + Preconditions.checkArgument(value > 0, "expungeChunkSize needs to be strictly positive"); + this.expungeChunkSize = Optional.of(value); + return this; + } + + public Builder flagsUpdateChunkSize(int value) { + Preconditions.checkArgument(value > 0, "flagsUpdateChunkSize needs to be strictly positive"); + this.flagsUpdateChunkSize = Optional.of(value); + return this; + } + + public Builder flagsUpdateMessageIdMaxRetry(int value) { + Preconditions.checkArgument(value > 0, "flagsUpdateMessageIdMaxRetry needs to be strictly positive"); + this.flagsUpdateMessageIdMaxRetry = Optional.of(value); + return this; + } + + public Builder flagsUpdateMessageMaxRetry(int value) { + Preconditions.checkArgument(value > 0, "flagsUpdateMessageMaxRetry needs to be strictly positive"); + this.flagsUpdateMessageMaxRetry = Optional.of(value); + return this; + } + + public Builder modSeqMaxRetry(int value) { + Preconditions.checkArgument(value > 0, "modSeqMaxRetry needs to be strictly positive"); + this.modSeqMaxRetry = Optional.of(value); + return this; + } + + public Builder uidMaxRetry(int value) { + Preconditions.checkArgument(value > 0, "uidMaxRetry needs to be strictly positive"); + this.uidMaxRetry = Optional.of(value); + return this; + } + + public Builder aclMaxRetry(int value) { + Preconditions.checkArgument(value > 0, "aclMaxRetry needs to be strictly positive"); + this.aclMaxRetry = Optional.of(value); + return this; + } + + public Builder fetchNextPageInAdvanceRow(int value) { + Preconditions.checkArgument(value > 0, "fetchNextPageInAdvanceRow needs to be strictly positive"); + this.fetchNextPageInAdvanceRow = Optional.of(value); + return this; + } + + public Builder blobPartSize(int value) { + Preconditions.checkArgument(value > 0, "blobPartSize needs to be strictly positive"); + this.blobPartSize = Optional.of(value); + return this; + } + + public Builder messageReadChunkSize(Optional<Integer> value) { + value.ifPresent(this::messageReadChunkSize); + return this; + } + + public Builder expungeChunkSize(Optional<Integer> value) { + value.ifPresent(this::expungeChunkSize); + return this; + } + + public Builder flagsUpdateChunkSize(Optional<Integer> value) { + value.ifPresent(this::flagsUpdateChunkSize); + return this; + } + + public Builder flagsUpdateMessageIdMaxRetry(Optional<Integer> value) { + value.ifPresent(this::flagsUpdateMessageIdMaxRetry); + return this; + } + + public Builder flagsUpdateMessageMaxRetry(Optional<Integer> value) { + value.ifPresent(this::flagsUpdateMessageMaxRetry); + return this; + } + + public Builder modSeqMaxRetry(Optional<Integer> value) { + value.ifPresent(this::modSeqMaxRetry); + return this; + } + + public Builder uidMaxRetry(Optional<Integer> value) { + value.ifPresent(this::uidMaxRetry); + return this; + } + + public Builder aclMaxRetry(Optional<Integer> value) { + value.ifPresent(this::aclMaxRetry); + return this; + } + + public Builder fetchNextPageInAdvanceRow(Optional<Integer> value) { + value.ifPresent(this::fetchNextPageInAdvanceRow); + return this; + } + + public Builder blobPartSize(Optional<Integer> value) { + value.ifPresent(this::blobPartSize); + return this; + } + + public CassandraConfiguration build() { + return new CassandraConfiguration(aclMaxRetry.orElse(DEFAULT_ACL_MAX_RETRY), + messageReadChunkSize.orElse(DEFAULT_MESSAGE_CHUNK_SIZE_ON_READ), + expungeChunkSize.orElse(DEFAULT_EXPUNGE_BATCH_SIZE), + flagsUpdateChunkSize.orElse(DEFAULT_UPDATE_FLAGS_BATCH_SIZE), + flagsUpdateMessageIdMaxRetry.orElse(DEFAULT_FLAGS_UPDATE_MESSAGE_ID_MAX_RETRY), + flagsUpdateMessageMaxRetry.orElse(DEFAULT_FLAGS_UPDATE_MESSAGE_MAX_RETRY), + modSeqMaxRetry.orElse(DEFAULT_MODSEQ_MAX_RETRY), + uidMaxRetry.orElse(DEFAULT_UID_MAX_RETRY), + fetchNextPageInAdvanceRow.orElse(DEFAULT_FETCH_NEXT_PAGE_ADVANCE_IN_ROW), + blobPartSize.orElse(DEFAULT_BLOB_PART_SIZE)); + } + } + + public static Builder builder() { + return new Builder(); + } + + private final int messageReadChunkSize; + private final int expungeChunkSize; + private final int flagsUpdateChunkSize; + private final int flagsUpdateMessageIdMaxRetry; + private final int flagsUpdateMessageMaxRetry; + private final int modSeqMaxRetry; + private final int uidMaxRetry; + private final int aclMaxRetry; + private final int fetchNextPageInAdvanceRow; + private final int blobPartSize; + + @VisibleForTesting + CassandraConfiguration(int aclMaxRetry, int messageReadChunkSize, int expungeChunkSize, + int flagsUpdateChunkSize, int flagsUpdateMessageIdMaxRetry, int flagsUpdateMessageMaxRetry, + int modSeqMaxRetry, int uidMaxRetry, int fetchNextPageInAdvanceRow, + int blobPartSize) { + this.aclMaxRetry = aclMaxRetry; + this.messageReadChunkSize = messageReadChunkSize; + this.expungeChunkSize = expungeChunkSize; + this.flagsUpdateMessageIdMaxRetry = flagsUpdateMessageIdMaxRetry; + this.flagsUpdateMessageMaxRetry = flagsUpdateMessageMaxRetry; + this.modSeqMaxRetry = modSeqMaxRetry; + this.uidMaxRetry = uidMaxRetry; + this.fetchNextPageInAdvanceRow = fetchNextPageInAdvanceRow; + this.flagsUpdateChunkSize = flagsUpdateChunkSize; + this.blobPartSize = blobPartSize; + } + + public int getBlobPartSize() { + return blobPartSize; + } + + public int getFlagsUpdateChunkSize() { + return flagsUpdateChunkSize; + } + + public int getAclMaxRetry() { + return aclMaxRetry; + } + + public int getMessageReadChunkSize() { + return messageReadChunkSize; + } + + public int getExpungeChunkSize() { + return expungeChunkSize; + } + + public int getFlagsUpdateMessageIdMaxRetry() { + return flagsUpdateMessageIdMaxRetry; + } + + public int getFlagsUpdateMessageMaxRetry() { + return flagsUpdateMessageMaxRetry; + } + + public int getModSeqMaxRetry() { + return modSeqMaxRetry; + } + + public int getUidMaxRetry() { + return uidMaxRetry; + } + + public int getFetchNextPageInAdvanceRow() { + return fetchNextPageInAdvanceRow; + } + + @Override + public final boolean equals(Object o) { + if (o instanceof CassandraConfiguration) { + CassandraConfiguration that = (CassandraConfiguration) o; + + return Objects.equals(this.aclMaxRetry, that.aclMaxRetry) + && Objects.equals(this.messageReadChunkSize, that.messageReadChunkSize) + && Objects.equals(this.expungeChunkSize, that.expungeChunkSize) + && Objects.equals(this.flagsUpdateMessageIdMaxRetry, that.flagsUpdateMessageIdMaxRetry) + && Objects.equals(this.flagsUpdateMessageMaxRetry, that.flagsUpdateMessageMaxRetry) + && Objects.equals(this.modSeqMaxRetry, that.modSeqMaxRetry) + && Objects.equals(this.uidMaxRetry, that.uidMaxRetry) + && Objects.equals(this.flagsUpdateChunkSize, that.flagsUpdateChunkSize) + && Objects.equals(this.fetchNextPageInAdvanceRow, that.fetchNextPageInAdvanceRow) + && Objects.equals(this.blobPartSize, that.blobPartSize); + } + return false; + } + + @Override + public final int hashCode() { + return Objects.hash(aclMaxRetry, messageReadChunkSize, expungeChunkSize, flagsUpdateMessageIdMaxRetry, + flagsUpdateMessageMaxRetry, modSeqMaxRetry, uidMaxRetry, fetchNextPageInAdvanceRow, flagsUpdateChunkSize, + blobPartSize); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("aclMaxRetry", aclMaxRetry) + .add("messageReadChunkSize", messageReadChunkSize) + .add("expungeChunkSize", expungeChunkSize) + .add("flagsUpdateMessageIdMaxRetry", flagsUpdateMessageIdMaxRetry) + .add("flagsUpdateMessageMaxRetry", flagsUpdateMessageMaxRetry) + .add("modSeqMaxRetry", modSeqMaxRetry) + .add("fetchNextPageInAdvanceRow", fetchNextPageInAdvanceRow) + .add("flagsUpdateChunkSize", flagsUpdateChunkSize) + .add("uidMaxRetry", uidMaxRetry) + .add("blobPartSize", blobPartSize) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraSessionConfiguration.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraSessionConfiguration.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraSessionConfiguration.java new file mode 100644 index 0000000..0e0047d --- /dev/null +++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraSessionConfiguration.java @@ -0,0 +1,29 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.backends.cassandra.init; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; + +public interface CassandraSessionConfiguration { + + PropertiesConfiguration getConfiguration() throws ConfigurationException; + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java index 95db5d9..2897035 100644 --- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java +++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTableManager.java @@ -35,6 +35,7 @@ public class CassandraTableManager { public CassandraTableManager ensureAllTables() { module.moduleTables() + .parallelStream() .forEach(table -> session.execute(table.getCreateStatement())); return this; } http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java index db85376..8154c71 100644 --- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java +++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesCreator.java @@ -34,7 +34,7 @@ public class CassandraTypesCreator { } public void initializeTypes() { - types.forEach((type) -> session.execute(type.getCreateStatement())); + types.parallelStream().forEach((type) -> session.execute(type.getCreateStatement())); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java index 12ae2b2..5fa74f5 100644 --- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java +++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/SessionWithInitializedTablesFactory.java @@ -19,30 +19,55 @@ package org.apache.james.backends.cassandra.init; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.james.backends.cassandra.components.CassandraModule; + import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Session; -import org.apache.james.backends.cassandra.components.CassandraModule; -public class SessionWithInitializedTablesFactory { +@Singleton +public class SessionWithInitializedTablesFactory implements Provider<Session> { + private final static String DEFAULT_KEYSPACE_NAME = "apache_james"; private final CassandraModule module; + private final Session session; - public SessionWithInitializedTablesFactory(CassandraModule module) { + @Inject + public SessionWithInitializedTablesFactory(CassandraSessionConfiguration configuration, Cluster cluster, CassandraModule module) throws ConfigurationException { + String keyspace = configuration.getConfiguration().getString("cassandra.keyspace", DEFAULT_KEYSPACE_NAME); this.module = module; + this.session = createSession(cluster, keyspace); } public Session createSession(Cluster cluster, String keyspace) { Session session = cluster.connect(keyspace); - new CassandraTypesCreator(module, session) - .initializeTypes(); - new CassandraTableManager(module, session) - .ensureAllTables(); + try { + new CassandraTypesCreator(module, session) + .initializeTypes(); + new CassandraTableManager(module, session) + .ensureAllTables(); + return session; + } catch (Exception e) { + session.close(); + throw e; + } + } + + @Override + public Session get() { return session; } - public Session createSession(Cluster cluster) { - return createSession(cluster, DEFAULT_KEYSPACE_NAME); + @PreDestroy + public synchronized void destroy() { + session.close(); } + } http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/utils/CassandraUtils.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/utils/CassandraUtils.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/utils/CassandraUtils.java index 568b2bf..5d6dc33 100644 --- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/utils/CassandraUtils.java +++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/utils/CassandraUtils.java @@ -24,7 +24,7 @@ import java.util.stream.StreamSupport; import javax.inject.Inject; -import org.apache.james.backends.cassandra.CassandraConfiguration; +import org.apache.james.backends.cassandra.init.CassandraConfiguration; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java index 40f6fbe..d649c31 100644 --- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java +++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java @@ -22,9 +22,13 @@ import java.util.Optional; import javax.annotation.PreDestroy; import javax.inject.Inject; +import javax.inject.Named; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.lang.RandomStringUtils; import org.apache.james.backends.cassandra.components.CassandraModule; -import org.apache.james.backends.cassandra.init.CassandraTableManager; +import org.apache.james.backends.cassandra.init.CassandraSessionConfiguration; import org.apache.james.backends.cassandra.init.CassandraTypesProvider; import org.apache.james.backends.cassandra.init.ClusterBuilder; import org.apache.james.backends.cassandra.init.ClusterWithKeyspaceCreatedFactory; @@ -37,8 +41,7 @@ import com.datastax.driver.core.exceptions.NoHostAvailableException; import com.google.common.base.Throwables; public final class CassandraCluster implements AutoCloseable { - private static final String CLUSTER_IP = "localhost"; - private static final String KEYSPACE_NAME = "apache_james"; + private static final int REPLICATION_FACTOR = 1; private static final long SLEEP_BEFORE_RETRY = 200; @@ -48,19 +51,31 @@ public final class CassandraCluster implements AutoCloseable { private Session session; private CassandraTypesProvider typesProvider; private Cluster cluster; + private String keyspace; + private CassandraSessionConfiguration cassandraSessionConfiguration; - public static CassandraCluster create(CassandraModule module) throws RuntimeException { - return new CassandraCluster(module, EmbeddedCassandra.createStartServer()); + public static CassandraCluster create(CassandraModule module, String host, int port) { + return new CassandraCluster(module, host, port); } - + @Inject - private CassandraCluster(CassandraModule module, EmbeddedCassandra embeddedCassandra) throws RuntimeException { + private CassandraCluster(CassandraModule module, @Named("cassandraHost") String host, @Named("cassandraPort") int port) throws RuntimeException { this.module = module; try { cluster = ClusterBuilder.builder() - .host(CLUSTER_IP) - .port(embeddedCassandra.getPort()) + .host(host) + .port(port) .build(); + keyspace = RandomStringUtils.randomAlphabetic(10); + cassandraSessionConfiguration = () -> { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.addProperty("cassandra.nodes", host + ":" + port); + conf.addProperty("cassandra.keyspace", keyspace); + conf.addProperty("cassandra.replication.factor", 1); + conf.addProperty("cassandra.retryConnection.maxRetries", 10); + conf.addProperty("cassandra.retryConnection", 5000); + return conf; + }; session = new FunctionRunnerWithRetry(MAX_RETRY).executeAndRetrieveObject(CassandraCluster.this::tryInitializeSession); typesProvider = new CassandraTypesProvider(module, session); } catch (Exception exception) { @@ -68,30 +83,31 @@ public final class CassandraCluster implements AutoCloseable { } } + + public Session getConf() { return session; } - public void ensureAllTables() { - new CassandraTableManager(module, session).ensureAllTables(); - } - @PreDestroy public void clearAllTables() { - new CassandraTableManager(module, session).clearAllTables(); + session.close(); + cluster.close(); } - + private Optional<Session> tryInitializeSession() { try { Cluster clusterWithInitializedKeyspace = ClusterWithKeyspaceCreatedFactory - .config(getCluster(), KEYSPACE_NAME) + .config(getCluster(), keyspace) .replicationFactor(REPLICATION_FACTOR) .disableDurableWrites() .clusterWithInitializedKeyspace(); - return Optional.of(new SessionWithInitializedTablesFactory(module).createSession(clusterWithInitializedKeyspace, KEYSPACE_NAME)); + return Optional.of(new SessionWithInitializedTablesFactory(cassandraSessionConfiguration, clusterWithInitializedKeyspace, module).createSession(clusterWithInitializedKeyspace, keyspace)); } catch (NoHostAvailableException exception) { sleep(SLEEP_BEFORE_RETRY); return Optional.empty(); + } catch (ConfigurationException e) { + throw new RuntimeException(e); } } @@ -113,6 +129,6 @@ public final class CassandraCluster implements AutoCloseable { @Override public void close() { - cluster.close(); + cluster.closeAsync(); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraConfigurationTest.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraConfigurationTest.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraConfigurationTest.java deleted file mode 100644 index 9366b13..0000000 --- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraConfigurationTest.java +++ /dev/null @@ -1,232 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.backends.cassandra; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.assertj.core.api.JUnitSoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import nl.jqno.equalsverifier.EqualsVerifier; - -public class CassandraConfigurationTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public final JUnitSoftAssertions softly = new JUnitSoftAssertions(); - - @Test - public void cassandraConfigurationShouldRespectBeanContract() { - EqualsVerifier.forClass(CassandraConfiguration.class).verify(); - } - - @Test - public void defaultBuilderShouldConstructDefaultConfiguration() { - assertThat(CassandraConfiguration.builder().build()) - .isEqualTo(CassandraConfiguration.DEFAULT_CONFIGURATION); - } - - @Test - public void aclMaxRetryShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .aclMaxRetry(-1); - } - - @Test - public void aclMaxRetryShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .aclMaxRetry(0); - } - - @Test - public void expungeChunkSizeShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .expungeChunkSize(-1); - } - - @Test - public void expungeChunkSizeShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .expungeChunkSize(0); - } - - @Test - public void messageReadChunkSizeShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .messageReadChunkSize(-1); - } - - @Test - public void messageReadChunkSizeShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .messageReadChunkSize(0); - } - - @Test - public void flagsUpdateChunkSizeShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .flagsUpdateChunkSize(-1); - } - - @Test - public void flagsUpdateChunkSizeShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .flagsUpdateChunkSize(0); - } - - @Test - public void flagsUpdateMessageIdMaxRetryShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .flagsUpdateMessageIdMaxRetry(-1); - } - - @Test - public void flagsUpdateMessageIdMaxRetryShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .flagsUpdateMessageIdMaxRetry(0); - } - - @Test - public void flagsUpdateMessageMaxRetryShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .flagsUpdateMessageMaxRetry(-1); - } - - @Test - public void flagsUpdateMessageMaxRetryShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .flagsUpdateMessageMaxRetry(0); - } - - @Test - public void fetchNextPageInAdvanceRowShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .fetchNextPageInAdvanceRow(-1); - } - - @Test - public void fetchNextPageInAdvanceRowShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .fetchNextPageInAdvanceRow(0); - } - - @Test - public void modSeqMaxRetryShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .modSeqMaxRetry(-1); - } - - @Test - public void modSeqMaxRetryShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .modSeqMaxRetry(0); - } - - @Test - public void uidMaxRetryShouldThrowOnNegativeValue() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .uidMaxRetry(-1); - } - - @Test - public void uidMaxRetryShouldThrowOnZero() { - expectedException.expect(IllegalArgumentException.class); - - CassandraConfiguration.builder() - .uidMaxRetry(0); - } - - @Test - public void builderShouldCreateTheRightObject() { - int aclMaxRetry = 1; - int modSeqMaxRetry = 2; - int uidMaxRetry = 3; - int fetchNextPageInAdvanceRow = 4; - int flagsUpdateMessageMaxRetry = 5; - int flagsUpdateMessageIdMaxRetry = 6; - int flagsUpdateChunkSize = 7; - int messageReadChunkSize = 8; - int expungeChunkSize = 9; - int blobPartSize = 10; - - CassandraConfiguration configuration = CassandraConfiguration.builder() - .aclMaxRetry(aclMaxRetry) - .modSeqMaxRetry(modSeqMaxRetry) - .uidMaxRetry(uidMaxRetry) - .fetchNextPageInAdvanceRow(fetchNextPageInAdvanceRow) - .flagsUpdateMessageMaxRetry(flagsUpdateMessageMaxRetry) - .flagsUpdateMessageIdMaxRetry(flagsUpdateMessageIdMaxRetry) - .flagsUpdateChunkSize(flagsUpdateChunkSize) - .messageReadChunkSize(messageReadChunkSize) - .expungeChunkSize(expungeChunkSize) - .blobPartSize(blobPartSize) - .build(); - - softly.assertThat(configuration.getAclMaxRetry()).isEqualTo(aclMaxRetry); - softly.assertThat(configuration.getModSeqMaxRetry()).isEqualTo(modSeqMaxRetry); - softly.assertThat(configuration.getUidMaxRetry()).isEqualTo(uidMaxRetry); - softly.assertThat(configuration.getFetchNextPageInAdvanceRow()).isEqualTo(fetchNextPageInAdvanceRow); - softly.assertThat(configuration.getFlagsUpdateMessageMaxRetry()).isEqualTo(flagsUpdateMessageMaxRetry); - softly.assertThat(configuration.getFlagsUpdateMessageIdMaxRetry()).isEqualTo(flagsUpdateMessageIdMaxRetry); - softly.assertThat(configuration.getFlagsUpdateChunkSize()).isEqualTo(flagsUpdateChunkSize); - softly.assertThat(configuration.getMessageReadChunkSize()).isEqualTo(messageReadChunkSize); - softly.assertThat(configuration.getExpungeChunkSize()).isEqualTo(expungeChunkSize); - softly.assertThat(configuration.getBlobPartSize()).isEqualTo(blobPartSize); - } - -} http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraWaitStrategy.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraWaitStrategy.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraWaitStrategy.java new file mode 100644 index 0000000..6695a07 --- /dev/null +++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraWaitStrategy.java @@ -0,0 +1,64 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.backends.cassandra; + +import java.io.IOException; +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +import org.rnorth.ducttape.unreliables.Unreliables; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.WaitStrategy; + +import com.google.common.primitives.Ints; + +public class CassandraWaitStrategy implements WaitStrategy { + + private static final Duration DEFAULT_TIMEOUT = Duration.ofMinutes(1); + private Duration timeout = DEFAULT_TIMEOUT; + + public CassandraWaitStrategy() { + this(DEFAULT_TIMEOUT); + } + + public CassandraWaitStrategy(Duration timeout) { + this.timeout = timeout; + } + + @Override + public void waitUntilReady(@SuppressWarnings("rawtypes") GenericContainer container) { + Unreliables.retryUntilTrue(Ints.checkedCast(timeout.getSeconds()), TimeUnit.SECONDS, () -> { + try { + return container + .execInContainer("cqlsh", "-e", "show host") + .getStdout() + .contains("Connected to Test Cluster"); + } catch (IOException|InterruptedException e) { + return false; + } + } + ); + } + + @Override + public WaitStrategy withStartupTimeout(Duration startupTimeout) { + return new CassandraWaitStrategy(startupTimeout); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java new file mode 100644 index 0000000..2579a14 --- /dev/null +++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java @@ -0,0 +1,147 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.backends.cassandra; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.DockerClientFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.output.OutputFrame; +import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.command.CreateVolumeCmd; +import com.github.dockerjava.api.command.RemoveVolumeCmd; +import com.github.dockerjava.api.model.Bind; +import com.github.dockerjava.api.model.Binds; +import com.github.dockerjava.api.model.Volume; + + +public class DockerCassandraRule implements TestRule { + + private static final Logger logger = LoggerFactory.getLogger(DockerCassandraRule.class); + + private static final int CASSANDRA_PORT = 9042; + private static final String CASSANDRA_CONFIG_DIR = "$CASSANDRA_CONFIG"; + private static final String CASSANDRA_YAML = CASSANDRA_CONFIG_DIR + "/cassandra.yaml"; + private static final String CASSANDRA_ENV = CASSANDRA_CONFIG_DIR + "/cassandra-env.sh"; + private static final String JVM_OPTIONS = CASSANDRA_CONFIG_DIR + "/jvm.options"; + + private final GenericContainer<?> cassandraContainer; + private final DockerClient client; + private final CreateVolumeCmd createTmpsFsCmd; + private final RemoveVolumeCmd deleteTmpsFsCmd; + + public DockerCassandraRule() { + String tmpFsName = "cassandraData" + RandomStringUtils.randomAlphabetic(10); + client = DockerClientFactory.instance().client(); + createTmpsFsCmd = client.createVolumeCmd() + .withName(tmpFsName) + .withDriver("local") + .withDriverOpts( + ImmutableMap.of( + "type", "tmpfs", + "device", "tmpfs", + "o", "size=100m")); + deleteTmpsFsCmd = client.removeVolumeCmd(tmpFsName); + boolean deleteOnExit = false; + cassandraContainer = new GenericContainer<>( + new ImageFromDockerfile("cassandra_2_2_10", deleteOnExit) + .withDockerfileFromBuilder(builder -> + builder + .from("cassandra:2.2.10") + .env("ENV CASSANDRA_CONFIG", "/etc/cassandra") + //avoiding token range computation helps starting faster + .run("echo \"JVM_OPTS=\\\"\\$JVM_OPTS -Dcassandra.initial_token=0\\\"\" >> " + CASSANDRA_ENV) + .run("sed -i -e \"s/num_tokens/\\#num_tokens/\" " + CASSANDRA_YAML) + //don't wait for other nodes communication to happen + .run("echo \"JVM_OPTS=\\\"\\$JVM_OPTS -Dcassandra.skip_wait_for_gossip_to_settle=0\\\"\" >> " + CASSANDRA_ENV) + //make sure commit log disk flush won't happen + .run("sed -i -e \"s/commitlog_sync_period_in_ms: 10000/commitlog_sync_period_in_ms: 9999999/\" " + CASSANDRA_YAML) + //auto_bootstrap should be useless when no existing data + .run("echo auto_bootstrap: false >> " + CASSANDRA_YAML) + .run("echo \"-Xms1500M\" >> " + JVM_OPTIONS) + .run("echo \"-Xmx1500M\" >> " + JVM_OPTIONS) + .build())) + .withCreateContainerCmdModifier(cmd -> cmd.getHostConfig().withBinds(new Binds(new Bind(tmpFsName, new Volume("/var/lib/cassandra"))))) + .withCreateContainerCmdModifier(cmd -> cmd.withMemory(2000*1024*1024L)) + .withExposedPorts(CASSANDRA_PORT) + .withLogConsumer(this::displayDockerLog) + .waitingFor(new CassandraWaitStrategy()); + } + + private void displayDockerLog(OutputFrame outputFrame) { + logger.info(outputFrame.getUtf8String()); + } + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + createTmpsFsCmd.exec(); + cassandraContainer.apply(base, description).evaluate(); + } finally { + deleteTmpsFsCmd.exec(); + } + } + }; + } + + public void start() { + createTmpsFsCmd.exec(); + cassandraContainer.start(); + } + + public void stop() { + try { + cassandraContainer.stop(); + } finally { + deleteTmpsFsCmd.exec(); + } + } + + public String getIp() { + return cassandraContainer.getContainerIpAddress(); + } + + public int getBindingPort() { + return cassandraContainer.getMappedPort(CASSANDRA_PORT); + } + + public GenericContainer<?> getRawContainer() { + return cassandraContainer; + } + + public void pause() { + client.pauseContainerCmd(cassandraContainer.getContainerId()); + } + + public void unpause() { + client.unpauseContainerCmd(cassandraContainer.getContainerId()); + } + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/a18a4488/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/EmbeddedCassandra.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/EmbeddedCassandra.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/EmbeddedCassandra.java deleted file mode 100644 index ab0a331..0000000 --- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/EmbeddedCassandra.java +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ -package org.apache.james.backends.cassandra; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.thrift.transport.TTransportException; -import org.cassandraunit.utils.EmbeddedCassandraServerHelper; - -import com.google.common.base.Throwables; - -public class EmbeddedCassandra { - - private int port; - - public static EmbeddedCassandra createStartServer() { - return new EmbeddedCassandra(); - } - - private EmbeddedCassandra() { - try { - EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.CASSANDRA_RNDPORT_YML_FILE, TimeUnit.SECONDS.toMillis(20)); - port = EmbeddedCassandraServerHelper.getNativeTransportPort(); - } catch (ConfigurationException | TTransportException | IOException e) { - Throwables.propagate(e); - } - } - - public int getPort() { - return port; - } -} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org