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; /**