From c936dffc8a7a4649fab7daf9ab3e5173d3598e63 Mon Sep 17 00:00:00 2001 From: Justin Cooke Date: Tue, 12 Dec 2017 14:19:21 +0000 Subject: [PATCH] Add IT for replays --- .../src/test/resources/log4j.properties | 7 + framework-tools-replay/start.sh | 8 + .../framework-event-listener/pom.xml | 35 +++ .../listener/FrameworkToolsTestListener.java | 20 ++ .../framework-event-listener.messaging.raml | 10 + .../raml/json/framework.example-test.json | 3 + .../json/schema/framework.example-test.json | 9 + .../src/main/resources/META-INF/beans.xml | 8 + .../framework-tools-it/pom.xml | 166 ++++++++++++ .../tools/replay/ReplayIntegrationIT.java | 176 +++++++++++++ .../tools/replay/TestEventLogRepository.java | 67 +++++ .../tools/replay/TestProperties.java | 41 +++ .../src/test/resources/standalone-ds.xml | 245 ++++++++++++++++++ .../src/test/resources/test.properties | 6 + framework-tools-test/pom.xml | 19 ++ pom.xml | 3 +- 16 files changed, 822 insertions(+), 1 deletion(-) create mode 100644 framework-tools-replay/src/test/resources/log4j.properties create mode 100644 framework-tools-test/framework-event-listener/pom.xml create mode 100644 framework-tools-test/framework-event-listener/src/main/java/uk/gov/justice/framework/tools/listener/FrameworkToolsTestListener.java create mode 100644 framework-tools-test/framework-event-listener/src/main/raml/framework-event-listener.messaging.raml create mode 100644 framework-tools-test/framework-event-listener/src/main/raml/json/framework.example-test.json create mode 100644 framework-tools-test/framework-event-listener/src/main/raml/json/schema/framework.example-test.json create mode 100644 framework-tools-test/framework-event-listener/src/main/resources/META-INF/beans.xml create mode 100644 framework-tools-test/framework-tools-it/pom.xml create mode 100644 framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/ReplayIntegrationIT.java create mode 100644 framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/TestEventLogRepository.java create mode 100644 framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/TestProperties.java create mode 100644 framework-tools-test/framework-tools-it/src/test/resources/standalone-ds.xml create mode 100644 framework-tools-test/framework-tools-it/src/test/resources/test.properties create mode 100644 framework-tools-test/pom.xml diff --git a/framework-tools-replay/src/test/resources/log4j.properties b/framework-tools-replay/src/test/resources/log4j.properties new file mode 100644 index 0000000..e9b2392 --- /dev/null +++ b/framework-tools-replay/src/test/resources/log4j.properties @@ -0,0 +1,7 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=INFO, A1 +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file diff --git a/framework-tools-replay/start.sh b/framework-tools-replay/start.sh index 0feb617..ec94409 100755 --- a/framework-tools-replay/start.sh +++ b/framework-tools-replay/start.sh @@ -12,3 +12,11 @@ java -jar target/event-buffer-liquibase-0.33.0.jar --url=jdbc:postgresql://local # Replay event streams java -jar target/framework-tools-replay-1.0.0-SNAPSHOT-swarm.jar replay -c standalone-ds.xml -l notification-event-listener-1.0.12-SNAPSHOT.war + + + + + + +java -jar /Users/justin/code/framework-tools/framework-tools-test/framework-tools-it/target/test-classes/framework-tools-replay-2.1.0-SNAPSHOT-swarm.jar replay -c /Users/justin/code/framework-tools/framework-tools-test/framework-tools-it/target/test-classes/standalone-ds.xml -l /Users/justin/code/framework-tools/framework-tools-test/framework-tools-it/target/test-classes/framework-tools-test-listener-1.0.0.war +ID: \ No newline at end of file diff --git a/framework-tools-test/framework-event-listener/pom.xml b/framework-tools-test/framework-event-listener/pom.xml new file mode 100644 index 0000000..3b7317d --- /dev/null +++ b/framework-tools-test/framework-event-listener/pom.xml @@ -0,0 +1,35 @@ + + + + framework-tools-test + uk.gov.justice + 2.1.0-SNAPSHOT + + 4.0.0 + + uk.gov.justice.framework.tools + framework-tools-test-listener + 1.0.0 + + war + + + EVENT_LISTENER + + + + + uk.gov.justice.services + event-listener + ${framework.version} + + + javax + javaee-api + provided + + + + \ No newline at end of file diff --git a/framework-tools-test/framework-event-listener/src/main/java/uk/gov/justice/framework/tools/listener/FrameworkToolsTestListener.java b/framework-tools-test/framework-event-listener/src/main/java/uk/gov/justice/framework/tools/listener/FrameworkToolsTestListener.java new file mode 100644 index 0000000..c4ab566 --- /dev/null +++ b/framework-tools-test/framework-event-listener/src/main/java/uk/gov/justice/framework/tools/listener/FrameworkToolsTestListener.java @@ -0,0 +1,20 @@ +package uk.gov.justice.framework.tools.listener; + +import uk.gov.justice.services.core.annotation.Component; +import uk.gov.justice.services.core.annotation.Handles; +import uk.gov.justice.services.core.annotation.ServiceComponent; +import uk.gov.justice.services.messaging.JsonEnvelope; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ServiceComponent(value = Component.EVENT_LISTENER) +public class FrameworkToolsTestListener { + + private static final Logger logger = LoggerFactory.getLogger(FrameworkToolsTestListener.class); + + @Handles("framework.example-test") + public void handle(final JsonEnvelope envelope) { + logger.info("caught a fish!"); + } +} diff --git a/framework-tools-test/framework-event-listener/src/main/raml/framework-event-listener.messaging.raml b/framework-tools-test/framework-event-listener/src/main/raml/framework-event-listener.messaging.raml new file mode 100644 index 0000000..e683e94 --- /dev/null +++ b/framework-tools-test/framework-event-listener/src/main/raml/framework-event-listener.messaging.raml @@ -0,0 +1,10 @@ +#%RAML 0.8 +title: API Using media type in the URL +baseUri: message://event/listener/message/cakeshop +version: v1 +/example.event: + post: + body: + application/vnd.framework.example-test+json: + schema: !include json/schema/framework.example-test.json + example: !include json/framework.example-test.json \ No newline at end of file diff --git a/framework-tools-test/framework-event-listener/src/main/raml/json/framework.example-test.json b/framework-tools-test/framework-event-listener/src/main/raml/json/framework.example-test.json new file mode 100644 index 0000000..babbe6f --- /dev/null +++ b/framework-tools-test/framework-event-listener/src/main/raml/json/framework.example-test.json @@ -0,0 +1,3 @@ +{ + "test":"test" +} \ No newline at end of file diff --git a/framework-tools-test/framework-event-listener/src/main/raml/json/schema/framework.example-test.json b/framework-tools-test/framework-event-listener/src/main/raml/json/schema/framework.example-test.json new file mode 100644 index 0000000..65b4690 --- /dev/null +++ b/framework-tools-test/framework-event-listener/src/main/raml/json/schema/framework.example-test.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "test": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/framework-tools-test/framework-event-listener/src/main/resources/META-INF/beans.xml b/framework-tools-test/framework-event-listener/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..a0aaf44 --- /dev/null +++ b/framework-tools-test/framework-event-listener/src/main/resources/META-INF/beans.xml @@ -0,0 +1,8 @@ + + + + diff --git a/framework-tools-test/framework-tools-it/pom.xml b/framework-tools-test/framework-tools-it/pom.xml new file mode 100644 index 0000000..06a4591 --- /dev/null +++ b/framework-tools-test/framework-tools-it/pom.xml @@ -0,0 +1,166 @@ + + + + framework-tools-test + uk.gov.justice + 2.1.0-SNAPSHOT + + 4.0.0 + + framework-tools-it + + + + + + + + + com.h2database + h2 + test + 1.4.187 + + + uk.gov.justice.utils + test-utils-core + ${test.utils.core.version} + test + + + com.h2database + h2 + + + + + junit + junit + test + + + org.hamcrest + hamcrest-library + test + + + uk.gov.justice.services + framework-api-messaging + ${framework.version} + test + + + uk.gov.justice.services + test-utils-core + ${framework.version} + test + + + + uk.gov.justice.services + event-repository-liquibase + ${framework.version} + test + + + uk.gov.justice.services + aggregate-snapshot-repository-liquibase + ${framework.version} + test + + + uk.gov.justice.services + event-buffer-liquibase + ${framework.version} + test + + + uk.gov.justice.utils + test-utils-logging-simple + pom + test + 1.5.0 + + + + + + + + com.edugility + h2-maven-plugin + + 8092 + + + + Spawn a new H2 TCP server + pre-integration-test + + spawn + + + + Stop a spawned H2 TCP server + post-integration-test + + stop + + + + + + com.h2database + h2 + 1.4.187 + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy + generate-test-sources + + copy + + + + + + + uk.gov.justice.framework.tools + framework-tools-test-listener + 1.0.0 + war + true + ${project.basedir}/target/test-classes + + + framework-tools + uk.gov.justice + ${project.version} + framework-tools-replay + jar + swarm + true + ${project.basedir}/target/test-classes + + + + false + true + + + + + \ No newline at end of file diff --git a/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/ReplayIntegrationIT.java b/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/ReplayIntegrationIT.java new file mode 100644 index 0000000..f9ac406 --- /dev/null +++ b/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/ReplayIntegrationIT.java @@ -0,0 +1,176 @@ +package uk.gov.justice.framework.tools.replay; + + +import static java.util.UUID.randomUUID; +import static org.junit.Assert.assertTrue; +import static uk.gov.justice.services.messaging.JsonObjectMetadata.metadataWithRandomUUID; +import static uk.gov.justice.services.test.utils.core.messaging.JsonEnvelopeBuilder.envelope; + +import uk.gov.justice.services.eventsourcing.repository.jdbc.eventlog.EventLog; +import uk.gov.justice.services.eventsourcing.repository.jdbc.exception.InvalidSequenceIdException; +import uk.gov.justice.services.messaging.JsonEnvelope; +import uk.gov.justice.services.messaging.Metadata; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.InputStreamReader; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.time.ZonedDateTime; +import java.util.UUID; +import java.util.regex.Pattern; + +import javax.sql.DataSource; + +import liquibase.Liquibase; +import liquibase.database.jvm.JdbcConnection; +import liquibase.resource.ClassLoaderResourceAccessor; +import org.apache.commons.dbcp2.BasicDataSource; +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ReplayIntegrationIT { + + private static final String SWARM_DEBUG_MODE = "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"; + + private static final TestProperties TEST_PROPERTIES = new TestProperties("test.properties"); + private static final String H2_DRIVER = "org.h2.Driver"; + + private static final UUID STREAM_ID = randomUUID(); + + private static TestEventLogRepository EVENT_LOG_REPOSITORY; + + + @Before + public void setUpDB() throws Exception { + EVENT_LOG_REPOSITORY = new TestEventLogRepository(initEventStoreDb()); + } + + @Test + public void runReplayTool() throws Exception { + final String command = createCommandToExecuteReplay(); + + final UUID streamId = randomUUID(); + insertEventLogData(streamId); + final boolean matches = runCommand(command); + assertTrue(matches); + } + + @After + public void tearDown() throws SQLException { + final PreparedStatement preparedStatement = EVENT_LOG_REPOSITORY.getDataSource().getConnection().prepareStatement("delete from event_log"); + preparedStatement.executeUpdate(); + EVENT_LOG_REPOSITORY.getDataSource().getConnection().close(); + } + + private static DataSource initEventStoreDb() throws Exception { + return initDatabase("db.eventstore.url", "db.eventstore.userName", + "db.eventstore.password", "liquibase/event-store-db-changelog.xml", "liquibase/snapshot-store-db-changelog.xml", "liquibase/event-buffer-changelog.xml"); + } + + private EventLog eventLogFrom(final String eventName) { + + final JsonEnvelope jsonEnvelope = envelope() + .with(metadataWithRandomUUID(eventName) + .createdAt(ZonedDateTime.now()) + .withStreamId(STREAM_ID).withVersion(1L)) + .withPayloadOf("test", "a string") + .build(); + + final Metadata metadata = jsonEnvelope.metadata(); + final UUID id = metadata.id(); + + final UUID streamId = metadata.streamId().get(); + final Long sequenceId = 1L; + final String name = metadata.name(); + final String payload = jsonEnvelope.payloadAsJsonObject().toString(); + final ZonedDateTime createdAt = metadata.createdAt().get(); + + return new EventLog(id, streamId, sequenceId, name, metadata.asJsonObject().toString(), payload, createdAt); + } + + + private String createCommandToExecuteReplay() { + + final String replayJarLocation = getResource("framework-tools-replay*.jar"); + final String standaloneDSLocation = getResource("standalone-ds.xml"); + final String listenerLocation = getResource("framework-tools-test-listener*.war"); + + String deubug = ""; + + if (TEST_PROPERTIES.value("swarm.debug").equals("true")) { + deubug = SWARM_DEBUG_MODE; + } + + final String command = commandFrom(deubug, replayJarLocation, standaloneDSLocation, listenerLocation); + + return command; + } + + private String commandFrom(final String debugString, + final String replayJarLocation, + final String standaloneDSLocation, + final String listenerLocation) { + return String.format("java -jar %s %s replay -c %s -l %s", + debugString, + replayJarLocation, + standaloneDSLocation, + listenerLocation); + } + + private static DataSource initDatabase(final String dbUrlPropertyName, + final String dbUserNamePropertyName, + final String dbPasswordPropertyName, + final String... liquibaseChangeLogXmls) throws Exception { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(H2_DRIVER); + + dataSource.setUrl(TEST_PROPERTIES.value(dbUrlPropertyName)); + dataSource.setUsername(TEST_PROPERTIES.value(dbUserNamePropertyName)); + dataSource.setPassword(TEST_PROPERTIES.value(dbPasswordPropertyName)); + boolean dropped = false; + final JdbcConnection jdbcConnection = new JdbcConnection(dataSource.getConnection()); + + for (String liquibaseChangeLogXml : liquibaseChangeLogXmls) { + Liquibase liquibase = new Liquibase(liquibaseChangeLogXml, + new ClassLoaderResourceAccessor(), jdbcConnection); + if (!dropped) { + liquibase.dropAll(); + dropped = true; + } + liquibase.update(""); + } + return dataSource; + } + + private String getResource(final String pattern) { + final File dir = new File(this.getClass().getClassLoader().getResource("").getPath()); + final FileFilter fileFilter = new WildcardFileFilter(pattern); + return dir.listFiles(fileFilter)[0].getAbsolutePath(); + } + + public boolean runCommand(final String command) throws Exception { + + final Process exec = Runtime.getRuntime().exec(command); + final BufferedReader reader = + new BufferedReader(new InputStreamReader(exec.getInputStream())); + + boolean matches = false; + String line = ""; + while ((line = reader.readLine()) != null) { + Pattern p = Pattern.compile(".*caught a fish.*", Pattern.MULTILINE | Pattern.DOTALL); + if (p.matcher(line).matches()) { + matches = true; + } + System.out.println(line); + } + return matches; + } + + private void insertEventLogData(final UUID streamId) throws SQLException, InvalidSequenceIdException { + EVENT_LOG_REPOSITORY.insert(eventLogFrom("framework.example-test")); + } +} diff --git a/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/TestEventLogRepository.java b/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/TestEventLogRepository.java new file mode 100644 index 0000000..e0aacfd --- /dev/null +++ b/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/TestEventLogRepository.java @@ -0,0 +1,67 @@ +package uk.gov.justice.framework.tools.replay; + + +import static java.lang.String.format; +import static java.sql.DriverManager.getDriver; +import static uk.gov.justice.services.test.utils.common.host.TestHostProvider.getHost; +import static uk.gov.justice.services.test.utils.common.reflection.ReflectionUtils.setField; + +import uk.gov.justice.services.eventsourcing.repository.jdbc.AnsiSQLEventLogInsertionStrategy; +import uk.gov.justice.services.eventsourcing.repository.jdbc.eventlog.EventLogJdbcRepository; + +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.apache.commons.dbcp2.BasicDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Standalone repository class to access event streams. To be used in integration testing + */ +public class TestEventLogRepository extends EventLogJdbcRepository { + private static final Logger LOGGER = LoggerFactory.getLogger(uk.gov.justice.services.test.utils.core.eventsource.TestEventLogRepository.class); + static final String SQL_FIND_ALL = "SELECT * FROM event_log"; + + private final DataSource datasource; + + public TestEventLogRepository(final DataSource datasource) { + this.datasource = datasource; + this.logger = LOGGER; + setField(this, "eventLogInsertionStrategy", new AnsiSQLEventLogInsertionStrategy()); + } + + public TestEventLogRepository(final String url, final String username, final String password, final String driverClassName) { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(driverClassName); + dataSource.setUrl(url); + dataSource.setUsername(username); + dataSource.setPassword(password); + this.datasource = dataSource; + this.logger = LOGGER; + + } + + public TestEventLogRepository(final String contextName) throws SQLException { + this(jdbcUrlFrom(contextName), contextName, contextName, getDriver(jdbcUrlFrom(contextName)).getClass().getName()); + } + + public static TestEventLogRepository forContext(final String contextName) { + try { + return new TestEventLogRepository(contextName); + } catch (SQLException e) { + throw new IllegalArgumentException(format("Error instantiating repository for context: %s", contextName), e); + } + } + + @Override + protected DataSource getDataSource() { + return datasource; + } + + private static String jdbcUrlFrom(final String contextName) { + return format("jdbc:postgresql://%s/%seventstore", getHost(), contextName); + } + +} diff --git a/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/TestProperties.java b/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/TestProperties.java new file mode 100644 index 0000000..94fb77d --- /dev/null +++ b/framework-tools-test/framework-tools-it/src/test/java/uk/gov/justice/framework/tools/replay/TestProperties.java @@ -0,0 +1,41 @@ +package uk.gov.justice.framework.tools.replay; + +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * Loads test.properties files from classpath and makes property values available through an + * accessor method + */ +public class TestProperties { + private static TestProperties instance; + private final Properties properties = new Properties(); + + public TestProperties(final String propertyFileName) { + final InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName); + + if (is != null) { + try { + properties.load(is); + } catch (IOException e) { + fail("error reading " + propertyFileName); + } + } else { + fail(propertyFileName + "not found in the classpath"); + } + } + + /** + * Accessor method to read property values + * + * @param propertyName - name of the property defined in the properties files + * @return value of the property + */ + public String value(final String propertyName) { + return properties.getProperty(propertyName); + } + +} diff --git a/framework-tools-test/framework-tools-it/src/test/resources/standalone-ds.xml b/framework-tools-test/framework-tools-it/src/test/resources/standalone-ds.xml new file mode 100644 index 0000000..faaea22 --- /dev/null +++ b/framework-tools-test/framework-tools-it/src/test/resources/standalone-ds.xml @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:tcp://localhost:8092/mem:eventstore;MVCC=true + h2 + + 3 + 3 + true + + + sa + sa + + + + + jdbc:h2:tcp://localhost:8092/mem:eventstore;MVCC=true + h2 + + 3 + 3 + true + + + sa + sa + + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/framework-tools-test/framework-tools-it/src/test/resources/test.properties b/framework-tools-test/framework-tools-it/src/test/resources/test.properties new file mode 100644 index 0000000..184e1a3 --- /dev/null +++ b/framework-tools-test/framework-tools-it/src/test/resources/test.properties @@ -0,0 +1,6 @@ +db.eventstore.url=jdbc:h2:tcp://localhost:8092/mem:eventstore;MVCC=true +db.eventstore.userName=sa +db.eventstore.password=sa + +#Set to 'true' and remote connect on port 5005 +swarm.debug=false \ No newline at end of file diff --git a/framework-tools-test/pom.xml b/framework-tools-test/pom.xml new file mode 100644 index 0000000..0e21176 --- /dev/null +++ b/framework-tools-test/pom.xml @@ -0,0 +1,19 @@ + + + + framework-tools + uk.gov.justice + 2.1.0-SNAPSHOT + + 4.0.0 + pom + + framework-event-listener + framework-tools-it + + + framework-tools-test + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index d009514..e1ac2a4 100644 --- a/pom.xml +++ b/pom.xml @@ -17,13 +17,14 @@ 2.2.1 2016.10.0 - + 1.15.0 framework-tools framework-tools-command framework-tools-replay + framework-tools-test