diff --git a/agent/apiharness/pom.xml b/agent/apiharness/pom.xml
index 72d39468b..c0de4cc8d 100644
--- a/agent/apiharness/pom.xml
+++ b/agent/apiharness/pom.xml
@@ -21,6 +21,11 @@
${project.version}
+
+ software.amazon.awssdk
+ cloudwatch
+
+
${project.groupId}
tank-api
@@ -71,12 +76,6 @@
${project.version}
-
- ${project.groupId}
- reporting-db
- ${project.version}
-
-
${project.groupId}
api
diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java
index c5fd046e3..4b50736ef 100644
--- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java
+++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java
@@ -23,7 +23,7 @@
import com.intuit.tank.vm.vmManager.models.VMStatus;
import com.intuit.tank.vm.vmManager.models.ValidationStatus;
import com.intuit.tank.harness.logging.LogUtil;
-import com.intuit.tank.reporting.api.TPSInfoContainer;
+import com.intuit.tank.reporting.models.TPSInfoContainer;
import com.intuit.tank.vm.agent.messages.WatsAgentStatusResponse;
import com.intuit.tank.vm.api.enumerated.JobStatus;
import com.intuit.tank.vm.api.enumerated.AgentCommand;
diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java
index 35edb17a3..f26ee36a4 100644
--- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java
+++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java
@@ -48,10 +48,10 @@
import com.intuit.tank.harness.logging.LogUtil;
import com.intuit.tank.logging.LogEventType;
import com.intuit.tank.logging.LoggingProfile;
-import com.intuit.tank.reporting.api.DummyResultsReporter;
-import com.intuit.tank.reporting.api.ResultsReporter;
-import com.intuit.tank.reporting.factory.ReportingFactory;
-import com.intuit.tank.results.TankResult;
+import com.intuit.tank.reporting.DummyResultsReporter;
+import com.intuit.tank.reporting.ResultsReporter;
+import com.intuit.tank.reporting.ReportingFactory;
+import com.intuit.tank.reporting.models.TankResult;
import com.intuit.tank.vm.agent.messages.AgentData;
import com.intuit.tank.vm.agent.messages.AgentTestStartData;
import com.intuit.tank.vm.agent.messages.DataFileRequest;
diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/TPSMonitor.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/TPSMonitor.java
index e0cf52a03..c9680eef3 100644
--- a/agent/apiharness/src/main/java/com/intuit/tank/harness/TPSMonitor.java
+++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/TPSMonitor.java
@@ -26,8 +26,8 @@
import org.apache.logging.log4j.Logger;
import com.intuit.tank.http.BaseRequest;
-import com.intuit.tank.reporting.api.TPSInfo;
-import com.intuit.tank.reporting.api.TPSInfoContainer;
+import com.intuit.tank.reporting.models.TPSInfo;
+import com.intuit.tank.reporting.models.TPSInfoContainer;
import com.intuit.tank.vm.settings.TimeUtil;
public class TPSMonitor {
diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/TestPlanStarter.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/TestPlanStarter.java
index 48a9f7e39..548a91420 100644
--- a/agent/apiharness/src/main/java/com/intuit/tank/harness/TestPlanStarter.java
+++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/TestPlanStarter.java
@@ -14,7 +14,7 @@
*/
import com.intuit.tank.harness.data.*;
-import com.intuit.tank.reporting.api.TPSInfoContainer;
+import com.intuit.tank.reporting.models.TPSInfoContainer;
import com.intuit.tank.runner.TestPlanRunner;
import com.intuit.tank.vm.api.enumerated.IncrementStrategy;
import org.apache.commons.lang3.time.DateUtils;
diff --git a/agent/apiharness/src/main/java/com/intuit/tank/runner/method/RequestRunner.java b/agent/apiharness/src/main/java/com/intuit/tank/runner/method/RequestRunner.java
index c488b8ac5..ad93b6d44 100644
--- a/agent/apiharness/src/main/java/com/intuit/tank/runner/method/RequestRunner.java
+++ b/agent/apiharness/src/main/java/com/intuit/tank/runner/method/RequestRunner.java
@@ -41,7 +41,7 @@
import com.intuit.tank.http.xml.XMLRequest;
import com.intuit.tank.logging.LogEventType;
import com.intuit.tank.logging.LoggingProfile;
-import com.intuit.tank.results.TankResultBuilder;
+import com.intuit.tank.reporting.TankResultBuilder;
import com.intuit.tank.runner.ErrorContainer;
import com.intuit.tank.runner.TestStepContext;
import com.intuit.tank.script.RequestDataPhase;
diff --git a/agent/apiharness/src/main/java/com/intuit/tank/runner/method/TimerMap.java b/agent/apiharness/src/main/java/com/intuit/tank/runner/method/TimerMap.java
index ea1307359..4f4943769 100644
--- a/agent/apiharness/src/main/java/com/intuit/tank/runner/method/TimerMap.java
+++ b/agent/apiharness/src/main/java/com/intuit/tank/runner/method/TimerMap.java
@@ -17,8 +17,8 @@
import java.util.Map;
import com.intuit.tank.harness.APITestHarness;
-import com.intuit.tank.results.TankResult;
-import com.intuit.tank.results.TankResultBuilder;
+import com.intuit.tank.reporting.models.TankResult;
+import com.intuit.tank.reporting.TankResultBuilder;
public class TimerMap {
private Map resultsMap = new HashMap();
diff --git a/agent/apiharness/src/main/java/com/intuit/tank/runner/method/TimerRunner.java b/agent/apiharness/src/main/java/com/intuit/tank/runner/method/TimerRunner.java
index 99d5b5f97..0689944f6 100644
--- a/agent/apiharness/src/main/java/com/intuit/tank/runner/method/TimerRunner.java
+++ b/agent/apiharness/src/main/java/com/intuit/tank/runner/method/TimerRunner.java
@@ -17,7 +17,7 @@
import com.intuit.tank.harness.APITestHarness;
import com.intuit.tank.harness.data.TimerStep;
-import com.intuit.tank.results.TankResult;
+import com.intuit.tank.reporting.models.TankResult;
import com.intuit.tank.runner.TestStepContext;
import com.intuit.tank.vm.common.TankConstants;
diff --git a/agent/apiharness/src/test/java/com/intuit/tank/common/TPSTest.java b/agent/apiharness/src/test/java/com/intuit/tank/common/TPSTest.java
deleted file mode 100644
index 1de5d83b6..000000000
--- a/agent/apiharness/src/test/java/com/intuit/tank/common/TPSTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.intuit.tank.common;
-
-/*
- * #%L
- * Intuit Tank Agent (apiharness)
- * %%
- * Copyright (C) 2011 - 2015 Intuit Inc.
- * %%
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * #L%
- */
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Random;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import com.intuit.tank.persistence.databases.AmazonDynamoDatabaseDocApi;
-import com.intuit.tank.persistence.databases.DatabaseKeys;
-import com.intuit.tank.reporting.api.TPSInfo;
-import com.intuit.tank.reporting.api.TPSInfoContainer;
-import com.intuit.tank.reporting.databases.Attribute;
-import com.intuit.tank.reporting.databases.IDatabase;
-import com.intuit.tank.test.TestGroups;
-import com.intuit.tank.vm.common.util.ReportUtil;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.api.Test;
-import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
-import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
-import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
-
-public class TPSTest {
- private static final Logger LOG = LogManager.getLogger(TPSTest.class);
-
- private DynamoDbClient dynamoDbClient;
-
- @BeforeAll
- @Tag(TestGroups.EXPERIMENTAL)
- public void init() {
- AwsCredentials credentials = AwsBasicCredentials.create(System.getProperty("AWS_KEY_ID"),
- System.getProperty("AWS_KEY"));
- dynamoDbClient = DynamoDbClient.builder().credentialsProvider(StaticCredentialsProvider.create(credentials)).build();
- }
-
- @Test
- @Tag(TestGroups.EXPERIMENTAL)
- private void sendTps() {
- TPSInfoContainer tpsInfo = createTPsInfo();
- try {
- IDatabase db = new AmazonDynamoDatabaseDocApi(dynamoDbClient);
- List items = new ArrayList();
- for (TPSInfo info : tpsInfo.getTpsInfos()) {
- com.intuit.tank.reporting.databases.Item item = createItem(info);
- items.add(item);
- }
- String tpsTableName = "test_qa";
- db.initNamespace(tpsTableName);
- LOG.info("Sending " + items.size() + " to TPS Table " + tpsTableName);
- db.addItems(tpsTableName, items, false);
- } catch (Exception e) {
- LOG.error("Error storing TPS: " + e, e);
- }
-
- }
-
- private TPSInfoContainer createTPsInfo() {
- Random rand = new Random();
- List infoList = new ArrayList();
- Calendar cal = Calendar.getInstance();
- cal.add(Calendar.HOUR, -234);
- cal.set(Calendar.MILLISECOND, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MINUTE, 0);
- Date min = cal.getTime();
- for (int i = 0; i < 100; i++) {
- Date start = cal.getTime();
- cal.add(Calendar.SECOND, 15);
- String key = "Apache v1 page 1::12::the other one";
- TPSInfo info = new TPSInfo(start, key, rand.nextInt(49) + 1, 15);
- infoList.add(info);
- }
- Date max = cal.getTime();
- return new TPSInfoContainer(min, max, 15, infoList);
- }
-
- private com.intuit.tank.reporting.databases.Item createItem(TPSInfo info) {
- com.intuit.tank.reporting.databases.Item item = new com.intuit.tank.reporting.databases.Item();
- List attributes = new ArrayList();
- String ts = ReportUtil.getTimestamp(info.getTimestamp());
- addAttribute(attributes, DatabaseKeys.TIMESTAMP_KEY.getShortKey(), ts);
- addAttribute(attributes, DatabaseKeys.JOB_ID_KEY.getShortKey(), "1234");
- addAttribute(attributes, DatabaseKeys.INSTANCE_ID_KEY.getShortKey(), "i-1234443322");
- addAttribute(attributes, DatabaseKeys.LOGGING_KEY_KEY.getShortKey(), info.getKey());
- addAttribute(attributes, DatabaseKeys.PERIOD_KEY.getShortKey(), Integer.toString(info.getPeriodInSeconds()));
- addAttribute(attributes, DatabaseKeys.TRANSACTIONS_KEY.getShortKey(), Integer.toString(info.getTransactions()));
- item.setAttributes(attributes);
- String name = "i-1234443322"
- + "_" + "1234"
- + "_" + info.getKey()
- + "_" + ts;
- item.setName(name);
- return item;
- }
-
- public static void addAttribute(List attributes, String key, String value) {
- if (value == null) {
- value = "";
- }
- attributes.add(new Attribute(key, value));
- }
-}
diff --git a/agent/apiharness/src/test/java/com/intuit/tank/harness/TPSMonitorTest.java b/agent/apiharness/src/test/java/com/intuit/tank/harness/TPSMonitorTest.java
index 3848a9a7c..c229e7e88 100644
--- a/agent/apiharness/src/test/java/com/intuit/tank/harness/TPSMonitorTest.java
+++ b/agent/apiharness/src/test/java/com/intuit/tank/harness/TPSMonitorTest.java
@@ -19,7 +19,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.intuit.tank.http.BaseRequest;
-import com.intuit.tank.reporting.api.TPSInfoContainer;
+import com.intuit.tank.reporting.models.TPSInfoContainer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
diff --git a/agent/apiharness/src/test/java/com/intuit/tank/runner/method/TimerMapTest.java b/agent/apiharness/src/test/java/com/intuit/tank/runner/method/TimerMapTest.java
index 66f3f63ba..dd5ba35f6 100644
--- a/agent/apiharness/src/test/java/com/intuit/tank/runner/method/TimerMapTest.java
+++ b/agent/apiharness/src/test/java/com/intuit/tank/runner/method/TimerMapTest.java
@@ -17,7 +17,7 @@
*/
import org.junit.jupiter.api.Test;
-import com.intuit.tank.results.TankResult;
+import com.intuit.tank.reporting.models.TankResult;
/**
* The class TimerMapTest
contains tests for the class {@link TimerMap}
.
diff --git a/api/src/main/java/com/intuit/tank/reporting/DummyResultsReader.java b/api/src/main/java/com/intuit/tank/reporting/DummyResultsReader.java
new file mode 100644
index 000000000..28154f759
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/DummyResultsReader.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting;
+
+import com.intuit.tank.reporting.models.TPSInfo;
+import com.intuit.tank.reporting.models.TankResult;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+
+import java.util.*;
+
+/**
+ * DummyResultsReader
+ *
+ * @author dangleton
+ *
+ */
+public class DummyResultsReader implements ResultsReader {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getAllTimingResults(String jobId) {
+ return new ArrayList();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public PagedTimingResults getPagedTimingResults(String jobId, Object nextToken) {
+ return new PagedTimingResults(null, new ArrayList());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasTimingData(String jobId) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void deleteTimingForJob(String jobId, boolean asynch) {
+ // no-op
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map> getTpsMapForJob(Date minDate, String... jobId) {
+ return new HashMap>();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map> getTpsMapForInstance(Date minDate, String jobId, String instanceId) {
+ return new HashMap>();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void config(HierarchicalConfiguration config) {
+ // no-op
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/DummyResultsReporter.java b/api/src/main/java/com/intuit/tank/reporting/DummyResultsReporter.java
new file mode 100644
index 000000000..2b0bf9e67
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/DummyResultsReporter.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting;
+
+import com.intuit.tank.reporting.models.TPSInfoContainer;
+import com.intuit.tank.reporting.models.TankResult;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+
+import java.util.List;
+
+/**
+ * DummyResultsReporter
+ *
+ * @author dangleton
+ *
+ */
+public class DummyResultsReporter implements ResultsReporter {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void sendTpsResults(String jobId, String instanceId, TPSInfoContainer container, boolean async) {
+ // do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void sendTimingResults(String jobId, String instanceId, List results, boolean asynch) {
+ // do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void config(HierarchicalConfiguration config) {
+ // do nothing
+
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/PagedTimingResults.java b/api/src/main/java/com/intuit/tank/reporting/PagedTimingResults.java
new file mode 100644
index 000000000..71ee041b1
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/PagedTimingResults.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting;
+
+import com.intuit.tank.reporting.models.TankResult;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class PagedTimingResults implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Object nextToken;
+ private List results;
+
+ public PagedTimingResults(Object nextToken, List results) {
+ super();
+ this.nextToken = nextToken;
+ this.results = results;
+ }
+
+ /**
+ * @return the nextToken
+ */
+ public Object getNextToken() {
+ return nextToken;
+ }
+
+ /**
+ * @return the results
+ */
+ public List getResults() {
+ return results;
+ }
+
+ /**
+ * returns if there are more results to fetch.
+ *
+ * @return
+ */
+ public boolean hasMoreResults() {
+ return nextToken != null;
+ }
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/ReportingFactory.java b/api/src/main/java/com/intuit/tank/reporting/ReportingFactory.java
new file mode 100644
index 000000000..7cd938d58
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/ReportingFactory.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting;
+
+import com.intuit.tank.vm.settings.ReportingConfig;
+import com.intuit.tank.vm.settings.TankConfig;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public final class ReportingFactory {
+
+ private static final Logger LOG = LogManager.getLogger(ReportingFactory.class);
+
+ private ReportingFactory() {
+
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static final ResultsReporter getResultsReporter() {
+ ResultsReporter ret = null;
+ try {
+ ReportingConfig config = new TankConfig().getReportingConfig();
+ String providerClass = config.getReporterClass();
+ ret = (ResultsReporter) Class.forName(providerClass).newInstance();
+ HierarchicalConfiguration providerConfig = config.getProviderConfig();
+ ret.config(providerConfig);
+ } catch (Exception e) {
+ LOG.error("Error instantiating reporter");
+ ret = new DummyResultsReporter();
+ }
+ return ret;
+ }
+ /**
+ *
+ * @return
+ */
+ public static final ResultsReader getResultsReader() {
+ ResultsReader ret = null;
+ try {
+ ReportingConfig config = new TankConfig().getReportingConfig();
+ String providerClass = config.getReaderClass();
+ ret = (ResultsReader) Class.forName(providerClass).newInstance();
+ HierarchicalConfiguration providerConfig = config.getProviderConfig();
+ ret.config(providerConfig);
+ } catch (Exception e) {
+ LOG.error("Error instantiating reporter");
+// ret = new DummyResultsReader();
+ }
+ return ret;
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/ResultsReader.java b/api/src/main/java/com/intuit/tank/reporting/ResultsReader.java
new file mode 100644
index 000000000..bd8bc9262
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/ResultsReader.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting;
+
+import com.intuit.tank.reporting.models.TPSInfo;
+import com.intuit.tank.reporting.models.TankResult;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+
+import javax.annotation.Nonnull;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+public interface ResultsReader {
+
+ /**
+ * Gets all the timing results for the given job
+ *
+ * @param jobId
+ * the job to get timing for
+ * @return list of TankResults
+ */
+ @Nonnull
+ public List getAllTimingResults(String jobId);
+
+ /**
+ * Gets the Results in a paged manner to limit the effect on memory heap.
+ *
+ * @param jobId
+ * the job to get timing for
+ * @param nextToken
+ * passing in a nonnull value will get results from the poing last retrieved.
+ * @return PagedTimingResults containing the linst of tank results and a nexttoken that if not null indicates that
+ * there are more items to be fetched.
+ */
+ @Nonnull
+ public PagedTimingResults getPagedTimingResults(String jobId, Object nextToken);
+
+ /**
+ * Tests if there is timing data for the specified job
+ *
+ * @param jobId
+ * the job to get timing for
+ * @return true if there is data
+ */
+ public boolean hasTimingData(String jobId);
+
+ /**
+ * deletes timing data from storage.
+ *
+ * @param jobId
+ * the job to get timing for
+ * @param asynch
+ * true to run deletion asynchronously
+ */
+ public void deleteTimingForJob(String jobId, boolean asynch);
+
+ /**
+ * Gets the TPS data as a map of maps for the list of jobs.
+ *
+ * @param jobId
+ * the job to get timing for
+ * @return Map of maps
+ */
+ @Nonnull
+ public Map> getTpsMapForJob(Date minDate, String... jobId);
+
+ /**
+ * Gets the TPS data as a map of maps for the instance.
+ *
+ * @param jobId
+ * the job to get timing for
+ * @param instanceId
+ * the instance to fetch the tps data for.
+ * @return Map of maps
+ */
+ @Nonnull
+ public Map> getTpsMapForInstance(Date minDate, String jobId, String instanceId);
+
+ /**
+ * configure this service from config file.
+ *
+ * @param config
+ * the config
+ */
+ public void config(HierarchicalConfiguration config);
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/ResultsReporter.java b/api/src/main/java/com/intuit/tank/reporting/ResultsReporter.java
new file mode 100644
index 000000000..2ffa554ce
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/ResultsReporter.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting;
+
+import com.intuit.tank.reporting.models.TPSInfoContainer;
+import com.intuit.tank.reporting.models.TankResult;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+
+import java.util.List;
+
+/**
+ *
+ * ResultsReporter interface for reporting results to controller. Default is DynamoDB but for standalone can use a rest
+ * service or file system implementation.
+ *
+ * @author dangleton
+ *
+ */
+public interface ResultsReporter {
+
+ /**
+ * Sends results to storage
+ *
+ * @param jobId
+ * the job id
+ * @param instanceId
+ * the instance id
+ * @param container
+ * the tps infos
+ * @param async
+ * true if the job should be run asynchronpously
+ */
+ public void sendTpsResults(String jobId, String instanceId, TPSInfoContainer container, boolean async);
+
+ /**
+ * Send the timing results to storage.
+ *
+ * @param jobId
+ * the job id
+ * @param instanceId
+ * the instance id
+ * @param results
+ * the reulsts
+ * @param async
+ * true if the job should be run asynchronpously
+ */
+ public void sendTimingResults(String jobId, String instanceId, List results, boolean async);
+
+ /**
+ * configure this service from config file.
+ *
+ * @param config
+ * the config
+ */
+ public void config(HierarchicalConfiguration config);
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/TankResultBuilder.java b/api/src/main/java/com/intuit/tank/reporting/TankResultBuilder.java
new file mode 100644
index 000000000..606b7d6d0
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/TankResultBuilder.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting;
+
+import com.intuit.tank.reporting.models.TankResult;
+
+import java.util.Date;
+
+public class TankResultBuilder extends TankResultBuilderBase {
+ public static TankResultBuilder tankResult() {
+ return new TankResultBuilder();
+ }
+
+ public TankResultBuilder() {
+ super(new TankResult());
+ }
+
+ public TankResult build() {
+ return getInstance();
+ }
+}
+
+class TankResultBuilderBase> {
+ private TankResult instance;
+
+ protected TankResultBuilderBase(TankResult aInstance) {
+ instance = aInstance;
+ }
+
+ protected TankResult getInstance() {
+ return instance;
+ }
+
+ @SuppressWarnings("unchecked")
+ public GeneratorT withResponseTime(int aValue) {
+ instance.setResponseTime(aValue);
+
+ return (GeneratorT) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public GeneratorT withJobId(String aValue) {
+ instance.setJobId(aValue);
+
+ return (GeneratorT) this;
+ }
+ @SuppressWarnings("unchecked")
+ public GeneratorT withInstanceId(String aValue) {
+ instance.setInstanceId(aValue);
+
+ return (GeneratorT) this;
+ }
+ @SuppressWarnings("unchecked")
+ public GeneratorT withTimestamp(Date aValue) {
+ instance.setTimeStamp(aValue);
+
+ return (GeneratorT) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public GeneratorT withStatusCode(int aValue) {
+ instance.setStatusCode(aValue);
+
+ return (GeneratorT) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public GeneratorT withResponseSize(int aValue) {
+ instance.setResponseSize(aValue);
+
+ return (GeneratorT) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public GeneratorT withError(boolean aValue) {
+ instance.setError(aValue);
+
+ return (GeneratorT) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public GeneratorT withRequestName(String aValue) {
+ instance.setRequestName(aValue);
+
+ return (GeneratorT) this;
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/models/CreateTableMessage.java b/api/src/main/java/com/intuit/tank/reporting/models/CreateTableMessage.java
new file mode 100644
index 000000000..f688c427b
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/models/CreateTableMessage.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting.models;
+
+import java.io.Serializable;
+
+public class CreateTableMessage implements Serializable {
+
+ private static final long serialVersionUID = 2597506740196523603L;
+ private String tableName;
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/models/Namespace.java b/api/src/main/java/com/intuit/tank/reporting/models/Namespace.java
new file mode 100644
index 000000000..909923ea1
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/models/Namespace.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting.models;
+
+/**
+ * Namespace
+ *
+ * @author dangleton
+ *
+ */
+public class Namespace {
+
+ public static final String NAMESPACE_V1 = "urn:tank/domain/reporting";
+
+ private Namespace() {
+ }
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/models/TPSInfo.java b/api/src/main/java/com/intuit/tank/reporting/models/TPSInfo.java
new file mode 100644
index 000000000..10f1c85bd
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/models/TPSInfo.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting.models;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import javax.xml.bind.annotation.*;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * TPSInfo class representing a tps for a specific key and a specific period
+ *
+ * @author dangleton
+ *
+ */
+@XmlRootElement(name = "TPSInfo", namespace = Namespace.NAMESPACE_V1)
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "TPSInfoType", namespace = Namespace.NAMESPACE_V1, propOrder = {
+ "timestamp",
+ "key",
+ "transactions",
+ "period"
+})
+public class TPSInfo implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @XmlElement(name = "timestamp", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private Date timestamp;
+
+ @XmlElement(name = "key", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private String key;
+
+ @XmlElement(name = "transactions", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private int transactions;
+
+ @XmlElement(name = "period", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private int period;
+
+ public TPSInfo() {
+ }
+
+ /**
+ *
+ * @param timestamp
+ * @param key
+ * @param transactions
+ * @param period
+ */
+ public TPSInfo(Date timestamp, String key, int transactions, int period) {
+ super();
+ this.timestamp = timestamp;
+ this.key = key;
+ this.transactions = transactions;
+ this.period = period;
+ }
+
+ public TPSInfo add(TPSInfo toAdd) {
+ return new TPSInfo(timestamp, key, transactions + toAdd.transactions, period);
+ }
+
+ /**
+ * @return the timestamp
+ */
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * @return the key
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * @return the transactions
+ */
+ public int getTransactions() {
+ return transactions;
+ }
+
+ /**
+ * @return the period
+ */
+ public int getPeriodInSeconds() {
+ return period;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public int getTPS() {
+ int tps = 0;
+ if (period != 0) {
+ tps = Math.round(transactions / period);
+ }
+ return tps;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("key", key).append("period", period).append("tps", getTPS())
+ .append("timestamp", timestamp).toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof TPSInfo)) {
+ return false;
+ }
+ TPSInfo entity = (TPSInfo) obj;
+ return new EqualsBuilder().append(timestamp, entity.timestamp).append(key, entity.key).isEquals();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(21, 43).append(timestamp).append(key).toHashCode();
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/models/TPSInfoContainer.java b/api/src/main/java/com/intuit/tank/reporting/models/TPSInfoContainer.java
new file mode 100644
index 000000000..e9b28cb75
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/models/TPSInfoContainer.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting.models;
+
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import javax.xml.bind.annotation.*;
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * TPSInfoContainer
+ *
+ * @author dangleton
+ *
+ */
+@XmlRootElement(name = "TPSInfoContainer", namespace = Namespace.NAMESPACE_V1)
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "TPSInfoContainerType", namespace = Namespace.NAMESPACE_V1, propOrder = {
+ "minTime",
+ "maxTime",
+ "period",
+ "totalTps",
+ "tpsInfos"
+})
+public class TPSInfoContainer implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @XmlElement(name = "minTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private Date minTime;
+
+ @XmlElement(name = "maxTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private Date maxTime;
+
+ @XmlElement(name = "period", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private int period;
+
+ @XmlElement(name = "totalTps", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private int totalTps;
+
+ @XmlElementWrapper(name = "tpsInfos", namespace = Namespace.NAMESPACE_V1)
+ @XmlElement(name = "tps", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private List tpsInfos = new ArrayList();
+
+ /**
+ * @FrameworkUseOnly
+ */
+ public TPSInfoContainer() {
+ }
+
+ public TPSInfoContainer(Date minTime, Date maxTime, int period, List tpsInfos) {
+ super();
+ this.minTime = minTime;
+ this.maxTime = maxTime;
+ this.tpsInfos = tpsInfos;
+ this.period = period;
+ if (tpsInfos != null) {
+ Map transactionMap = new HashMap();
+ for (TPSInfo info : tpsInfos) {
+ Integer tps = transactionMap.get(info.getTimestamp());
+ if (tps == null) {
+ tps = 0;
+ }
+ tps += info.getTransactions();
+ transactionMap.put(info.getTimestamp(), tps);
+ }
+ if (!transactionMap.isEmpty()) {
+ ArrayList dates = new ArrayList(transactionMap.keySet());
+ Collections.sort(dates);
+ Date date = dates.get(dates.size() - 1);
+ totalTps = transactionMap.get(date) / period;
+ }
+ }
+ }
+
+ /**
+ * @return the period
+ */
+ public int getPeriod() {
+ return period;
+ }
+
+ /**
+ *
+ * @return the total TPS
+ */
+ public int getTotalTps() {
+ return totalTps;
+ }
+
+ /**
+ * @return the tpsInfos
+ */
+ public List getTpsInfos() {
+ return tpsInfos;
+ }
+
+ /**
+ * @return the minTime
+ */
+ public Date getMinTime() {
+ return minTime;
+ }
+
+ /**
+ * @return the maxTime
+ */
+ public Date getMaxTime() {
+ return maxTime;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("period", period).append("minTime", minTime).append("maxTime", maxTime)
+ // .append(tpsInfos)
+ .toString();
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/models/TPSReportingPackage.java b/api/src/main/java/com/intuit/tank/reporting/models/TPSReportingPackage.java
new file mode 100644
index 000000000..89c2a4200
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/models/TPSReportingPackage.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting.models;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import javax.xml.bind.annotation.*;
+import java.io.Serializable;
+
+/**
+ * TPSReportingPackage
+ *
+ * @author dangleton
+ *
+ */
+@XmlRootElement(name = "TPSReportingPackage", namespace = Namespace.NAMESPACE_V1)
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "TPSReportingPackageType", namespace = Namespace.NAMESPACE_V1, propOrder = {
+ "jobId",
+ "instanceId",
+ "container"
+})
+public class TPSReportingPackage implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private String jobId;
+
+ @XmlElement(name = "instanceId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private String instanceId;
+
+ @XmlElement(name = "container", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private TPSInfoContainer container;
+
+
+ /**
+ * @FrameworkUseOnly
+ */
+ public TPSReportingPackage() {
+ }
+
+
+
+ public TPSReportingPackage(String jobId, String instanceId, TPSInfoContainer container) {
+ super();
+ this.jobId = jobId;
+ this.instanceId = instanceId;
+ this.container = container;
+ }
+
+
+
+
+ /**
+ * @return the jobId
+ */
+ public String getJobId() {
+ return jobId;
+ }
+
+
+
+ /**
+ * @return the instanceId
+ */
+ public String getInstanceId() {
+ return instanceId;
+ }
+
+
+
+ /**
+ * @return the container
+ */
+ public TPSInfoContainer getContainer() {
+ return container;
+ }
+
+
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("jobId", jobId).append("instanceId", instanceId).toString();
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/models/TankAgentStatusResponse.java b/api/src/main/java/com/intuit/tank/reporting/models/TankAgentStatusResponse.java
new file mode 100644
index 000000000..441c80bee
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/models/TankAgentStatusResponse.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting.models;
+
+import java.io.Serializable;
+
+public class TankAgentStatusResponse implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 230150628670367273L;
+
+ private int numVirtualUsers;
+ private int maxVirtualUsers;
+ private int rampTimeLeft;
+ private long runTime;
+
+ public TankAgentStatusResponse(long time, int num, int max, int ramp) {
+ runTime = time;
+ numVirtualUsers = num;
+ maxVirtualUsers = max;
+ rampTimeLeft = ramp;
+ }
+
+ public int getRampTimeLeft() {
+ return rampTimeLeft;
+ }
+
+ public long getRunTime() {
+ return runTime;
+ }
+
+ public int getCurrentNumberUsers() {
+ return numVirtualUsers;
+ }
+
+ public int getMaxVirtualUsers() {
+ return maxVirtualUsers;
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/models/TankResult.java b/api/src/main/java/com/intuit/tank/reporting/models/TankResult.java
new file mode 100644
index 000000000..feb37c324
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/models/TankResult.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting.models;
+
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import javax.xml.bind.annotation.*;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * WatsResult represents a result to log or store to database.
+ *
+ * @author dangleton
+ *
+ */
+@XmlRootElement(name = "TankResult", namespace = Namespace.NAMESPACE_V1)
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "TankResultType", namespace = Namespace.NAMESPACE_V1, propOrder = {
+ "jobId",
+ "instanceId",
+ "responseTime",
+ "statusCode",
+ "responseSize",
+ "requestName",
+ "error",
+ "timeStamp"
+})
+public class TankResult implements Serializable, Comparable {
+
+ private static final long serialVersionUID = 1L;
+
+ @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private String jobId;
+
+ @XmlElement(name = "instanceId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private String instanceId;
+
+ @XmlElement(name = "responseTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private int responseTime;
+
+ @XmlElement(name = "statusCode", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private int statusCode;
+
+ @XmlElement(name = "responseSize", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private int responseSize;
+
+ @XmlElement(name = "requestName", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private String requestName;
+
+ @XmlElement(name = "error", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private boolean error;
+
+ @XmlElement(name = "timestamp", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private Date timeStamp = new Date();
+
+ /**
+ * @return the jobId
+ */
+ public String getJobId() {
+ return jobId;
+ }
+
+ /**
+ * @param jobId
+ * the jobId to set
+ */
+ public void setJobId(String jobId) {
+ this.jobId = jobId;
+ }
+
+ /**
+ * @return the instanceId
+ */
+ public String getInstanceId() {
+ return instanceId;
+ }
+
+ /**
+ * @param instanceId
+ * the instanceId to set
+ */
+ public void setInstanceId(String instanceId) {
+ this.instanceId = instanceId;
+ }
+
+ public int getResponseTime() {
+ return responseTime;
+ }
+
+ public void setResponseTime(int connectionTime) {
+ this.responseTime = connectionTime;
+ }
+
+ public int getResponseSize() {
+ return responseSize;
+ }
+
+ public void setResponseSize(int responseSize) {
+ this.responseSize = responseSize;
+ }
+
+ public boolean isError() {
+ return error;
+ }
+
+ public void setError(boolean error) {
+ this.error = error;
+ }
+
+ public void setRequestName(String requestName) {
+ this.requestName = requestName;
+ }
+
+ public String getRequestName() {
+ return requestName;
+ }
+
+ /**
+ * @return the timeStamp
+ */
+ public Date getTimeStamp() {
+ return timeStamp;
+ }
+
+ /**
+ * @param timeStamp
+ * the timeStamp to set
+ */
+ public void setTimeStamp(Date timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ /**
+ * @return the statusCode
+ */
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ /**
+ * @param statusCode
+ * the statusCode to set
+ */
+ public void setStatusCode(int statusCode) {
+ this.statusCode = statusCode;
+ }
+
+ public void add(TankResult result) {
+ responseTime += result.getResponseTime();
+ responseSize += result.getResponseSize();
+ timeStamp = result.getTimeStamp();
+ if (statusCode <= 0) {
+ statusCode = result.getStatusCode();
+ }
+ if (result.error) {
+ error = result.error;
+ }
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.requestName.compareTo(((TankResult)o).getRequestName());
+ }
+
+}
diff --git a/api/src/main/java/com/intuit/tank/reporting/models/TankResultPackage.java b/api/src/main/java/com/intuit/tank/reporting/models/TankResultPackage.java
new file mode 100644
index 000000000..aefe938ba
--- /dev/null
+++ b/api/src/main/java/com/intuit/tank/reporting/models/TankResultPackage.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright 2015-2023 Intuit Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.intuit.tank.reporting.models;
+
+import javax.xml.bind.annotation.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TankResultPackage
+ *
+ * @author dangleton
+ *
+ */
+@XmlRootElement(name = "TankResultPackage", namespace = Namespace.NAMESPACE_V1)
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "TankResultPackageType", namespace = Namespace.NAMESPACE_V1, propOrder = {
+ "jobId",
+ "instanceId",
+ "results"
+})
+public class TankResultPackage implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private String jobId;
+
+ @XmlElement(name = "instanceId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private String instanceId;
+
+ @XmlElementWrapper(name = "results", namespace = Namespace.NAMESPACE_V1)
+ @XmlElement(name = "TankResult", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false)
+ private List results = new ArrayList();
+
+ /**
+ * @FrameworkUseOnly
+ */
+ public TankResultPackage() {
+ }
+
+ public TankResultPackage(String jobId, String instanceId, List results) {
+ super();
+ this.jobId = jobId;
+ this.instanceId = instanceId;
+ this.results = results;
+ }
+
+ /**
+ * @return the serialversionuid
+ */
+ public static long getSerialversionuid() {
+ return serialVersionUID;
+ }
+
+ /**
+ * @return the jobId
+ */
+ public String getJobId() {
+ return jobId;
+ }
+
+ /**
+ * @return the instanceId
+ */
+ public String getInstanceId() {
+ return instanceId;
+ }
+
+ /**
+ * @return the results
+ */
+ public List getResults() {
+ return results;
+ }
+
+}
diff --git a/web/web_support/pom.xml b/web/web_support/pom.xml
index 106f2298f..d7dcdd41a 100644
--- a/web/web_support/pom.xml
+++ b/web/web_support/pom.xml
@@ -109,6 +109,12 @@
commons-fileupload
+
+ commons-beanutils
+ commons-beanutils
+ 1.9.4
+
+
javax.validation
diff --git a/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java b/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java
index bb0c7629b..23e05d74c 100644
--- a/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java
+++ b/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java
@@ -65,9 +65,9 @@
import com.intuit.tank.job.VMNodeBean;
import com.intuit.tank.prefs.TablePreferences;
import com.intuit.tank.prefs.TableViewState;
-import com.intuit.tank.reporting.api.ResultsReader;
-import com.intuit.tank.reporting.api.TPSInfo;
-import com.intuit.tank.reporting.factory.ReportingFactory;
+import com.intuit.tank.reporting.ResultsReader;
+import com.intuit.tank.reporting.models.TPSInfo;
+import com.intuit.tank.reporting.ReportingFactory;
import com.intuit.tank.util.ExceptionHandler;
/**