diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/AbstractServerReplicationTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/AbstractServerReplicationTest.java index 723dfa453bd..211737f2c3c 100755 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/AbstractServerReplicationTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/AbstractServerReplicationTest.java @@ -14,6 +14,11 @@ import com.sap.sse.mongodb.MongoDBService; public abstract class AbstractServerReplicationTest extends com.sap.sse.replication.testsupport.AbstractServerWithSingleServiceReplicationTest { protected ServerReplicationTestSetUp testSetUp; + protected AbstractServerReplicationTest(ServerReplicationTestSetUp testSetUp) { + super(testSetUp); + this.testSetUp = testSetUp; + } + public AbstractServerReplicationTest() { super(new ServerReplicationTestSetUp()); testSetUp = (ServerReplicationTestSetUp) super.testSetUp; diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/ConnectionResetAndReconnectTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/ConnectionResetAndReconnectTest.java index 65da3647ea9..170313fa30c 100644 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/ConnectionResetAndReconnectTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/ConnectionResetAndReconnectTest.java @@ -12,7 +12,6 @@ import java.util.List; import java.util.UUID; import java.util.logging.Logger; -import org.junit.Before; import org.junit.Test; import com.rabbitmq.client.Channel; @@ -33,6 +32,10 @@ import com.sap.sse.replication.impl.ReplicationMasterDescriptorImpl; public class ConnectionResetAndReconnectTest extends AbstractServerReplicationTest { static final Logger logger = Logger.getLogger(ConnectionResetAndReconnectTest.class.getName()); + public ConnectionResetAndReconnectTest() { + super(new ServerReplicationTestSetUp()); + } + public static boolean forceStopDelivery = false; static class QueuingConsumerTest extends QueueingConsumer { @@ -81,9 +84,8 @@ public class ConnectionResetAndReconnectTest extends AbstractServerReplicationTe } - protected static class ServerReplicationTestSetUp extends + private static class ServerReplicationTestSetUp extends com.sap.sailing.server.replication.test.AbstractServerReplicationTest.ServerReplicationTestSetUp { - @Before @Override public void setUp() throws Exception { try { @@ -106,7 +108,7 @@ public class ConnectionResetAndReconnectTest extends AbstractServerReplicationTe /* until here both instances should have the same in-memory state. * now lets add an event on master and stop the messaging queue. */ stopMessagingExchange(); - testSetUp.getReplicaReplicator().startToReplicateFrom(testSetUp.getMasterDescriptor()); + replicaReplicator.startToReplicateFrom(masterDescriptor); Event event = addEventOnMaster(); Thread.sleep(1000); // wait for master queue to get filled assertNull(replica.getEvent(event.getId())); diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/PrematureOperationReceiptTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/PrematureOperationReceiptTest.java index 325e88864d0..9eddbb77f1f 100755 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/PrematureOperationReceiptTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/PrematureOperationReceiptTest.java @@ -15,20 +15,21 @@ import com.sap.sailing.server.operationaltransformation.CreateFlexibleLeaderboar import com.sap.sse.common.Util.Pair; import com.sap.sse.replication.ReplicationMasterDescriptor; import com.sap.sse.replication.impl.ReplicationReceiver; -import com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp.ReplicationServiceTestImpl; public class PrematureOperationReceiptTest extends AbstractServerReplicationTest { - private ReplicationReceiver replicator; + private static ReplicationReceiver replicator; + + public PrematureOperationReceiptTest() { + super(new ServerReplicationTestSetUp()); + } - /** - * Drops the test DB. Sets up master and replica, starts the JMS message broker and registers the replica with the master. - */ - @Before - @Override - public void setUp() throws Exception { - Pair, ReplicationMasterDescriptor> result = - basicSetUp(/* dropDB */ true, /* master=null means create a new one */ null, /* replica=null means create a new one */ null); - replicator = replicaReplicator.startToReplicateFromButDontYetFetchInitialLoad(result.getB(), /* startReplicatorSuspended */ true); + private static class ServerReplicationTestSetUp extends AbstractServerReplicationTest.ServerReplicationTestSetUp { + @Override + public void setUp() throws Exception { + Pair, ReplicationMasterDescriptor> result = + basicSetUp(/* dropDB */ true, /* master=null means create a new one */ null, /* replica=null means create a new one */ null); + replicator = replicaReplicator.startToReplicateFromButDontYetFetchInitialLoad(result.getB(), /* startReplicatorSuspended */ true); + } } /** diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/RaceLogReplicationTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/RaceLogReplicationTest.java index 791aaa82e29..44fb244da54 100755 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/RaceLogReplicationTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/RaceLogReplicationTest.java @@ -38,36 +38,23 @@ import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.RegattaLeaderboard; -import com.sap.sailing.server.RacingEventService; import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard; import com.sap.sailing.server.operationaltransformation.AddColumnToSeries; import com.sap.sailing.server.operationaltransformation.CreateRegattaLeaderboard; import com.sap.sailing.server.operationaltransformation.RenameLeaderboard; import com.sap.sse.common.Util; -import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.MillisecondsTimePoint; -import com.sap.sse.replication.ReplicationMasterDescriptor; -import com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp.ReplicationServiceTestImpl; public class RaceLogReplicationTest extends AbstractLogReplicationTest { - - private Pair, ReplicationMasterDescriptor> replicationDescriptorPair; private RaceLogEvent raceLogEvent; private RaceLogEvent anotherRaceLogEvent; private AbstractLogEventAuthor author = new LogEventAuthorImpl("Test Author", 1); @Before - @Override - public void setUp() throws Exception { + public void createEvents() throws Exception { raceLogEvent = RaceLogEventFactory.INSTANCE.createRaceStatusEvent(new MillisecondsTimePoint(1), author, 42, RaceLogRaceStatus.UNKNOWN); anotherRaceLogEvent = RaceLogEventFactory.INSTANCE.createRaceStatusEvent(new MillisecondsTimePoint(2), author, 42, RaceLogRaceStatus.UNKNOWN); - try { - replicationDescriptorPair = basicSetUp(/* dropDB */ true, null, null); - } catch (Exception e) { - e.printStackTrace(); - tearDown(); - } } @Test @@ -78,7 +65,7 @@ public class RaceLogReplicationTest extends AbstractLogReplicationTest { - - private Pair, ReplicationMasterDescriptor> replicationDescriptorPair; private RegattaLogEvent regattaLogEvent; // private RegattaLogEvent anotherRegattaLogEvent; @@ -38,17 +32,10 @@ public class RegattaLogReplicationTest extends } @Before - @Override - public void setUp() throws Exception { + public void createEvent() throws Exception { final Competitor competitor = TrackBasedTest.createCompetitor("Test Competitor"); regattaLogEvent = new RegattaLogRegisterCompetitorEventImpl(t(0), author, t(0), 0, competitor); // anotherRegattaLogEvent = new RegattaLogRegisterCompetitorEventImpl(t(1), author, t(1), 1, null); - try { - replicationDescriptorPair = basicSetUp(/* dropDB */ true, null, null); - } catch (Exception e) { - e.printStackTrace(); - tearDown(); - } } @Test @@ -58,7 +45,7 @@ public class RegattaLogReplicationTest extends final String fleetName = "Default"; Regatta regatta = setupRegatta(RegattaImpl.getDefaultName(regattaName, BOAT_CLASS_NAME_49er), seriesName, fleetName, BOAT_CLASS_NAME_49er); RegattaLog masterLog = regatta.getRegattaLog(); - replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB()); + replicaReplicator.startToReplicateFrom(masterDescriptor); RegattaLog replicaLog = getReplicaLog(regatta); addAndValidateEventIds(masterLog, replicaLog); } @@ -71,7 +58,7 @@ public class RegattaLogReplicationTest extends Regatta regatta = setupRegatta(RegattaImpl.getDefaultName(regattaName, BOAT_CLASS_NAME_49er), seriesName, fleetName, BOAT_CLASS_NAME_49er); RegattaLog masterLog = regatta.getRegattaLog(); masterLog.add(regattaLogEvent); - replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB()); + replicaReplicator.startToReplicateFrom(masterDescriptor); RegattaLog replicaLog = getReplicaLog(regatta); addAndValidateEventIds(masterLog, replicaLog); } @@ -84,7 +71,7 @@ public class RegattaLogReplicationTest extends Regatta masterRegatta = setupRegatta(RegattaImpl.getDefaultName(regattaName, BOAT_CLASS_NAME_49er), seriesName, fleetName, BOAT_CLASS_NAME_49er); RegattaLog masterLog = masterRegatta.getRegattaLog(); masterLog.add(regattaLogEvent); - replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB()); + replicaReplicator.startToReplicateFrom(masterDescriptor); RegattaLog replicaLog = getReplicaLog(masterRegatta); addAndValidateEventIds(masterLog, replicaLog, regattaLogEvent); } @@ -95,7 +82,7 @@ public class RegattaLogReplicationTest extends FlexibleLeaderboard masterLeaderboard = setupFlexibleLeaderboard(leaderboardName); RegattaLog masterLog = masterLeaderboard.getRegattaLog(); masterLog.add(regattaLogEvent); - replicationDescriptorPair.getA().startToReplicateFrom(replicationDescriptorPair.getB()); + replicaReplicator.startToReplicateFrom(masterDescriptor); RegattaLog replicaLog = getReplicaLog(masterLeaderboard); addAndValidateEventIds(masterLog, replicaLog, regattaLogEvent); } diff --git a/java/com.sap.sse.mail.replication.test/.classpath b/java/com.sap.sse.mail.replication.test/.classpath new file mode 100755 index 00000000000..eca7bdba8f0 --- /dev/null +++ b/java/com.sap.sse.mail.replication.test/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/com.sap.sse.mail.replication.test/.project b/java/com.sap.sse.mail.replication.test/.project new file mode 100755 index 00000000000..51fa2fe50fb --- /dev/null +++ b/java/com.sap.sse.mail.replication.test/.project @@ -0,0 +1,28 @@ + + + com.sap.sse.mail.replication.test + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/java/com.sap.sse.mail.replication.test/.settings/org.eclipse.jdt.core.prefs b/java/com.sap.sse.mail.replication.test/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 00000000000..0c68a61dca8 --- /dev/null +++ b/java/com.sap.sse.mail.replication.test/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/java/com.sap.sse.mail.replication.test/.settings/org.eclipse.pde.core.prefs b/java/com.sap.sse.mail.replication.test/.settings/org.eclipse.pde.core.prefs new file mode 100755 index 00000000000..f29e940a005 --- /dev/null +++ b/java/com.sap.sse.mail.replication.test/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/java/com.sap.sse.mail.replication.test/META-INF/MANIFEST.MF b/java/com.sap.sse.mail.replication.test/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..2757ce82521 --- /dev/null +++ b/java/com.sap.sse.mail.replication.test/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Test +Bundle-SymbolicName: com.sap.sse.mail.replication.test +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: SAP +Fragment-Host: com.sap.sse.mail +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: org.hamcrest;bundle-version="1.1.0", + org.junit4;bundle-version="4.8.2", + com.rabbitmq.client, + com.sap.sse.replication.testsupport, + com.sap.sse.mail.replication.testsupport diff --git a/java/com.sap.sse.mail.replication.test/build.properties b/java/com.sap.sse.mail.replication.test/build.properties new file mode 100755 index 00000000000..34d2e4d2dad --- /dev/null +++ b/java/com.sap.sse.mail.replication.test/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/java/com.sap.sse.mail.replication.test/pom.xml b/java/com.sap.sse.mail.replication.test/pom.xml new file mode 100755 index 00000000000..eb287b53335 --- /dev/null +++ b/java/com.sap.sse.mail.replication.test/pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + root + com.sap.sailing + 1.0.0-SNAPSHOT + + com.sap.sse.mail.replication.test + eclipse-plugin + diff --git a/java/com.sap.sse.mail.replication.test/src/com/sap/sse/mail/replication/test/SimpleMailServiceReplicationTest.java b/java/com.sap.sse.mail.replication.test/src/com/sap/sse/mail/replication/test/SimpleMailServiceReplicationTest.java new file mode 100755 index 00000000000..7692ee59b1e --- /dev/null +++ b/java/com.sap.sse.mail.replication.test/src/com/sap/sse/mail/replication/test/SimpleMailServiceReplicationTest.java @@ -0,0 +1,25 @@ +package com.sap.sse.mail.replication.test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +import org.junit.Test; + +import com.sap.sse.common.mail.MailException; +import com.sap.sse.mail.replication.testsupport.AbstractMailServiceReplicationTest; + +public class SimpleMailServiceReplicationTest extends AbstractMailServiceReplicationTest { + @Test + public void testReplicationOfSendMail() throws InterruptedException, + IllegalAccessException, MailException { + master.sendMail("test@ing.me", "oh what a beatiful mail", "to be sent on this day"); + + replicaReplicator.waitUntilQueueIsEmpty(); + Thread.sleep(3000); + + assertThat("mail was not sent on replica", + AbstractMailServiceReplicationTest.numberOfMailsSent.get(replica), equalTo(null)); + assertThat("mail was sent on master", + AbstractMailServiceReplicationTest.numberOfMailsSent.get(master), equalTo(1)); + } +} diff --git a/java/com.sap.sse.mail.replication.testsupport/.classpath b/java/com.sap.sse.mail.replication.testsupport/.classpath new file mode 100755 index 00000000000..eca7bdba8f0 --- /dev/null +++ b/java/com.sap.sse.mail.replication.testsupport/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/com.sap.sse.mail.replication.testsupport/.project b/java/com.sap.sse.mail.replication.testsupport/.project new file mode 100755 index 00000000000..1d1e9965612 --- /dev/null +++ b/java/com.sap.sse.mail.replication.testsupport/.project @@ -0,0 +1,28 @@ + + + com.sap.sse.mail.replication.testsupport + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/java/com.sap.sse.mail.replication.testsupport/.settings/org.eclipse.jdt.core.prefs b/java/com.sap.sse.mail.replication.testsupport/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 00000000000..0c68a61dca8 --- /dev/null +++ b/java/com.sap.sse.mail.replication.testsupport/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/java/com.sap.sse.mail.replication.testsupport/.settings/org.eclipse.pde.core.prefs b/java/com.sap.sse.mail.replication.testsupport/.settings/org.eclipse.pde.core.prefs new file mode 100755 index 00000000000..f29e940a005 --- /dev/null +++ b/java/com.sap.sse.mail.replication.testsupport/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/java/com.sap.sse.mail.replication.testsupport/META-INF/MANIFEST.MF b/java/com.sap.sse.mail.replication.testsupport/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..84cf686c18a --- /dev/null +++ b/java/com.sap.sse.mail.replication.testsupport/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Test +Bundle-SymbolicName: com.sap.sse.mail.replication.testsupport +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: SAP +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: com.sap.sse.replication, + com.sap.sse.replication.testsupport, + com.sap.sse.mail, + com.sap.sse, + com.sap.sse.common, + org.hamcrest;bundle-version="1.1.0", + org.junit4;bundle-version="4.8.2", + org.mockito.mockito-core;bundle-version="1.10.14", + com.sun.mail.javax.mail;bundle-version="1.4.5" +Export-Package: com.sap.sse.mail.replication.testsupport diff --git a/java/com.sap.sse.mail.replication.testsupport/build.properties b/java/com.sap.sse.mail.replication.testsupport/build.properties new file mode 100755 index 00000000000..34d2e4d2dad --- /dev/null +++ b/java/com.sap.sse.mail.replication.testsupport/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/java/com.sap.sse.mail.replication.testsupport/pom.xml b/java/com.sap.sse.mail.replication.testsupport/pom.xml new file mode 100755 index 00000000000..2ed85a10b24 --- /dev/null +++ b/java/com.sap.sse.mail.replication.testsupport/pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + root + com.sap.sailing + 1.0.0-SNAPSHOT + + com.sap.sse.mail.replication.testsupport + eclipse-plugin + diff --git a/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java b/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java new file mode 100644 index 00000000000..835afedebab --- /dev/null +++ b/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java @@ -0,0 +1,59 @@ +package com.sap.sse.mail.replication.testsupport; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; + +import com.sap.sse.common.mail.MailException; +import com.sap.sse.mail.MailService; +import com.sap.sse.mail.impl.MailServiceImpl; +import com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp; +import com.sap.sse.replication.testsupport.AbstractServerWithSingleServiceReplicationTest; + +public class AbstractMailServiceReplicationTest extends AbstractServerWithSingleServiceReplicationTest { + public AbstractMailServiceReplicationTest() { + super(new MailServerReplicationTestSetUp()); + } + + public static final Map numberOfMailsSent = new HashMap<>(); + + @Before + public void clearNumberOfMailsSent() { + numberOfMailsSent.clear(); + } + + public static MailServiceImpl createMailCountingService(final boolean canSendMail) { + return new MailServiceImpl(null) { + @Override + protected void internalSendMail(String toAddress, String subject, ContentSetter contentSetter) + throws MailException { + if (canSendMail) { + Integer old = numberOfMailsSent.get(this); + numberOfMailsSent.put(this, old == null ? 1 : old + 1); + } + } + }; + } + + public static class MailServerReplicationTestSetUp extends AbstractServerReplicationTestSetUp { + public MailServerReplicationTestSetUp() { + super(); + } + + public MailServerReplicationTestSetUp(int servletPort) { + super(servletPort); + } + + @Override + protected MailServiceImpl createNewMaster() throws MailException { + return createMailCountingService(true); + } + + @Override + protected MailServiceImpl createNewReplica() throws MailException { + return createMailCountingService(false); + } + } + +} diff --git a/java/com.sap.sse.mail/META-INF/MANIFEST.MF b/java/com.sap.sse.mail/META-INF/MANIFEST.MF index ccf3a8d0850..d5aff706f24 100755 --- a/java/com.sap.sse.mail/META-INF/MANIFEST.MF +++ b/java/com.sap.sse.mail/META-INF/MANIFEST.MF @@ -6,7 +6,8 @@ Bundle-Version: 1.0.0.qualifier Bundle-Vendor: SAP Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Activator: com.sap.sse.mail.impl.Activator -Export-Package: com.sap.sse.mail +Export-Package: com.sap.sse.mail, + com.sap.sse.mail.impl Import-Package: javax.mail, javax.mail.internet, org.osgi.framework diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/MailServiceImpl.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/MailServiceImpl.java index 78042958f07..13d0032c104 100644 --- a/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/MailServiceImpl.java +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/MailServiceImpl.java @@ -6,6 +6,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.net.MalformedURLException; +import java.util.HashSet; import java.util.Properties; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -26,9 +27,8 @@ import com.sap.sse.replication.OperationExecutionListener; import com.sap.sse.replication.OperationWithResult; import com.sap.sse.replication.ReplicationMasterDescriptor; import com.sap.sse.replication.impl.OperationWithResultWithIdWrapper; -import com.sap.sse.util.ClearStateTestSupport; -public class MailServiceImpl implements ReplicableMailService, ClearStateTestSupport { +public class MailServiceImpl implements ReplicableMailService { private static final Logger logger = Logger.getLogger(MailServiceImpl.class.getName()); private Properties mailProperties; @@ -39,7 +39,7 @@ public class MailServiceImpl implements ReplicableMailService, ClearStateTestSup */ private ReplicationMasterDescriptor replicatingFromMaster; private final ConcurrentHashMap, OperationExecutionListener> operationExecutionListeners; - private Set> operationsSentToMasterForReplication; + private final Set> operationsSentToMasterForReplication = new HashSet<>(); private ThreadLocal currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster = ThreadLocal .withInitial(() -> false); @@ -56,12 +56,17 @@ public class MailServiceImpl implements ReplicableMailService, ClearStateTestSup } } - private static interface ContentSetter { + protected static interface ContentSetter { void setContent(MimeMessage msg) throws MessagingException; } - private void internalSendMail(String toAddress, String subject, ContentSetter contentSetter) throws MailException { - if (mailProperties != null && mailProperties.containsKey("mail.transport.protocol")) { + private boolean canSendMail() { + return mailProperties != null && mailProperties.containsKey("mail.transport.protocol"); + } + + //protected for testing purposes + protected void internalSendMail(String toAddress, String subject, ContentSetter contentSetter) throws MailException { + if (canSendMail()) { if (toAddress != null) { Session session = Session.getInstance(mailProperties, new SMTPAuthenticator()); MimeMessage msg = new MimeMessage(session); @@ -213,9 +218,4 @@ public class MailServiceImpl implements ReplicableMailService, ClearStateTestSup this.currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster .set(currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster); } - - @Override - public void clearState() throws Exception { - mailProperties.clear(); - } } diff --git a/java/com.sap.sse.replication.testsupport/src/com/sap/sse/replication/testsupport/AbstractServerReplicationTestSetUp.java b/java/com.sap.sse.replication.testsupport/src/com/sap/sse/replication/testsupport/AbstractServerReplicationTestSetUp.java index 2145e775726..df85fc4ce60 100644 --- a/java/com.sap.sse.replication.testsupport/src/com/sap/sse/replication/testsupport/AbstractServerReplicationTestSetUp.java +++ b/java/com.sap.sse.replication.testsupport/src/com/sap/sse/replication/testsupport/AbstractServerReplicationTestSetUp.java @@ -51,7 +51,15 @@ public abstract class AbstractServerReplicationTestSetUp replicaReplicator; private ReplicaDescriptor replicaDescriptor; private ReplicationServiceImpl masterReplicator; - protected ReplicationMasterDescriptor masterDescriptor; + protected ReplicationMasterDescriptor masterDescriptor; + + protected AbstractServerReplicationTestSetUp() { + servletPort = DEFAULT_SERVLET_PORT; + } + + protected AbstractServerReplicationTestSetUp(int servletPort) { + this.servletPort = servletPort; + } protected AbstractServerReplicationTestSetUp() { servletPort = DEFAULT_SERVLET_PORT; diff --git a/java/com.sap.sse.security.replication.test/META-INF/MANIFEST.MF b/java/com.sap.sse.security.replication.test/META-INF/MANIFEST.MF index a73b2c7998e..69111890757 100644 --- a/java/com.sap.sse.security.replication.test/META-INF/MANIFEST.MF +++ b/java/com.sap.sse.security.replication.test/META-INF/MANIFEST.MF @@ -6,10 +6,14 @@ Bundle-Version: 1.0.0.qualifier Bundle-Vendor: SAP Fragment-Host: com.sap.sse.security Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Require-Bundle: org.junit4;bundle-version="4.8.2", +Require-Bundle: org.hamcrest;bundle-version="1.1.0", + org.junit4;bundle-version="4.8.2", com.sap.sse.security.userstore.mongodb, com.sap.sse.mongodb, com.rabbitmq.client, org.mongodb.mongo-java-driver;bundle-version="2.13.0", com.sap.sse.replication.testsupport, - com.sap.sse.mail.replication.testsupport + com.sap.sse.mail.replication.testsupport, + org.objenesis;bundle-version="2.1.0", + org.mockito.mockito-core;bundle-version="1.10.14" +Import-Package: org.osgi.util.tracker;version="1.5.1" diff --git a/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/AbstractSecurityReplicationTest.java b/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/AbstractSecurityReplicationTest.java index af5d80c108d..97fec10c49c 100755 --- a/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/AbstractSecurityReplicationTest.java +++ b/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/AbstractSecurityReplicationTest.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.net.MalformedURLException; import com.sap.sse.mongodb.MongoDBService; +import com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp; import com.sap.sse.replication.testsupport.AbstractServerWithSingleServiceReplicationTest; import com.sap.sse.security.SecurityService; import com.sap.sse.security.impl.SecurityServiceImpl; @@ -11,10 +12,10 @@ import com.sap.sse.security.userstore.mongodb.UserStoreImpl; public abstract class AbstractSecurityReplicationTest extends AbstractServerWithSingleServiceReplicationTest { public AbstractSecurityReplicationTest() { - super(new ServerReplicationTestSetUp()); + super(new SecurityServerReplicationTestSetUp()); } - private static class ServerReplicationTestSetUp extends com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp { + public static class SecurityServerReplicationTestSetUp extends AbstractServerReplicationTestSetUp { private MongoDBService mongoDBService; @Override diff --git a/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/SecurityReplicationLeadingToEmailReplicationTest.java b/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/SecurityReplicationLeadingToEmailReplicationTest.java new file mode 100644 index 00000000000..804ab07da17 --- /dev/null +++ b/java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/SecurityReplicationLeadingToEmailReplicationTest.java @@ -0,0 +1,152 @@ +package com.sap.sse.security.replication.test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +import java.io.IOException; +import java.net.MalformedURLException; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.osgi.util.tracker.ServiceTracker; + +import com.sap.sse.common.mail.MailException; +import com.sap.sse.mail.MailService; +import com.sap.sse.mail.impl.MailServiceImpl; +import com.sap.sse.mail.replication.testsupport.AbstractMailServiceReplicationTest; +import com.sap.sse.replication.testsupport.AbstractServerWithMultipleServicesReplicationTest; +import com.sap.sse.security.SecurityService; +import com.sap.sse.security.impl.SecurityServiceImpl; +import com.sap.sse.security.shared.UserManagementException; +import com.sap.sse.security.userstore.mongodb.UserStoreImpl; + +/** + * See if transitively triggered email operation ultimately behaves well and results in only one outbound email. + * + * @author Fredrik Teschke + */ +public class SecurityReplicationLeadingToEmailReplicationTest extends AbstractServerWithMultipleServicesReplicationTest { + private final SecurityServerReplicationTestSetUp securitySetUp = new SecurityServerReplicationTestSetUp(); + private final MailServerReplicationTestSetUp mailSetUp = new MailServerReplicationTestSetUp(); + + private MailServiceImpl masterMailService; + private MailServiceImpl replicaMailService; + + @Before + @Override + public void setUp() throws Exception { + masterMailService = AbstractMailServiceReplicationTest.createMailCountingService(true); + replicaMailService = AbstractMailServiceReplicationTest.createMailCountingService(false); + AbstractMailServiceReplicationTest.numberOfMailsSent.clear(); + super.setUp(); + } + + private class SecurityServerReplicationTestSetUp extends + AbstractSecurityReplicationTest.SecurityServerReplicationTestSetUp { + @Override + protected SecurityServiceImpl createNewMaster() throws MalformedURLException, IOException, InterruptedException { + @SuppressWarnings("unchecked") + ServiceTracker trackerMock = mock(ServiceTracker.class); + doReturn(masterMailService).when(trackerMock).getService(); + SecurityServiceImpl result = new SecurityServiceImpl(trackerMock, new UserStoreImpl()); + result.clearReplicaState(); + return result; + } + + @Override + protected SecurityServiceImpl createNewReplica() { + @SuppressWarnings("unchecked") + ServiceTracker trackerMock = mock(ServiceTracker.class); + doReturn(replicaMailService).when(trackerMock).getService(); + SecurityServiceImpl result = new SecurityServiceImpl(trackerMock, new UserStoreImpl()); + return result; + } + } + + private class MailServerReplicationTestSetUp extends AbstractMailServiceReplicationTest.MailServerReplicationTestSetUp { + private static final int SERVLET_PORT = 9991; + + public MailServerReplicationTestSetUp() { + super(SERVLET_PORT); + } + + @Override + protected MailServiceImpl createNewMaster() throws MailException { + return masterMailService; + } + + @Override + protected MailServiceImpl createNewReplica() throws MailException { + return replicaMailService; + } + } + + public SecurityReplicationLeadingToEmailReplicationTest() { + testSetUps.add(securitySetUp); + testSetUps.add(mailSetUp); + } + + /** + * See if sending an email (triggered by creating the user on the master) results in only one mail being sent + * (on the master). + */ + @Test + public void triggerEmailSendByAddingUserOnMaster() + throws UserManagementException, MailException, IllegalAccessException, InterruptedException { + //TODO IllegalStateExceptions thrown, probably because the two replication services per instance share the + //same message queue, but don't know about each other (unlike actual OSGi setup, where there is only + //one replication service per instance that nows all Replicables) + SecurityService masterSecurityService = securitySetUp.getMaster(); + + final String username = "Ernie"; + final String email = "ernie@sesame-street.com"; + final String password = "BertMyFriend"; + final String validationBaseURL = null; //so that validation email is not sent + + masterSecurityService.createSimpleUser(username, email, password, validationBaseURL); + + masterSecurityService.sendMail(username, "subject", "body"); + + securitySetUp.getReplicaReplicator().waitUntilQueueIsEmpty(); + mailSetUp.getReplicaReplicator().waitUntilQueueIsEmpty(); + Thread.sleep(3000); + + assertThat("mail was not sent on replica", + AbstractMailServiceReplicationTest.numberOfMailsSent.get(replicaMailService), equalTo(null)); + assertThat("mail was sent on master", + AbstractMailServiceReplicationTest.numberOfMailsSent.get(masterMailService), equalTo(1)); + } + + + /** + * Try the other way round - have to ignore for now, no replication test seems to try applying + * operations on the replica. + */ + @Test + @Ignore + public void triggerEmailSendByAddingUserOnReplica() + throws UserManagementException, MailException, IllegalAccessException, InterruptedException { + SecurityService replicaSecurityService = securitySetUp.getReplica(); + + final String username = "Ernie"; + final String email = "ernie@sesame-street.com"; + final String password = "BertMyFriend"; + final String validationBaseURL = null; //so that validation email is not sent + + replicaSecurityService.createSimpleUser(username, email, password, validationBaseURL); + + replicaSecurityService.sendMail(username, "subject", "body"); + + securitySetUp.getReplicaReplicator().waitUntilQueueIsEmpty(); + mailSetUp.getReplicaReplicator().waitUntilQueueIsEmpty(); + Thread.sleep(3000); + + assertThat("mail was not sent on replica", + AbstractMailServiceReplicationTest.numberOfMailsSent.get(replicaMailService), equalTo(null)); + assertThat("mail was sent on master", + AbstractMailServiceReplicationTest.numberOfMailsSent.get(masterMailService), equalTo(1)); + } +} diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java b/java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java index 00ba1efcd8a..9424aed58a4 100644 --- a/java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java @@ -185,6 +185,10 @@ public class SecurityServiceImpl extends RemoteServiceServlet implements Replica } } } + + private MailService getMailService() { + return mailServiceTracker == null ? null : mailServiceTracker.getService(); + } @Override public void sendMail(String username, String subject, String body) throws MailException { @@ -192,7 +196,12 @@ public class SecurityServiceImpl extends RemoteServiceServlet implements Replica if (user != null) { final String toAddress = user.getEmail(); if (toAddress != null) { - mailServiceTracker.getService().sendMail(username, subject, body); + MailService mailService = getMailService(); + if (mailService == null) { + logger.warning(String.format("Could not send mail to user %s: no MailService found", username)); + } else { + getMailService().sendMail(username, subject, body); + } } } } diff --git a/java/pom.xml b/java/pom.xml index d3fbc338c41..0ce55ac73db 100755 --- a/java/pom.xml +++ b/java/pom.xml @@ -16,7 +16,9 @@ com.sap.sse com.sap.sse.common com.sap.sse.shared.android - com.sap.sse.mail + com.sap.sse.mail + com.sap.sse.mail.replication.test + com.sap.sse.mail.replication.testsupport com.sap.sse.mongodb com.sap.sse.gwt com.sap.sse.gwt.adminconsole