diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3481203..9a9be2c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,9 +5,12 @@ on [Keep a CHANGELOG](http://keepachangelog.com/). This project adheres to
## [Unreleased]
+### Added
+- Generate reports on the messages on the DLQ
+
## [3.2.0] - 2019-02-11
-###Added
+### Added
- Output of consumer name so that it's easy to see where the DLQ message was going to
## [3.1.0] - 2018-10-30
diff --git a/README.md b/README.md
index 4736b60..a37eff9 100644
--- a/README.md
+++ b/README.md
@@ -80,8 +80,19 @@ In the examples below it is assumed a configuration file of artemis.config has b
**Note: ReprocessAll uses JMX port to connect to the Artemis broker.**
-`java -jar artemis-manager.jar reprocessall @artemis.config
+`java -jar artemis-manager.jar reprocessall @artemis.config`
+## Reports on DLQ
+
+* Generate report on the contents of the DLQ. There are three different reports available.
+
+**Note: Report uses JMS to connect to the Artemis broker.**
+
+`java -jar artemis-manager.jar browse @artemis.config -report totals-by-name-report`
+
+`java -jar artemis-manager.jar browse @artemis.config -report names-by-original-destination-report`
+
+`java -jar artemis-manager.jar browse @artemis.config -report created-at-name-total-report`
## Chaining Commands
diff --git a/pom.xml b/pom.xml
index 5b67e73..ddfe459 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,8 @@
1.7.10
1.3
1.48
+ 1.16.2
+ 4.5
artemis-manager
@@ -105,6 +107,13 @@
throwing-function
${throwing-function.version}
+
+ uk.gov.justice.utils
+ utilities-core
+ ${utilities.version}
+
+
+
junit
junit
@@ -125,6 +134,12 @@
mockito-core
test
+
+ com.opencsv
+ opencsv
+ ${opencsv.version}
+ test
+
@@ -160,7 +175,8 @@
- org.slf4j:slf4j-log4j12
+ org.slf4j:slf4j-log4j12
+
diff --git a/src/main/java/uk/gov/justice/framework/tools/command/Report.java b/src/main/java/uk/gov/justice/framework/tools/command/Report.java
new file mode 100644
index 0000000..6d06ba4
--- /dev/null
+++ b/src/main/java/uk/gov/justice/framework/tools/command/Report.java
@@ -0,0 +1,32 @@
+package uk.gov.justice.framework.tools.command;
+
+import static uk.gov.justice.report.ReportGeneratorFactory.CREATED_AT_NAME_TOTAL_REPORT;
+
+import uk.gov.justice.artemis.manager.connector.MessageData;
+import uk.gov.justice.framework.tools.common.command.ShellCommand;
+import uk.gov.justice.report.ReportGeneratorFactory;
+
+import java.util.List;
+
+import com.beust.jcommander.Parameter;
+
+public class Report extends AbstractArtemisCommand implements ShellCommand {
+
+ @Parameter(names = "-reportType", description = CREATED_AT_NAME_TOTAL_REPORT)
+ String reportType;
+
+ @Override
+ public void run(final String[] args) {
+ try {
+ super.setup();
+
+ final List messageData = artemisConnector.messagesOf("DLQ");
+
+ final String report = new ReportGeneratorFactory().reportGeneratorFor(reportType).generate(messageData);
+
+ outputPrinter.write(report);
+ } catch (final Exception exception) {
+ outputPrinter.writeStackTrace(exception);
+ }
+ }
+}
diff --git a/src/main/java/uk/gov/justice/report/CreatedAtNameTotalReportGenerator.java b/src/main/java/uk/gov/justice/report/CreatedAtNameTotalReportGenerator.java
new file mode 100644
index 0000000..ebd32e2
--- /dev/null
+++ b/src/main/java/uk/gov/justice/report/CreatedAtNameTotalReportGenerator.java
@@ -0,0 +1,91 @@
+package uk.gov.justice.report;
+
+import static java.lang.System.lineSeparator;
+import static java.util.stream.Collectors.joining;
+
+import uk.gov.justice.artemis.manager.connector.MessageData;
+import uk.gov.justice.services.common.converter.ZonedDateTimes;
+import uk.gov.justice.services.messaging.JsonObjects;
+
+import java.time.LocalDate;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.json.JsonObject;
+import javax.json.JsonString;
+
+public class CreatedAtNameTotalReportGenerator implements ReportGenerator {
+
+ @Override
+ public String generate(final List messageData) {
+
+ final Map> createdAtNameTotals = new HashMap<>();
+
+ messageData.forEach(message -> {
+ final JsonObject msgContent = message.getMsgContent();
+
+ final Optional nameJson = JsonObjects.getJsonString(msgContent, "_metadata", "name");
+ final Optional createdAtJson = JsonObjects.getJsonString(msgContent, "_metadata", "createdAt");
+
+ if (createdAtJson.isPresent()) {
+
+ final LocalDate createdAtDate = ZonedDateTimes.fromJsonString(createdAtJson.get()).toLocalDate();
+
+ if (nameJson.isPresent()) {
+ final String name = nameJson.get().getString();
+
+ final Map totalsByName = createdAtNameTotals.computeIfAbsent(createdAtDate, key -> new HashMap<>());
+ final TotalByName totalByName = totalsByName.computeIfAbsent(name, name1 -> new TotalByName(createdAtDate, name1));
+
+ totalByName.addOneToTotal();
+ }
+ }
+ });
+
+ final String csv = createdAtNameTotals.keySet().stream()
+ .sorted()
+ .map(localDate -> createdAtNameTotals.get(localDate).values().stream()
+ .sorted()
+ .map(TotalByName::toString)
+ .collect(joining(lineSeparator())))
+ .collect(joining(lineSeparator()));
+
+ return "Created At,Name,Total Messages"
+ + lineSeparator()
+ + csv
+ + lineSeparator()
+ + "Total Messages,," + (long) messageData.size();
+ }
+
+ private class TotalByName implements Comparable {
+
+ private final LocalDate createdAt;
+ private final String name;
+ private Long totalMessages = 0L;
+
+ TotalByName(final LocalDate createdAt, final String name) {
+ this.createdAt = createdAt;
+ this.name = name;
+ }
+
+ Long getTotalMessages() {
+ return totalMessages;
+ }
+
+ void addOneToTotal() {
+ totalMessages = totalMessages + 1L;
+ }
+
+ @Override
+ public String toString() {
+ return createdAt + "," + name + "," + totalMessages;
+ }
+
+ @Override
+ public int compareTo(final TotalByName other) {
+ return totalMessages.compareTo(other.getTotalMessages());
+ }
+ }
+}
diff --git a/src/main/java/uk/gov/justice/report/NamesByOriginalDestinationReportGenerator.java b/src/main/java/uk/gov/justice/report/NamesByOriginalDestinationReportGenerator.java
new file mode 100644
index 0000000..606d64f
--- /dev/null
+++ b/src/main/java/uk/gov/justice/report/NamesByOriginalDestinationReportGenerator.java
@@ -0,0 +1,80 @@
+package uk.gov.justice.report;
+
+import static java.lang.System.lineSeparator;
+import static java.util.stream.Collectors.joining;
+
+import uk.gov.justice.artemis.manager.connector.MessageData;
+import uk.gov.justice.services.messaging.JsonObjects;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.json.JsonObject;
+import javax.json.JsonString;
+
+public class NamesByOriginalDestinationReportGenerator implements ReportGenerator {
+
+ public String generate(final List messageData) {
+
+ final Map messageTypesByOriginalDestination = new HashMap<>();
+
+ messageData.forEach(message -> {
+ final JsonObject msgContent = message.getMsgContent();
+
+ final Optional nameJson = JsonObjects.getJsonString(msgContent, "_metadata", "name");
+ final String originalDestination = message.getOriginalDestination();
+
+ if (nameJson.isPresent()) {
+ final String name = nameJson.get().getString();
+ final NameByOriginalDestination nameByOriginalDestination = messageTypesByOriginalDestination.computeIfAbsent(originalDestination, NameByOriginalDestination::new);
+
+ nameByOriginalDestination.addMessageType(name);
+ }
+ });
+
+ final String csv = messageTypesByOriginalDestination.values().stream()
+ .sorted()
+ .map(NameByOriginalDestination::toString)
+ .collect(joining());
+
+ return "Original Destination,Name" + lineSeparator() + csv;
+ }
+
+ private class NameByOriginalDestination implements Comparable {
+
+ private final String originalDestination;
+ private final Set names = new TreeSet<>();
+
+ NameByOriginalDestination(final String originalDestination) {
+ this.originalDestination = originalDestination;
+ }
+
+ void addMessageType(final String messageType) {
+ names.add(messageType);
+ }
+
+ @Override
+ public int compareTo(final NameByOriginalDestination other) {
+ return originalDestination.compareTo(other.originalDestination);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder stringBuilder = new StringBuilder();
+
+ for (String messageType : names) {
+ stringBuilder
+ .append(originalDestination)
+ .append(",")
+ .append(messageType)
+ .append(lineSeparator());
+ }
+
+ return stringBuilder.toString();
+ }
+ }
+}
diff --git a/src/main/java/uk/gov/justice/report/ReportGenerator.java b/src/main/java/uk/gov/justice/report/ReportGenerator.java
new file mode 100644
index 0000000..b4af64b
--- /dev/null
+++ b/src/main/java/uk/gov/justice/report/ReportGenerator.java
@@ -0,0 +1,10 @@
+package uk.gov.justice.report;
+
+import uk.gov.justice.artemis.manager.connector.MessageData;
+
+import java.util.List;
+
+public interface ReportGenerator {
+
+ String generate(final List messageData);
+}
diff --git a/src/main/java/uk/gov/justice/report/ReportGeneratorFactory.java b/src/main/java/uk/gov/justice/report/ReportGeneratorFactory.java
new file mode 100644
index 0000000..ad0262b
--- /dev/null
+++ b/src/main/java/uk/gov/justice/report/ReportGeneratorFactory.java
@@ -0,0 +1,28 @@
+package uk.gov.justice.report;
+
+import static java.lang.String.format;
+
+public class ReportGeneratorFactory {
+
+ public static final String TOTALS_BY_NAME_REPORT = "totals-by-name-report";
+ public static final String NAMES_BY_ORIGINAL_DESTINATION_REPORT = "names-by-original-destination-report";
+ public static final String CREATED_AT_NAME_TOTAL_REPORT = "created-at-name-total-report";
+
+ public ReportGenerator reportGeneratorFor(final String reportType) {
+
+ if (TOTALS_BY_NAME_REPORT.equals(reportType.toLowerCase())) {
+ return new TotalsByNameReportGenerator();
+ }
+
+ if (NAMES_BY_ORIGINAL_DESTINATION_REPORT.equals(reportType.toLowerCase())) {
+ return new NamesByOriginalDestinationReportGenerator();
+ }
+
+ if (CREATED_AT_NAME_TOTAL_REPORT.equals(reportType.toLowerCase())) {
+ return new CreatedAtNameTotalReportGenerator();
+ }
+
+ throw new ReportGeneratorFactoryException(format("Incorrect report type '%s'. Accepted types are: '%s', '%s', '%s'",
+ reportType, TOTALS_BY_NAME_REPORT, NAMES_BY_ORIGINAL_DESTINATION_REPORT, CREATED_AT_NAME_TOTAL_REPORT));
+ }
+}
diff --git a/src/main/java/uk/gov/justice/report/ReportGeneratorFactoryException.java b/src/main/java/uk/gov/justice/report/ReportGeneratorFactoryException.java
new file mode 100644
index 0000000..d5bcf55
--- /dev/null
+++ b/src/main/java/uk/gov/justice/report/ReportGeneratorFactoryException.java
@@ -0,0 +1,8 @@
+package uk.gov.justice.report;
+
+public class ReportGeneratorFactoryException extends RuntimeException {
+
+ public ReportGeneratorFactoryException(final String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/uk/gov/justice/report/TotalsByNameReportGenerator.java b/src/main/java/uk/gov/justice/report/TotalsByNameReportGenerator.java
new file mode 100644
index 0000000..bfbc83d
--- /dev/null
+++ b/src/main/java/uk/gov/justice/report/TotalsByNameReportGenerator.java
@@ -0,0 +1,76 @@
+package uk.gov.justice.report;
+
+import static java.lang.System.lineSeparator;
+import static java.util.Collections.reverseOrder;
+import static java.util.stream.Collectors.joining;
+
+import uk.gov.justice.artemis.manager.connector.MessageData;
+import uk.gov.justice.services.messaging.JsonObjects;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.json.JsonObject;
+import javax.json.JsonString;
+
+public class TotalsByNameReportGenerator implements ReportGenerator {
+
+ public String generate(final List messageData) {
+
+ final Map totalsByMessageType = new HashMap<>();
+
+ messageData.forEach(message -> {
+ final JsonObject msgContent = message.getMsgContent();
+
+ final Optional nameJson = JsonObjects.getJsonString(msgContent, "_metadata", "name");
+
+ if (nameJson.isPresent()) {
+ final String name = nameJson.get().getString();
+ final TotalByName totalByName = totalsByMessageType.computeIfAbsent(name, TotalByName::new);
+
+ totalByName.addOneToTotal();
+ }
+ });
+
+ final String csv = totalsByMessageType.values().stream()
+ .sorted(reverseOrder())
+ .map(TotalByName::toString)
+ .collect(joining(lineSeparator()));
+
+ return "Name,Total Messages"
+ + lineSeparator()
+ + csv
+ + lineSeparator()
+ + "Total Messages," + messageData.size();
+ }
+
+ private class TotalByName implements Comparable {
+
+ private final String name;
+ private Long totalMessages = 0L;
+
+ TotalByName(final String name) {
+ this.name = name;
+ }
+
+ Long getTotalMessages() {
+ return totalMessages;
+ }
+
+ void addOneToTotal() {
+ totalMessages = totalMessages + 1L;
+ }
+
+ @Override
+ public String toString() {
+ return name + "," + totalMessages;
+ }
+
+ @Override
+ public int compareTo(final TotalByName other) {
+ return totalMessages.compareTo(other.getTotalMessages());
+ }
+ }
+}
diff --git a/src/test/java/uk/gov/justice/artemis/manager/ArtemisManagerIT.java b/src/test/java/uk/gov/justice/artemis/manager/ArtemisManagerIT.java
index cb7053f..149993f 100644
--- a/src/test/java/uk/gov/justice/artemis/manager/ArtemisManagerIT.java
+++ b/src/test/java/uk/gov/justice/artemis/manager/ArtemisManagerIT.java
@@ -13,11 +13,13 @@
import static uk.gov.justice.artemis.manager.util.JmsTestUtil.putInQueue;
import java.io.IOException;
+import java.io.StringReader;
import java.util.List;
import javax.jms.JMSException;
import com.jayway.jsonpath.JsonPath;
+import com.opencsv.CSVReader;
import org.apache.commons.io.IOUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -28,6 +30,7 @@ public class ArtemisManagerIT {
private static final String DLQ = "DLQ";
private static final String COMMAND_LINE_BROWSE = "env -u _JAVA_OPTIONS java -jar target/artemis-manager.jar browse -brokerName 0.0.0.0 -jmxUrl service:jmx:rmi:///jndi/rmi://localhost:3000/jmxrmi -jmsUrl tcp://localhost:61616?clientID=artemis-manager";
+ private static final String COMMAND_LINE_REPORT = "env -u _JAVA_OPTIONS java -jar target/artemis-manager.jar report -reportType %s -brokerName 0.0.0.0 -jmxUrl service:jmx:rmi:///jndi/rmi://localhost:3000/jmxrmi -jmsUrl tcp://localhost:61616?clientID=artemis-manager";
private static final String COMMAND_LINE_REPROCESS = "env -u _JAVA_OPTIONS java -jar target/artemis-manager.jar reprocess -brokerName 0.0.0.0 -jmxUrl service:jmx:rmi:///jndi/rmi://localhost:3000/jmxrmi -jmsUrl tcp://localhost:61616?clientID=artemis-manager";
private static final String COMMAND_LINE_REMOVE = "env -u _JAVA_OPTIONS java -jar target/artemis-manager.jar remove -brokerName 0.0.0.0 -jmxUrl service:jmx:rmi:///jndi/rmi://localhost:3000/jmxrmi -jmsUrl tcp://localhost:61616?clientID=artemis-manager";
@@ -67,6 +70,94 @@ public void shouldBrowseMessagesInDLQ() throws Exception {
assertThat(standardOutput, hasJsonPath("$[1].consumer", equalTo("consumer2")));
}
+ @Test
+ public void shouldGenerateTotalsByNameReportWithDLQ() throws Exception {
+ cleanQueue(DLQ);
+
+ putInQueue(DLQ, "{\"_metadata\":{\"name\":\"some.name\",\"id\":\"c97c5b7b-abc3-49d4-96a9-bcd83aa4ea12\"}}", "consumer1", "jms.queue.abracadabra");
+ putInQueue(DLQ, "{\"_metadata\":{\"name\":\"some.other.name\",\"id\":\"c97c5b7b-abc3-49d4-96a9-bcd83aa4ea13\"}}", "consumer2", "jms.queue.hocuspocus");
+
+ final Output output = execute(String.format(COMMAND_LINE_REPORT, "totals-by-name-report"));
+ assertThat(output.errorOutput, isEmptyString());
+
+ final String standardOutput = output.standardOutput();
+
+ final CSVReader reader = new CSVReader(new StringReader(standardOutput));
+
+ final List lines = reader.readAll();
+
+ assertThat(lines.get(0)[0], is("Name"));
+ assertThat(lines.get(0)[1], is("Total Messages"));
+
+ assertThat(lines.get(1)[0], is("some.other.name"));
+ assertThat(lines.get(1)[1], is("1"));
+
+ assertThat(lines.get(2)[0], is("some.name"));
+ assertThat(lines.get(2)[1], is("1"));
+
+ assertThat(lines.get(3)[0], is("Total Messages"));
+ assertThat(lines.get(3)[1], is("2"));
+ }
+
+ @Test
+ public void shouldGenerateNamesByOriginalDestinationReportWithDLQ() throws Exception {
+ cleanQueue(DLQ);
+
+ putInQueue(DLQ, "{\"_metadata\":{\"name\":\"some.name\",\"id\":\"c97c5b7b-abc3-49d4-96a9-bcd83aa4ea12\"}}", "consumer1", "jms.queue.abracadabra");
+ putInQueue(DLQ, "{\"_metadata\":{\"name\":\"some.other.name\",\"id\":\"c97c5b7b-abc3-49d4-96a9-bcd83aa4ea13\"}}", "consumer2", "jms.queue.hocuspocus");
+
+ final Output output = execute(String.format(COMMAND_LINE_REPORT, "names-by-original-destination-report"));
+ assertThat(output.errorOutput, isEmptyString());
+
+ final String standardOutput = output.standardOutput();
+
+ final CSVReader reader = new CSVReader(new StringReader(standardOutput));
+
+ final List lines = reader.readAll();
+
+ assertThat(lines.get(0)[0], is("Original Destination"));
+ assertThat(lines.get(0)[1], is("Name"));
+
+ assertThat(lines.get(1)[0], is("jms.queue.abracadabra"));
+ assertThat(lines.get(1)[1], is("some.name"));
+
+ assertThat(lines.get(2)[0], is("jms.queue.hocuspocus"));
+ assertThat(lines.get(2)[1], is("some.other.name"));
+ }
+
+ @Test
+ public void shouldGenerateCreatedAtNameTotalReportWithDLQ() throws Exception {
+ cleanQueue(DLQ);
+
+ putInQueue(DLQ, "{\"_metadata\":{\"name\":\"some.name\",\"createdAt\":\"2019-04-06T16:32:48.725Z\",\"id\":\"c97c5b7b-abc3-49d4-96a9-bcd83aa4ea12\"}}", "consumer1", "jms.queue.abracadabra");
+ putInQueue(DLQ, "{\"_metadata\":{\"name\":\"some.other.name\",\"createdAt\":\"2019-04-06T16:32:48.725Z\",\"id\":\"c97c5b7b-abc3-49d4-96a9-bcd83aa4ea13\"}}", "consumer2", "jms.queue.hocuspocus");
+
+ final Output output = execute(String.format(COMMAND_LINE_REPORT, "created-at-name-total-report"));
+ assertThat(output.errorOutput, isEmptyString());
+
+ final String standardOutput = output.standardOutput();
+
+ final CSVReader reader = new CSVReader(new StringReader(standardOutput));
+
+ final List lines = reader.readAll();
+
+ assertThat(lines.get(0)[0], is("Created At"));
+ assertThat(lines.get(0)[1], is("Name"));
+ assertThat(lines.get(0)[2], is("Total Messages"));
+
+ assertThat(lines.get(1)[0], is("2019-04-06"));
+ assertThat(lines.get(1)[1], is("some.other.name"));
+ assertThat(lines.get(1)[2], is("1"));
+
+ assertThat(lines.get(2)[0], is("2019-04-06"));
+ assertThat(lines.get(2)[1], is("some.name"));
+ assertThat(lines.get(2)[2], is("1"));
+
+ assertThat(lines.get(3)[0], is("Total Messages"));
+ assertThat(lines.get(3)[1], is(""));
+ assertThat(lines.get(3)[2], is("2"));
+ }
+
@Test
public void shouldRemoveMessageById() throws Exception {
diff --git a/src/test/java/uk/gov/justice/framework/tools/command/ReportTest.java b/src/test/java/uk/gov/justice/framework/tools/command/ReportTest.java
new file mode 100644
index 0000000..50cae92
--- /dev/null
+++ b/src/test/java/uk/gov/justice/framework/tools/command/ReportTest.java
@@ -0,0 +1,32 @@
+package uk.gov.justice.framework.tools.command;
+
+import static java.util.Collections.singletonList;
+import static org.mockito.Mockito.verify;
+
+import uk.gov.justice.artemis.manager.connector.ArtemisConnector;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ReportTest {
+
+ @Mock
+ ArtemisConnector artemisConnector;
+
+ @InjectMocks
+ Report report;
+
+ @Test
+ public void shouldInvokeConnector() throws Exception {
+ report.jmxURLs = singletonList("service:jmx:rmi:///jndi/rmi://localhost:3000/jmxrmi");
+ report.jmsURL = "tcp://localhost:61616";
+ report.brokerName = "brokerabc";
+
+ report.run(null);
+ verify(artemisConnector).messagesOf("DLQ");
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/uk/gov/justice/report/CreatedAtNameTotalReportGeneratorTest.java b/src/test/java/uk/gov/justice/report/CreatedAtNameTotalReportGeneratorTest.java
new file mode 100644
index 0000000..06c579f
--- /dev/null
+++ b/src/test/java/uk/gov/justice/report/CreatedAtNameTotalReportGeneratorTest.java
@@ -0,0 +1,80 @@
+package uk.gov.justice.report;
+
+import static java.util.Arrays.asList;
+import static java.util.UUID.randomUUID;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import uk.gov.justice.artemis.manager.connector.MessageData;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.UUID;
+
+import com.opencsv.CSVReader;
+import org.junit.Test;
+
+public class CreatedAtNameTotalReportGeneratorTest {
+
+ @Test
+ public void shouldCreateReportFromMessageData() throws Exception {
+
+ final UUID streamId_1 = UUID.randomUUID();
+ final UUID streamId_2 = UUID.randomUUID();
+ final UUID streamId_3 = UUID.randomUUID();
+
+ final String name_1 = "example.command.add-recipe";
+ final String name_2 = "example.command.delete-recipe";
+ final String name_3 = "example.command.update-recipe";
+
+ final String message_1 = "{\"_metadata\":{\"createdAt\":\"2019-04-06T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_1 + "\"}}}";
+ final String message_2 = "{\"_metadata\":{\"createdAt\":\"2019-04-06T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_2 + "\"}}}";
+ final String message_3 = "{\"_metadata\":{\"createdAt\":\"2019-04-07T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_3 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_2 + "\"}}}";
+ final String message_4 = "{\"_metadata\":{\"createdAt\":\"2019-04-07T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_3 + "\"}}}";
+ final String message_5 = "{\"_metadata\":{\"createdAt\":\"2019-04-08T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_2 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_1 + "\"}}}";
+ final String message_6 = "{\"_metadata\":{\"createdAt\":\"2019-04-08T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_3 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_3 + "\"}}}";
+
+ final List messageData = asList(
+ new MessageData(randomUUID().toString(), "queue.example1", message_1, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example2", message_2, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example2", message_3, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example3", message_4, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example1", message_5, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example3", message_6, "consumer")
+ );
+
+ final String csv = new CreatedAtNameTotalReportGenerator().generate(messageData);
+
+ final CSVReader reader = new CSVReader(new StringReader(csv));
+
+ final List lines = reader.readAll();
+
+ assertThat(lines.get(0)[0], is("Created At"));
+ assertThat(lines.get(0)[1], is("Name"));
+ assertThat(lines.get(0)[2], is("Total Messages"));
+
+ assertThat(lines.get(1)[0], is("2019-04-06"));
+ assertThat(lines.get(1)[1], is(name_1));
+ assertThat(lines.get(1)[2], is("2"));
+
+ assertThat(lines.get(2)[0], is("2019-04-07"));
+ assertThat(lines.get(2)[1], is(name_1));
+ assertThat(lines.get(2)[2], is("1"));
+
+ assertThat(lines.get(3)[0], is("2019-04-07"));
+ assertThat(lines.get(3)[1], is(name_3));
+ assertThat(lines.get(3)[2], is("1"));
+
+ assertThat(lines.get(4)[0], is("2019-04-08"));
+ assertThat(lines.get(4)[1], is(name_2));
+ assertThat(lines.get(4)[2], is("1"));
+
+ assertThat(lines.get(5)[0], is("2019-04-08"));
+ assertThat(lines.get(5)[1], is(name_3));
+ assertThat(lines.get(5)[2], is("1"));
+
+ assertThat(lines.get(6)[0], is("Total Messages"));
+ assertThat(lines.get(6)[1], is(""));
+ assertThat(lines.get(6)[2], is("6"));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/uk/gov/justice/report/NamesByOriginalDestinationReportGeneratorTest.java b/src/test/java/uk/gov/justice/report/NamesByOriginalDestinationReportGeneratorTest.java
new file mode 100644
index 0000000..b2dfa36
--- /dev/null
+++ b/src/test/java/uk/gov/justice/report/NamesByOriginalDestinationReportGeneratorTest.java
@@ -0,0 +1,77 @@
+package uk.gov.justice.report;
+
+import static java.util.Arrays.asList;
+import static java.util.UUID.randomUUID;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import uk.gov.justice.artemis.manager.connector.MessageData;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.UUID;
+
+import com.opencsv.CSVReader;
+import org.junit.Test;
+
+public class NamesByOriginalDestinationReportGeneratorTest {
+
+ @Test
+ public void shouldCreateReportFromMessageData() throws Exception {
+
+ final UUID streamId_1 = UUID.randomUUID();
+ final UUID streamId_2 = UUID.randomUUID();
+ final UUID streamId_3 = UUID.randomUUID();
+
+ final String name_1 = "example.command.add-recipe";
+ final String name_2 = "example.command.delete-recipe";
+ final String name_3 = "example.command.update-recipe";
+
+ final String message_1 = "{\"_metadata\":{\"createdAt\":\"2019-04-06T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_1 + "\"}}}";
+ final String message_2 = "{\"_metadata\":{\"createdAt\":\"2019-04-06T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_2 + "\"}}}";
+ final String message_3 = "{\"_metadata\":{\"createdAt\":\"2019-04-07T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_3 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_2 + "\"}}}";
+ final String message_4 = "{\"_metadata\":{\"createdAt\":\"2019-04-07T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_3 + "\"}}}";
+ final String message_5 = "{\"_metadata\":{\"createdAt\":\"2019-04-08T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_2 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_1 + "\"}}}";
+ final String message_6 = "{\"_metadata\":{\"createdAt\":\"2019-04-08T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_3 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_3 + "\"}}}";
+
+ final String originalDestination_1 = "queue.example1";
+ final String originalDestination_2 = "queue.example2";
+ final String originalDestination_3 = "queue.example3";
+
+ final List messageData = asList(
+ new MessageData(randomUUID().toString(), originalDestination_1, message_1, "consumer"),
+ new MessageData(randomUUID().toString(), originalDestination_2, message_2, "consumer"),
+ new MessageData(randomUUID().toString(), originalDestination_2, message_3, "consumer"),
+ new MessageData(randomUUID().toString(), originalDestination_3, message_4, "consumer"),
+ new MessageData(randomUUID().toString(), originalDestination_1, message_5, "consumer"),
+ new MessageData(randomUUID().toString(), originalDestination_3, message_6, "consumer")
+ );
+
+ final String csv = new NamesByOriginalDestinationReportGenerator().generate(messageData);
+
+ final CSVReader reader = new CSVReader(new StringReader(csv));
+
+ final List lines = reader.readAll();
+
+ assertThat(lines.get(0)[0], is("Original Destination"));
+ assertThat(lines.get(0)[1], is("Name"));
+
+ assertThat(lines.get(1)[0], is(originalDestination_1));
+ assertThat(lines.get(1)[1], is(name_1));
+
+ assertThat(lines.get(2)[0], is(originalDestination_1));
+ assertThat(lines.get(2)[1], is(name_2));
+
+ assertThat(lines.get(3)[0], is(originalDestination_2));
+ assertThat(lines.get(3)[1], is(name_1));
+
+ assertThat(lines.get(4)[0], is(originalDestination_2));
+ assertThat(lines.get(4)[1], is(name_3));
+
+ assertThat(lines.get(5)[0], is(originalDestination_3));
+ assertThat(lines.get(5)[1], is(name_1));
+
+ assertThat(lines.get(6)[0], is(originalDestination_3));
+ assertThat(lines.get(6)[1], is(name_3));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/uk/gov/justice/report/ReportGeneratorFactoryTest.java b/src/test/java/uk/gov/justice/report/ReportGeneratorFactoryTest.java
new file mode 100644
index 0000000..08b2308
--- /dev/null
+++ b/src/test/java/uk/gov/justice/report/ReportGeneratorFactoryTest.java
@@ -0,0 +1,49 @@
+package uk.gov.justice.report;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static uk.gov.justice.report.ReportGeneratorFactory.CREATED_AT_NAME_TOTAL_REPORT;
+import static uk.gov.justice.report.ReportGeneratorFactory.NAMES_BY_ORIGINAL_DESTINATION_REPORT;
+import static uk.gov.justice.report.ReportGeneratorFactory.TOTALS_BY_NAME_REPORT;
+
+import org.junit.Test;
+
+public class ReportGeneratorFactoryTest {
+
+ @Test
+ public void shouldCreateTotalsByNameReportGenerator() {
+
+ final ReportGenerator reportGenerator = new ReportGeneratorFactory().reportGeneratorFor(TOTALS_BY_NAME_REPORT);
+
+ assertThat(reportGenerator, instanceOf(TotalsByNameReportGenerator.class));
+ }
+
+ @Test
+ public void shouldCreateNamesByOriginalDestinationReportGenerator() {
+
+ final ReportGenerator reportGenerator = new ReportGeneratorFactory().reportGeneratorFor(NAMES_BY_ORIGINAL_DESTINATION_REPORT);
+
+ assertThat(reportGenerator, instanceOf(NamesByOriginalDestinationReportGenerator.class));
+ }
+
+ @Test
+ public void shouldCreateCreatedAtNameTotalReportGenerator() {
+
+ final ReportGenerator reportGenerator = new ReportGeneratorFactory().reportGeneratorFor(CREATED_AT_NAME_TOTAL_REPORT);
+
+ assertThat(reportGenerator, instanceOf(CreatedAtNameTotalReportGenerator.class));
+ }
+
+ @Test
+ public void shouldThrowExceptionIfUnknownReportGeneratorRequested() {
+
+ try {
+ new ReportGeneratorFactory().reportGeneratorFor("unknown-report");
+ fail("Exception expected");
+ } catch (final ReportGeneratorFactoryException e) {
+ assertThat(e.getMessage(), is("Incorrect report type 'unknown-report'. Accepted types are: 'totals-by-name-report', 'names-by-original-destination-report', 'created-at-name-total-report'"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/uk/gov/justice/report/TotalsByNameReportGeneratorTest.java b/src/test/java/uk/gov/justice/report/TotalsByNameReportGeneratorTest.java
new file mode 100644
index 0000000..da82807
--- /dev/null
+++ b/src/test/java/uk/gov/justice/report/TotalsByNameReportGeneratorTest.java
@@ -0,0 +1,67 @@
+package uk.gov.justice.report;
+
+import static java.util.Arrays.asList;
+import static java.util.UUID.randomUUID;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import uk.gov.justice.artemis.manager.connector.MessageData;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.UUID;
+
+import com.opencsv.CSVReader;
+import org.junit.Test;
+
+public class TotalsByNameReportGeneratorTest {
+
+ @Test
+ public void shouldCreateReportFromMessageData() throws Exception {
+
+ final UUID streamId_1 = UUID.randomUUID();
+ final UUID streamId_2 = UUID.randomUUID();
+ final UUID streamId_3 = UUID.randomUUID();
+
+ final String name_1 = "example.command.add-recipe";
+ final String name_2 = "example.command.delete-recipe";
+ final String name_3 = "example.command.update-recipe";
+
+ final String message_1 = "{\"_metadata\":{\"createdAt\":\"2019-04-06T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_1 + "\"}}}";
+ final String message_2 = "{\"_metadata\":{\"createdAt\":\"2019-04-06T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_2 + "\"}}}";
+ final String message_3 = "{\"_metadata\":{\"createdAt\":\"2019-04-07T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_3 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_2 + "\"}}}";
+ final String message_4 = "{\"_metadata\":{\"createdAt\":\"2019-04-07T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_1 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_3 + "\"}}}";
+ final String message_5 = "{\"_metadata\":{\"createdAt\":\"2019-04-08T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_2 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_1 + "\"}}}";
+ final String message_6 = "{\"_metadata\":{\"createdAt\":\"2019-04-08T16:32:48.725Z\",\"id\":\"00b78ee7-5d2c-4b6d-858e-0701d0412515\",\"name\":\"" + name_3 + "\",\"causation\":[\"63bc8905-2705-41f9-892e-946e632b1837\"],\"stream\":{\"id\":\"" + streamId_3 + "\"}}}";
+
+ final List messageData = asList(
+ new MessageData(randomUUID().toString(), "queue.example", message_1, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example", message_2, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example", message_3, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example", message_4, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example", message_5, "consumer"),
+ new MessageData(randomUUID().toString(), "queue.example", message_6, "consumer")
+ );
+
+ final String csv = new TotalsByNameReportGenerator().generate(messageData);
+
+ final CSVReader reader = new CSVReader(new StringReader(csv));
+
+ final List lines = reader.readAll();
+
+ assertThat(lines.get(0)[0], is("Name"));
+ assertThat(lines.get(0)[1], is("Total Messages"));
+
+ assertThat(lines.get(1)[0], is(name_1));
+ assertThat(lines.get(1)[1], is("3"));
+
+ assertThat(lines.get(2)[0], is(name_3));
+ assertThat(lines.get(2)[1], is("2"));
+
+ assertThat(lines.get(3)[0], is(name_2));
+ assertThat(lines.get(3)[1], is("1"));
+
+ assertThat(lines.get(4)[0], is("Total Messages"));
+ assertThat(lines.get(4)[1], is("6"));
+ }
+}
\ No newline at end of file