Skip to content

Commit

Permalink
Merge 1d8e1dc into 9409bf6
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-rich committed Jan 26, 2018
2 parents 9409bf6 + 1d8e1dc commit cf99560
Show file tree
Hide file tree
Showing 14 changed files with 291 additions and 51 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
[![Build Status](https://travis-ci.org/CJSCommonPlatform/framework-tools.svg?branch=master)](https://travis-ci.org/CJSCommonPlatform/framework-tools) [![Coverage Status](https://coveralls.io/repos/github/CJSCommonPlatform/framework-tools/badge.svg?branch=master)](https://coveralls.io/github/CJSCommonPlatform/framework-tools?branch=master)

Tools for working with services using the microservice framework.

# Replay Tool
For instruction on how to use the replay tool, please see the [replay tool page](https://github.com/CJSCommonPlatform/framework-tools/tree/master/framework-tools-replay)
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package uk.gov.justice.framework.tools.fraction.runtime;

import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
import static org.jboss.shrinkwrap.api.ShrinkWrap.createFromZipFile;

import java.nio.file.Paths;

import javax.inject.Inject;

import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.wildfly.swarm.spi.api.DeploymentProcessor;
import org.wildfly.swarm.spi.runtime.annotations.ConfigurationValue;
import org.wildfly.swarm.spi.runtime.annotations.DeploymentScoped;
import org.wildfly.swarm.undertow.WARArchive;

import javax.inject.Inject;

import java.nio.file.Paths;

import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
import static org.jboss.shrinkwrap.api.ShrinkWrap.createFromZipFile;


@DeploymentScoped
public class ArchiveLoader implements DeploymentProcessor {
Expand All @@ -36,21 +36,23 @@ public ArchiveLoader(final Archive archive) {
@Override
public void process() {

final WebArchive webArchive = createFromZipFile(WebArchive.class, Paths.get(library).toFile());

final FrameworkLibraries frameworkLibraries = new FrameworkLibraries(
"uk.gov.justice.services:event-repository-jdbc",
"uk.gov.justice.framework-api:framework-api-core",
"uk.gov.justice.services:core",
"uk.gov.justice.services:persistence-jdbc",
"uk.gov.justice.services:event-buffer-core");
final WebArchive webArchive = createFromZipFile(WebArchive.class, Paths.get(library).toFile());

final FrameworkLibraries frameworkLibraries = new FrameworkLibraries(
"uk.gov.justice.services:event-repository-jdbc",
"uk.gov.justice.framework-api:framework-api-core",
"uk.gov.justice.services:core",
"uk.gov.justice.services:messaging-jms",
"uk.gov.justice.services:messaging-core",
"uk.gov.justice.services:persistence-jdbc",
"uk.gov.justice.services:event-buffer-core",
"uk.gov.justice.utilities:utilities-core");

final WebArchive excludeGeneratedApiClasses = create(WebArchive.class, "ExcludeGeneratedApiClasses")
.merge(webArchive, frameworkLibraries.exclusionFilter());
final WebArchive excludeGeneratedApiClasses = create(WebArchive.class, "ExcludeGeneratedApiClasses")
.merge(webArchive, frameworkLibraries.exclusionFilter());

final WARArchive war = archive.as(WARArchive.class);
final WARArchive war = archive.as(WARArchive.class);

war.merge(excludeGeneratedApiClasses);
war.merge(excludeGeneratedApiClasses);
}
}
72 changes: 72 additions & 0 deletions framework-tools-replay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Replay Tool

The replay-tool is a tool to support the re-population of a view_store (projection) that has been implemented within the [microservice_framework](https://github.com/CJSCommonPlatform/microservice_framework)

The tool works by connecting to a chosen event_store (as per configuration) and reads all of the events from each 'active' stream, passing them to the Listener component which converts them into the required read model (view_store).

> Note: The replay-tool is a WildFly Swarm application.
> Note: The replay-tool requires the 'Event Listener' component war for the view_store being repopulated to be provided at runtime.
# How to Build the Replay-Tool

The replay-tool attempts to be a well-behaved Maven project. To install to your local repository for usage:
```bash
mvn clean install
```

The WildFly Swarm application `framework-tools-replay-x.x.x-swarm.jar` will be produced in the `framework-tools-replay/target/` directory.

# Running the Replay Tool

To run the framework-tools-replay WildFly Swarm application you require:
* The built application jar: `framework-tools-replay-3.1.0-SNAPSHOT-swarm.jar`
* A configuration file with datasource of the event_store and view_store: `standalone-ds.xml`
* A war of the 'Event Listener' component that should be used to repopulate your viewstore: `myservice-event-listener-0.0.1-SNAPSHOT.war`

Additionally to trigger the automatic shutdown hook on completion you need to create a file and provide the fully qualified file as `org.wildfly.swarm.mainProcessFile` System property

```bash
touch processFile
java -jar -Dorg.wildfly.swarm.mainProcessFile=/Fully/Qualified/Path/processFile -Devent.listener.war=myservice-event-listener.war -jar framework-tools-replay-3.1.0-SNAPSHOT-swarm.jar replay -c standalone-ds.xml
```

# Configuration

This will require standard wilfdly datasource configuration in your `standalone-ds.xml` for the event_store to read the events from and view_store to be repopulated.

```xml
<datasources>
<!-- Event Store -->
<datasource jndi-name="java:/app/replay-tool/DS.eventstore"
pool-name="DS.replay-tool.eventstore" enabled="true"
use-java-context="true">
<driver>postgres</driver>
<xa-datasource-property name="ServerName">localhost</xa-datasource-property>
<xa-datasource-property name="PortNumber">5432</xa-datasource-property>
<xa-datasource-property name="DatabaseName">myserviceeventstore</xa-datasource-property>
<xa-datasource-property name="ApplicationName">myservice</xa-datasource-property>
...
<security>
<user-name>myservice_username</user-name>
<password>myservice_password</password>
</security>
</datasource>

<!-- View Store -->
<xa-datasource jndi-name="java:/DS.myservice"
pool-name="DS.myservice" enabled="true"
use-java-context="true" spy="true" use-ccm="true" statistics-enabled="true">
<driver>postgres</driver>
<xa-datasource-property name="ServerName">localhost</xa-datasource-property>
<xa-datasource-property name="PortNumber">5432</xa-datasource-property>
<xa-datasource-property name="DatabaseName">myserviceviewtstore</xa-datasource-property>
<xa-datasource-property name="ApplicationName">myservice</xa-datasource-property>
...
<security>
<user-name>myservice_username</user-name>
<password>myservice_password</password>
</security>
</datasource>
</datasources>
```
1 change: 0 additions & 1 deletion framework-tools-replay/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
<dependency>
<groupId>uk.gov.justice.services</groupId>
<artifactId>core</artifactId>
<version>${framework.version}</version>
</dependency>
<dependency>
<groupId>uk.gov.justice.services</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class StartReplay implements ManagedTaskListener {
void go() {
logger.info("-------------- Invoke Event Streams Replay-------------!");
checkForMainProcessFile();
jdbcEventRepository.getStreamOfAllEventStreams()
jdbcEventRepository.getStreamOfAllActiveEventStreams()
.forEach(eventStream -> {
StreamDispatchTask dispatchTask = new StreamDispatchTask(eventStream, asyncStreamDispatcher, this);
outstandingTasks.add(executorService.submit(dispatchTask));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
package uk.gov.justice.framework.tools.replay;

import static java.util.UUID.randomUUID;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static uk.gov.justice.services.test.utils.core.matchers.JsonEnvelopeMatcher.jsonEnvelope;
import static uk.gov.justice.services.test.utils.core.matchers.JsonEnvelopeMetadataMatcher.metadata;
import static uk.gov.justice.services.test.utils.core.messaging.JsonEnvelopeBuilder.envelope;
import static uk.gov.justice.services.test.utils.core.messaging.MetadataBuilderFactory.metadataWithDefaults;
import static uk.gov.justice.services.test.utils.core.messaging.MetadataBuilderFactory.metadataWithRandomUUID;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import uk.gov.justice.services.core.handler.exception.MissingHandlerException;
import uk.gov.justice.services.event.buffer.core.repository.streamstatus.StreamStatus;
import uk.gov.justice.services.event.buffer.core.repository.streamstatus.StreamStatusJdbcRepository;
import uk.gov.justice.services.messaging.JsonEnvelope;
import uk.gov.justice.services.test.utils.core.matchers.JsonEnvelopeMatcher;
import uk.gov.justice.services.test.utils.core.messaging.JsonEnvelopeBuilder;

import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;

import static java.util.UUID.randomUUID;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static uk.gov.justice.services.messaging.JsonObjectMetadata.metadataWithDefaults;
import static uk.gov.justice.services.messaging.JsonObjectMetadata.metadataWithRandomUUID;
import static uk.gov.justice.services.test.utils.core.matchers.JsonEnvelopeMatcher.jsonEnvelope;
import static uk.gov.justice.services.test.utils.core.matchers.JsonEnvelopeMetadataMatcher.metadata;
import static uk.gov.justice.services.test.utils.core.messaging.JsonEnvelopeBuilder.envelope;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class AsyncStreamDispatcherTest {
Expand Down Expand Up @@ -64,8 +67,12 @@ public void shouldDispatchEnvelopes() {
public void shouldUpdateStreamBufferStatus() {

final UUID streamId = randomUUID();
final JsonEnvelope envelope1 = envelope().with(metadataWithDefaults().withStreamId(streamId).withVersion(4L)).build();
final JsonEnvelope envelope2 = envelope().with(metadataWithDefaults().withStreamId(streamId).withVersion(5L)).build();
final JsonEnvelope envelope1 = JsonEnvelopeBuilder.envelope().with(
metadataWithDefaults().withStreamId(streamId).withVersion(4L))
.build();
final JsonEnvelope envelope2 = JsonEnvelopeBuilder.envelope().with(
metadataWithDefaults().withStreamId(streamId).withVersion(5L))
.build();

asyncStreamDispatcher.dispatch(Stream.of(envelope1, envelope2));

Expand Down Expand Up @@ -97,12 +104,12 @@ public void shouldProcessStreamWhenThereIsNoHandlerDefined() {


final JsonEnvelope envelope1 = envelope().with(metadataWithRandomUUID("event-with-handler")
.withStreamId(streamId)
.withVersion(1L))
.build();
.withStreamId(streamId)
.withVersion(1L))
.build();
final JsonEnvelope envelope2 = envelope().with(metadataWithRandomUUID("event-without-handler")
.withStreamId(streamId)
.withVersion(2L)).build();
.withStreamId(streamId)
.withVersion(2L)).build();
final JsonEnvelope envelope3 = envelope().with(metadataWithRandomUUID("event-with-handler").withStreamId(streamId).withVersion(3L)).build();

asyncStreamDispatcher.dispatch(Stream.of(envelope1, envelope2, envelope3));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void shouldDispatchStreams() throws IOException {
final Stream<Stream<JsonEnvelope>> streamOfStreams = Stream.of(mockStream, mockStream);
createMainProcessFile();

when(jdbcEventRepository.getStreamOfAllEventStreams()).thenReturn(streamOfStreams);
when(jdbcEventRepository.getStreamOfAllActiveEventStreams()).thenReturn(streamOfStreams);
when(executorService.submit(any(StreamDispatchTask.class))).thenReturn(dispatchTaskFuture);
when(outstandingTasks.isEmpty()).thenReturn(true);

Expand All @@ -70,7 +70,7 @@ public void shouldDispatchStreams() throws IOException {
public void shouldDispatchStreamsAndShutdownByForce() {
final Stream<Stream<JsonEnvelope>> streamOfStreams = Stream.of(mockStream, mockStream);

when(jdbcEventRepository.getStreamOfAllEventStreams()).thenReturn(streamOfStreams);
when(jdbcEventRepository.getStreamOfAllActiveEventStreams()).thenReturn(streamOfStreams);
when(executorService.submit(any(StreamDispatchTask.class))).thenReturn(dispatchTaskFuture);
when(outstandingTasks.isEmpty()).thenReturn(true);

Expand Down
22 changes: 19 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
<version>3.1.0-SNAPSHOT</version>

<properties>
<cpp.repo.name>framework-tools</cpp.repo.name>
<common-bom.version>1.22.0</common-bom.version>
<framework-api.version>1.1.0</framework-api.version>
<framework.version>3.0.0</framework.version>
<framework.version>3.1.0</framework.version>
<wildfly.swarm.version>2017.11.0</wildfly.swarm.version>
<test.utils.version>1.16.0</test.utils.version>
<cpp.repo.name>framework-tools</cpp.repo.name>
<schema-service.version>1.1.0</schema-service.version>
<version.swarm.fraction-plugin>77</version.swarm.fraction-plugin>
<!--
note h2 version is because swarm has its own version of h2 which we must use
Expand Down Expand Up @@ -52,7 +54,21 @@
<dependency>
<groupId>uk.gov.justice</groupId>
<artifactId>maven-common-bom</artifactId>
<version>1.17.0</version>
<version>${common-bom.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>uk.gov.justice.framework-api</groupId>
<artifactId>framework-api-bom</artifactId>
<version>${framework-api.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>uk.gov.justice.services</groupId>
<artifactId>framework-bom</artifactId>
<version>${framework.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
Expand Down
1 change: 1 addition & 0 deletions replay-tool-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<properties>
<replay-tool-it-example-listener.version>1.0.0</replay-tool-it-example-listener.version>
<metrics-servlet.version>1.1.0</metrics-servlet.version>
</properties>

<artifactId>replay-tool-test</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.io.FileFilter;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.sql.DataSource;
Expand All @@ -28,19 +29,21 @@ public class ReplayIntegrationIT {
private static final String EXECUTION_TIMEOUT = TEST_PROPERTIES.value("replay.execution.timeout");

private static TestEventRepository EVENT_LOG_REPOSITORY;
private static TestEventStreamJdbcRepository EVENT_STREAM_JDBC_REPOSITORY;

private static DataSource viewStoreDataSource;

@Before
public void setUpDB() throws Exception {
EVENT_LOG_REPOSITORY = new TestEventRepository();
EVENT_STREAM_JDBC_REPOSITORY = new TestEventStreamJdbcRepository(EVENT_LOG_REPOSITORY.getDataSource());
viewStoreDataSource = initViewStoreDb();
createProcessFile();
}

@Test
public void runReplayTool() throws Exception {
final List<String> insertedEvents = EVENT_LOG_REPOSITORY.insertEventData(randomUUID());
final List<String> insertedEvents = insertEventData(randomUUID());
runCommand(createCommandToExecuteReplay());
viewStoreEvents(viewStoreDataSource).forEach(viewStoreEvent -> {
System.out.println(format("viewStoreEvent with id %s", viewStoreEvent));
Expand All @@ -49,6 +52,11 @@ public void runReplayTool() throws Exception {
assertTrue(insertedEvents.isEmpty());
}

private List<String> insertEventData(final UUID streamId) {
EVENT_STREAM_JDBC_REPOSITORY.insert(streamId);
return EVENT_LOG_REPOSITORY.insertEventData(streamId);
}

@After
public void tearDown() throws SQLException {
cleanupDataSource(EVENT_LOG_REPOSITORY.getDataSource(), "event_log");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package uk.gov.justice.framework.tools.replay;

import static uk.gov.justice.services.test.utils.common.reflection.ReflectionUtils.setField;

import uk.gov.justice.services.common.util.UtcClock;
import uk.gov.justice.services.eventsourcing.repository.jdbc.eventstream.EventStreamJdbcRepository;
import uk.gov.justice.services.jdbc.persistence.JdbcRepositoryHelper;

import javax.sql.DataSource;

public class TestEventStreamJdbcRepository extends EventStreamJdbcRepository {

private final DataSource dbsource;

public TestEventStreamJdbcRepository(DataSource dataSource) {
this.dbsource = dataSource;
setField(this, "dataSource", dbsource);
setField(this, "eventStreamJdbcRepositoryHelper", new JdbcRepositoryHelper());
setField(this, "clock", new UtcClock());
}

public DataSource getDatasource() {
return dbsource;
}
}
Loading

0 comments on commit cf99560

Please sign in to comment.