modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
| 100 ---------
modules/core/domain/src/test/java/org/rhq/core/domain/measurement/test/MeasurementBaselineTest.java
| 54 +++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
| 108 +---------
modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricBaselineCalculator.java
| 67 ++++++
4 files changed, 146 insertions(+), 183 deletions(-)
New commits:
commit 211ca70a03647ccdc99bb8f22f3a296beb52320b
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Dec 13 16:00:43 2012 -0600
Move baseline calculation away from SQL db. The baselines will continue to be stored
and retrieved from SQL but the data for the calculation will have to come from new metrics
storage system. Also removed most of the references to the old way of calculating
baselines.
Cassandra integration is still to be added.
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
index 4df256b..7b3e4a7 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
@@ -42,49 +42,9 @@ import javax.persistence.Table;
@Entity
@NamedQueries( {
- // Unfortunately, hibernate is broken after 3.2.0.rc4 - we can't process these
insert/delete HQL queries.
- //
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2833
- // Instead, take these HQLs, plug into Eclipse Hibernate Tool and look at the
generated native SQL.
- // Take those native queries (for each supported database) and create native queries
here.
- // Can't use NamedNativeQuery either, hibernate doesn't support that.
-
- // update: RHQ-716 proved that this still isn't working, even with a version of
Hibernate containing a fix
- // for HHH-2833. Basically, CURRENT_TIMESTAMP returns a timestamp data type, but
computeTime field expects
- // a long. this incompatibility forces the query analysis to bomb at compile time.
this issue could have been
- // by-passed if Hibernate allows binding parameters in the select list, but that is
disallowed as well.
- /*
- @NamedQuery(name = MeasurementBaseline.QUERY_CALC_FIRST_AUTOBASELINE, query =
"" //
- + " INSERT INTO MeasurementBaseline
(baselineMin,baselineMax,baselineMean,computeTime,scheduleId) "
- + " SELECT min(d.min) AS baselineMin, "
- + " max(d.max) AS baselineMax, "
- + " avg(d.value) AS baselineMean, "
- + " CURRENT_TIMESTAMP AS currentTime, "
- + " d.id.scheduleId AS scheduleId "
- + " FROM MeasurementDataNumeric1H d "
- + " JOIN d.schedule s "
- + " LEFT JOIN s.baseline b "
- + " WHERE s.definition.numericType = 0 "
- + " AND b.id IS NULL "
- + " AND d.id.timestamp BETWEEN :startTime AND :endTime "
- + " GROUP BY d.id.scheduleId "
- + " HAVING d.id.scheduleId IN (SELECT d1.id.scheduleId "
- + " FROM MeasurementDataNumeric1H d1 "
- + " WHERE d1.id.timestamp <= :startTime)
"),
- @NamedQuery(name = MeasurementBaseline.QUERY_DELETE_EXISTING_AUTOBASELINES, query =
"" //
- + " DELETE MeasurementBaseline AS doomed WHERE doomed.scheduleId IN "
- + "( "
- + " SELECT d.id.scheduleId AS scheduleId "
- + " FROM MeasurementDataNumeric1H d "
- + " JOIN d.schedule s "
- + " LEFT JOIN s.baseline b "
- + " WHERE b.id IS NOT NULL "
- + " AND d.id.timestamp BETWEEN :startTime AND :endTime "
- + " AND b.userEntered = FALSE "
- + " GROUP BY d.id.scheduleId "
- + " HAVING d.id.scheduleId IN (SELECT d1.id.scheduleId "
- + " FROM MeasurementDataNumeric1H d1 "
- + " WHERE d1.id.timestamp <= :startTime)
" + ") "),
- */
+ @NamedQuery(name =
MeasurementBaseline.QUERY_FIND_MEASUREMENT_SCHEDULES_WITHOUT_AUTOBASELINES, query =
"SELECT schedule.id FROM MeasurementSchedule schedule "
+ + "WHERE schedule.definition.numericType = 0 AND "
+ + "schedule.id NOT IN (SELECT scheduleId FROM MeasurementBaseline)"),
@NamedQuery(name = MeasurementBaseline.QUERY_FIND_BY_RESOURCE, query = "SELECT
mb FROM MeasurementBaseline mb WHERE mb.schedule.resource.id = :resourceId"),
@NamedQuery(name = MeasurementBaseline.QUERY_FIND_BY_RESOURCE_IDS_AND_DEF_IDS, query
= "SELECT mb FROM MeasurementBaseline mb "
+ "WHERE mb.schedule.resource.id IN (:resourceIds) AND
mb.schedule.definition.id IN (:definitionIds)"),
@@ -112,9 +72,8 @@ public class MeasurementBaseline implements Serializable {
public static final String QUERY_DELETE_BY_RESOURCES =
"MeasurementBaseline.deleteByResources";
public static final String QUERY_CALC_FIRST_AUTOBASELINE =
"MeasurementBaseline.calcFirstAutoBaseline";
public static final String QUERY_DELETE_EXISTING_AUTOBASELINES =
"MeasurementBaseline.deleteExistingAutoBaseline";
+ public static final String QUERY_FIND_MEASUREMENT_SCHEDULES_WITHOUT_AUTOBASELINES =
"MeasurementBaseline.findMetricSchedulesWithoutAutoBaselines";
public static final String NATIVE_QUERY_CALC_FIRST_AUTOBASELINE_POSTGRES;
- public static final String NATIVE_QUERY_CALC_FIRST_AUTOBASELINE_ORACLE;
- public static final String NATIVE_QUERY_CALC_FIRST_AUTOBASELINE_SQLSERVER;
static {
/*
@@ -131,7 +90,7 @@ public class MeasurementBaseline implements Serializable {
+ " FROM RHQ_MEASUREMENT_DATA_NUM_1H data1h " //
baselines are 1H data statistics
+ " INNER JOIN RHQ_MEASUREMENT_SCHED sched " // baselines are
aggregates of schedules
+ " ON data1h.SCHEDULE_ID = sched.id " //
- + " INNER JOIN RHQ_MEASUREMENT_DEF def " // only compute off of
dynamic types
+ + " INNER JOIN RHQ_MEASUREMENT_DEF def " // only compute off of
dynamic types
+ " ON sched.definition = def.id " //
+ "LEFT OUTER JOIN RHQ_MEASUREMENT_BLINE bline " // we want null
entries on purpose
+ " ON sched.id = bline.SCHEDULE_ID " //
@@ -144,55 +103,6 @@ public class MeasurementBaseline implements Serializable {
+ " FROM
RHQ_MEASUREMENT_DATA_NUM_1H mdata " //
+ " WHERE mdata.TIME_STAMP <=
? ) " // ?4=startTime
+ " LIMIT 100000 "; // batch at most 100K inserts at a
time to shrink the xtn size
-
- NATIVE_QUERY_CALC_FIRST_AUTOBASELINE_ORACLE = "" //
- + " INSERT INTO RHQ_MEASUREMENT_BLINE ( id, BL_MIN, BL_MAX, BL_MEAN,
BL_COMPUTE_TIME, SCHEDULE_ID ) "
- + " SELECT RHQ_MEASUREMENT_BLINE_ID_SEQ.nextval, " //
- + " blMin, blMax, blAvg, coTime, schId "
- + " FROM ( SELECT MIN(data1h.minvalue) AS blMin, " //
- + " MAX(data1h.maxvalue) AS blMax, " //
- + " AVG(data1h.value) AS blAvg, " //
- + " ? as coTime, " // ?1=computeTime
- + " data1h.SCHEDULE_ID as schId " //
- + " FROM RHQ_MEASUREMENT_DATA_NUM_1H data1h " //
baselines are 1H data statistics
- + " INNER JOIN RHQ_MEASUREMENT_SCHED sched " //
baselines are aggregates of schedules
- + " ON data1h.SCHEDULE_ID = sched.id " //
- + " INNER JOIN RHQ_MEASUREMENT_DEF def " // only
compute off of dynamic types
- + " ON sched.definition = def.id " //
- + " LEFT OUTER JOIN RHQ_MEASUREMENT_BLINE bline " // we
want null entries on purpose
- + " ON sched.id = bline.SCHEDULE_ID " //
- + " WHERE ( def.numeric_type = 0 ) " // only
dynamics (NumericType.DYNAMIC)
- + " AND ( bline.id IS NULL ) " // no baseline
means it was deleted or never calculated
- + " AND ( data1h.TIME_STAMP BETWEEN ? AND ? ) "
// ?2=startTime, ?3=endTime
- + " AND ROWNUM < 100001 " // batch at most
100K inserts at a time to shrink the xtn size
- + " GROUP BY data1h.SCHEDULE_ID " // baselines are
aggregates per schedule
- // but only calculate baselines for schedules where we have data that fills
(startTime, endTime)
- + " HAVING data1h.SCHEDULE_ID in ( SELECT distinct
(mdata.SCHEDULE_ID) " //
- + " FROM
RHQ_MEASUREMENT_DATA_NUM_1H mdata "
- + " WHERE
mdata.TIME_STAMP <= ? ) ) "; // ?4=startTime
-
- NATIVE_QUERY_CALC_FIRST_AUTOBASELINE_SQLSERVER = "" //
- + " INSERT INTO RHQ_MEASUREMENT_BLINE ( BL_MIN, BL_MAX, BL_MEAN,
BL_COMPUTE_TIME, SCHEDULE_ID ) "
- + " SELECT MIN(data1h.minvalue) AS blMin, " //
- + " MAX(data1h.maxvalue) AS blMax, " //
- + " AVG(data1h.value) AS blAvg, " //
- + " ? as coTime, " // ?1=computeTime
- + " data1h.SCHEDULE_ID as schId " //
- + " FROM RHQ_MEASUREMENT_DATA_NUM_1H data1h " //
baselines are 1H data statistics
- + " INNER JOIN RHQ_MEASUREMENT_SCHED sched " // baselines are
aggregates of schedules
- + " ON data1h.SCHEDULE_ID = sched.id " //
- + " INNER JOIN RHQ_MEASUREMENT_DEF def " // only compute off of
dynamic types
- + " ON sched.definition = def.id " //
- + "LEFT OUTER JOIN RHQ_MEASUREMENT_BLINE bline " // we want null
entries on purpose
- + " ON sched.id = bline.SCHEDULE_ID " //
- + " WHERE ( def.numeric_type = 0 ) " // only dynamics
(NumericType.DYNAMIC)
- + " AND ( bline.id IS NULL ) " // no baseline means it
was deleted or never calculated
- + " AND ( data1h.TIME_STAMP BETWEEN ? AND ? ) " //
?2=startTime, ?3=endTime
- + " GROUP BY data1h.SCHEDULE_ID " // baselines are
aggregates per schedule
- // but only calculate baselines for schedules where we have data that fills
(startTime, endTime)
- + " HAVING data1h.SCHEDULE_ID in ( SELECT distinct
(mdata.SCHEDULE_ID) " //
- + " FROM
RHQ_MEASUREMENT_DATA_NUM_1H mdata "
- + " WHERE mdata.TIME_STAMP <=
? ) "; // ?4=startTime
}
private static final long serialVersionUID = 1L;
@GeneratedValue(strategy = GenerationType.AUTO, generator = "MEAS_BL_GEN")
diff --git
a/modules/core/domain/src/test/java/org/rhq/core/domain/measurement/test/MeasurementBaselineTest.java
b/modules/core/domain/src/test/java/org/rhq/core/domain/measurement/test/MeasurementBaselineTest.java
new file mode 100644
index 0000000..57d45e0
--- /dev/null
+++
b/modules/core/domain/src/test/java/org/rhq/core/domain/measurement/test/MeasurementBaselineTest.java
@@ -0,0 +1,54 @@
+ /*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.core.domain.measurement.test;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.measurement.MeasurementBaseline;
+import org.rhq.core.domain.test.AbstractEJB3Test;
+
+/**
+ * Tests for MeasurementBaseline entity
+ *
+ * @author Stefan Negrea
+ */
+@Test(groups = "integration.ejb3")
+public class MeasurementBaselineTest extends AbstractEJB3Test {
+
+ @Test
+ public void testSelectQuery() throws Exception {
+ EntityManager entityManager = getEntityManager();
+ Query query = entityManager
+
.createNamedQuery(MeasurementBaseline.QUERY_FIND_MEASUREMENT_SCHEDULES_WITHOUT_AUTOBASELINES);
+ List<String> rows = query.getResultList();
+
System.out.println("----------------------------------------------------------------------------");
+ System.out.println(rows.size());
+ System.out.println(rows);
+
System.out.println("----------------------------------------------------------------------------");
+ }
+}
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
index 1d64102..4dee6fa 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
@@ -18,8 +18,6 @@
*/
package org.rhq.enterprise.server.measurement;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -37,12 +35,6 @@ import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.rhq.core.db.DatabaseType;
-import org.rhq.core.db.DatabaseTypeFactory;
-import org.rhq.core.db.H2DatabaseType;
-import org.rhq.core.db.OracleDatabaseType;
-import org.rhq.core.db.PostgresqlDatabaseType;
-import org.rhq.core.db.SQLServerDatabaseType;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.measurement.MeasurementBaseline;
@@ -58,6 +50,7 @@ import org.rhq.enterprise.server.cloud.StatusManagerLocal;
import org.rhq.enterprise.server.measurement.instrumentation.MeasurementMonitor;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.system.SystemManagerLocal;
+import org.rhq.server.metrics.MetricBaselineCalculator;
/**
* A manager for {@link MeasurementBaseline}s.
@@ -95,6 +88,7 @@ public class MeasurementBaselineManagerBean implements
MeasurementBaselineManage
private ResourceManagerLocal resourceManager;
private final Log log = LogFactory.getLog(MeasurementBaselineManagerBean.class);
+ private static final int BASELINE_PROCESSING_LIMIT = 50000;
@TransactionAttribute(TransactionAttributeType.NEVER)
public void calculateAutoBaselines() {
@@ -194,7 +188,7 @@ public class MeasurementBaselineManagerBean implements
MeasurementBaselineManage
int inserted =
measurementBaselineManager._calculateAutoBaselinesINSERT(amountOfData);
totalInserted += inserted;
// since we're batch 100K inserts at a time, we're done if we
didn't have that many to insert
- if (inserted < 100000) {
+ if (inserted < BASELINE_PROCESSING_LIMIT) {
break;
}
}
@@ -213,7 +207,6 @@ public class MeasurementBaselineManagerBean implements
MeasurementBaselineManage
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- //@TransactionTimeout( 60 * 60 )
public int _calculateAutoBaselinesDELETE(long olderThanTime) throws Exception {
Query query =
entityManager.createNamedQuery(MeasurementBaseline.QUERY_DELETE_BY_COMPUTE_TIME);
query.setParameter("timestamp", olderThanTime);
@@ -221,92 +214,31 @@ public class MeasurementBaselineManagerBean implements
MeasurementBaselineManage
return rowsAffected;
}
+ @SuppressWarnings("unchecked")
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- //@TransactionTimeout( 60 * 60 )
public int _calculateAutoBaselinesINSERT(long amountOfData) throws Exception {
- long now = System.currentTimeMillis();
- long computeTime = now;
- long endTime = now;
+ long endTime = System.currentTimeMillis();
long startTime = endTime - amountOfData;
- Connection conn = null;
- PreparedStatement insertQuery = null;
-
- try {
- // calculate the baselines for schedules that have no baseline yet (or were
just deleted)
- // do everything via JDBC - our perf testing shows that we hit entity cache
locking timeouts
- // when the entity manager performs native queries under heavy load
- conn = dataSource.getConnection();
- DatabaseType dbType = DatabaseTypeFactory.getDatabaseType(conn);
-
- if (dbType instanceof PostgresqlDatabaseType || dbType instanceof
H2DatabaseType) {
- insertQuery =
conn.prepareStatement(MeasurementBaseline.NATIVE_QUERY_CALC_FIRST_AUTOBASELINE_POSTGRES);
- insertQuery.setLong(1, computeTime);
- insertQuery.setLong(2, startTime);
- insertQuery.setLong(3, endTime);
- insertQuery.setLong(4, startTime);
- } else if (dbType instanceof OracleDatabaseType) {
- insertQuery =
conn.prepareStatement(MeasurementBaseline.NATIVE_QUERY_CALC_FIRST_AUTOBASELINE_ORACLE);
- insertQuery.setLong(1, computeTime);
- insertQuery.setLong(2, startTime);
- insertQuery.setLong(3, endTime);
- insertQuery.setLong(4, startTime);
- } else if (dbType instanceof SQLServerDatabaseType) {
- insertQuery =
conn.prepareStatement(MeasurementBaseline.NATIVE_QUERY_CALC_FIRST_AUTOBASELINE_SQLSERVER);
- insertQuery.setLong(1, computeTime);
- insertQuery.setLong(2, startTime);
- insertQuery.setLong(3, endTime);
- insertQuery.setLong(4, startTime);
- } else {
- throw new IllegalArgumentException("Unknown database type, can't
continue: " + dbType);
- }
+ //1. Find dynamic schedule ids that do not have baseline calculated
+ Query query = this.entityManager
+
.createNamedQuery(MeasurementBaseline.QUERY_FIND_MEASUREMENT_SCHEDULES_WITHOUT_AUTOBASELINES);
+ query.setMaxResults(BASELINE_PROCESSING_LIMIT);
+ List<String> scheduleIdsWithoutBaselines = query.getResultList();
- int inserted = insertQuery.executeUpdate();
- return inserted;
- } finally {
- if (insertQuery != null) {
- try {
- insertQuery.close();
- } catch (Exception e) {
- }
- }
+ //2. calculate the baselines based metrics data
+ MetricBaselineCalculator baselineCalculator = new MetricBaselineCalculator();
+ List<MeasurementBaseline> results =
baselineCalculator.calculateBaselines(scheduleIdsWithoutBaselines,
+ startTime, endTime);
- if (conn != null) {
- try {
- conn.close();
- } catch (Exception e) {
- }
- }
+ //3. persist all calculated baselines to SQL db
+ for (Object result : results) {
+ entityManager.persist(result);
}
- }
-
- @SuppressWarnings("unused")
- @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- //@TransactionTimeout( 60 * 60 )
- private int _calculateAutoBaselinesDELETE_HQL(long startTime, long endTime) throws
Exception {
- Query query =
entityManager.createNamedQuery(MeasurementBaseline.QUERY_DELETE_EXISTING_AUTOBASELINES);
-
- query.setParameter("startTime", startTime);
- query.setParameter("endTime", endTime);
-
- int rowsModified = query.executeUpdate();
-
- return rowsModified;
- }
-
- @SuppressWarnings("unused")
- @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- //@TransactionTimeout( 60 * 60 )
- private int _calculateAutoBaselinesINSERT_HQL(long startTime, long endTime, long
computeTime) throws Exception {
- Query query =
entityManager.createNamedQuery(MeasurementBaseline.QUERY_CALC_FIRST_AUTOBASELINE);
-
- //query.setParameter("computeTime", computeTime);
- query.setParameter("startTime", startTime);
- query.setParameter("endTime", endTime);
-
- int rowsModified = query.executeUpdate();
+ entityManager.flush();
- return rowsModified;
+ //4. return the number of schedule ids initially retrieved for calculation
+ return scheduleIdsWithoutBaselines.size();
}
/**
diff --git
a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricBaselineCalculator.java
b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricBaselineCalculator.java
new file mode 100644
index 0000000..67853e3
--- /dev/null
+++
b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricBaselineCalculator.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+package org.rhq.server.metrics;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.rhq.core.domain.measurement.MeasurementBaseline;
+
+/**
+ * @author Stefan Negrea
+ */
+public class MetricBaselineCalculator {
+
+ public List<MeasurementBaseline> calculateBaselines(List<String>
scheduleIds, long startTime, long endTime) {
+ List<MeasurementBaseline> calculatedBaselines = new
ArrayList<MeasurementBaseline>();
+
+ MeasurementBaseline measurementBaseline;
+ for (String scheduleId : scheduleIds) {
+ //TODO: do processing to find the actual baseline for this schedule id
+ //!use data from Cassandra!
+
+ //for now just return a values
+ measurementBaseline = this.generateRandomBaseline();
+
+ if (measurementBaseline != null) {
+ calculatedBaselines.add(measurementBaseline);
+ }
+ }
+
+ return calculatedBaselines;
+ }
+
+ private MeasurementBaseline generateRandomBaseline() {
+ Random random = new Random(12345);
+
+ MeasurementBaseline randomBaseline = new MeasurementBaseline();
+ randomBaseline.setMax(random.nextDouble() * 1000);
+ randomBaseline.setMin(random.nextDouble() * 1000);
+ randomBaseline.setMean(random.nextDouble() * 1000);
+
+ return new MeasurementBaseline();
+ }
+}