Merge pull request #516 from bsinno/fix_remove_report_mgmt

Remove unused report management.
This commit is contained in:
Kai Zimmermann
2017-05-19 15:35:34 +02:00
committed by GitHub
4 changed files with 0 additions and 1191 deletions

View File

@@ -1,211 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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 org.eclipse.hawkbit.repository;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.report.model.DataReportSeries;
import org.eclipse.hawkbit.repository.report.model.InnerOuterDataReportSeries;
import org.eclipse.hawkbit.repository.report.model.ListReportSeries;
import org.eclipse.hawkbit.repository.report.model.SeriesTime;
import org.springframework.security.access.prepost.PreAuthorize;
/**
* Service layer for generating hawkBit statistics and reports.
*
*/
public interface ReportManagement {
/**
* Data base format.
*
*
*
* @param <T>
*/
public interface DateType<T> {
/**
* @param s
* @return T
*/
T format(String s);
/**
* h2 format.
*
* @return String
*/
String h2Format();
/**
* mysql format.
*
* @return String
*/
String mySqlFormat();
}
/**
* Return DateTypes.
*/
public static final class DateTypes implements Serializable {
private static final long serialVersionUID = 1L;
private static final PerMonth PER_MONTH = new PerMonth();
private DateTypes() {
// Utility class
}
/**
* @return PerMonth
*/
public static PerMonth perMonth() {
return PER_MONTH;
}
}
/**
* Gives the date format based on DB H2 or mySql.
*
*
*
*/
public static final class PerMonth implements DateType<LocalDate>, Serializable {
private static final long serialVersionUID = 1L;
private static final String DATE_PATTERN = "yyyy-MM";
@Override
public LocalDate format(final String s) {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
final YearMonth ym = YearMonth.parse(s, formatter);
return ym.atDay(1);
}
@Override
public String h2Format() {
return DATE_PATTERN;
}
@Override
public String mySqlFormat() {
return "%Y-%m";
}
}
/**
* Generates a report of the top x distribution set assigned usage as a list
* of {@link InnerOuterDataReportSeries} which is ideal for generate a donut
* chart out of it. The inner series contains the distribution set names and
* total count usage. The outer series contains each version usage and its
* usage count. {@code inner: ds1:5 -> outer: vers 0.0.0:3, vers 1.0.0:2}
* {@code inner: ds2:1 -> outer: vers 0.0.1:1}
*
* The top x entries are seperated within the series, the rest of the
* distribution sets usage are summarized to a "misc" series.
*
* @param topXEntries
* the top entries which should be shown, the rest distribution
* set entries are summarized as "misc"
* @return a list of inner and outer series of distribution set usage
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
List<InnerOuterDataReportSeries<String>> distributionUsageAssigned(int topXEntries);
/**
* Generates a report of the top x distribution set installed usage as a
* list of {@link InnerOuterDataReportSeries} which is ideal for generate a
* donut chart out of it. The inner series contains the distribution set
* names and total count usage. The outer series contains each version usage
* and its usage count.
* {@code inner: ds1:5 -> outer: vers 0.0.0:3, vers 1.0.0:2}
* {@code inner: ds2:1 -> outer: vers 0.0.1:1}
*
* The top x entries are seperated within the series, the rest of the
* distribution sets usage are summarized to a "misc" series.
*
* @param topXEntries
* the top entries which should be shown, the rest distribution
* set entries are summarized as "misc"
* @return a list of inner and outer series of distribution set usage
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
List<InnerOuterDataReportSeries<String>> distributionUsageInstalled(int topXEntries);
/**
* Generates report for feedback over period.
*
* @param dateType
* {@link PerMonth}
* @param from
* start date
* @param to
* end date
* @return <T> DataReportSeries<T> ListReportSeries list of action status
* count
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
<T extends Serializable> DataReportSeries<T> feedbackReceivedOverTime(@NotNull DateType<T> dateType,
@NotNull LocalDateTime from, @NotNull LocalDateTime to);
/**
* Generates report for target created over period.
*
* @param dateType
* {@link PerMonth}
* @param from
* start date
* @param to
* end date
* @return <T> DataReportSeries<T> ListReportSeries list of target created
* count
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
<T extends Serializable> DataReportSeries<T> targetsCreatedOverPeriod(@NotNull DateType<T> dateType,
@NotNull LocalDateTime from, @NotNull LocalDateTime to);
/**
* Generates a report as a {@link ListReportSeries} targets polled based on
* the {@link Target#getLastTargetQuery()} within an hour, day, week, month,
* year, more than a year, never.
*
* The order of the numbers within the {@link DataReportSeries} is the order
* hour, day, week, month, year, more than a year, never.
*
* @return a {@link DataReportSeries} which contains the number of targets
* which have not been polled in the last hour, day, ... year,more
* than a year, never.
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
DataReportSeries<SeriesTime> targetsLastPoll();
/**
* Generates a report of all targets of their current update status count.
* For each {@link TargetUpdateStatus} an total count of targets which are
* in this status currently.
*
* @return a data report series which contains the target count for each
* target update status
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
DataReportSeries<TargetUpdateStatus> targetStatus();
}

View File

@@ -1,421 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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 org.eclipse.hawkbit.repository.jpa;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Root;
import org.eclipse.hawkbit.repository.ReportManagement;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.report.model.DataReportSeries;
import org.eclipse.hawkbit.repository.report.model.DataReportSeriesItem;
import org.eclipse.hawkbit.repository.report.model.InnerOuterDataReportSeries;
import org.eclipse.hawkbit.repository.report.model.SeriesTime;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
/**
* JPA implementation of {@link ReportManagement}.
*
*/
@Transactional(readOnly = true)
@Validated
public class JpaReportManagement implements ReportManagement {
@Value("${spring.jpa.database}")
private String databaseType;
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM");
private static final String H2_TARGET_CREATED_SQL_TEMPLATE = "SELECT TO_CHAR( DATEADD('second', target0_.created_at / 1000, DATE '1970-01-01'), '%s') AS col_0_0_, count(target0_.controller_id) AS col_1_0_ from sp_target target0_ WHERE TO_CHAR(DATEADD('second', target0_.created_at / 1000, DATE '1970-01-01'),'%s') BETWEEN TO_CHAR('%s', '%s') and TO_CHAR('%s', '%s') AND UPPER(target0_.tenant)=UPPER('%s') GROUP BY TO_CHAR(DATEADD('second', target0_.created_at / 1000, DATE '1970-01-01'), '%s')";
private static final String H2_CONTROLLER_FRRDBACK_SQL_TEMPLATE = "SELECT TO_CHAR(DATEADD('second', action_.created_at / 1000, DATE '1970-01-01'), '%s') AS col_0_0_, count(action_.id) AS col_1_0_ FROM sp_action action_ WHERE TO_CHAR(DATEADD('second', action_.created_at / 1000, DATE '1970-01-01'), '%s') BETWEEN TO_CHAR('%s', '%s') AND TO_CHAR('%s', '%s') AND UPPER(action_.tenant)=UPPER('%s') GROUP BY TO_CHAR(DATEADD('second', action_.created_at / 1000, DATE '1970-01-01'), '%s')";
private static final String MYSQL_TARGET_CREATED_SQL_TEMPLATE = "SELECT DATE_FORMAT(FROM_UNIXTIME(target0_.created_at / 1000), '%s') AS col_0_0_, COUNT(target0_.controller_id) AS col_1_0_ FROM sp_target target0_ WHERE DATE_FORMAT(FROM_UNIXTIME(target0_.created_at / 1000),'%s') BETWEEN DATE_FORMAT('%s', '%s') AND DATE_FORMAT('%s', '%s') AND UPPER(target0_.tenant)=UPPER('%s') GROUP BY DATE_FORMAT(FROM_UNIXTIME(target0_.created_at / 1000), '%s')";
private static final String MYSQL_CONTROLLER_FRRDBACK_SQL_TEMPLATE = "SELECT DATE_FORMAT(FROM_UNIXTIME(action_.created_at / 1000), '%s') AS col_0_0_, COUNT(action_.id) as col_1_0_ FROM sp_action action_ WHERE DATE_FORMAT(FROM_UNIXTIME(action_.created_at / 1000),'%s') BETWEEN DATE_FORMAT('%s', '%s') AND DATE_FORMAT('%s', '%s') AND UPPER(action_.tenant)=UPPER('%s') GROUP BY DATE_FORMAT(FROM_UNIXTIME(action_.created_at / 1000), '%s')";
private static final String MYSQL_DB_TYPE = "MYSQL";
private static final String H2_DB_TYPE = "H2";
@Autowired
private EntityManager entityManager;
@Autowired
private TenantAware tenantAware;
@Override
public DataReportSeries<TargetUpdateStatus> targetStatus() {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
final Expression<Long> countColumn = cb.count(targetRoot.get(JpaTarget_.id));
final CriteriaQuery<Object[]> multiselect = query
.multiselect(targetRoot.get(JpaTarget_.updateStatus), countColumn)
.groupBy(targetRoot.get(JpaTarget_.updateStatus))
.orderBy(cb.desc(targetRoot.get(JpaTarget_.updateStatus)));
// | col1 | col2 |
// | U_STATUS | COUNT |
final List<Object[]> resultList = entityManager.createQuery(multiselect).getResultList();
final List<DataReportSeriesItem<TargetUpdateStatus>> reportSeriesItems = resultList.stream()
.map(r -> new DataReportSeriesItem<>((TargetUpdateStatus) r[0], (Long) r[1]))
.collect(Collectors.toList());
return new DataReportSeries<>("Target Status Overview", reportSeriesItems);
}
@Override
public DataReportSeries<SeriesTime> targetsLastPoll() {
final LocalDateTime now = LocalDateTime.now();
final LocalDateTime beforeHour = now.minusHours(1);
final LocalDateTime beforeDay = now.minusDays(1);
final LocalDateTime beforeWeek = now.minusWeeks(1);
final LocalDateTime beforeMonth = now.minusMonths(1);
final LocalDateTime beforeYear = now.minusYears(1);
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final List<DataReportSeriesItem<SeriesTime>> resultList = new ArrayList<>();
// hours
resultList.add(new DataReportSeriesItem<>(SeriesTime.HOUR,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, beforeHour, now)).getSingleResult()));
// days
resultList.add(new DataReportSeriesItem<>(SeriesTime.DAY, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeDay, beforeHour)).getSingleResult()));
// weeks
resultList.add(new DataReportSeriesItem<>(SeriesTime.WEEK, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeWeek, beforeDay)).getSingleResult()));
// months
resultList.add(new DataReportSeriesItem<>(SeriesTime.MONTH, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeMonth, beforeWeek)).getSingleResult()));
// years
resultList.add(new DataReportSeriesItem<>(SeriesTime.YEAR, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeYear, beforeMonth)).getSingleResult()));
// years
resultList.add(new DataReportSeriesItem<>(SeriesTime.MORE_THAN_YEAR,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, beforeYear)).getSingleResult()));
// never
resultList.add(new DataReportSeriesItem<>(SeriesTime.NEVER,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, null)).getSingleResult()));
return new DataReportSeries<>("TargetLastPoll", resultList);
}
@Override
public List<InnerOuterDataReportSeries<String>> distributionUsageAssigned(final int topXEntries) {
// top X entries distribution usage
final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> queryTopX = cbTopX.createQuery(Object[].class);
final Root<JpaDistributionSet> rootTopX = queryTopX.from(JpaDistributionSet.class);
final ListJoin<JpaDistributionSet, JpaTarget> joinTopX = rootTopX.join(JpaDistributionSet_.assignedToTargets,
JoinType.LEFT);
final Expression<Long> countColumn = cbTopX.count(joinTopX);
// top x usage query
final CriteriaQuery<Object[]> groupBy = queryTopX
.multiselect(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version),
countColumn)
.where(cbTopX.equal(rootTopX.get(JpaDistributionSet_.deleted), false))
.groupBy(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version))
.orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(JpaDistributionSet_.name)));
// | col1 | col2 | col3 |
// | NAME | VER | COUNT |
final List<Object[]> resultListTop = entityManager.createQuery(groupBy).getResultList();
// end of top X entries distribution usage
return mapDistirbutionUsageResultToDataReport(topXEntries, resultListTop);
}
@Override
public List<InnerOuterDataReportSeries<String>> distributionUsageInstalled(final int topXEntries) {
// top X entries distribution usage
final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> queryTopX = cbTopX.createQuery(Object[].class);
final Root<JpaDistributionSet> rootTopX = queryTopX.from(JpaDistributionSet.class);
final ListJoin<JpaDistributionSet, JpaTarget> joinTopX = rootTopX.join(JpaDistributionSet_.installedAtTargets,
JoinType.LEFT);
final Expression<Long> countColumn = cbTopX.count(joinTopX);
// top x usage query
final CriteriaQuery<Object[]> groupBy = queryTopX
.multiselect(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version),
countColumn)
.where(cbTopX.equal(rootTopX.get(JpaDistributionSet_.deleted), false))
.groupBy(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version))
.orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(JpaDistributionSet_.name)));
// | col1 | col2 | col3 |
// | NAME | VER | COUNT |
final List<Object[]> resultListTop = entityManager.createQuery(groupBy).getResultList();
// end of top X entries distribution usage
return mapDistirbutionUsageResultToDataReport(topXEntries, resultListTop);
}
@Override
public <T extends Serializable> DataReportSeries<T> targetsCreatedOverPeriod(final DateType<T> dateType,
final LocalDateTime from, final LocalDateTime to) {
final Query createNativeQuery = entityManager
.createNativeQuery(getTargetsCreatedQueryTemplate(dateType, from, to));
final List<Object[]> resultList = createNativeQuery.getResultList();
final List<DataReportSeriesItem<T>> reportItems = resultList.stream()
.map(r -> new DataReportSeriesItem<>(dateType.format((String) r[0]), ((Number) r[1]).longValue()))
.collect(Collectors.toList());
return new DataReportSeries<>("CreatedTargets", reportItems);
}
private String getTargetsCreatedQueryTemplate(final DateType<?> dateType, final LocalDateTime from,
final LocalDateTime to) {
switch (databaseType) {
case H2_DB_TYPE:
return String.format(H2_TARGET_CREATED_SQL_TEMPLATE, dateTimeFormatToSqlFormat(dateType),
dateTimeFormatToSqlFormat(dateType), from.format(DATE_FORMAT), dateTimeFormatToSqlFormat(dateType),
to.format(DATE_FORMAT), dateTimeFormatToSqlFormat(dateType), tenantAware.getCurrentTenant(),
dateTimeFormatToSqlFormat(dateType));
case MYSQL_DB_TYPE:
return String.format(MYSQL_TARGET_CREATED_SQL_TEMPLATE, dateTimeFormatToSqlFormat(dateType),
dateTimeFormatToSqlFormat(dateType), from.toString(), dateTimeFormatToSqlFormat(dateType),
to.toString(), dateTimeFormatToSqlFormat(dateType), tenantAware.getCurrentTenant(),
dateTimeFormatToSqlFormat(dateType));
default:
return null;
}
}
private String getFeedbackReceivedQueryTemplate(final DateType<?> dateType, final LocalDateTime from,
final LocalDateTime to) {
switch (databaseType) {
case H2_DB_TYPE:
return String.format(H2_CONTROLLER_FRRDBACK_SQL_TEMPLATE, dateTimeFormatToSqlFormat(dateType),
dateTimeFormatToSqlFormat(dateType), from.format(DATE_FORMAT), dateTimeFormatToSqlFormat(dateType),
to.format(DATE_FORMAT), dateTimeFormatToSqlFormat(dateType), tenantAware.getCurrentTenant(),
dateTimeFormatToSqlFormat(dateType));
case MYSQL_DB_TYPE:
return String.format(MYSQL_CONTROLLER_FRRDBACK_SQL_TEMPLATE, dateTimeFormatToSqlFormat(dateType),
dateTimeFormatToSqlFormat(dateType), from.toString(), dateTimeFormatToSqlFormat(dateType),
to.toString(), dateTimeFormatToSqlFormat(dateType), tenantAware.getCurrentTenant(),
dateTimeFormatToSqlFormat(dateType));
default:
return null;
}
}
@Override
public <T extends Serializable> DataReportSeries<T> feedbackReceivedOverTime(final DateType<T> dateType,
final LocalDateTime from, final LocalDateTime to) {
final Query createNativeQuery = entityManager
.createNativeQuery(getFeedbackReceivedQueryTemplate(dateType, from, to));
@SuppressWarnings("unchecked")
final List<Object[]> resultList = createNativeQuery.getResultList();
final List<DataReportSeriesItem<T>> reportItems = resultList.stream()
.map(r -> new DataReportSeriesItem<>(dateType.format((String) r[0]), ((Number) r[1]).longValue()))
.collect(Collectors.toList());
return new DataReportSeries<>("FeedbackRecieved", reportItems);
}
private static CriteriaQuery<Long> createCountSelectTargetsLastPoll(final CriteriaBuilder cb,
final LocalDateTime from, final LocalDateTime to) {
Long start = null;
Long end = null;
if (from != null) {
start = from.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
if (to != null) {
end = to.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
// count select statement
final CriteriaQuery<Long> countSelect = cb.createQuery(Long.class);
final Root<JpaTarget> countSelectRoot = countSelect.from(JpaTarget.class);
countSelect.select(cb.count(countSelectRoot));
if (start != null && end != null) {
countSelect.where(cb.between(countSelectRoot.get(JpaTarget_.lastTargetQuery), start, end));
} else if (from == null && to != null) {
countSelect.where(cb.lessThanOrEqualTo(countSelectRoot.get(JpaTarget_.lastTargetQuery), end));
} else {
countSelect.where(cb.isNull(countSelectRoot.get(JpaTarget_.lastTargetQuery)));
}
return countSelect;
}
private static List<InnerOuterDataReportSeries<String>> mapDistirbutionUsageResultToDataReport(
final int topXEntries, final List<Object[]> resultListTop) {
final List<InnerOuterDataReportSeries<String>> innerOuterReport = new ArrayList<>();
final Map<DSName, InnerOuter> map = new LinkedHashMap<>();
int topXCounter = 0;
for (final Object[] objects : resultListTop) {
final boolean containsInnerOuter = map.containsKey(new DSName((String) objects[0]));
final String name = containsInnerOuter || topXCounter < topXEntries ? (String) objects[0] : null;
final DSName dsName = new DSName(name);
final String version = containsInnerOuter || topXCounter < topXEntries ? (String) objects[1] : null;
final Long count = (Long) objects[2];
InnerOuter innerouter = map.get(dsName);
if (innerouter == null) {
topXCounter++;
innerouter = new InnerOuter(dsName);
map.put(new DSName(name), innerouter);
}
innerouter.addOuter(new DSName(version), count);
}
for (final InnerOuter inner : map.values()) {
final List<DataReportSeriesItem<String>> outerReportItems = new ArrayList<>();
if (inner.name.getName() != null) {
for (final InnerOuter outer : inner.outer) {
outerReportItems.add(outer.toItem());
}
} else {
outerReportItems.add(new DataReportSeriesItem<>("misc", inner.count));
}
innerOuterReport.add(new InnerOuterDataReportSeries<>(
new DataReportSeries<>("DS-Name", Collections.singletonList(inner.toItem())),
new DataReportSeries<>("DS-Version", outerReportItems)));
}
return innerOuterReport;
}
private static final class InnerOuter {
final DSName name;
long count;
final List<InnerOuter> outer;
private InnerOuter(final DSName idName) {
name = idName;
outer = new ArrayList<>();
}
private InnerOuter(final DSName idName, final long count) {
name = idName;
this.count = count;
outer = new ArrayList<>();
}
private void addOuter(final DSName idName, final long count) {
outer.add(new InnerOuter(idName, count));
this.count += count;
}
private DataReportSeriesItem<String> toItem() {
return new DataReportSeriesItem<>(name.getName() != null ? name.getName() : "misc", count);
}
}
/**
* Object contains the name and the id of an entity.
*
*/
private static final class DSName {
private final String name;
/**
* @param id
* the ID of an entity
* @param name
* the name of an entity
*/
private DSName(final String name) {
this.name = name;
}
/**
* @return the name
*/
private String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (name == null ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is
// generated
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DSName other = (DSName) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
@Override
public String toString() {
return "DSName [name=" + name + "]";
}
}
private String dateTimeFormatToSqlFormat(final DateType<?> datatype) {
switch (databaseType) {
case H2_DB_TYPE:
return datatype.h2Format();
case MYSQL_DB_TYPE:
return datatype.mySqlFormat();
default:
return null;
}
}
}

View File

@@ -20,7 +20,6 @@ import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.PropertiesQuotaManagement;
import org.eclipse.hawkbit.repository.ReportManagement;
import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutManagement;
@@ -329,17 +328,6 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
return new JpaSystemManagement();
}
/**
* {@link JpaReportManagement} bean.
*
* @return a new {@link ReportManagement}
*/
@Bean
@ConditionalOnMissingBean
ReportManagement reportManagement() {
return new JpaReportManagement();
}
/**
* {@link JpaDistributionSetManagement} bean.
*

View File

@@ -1,547 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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 org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.ReportManagement;
import org.eclipse.hawkbit.repository.ReportManagement.DateTypes;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.report.model.DataReportSeries;
import org.eclipse.hawkbit.repository.report.model.DataReportSeriesItem;
import org.eclipse.hawkbit.repository.report.model.InnerOuterDataReportSeries;
import org.eclipse.hawkbit.repository.report.model.SeriesTime;
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
import org.eclipse.hawkbit.repository.test.util.WithUser;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.auditing.AuditingHandler;
import org.springframework.data.auditing.CurrentDateTimeProvider;
import org.springframework.data.auditing.DateTimeProvider;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import com.google.common.collect.Lists;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Report Management")
public class ReportManagementTest extends AbstractJpaIntegrationTest {
private static final String TEST_MESSAGE = "some message";
@Autowired
private ReportManagement reportManagement;
@Autowired
private AuditingHandler auditingHandler;
@After
public void afterTest() {
auditingHandler.setDateTimeProvider(CurrentDateTimeProvider.INSTANCE);
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void targetsCreatedOverPeriod() {
// the maximum months going back from now
// create more targets than asking the report so we can check if the
// report is returning the
// correct timeframe
final int maxMonthBackAmountCreateTargets = 10;
final int maxMonthBackAmountReportTargets = 4;
final DynamicDateTimeProvider dynamicDateTimeProvider = new DynamicDateTimeProvider();
auditingHandler.setDateTimeProvider(dynamicDateTimeProvider);
for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) {
dynamicDateTimeProvider.nowMinusMonths(month);
testdataFactory.createTarget("t" + month);
}
final LocalDateTime to = LocalDateTime.now();
final LocalDateTime from = to.minusMonths(maxMonthBackAmountReportTargets);
DataReportSeries<LocalDate> targetsCreatedOverPeriod = reportManagement
.targetsCreatedOverPeriod(DateTypes.perMonth(), from, to);
// +1 because we go back #maxMonthBackAmountReportTargets but in the
// report the current month
// is included for sure, so from this month we go back
assertThat(targetsCreatedOverPeriod.getData()).as("created over period has wrong size")
.hasSize(maxMonthBackAmountReportTargets + 1);
for (final DataReportSeriesItem<LocalDate> reportItem : targetsCreatedOverPeriod.getData()) {
// only one target is created for each month
assertThat(reportItem.getData().intValue()).as("Target for each month").isEqualTo(1);
}
// check cache evict
for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) {
dynamicDateTimeProvider.nowMinusMonths(month);
testdataFactory.createTarget("t2" + month);
}
targetsCreatedOverPeriod = reportManagement.targetsCreatedOverPeriod(DateTypes.perMonth(), from, to);
for (final DataReportSeriesItem<LocalDate> reportItem : targetsCreatedOverPeriod.getData()) {
assertThat(reportItem.getData().intValue()).as("Target for each month").isEqualTo(2);
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void targetsFeedbackOverPeriod() {
// the maximum months going back from now
// create more targets than asking the report so we can check if the
// report is returning the
// correct timeframe
final int maxMonthBackAmountCreateTargets = 10;
final int maxMonthBackAmountReportTargets = 4;
final LocalDateTime to = LocalDateTime.now();
final LocalDateTime from = to.minusMonths(maxMonthBackAmountReportTargets);
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds");
final DynamicDateTimeProvider dynamicDateTimeProvider = new DynamicDateTimeProvider();
auditingHandler.setDateTimeProvider(dynamicDateTimeProvider);
for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) {
dynamicDateTimeProvider.nowMinusMonths(month);
final Target createTarget = testdataFactory.createTarget("t" + month);
final DistributionSetAssignmentResult result = assignDistributionSet(distributionSet,
Lists.newArrayList(createTarget));
controllerManagement.registerRetrieved(result.getActions().get(0),
"Controller retrieved update action and should start now the download.");
}
DataReportSeries<LocalDate> feedbackReceivedOverTime = reportManagement
.feedbackReceivedOverTime(DateTypes.perMonth(), from, to);
// +1 because we go back #maxMonthBackAmountReportTargets but in the
// report the current month
// is included for sure, so from this month we go back
assertThat(feedbackReceivedOverTime.getData()).as("feedback receiver has wrong data size")
.hasSize(maxMonthBackAmountReportTargets + 1);
for (final DataReportSeriesItem<LocalDate> reportItem : feedbackReceivedOverTime.getData()) {
// only one target feedback is created for each month
assertThat(reportItem.getData().intValue()).as("data size is wrong").isEqualTo(1);
}
// check cache evict
for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) {
dynamicDateTimeProvider.nowMinusMonths(month);
final Target createTarget = testdataFactory.createTarget("t2" + month);
final DistributionSetAssignmentResult result = assignDistributionSet(distributionSet,
Lists.newArrayList(createTarget));
controllerManagement.registerRetrieved(result.getActions().get(0),
"Controller retrieved update action and should start now the download.");
}
feedbackReceivedOverTime = reportManagement.feedbackReceivedOverTime(DateTypes.perMonth(), from, to);
for (final DataReportSeriesItem<LocalDate> reportItem : feedbackReceivedOverTime.getData()) {
assertThat(reportItem.getData().intValue()).as("report item has wrong data size").isEqualTo(2);
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void distributionUsageInstalled() {
final Target knownTarget1 = testdataFactory.createTarget("t1");
final Target knownTarget2 = testdataFactory.createTarget("t2");
final Target knownTarget3 = testdataFactory.createTarget("t3");
final Target knownTarget4 = testdataFactory.createTarget("t4");
final Target knownTarget5 = testdataFactory.createTarget("t5");
final SoftwareModule ah = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_APP);
final SoftwareModule jvm = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_RT);
final SoftwareModule os = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_OS);
final DistributionSet distributionSet1 = testdataFactory.createDistributionSet("ds1", "0.0.0", standardDsType,
Lists.newArrayList(os, jvm, ah));
final DistributionSet distributionSet11 = testdataFactory.createDistributionSet("ds1", "0.0.1", standardDsType,
Lists.newArrayList(os, jvm, ah));
final DistributionSet distributionSet2 = testdataFactory.createDistributionSet("ds2", "0.0.2", standardDsType,
Lists.newArrayList(os, jvm, ah));
final DistributionSet distributionSet3 = testdataFactory.createDistributionSet("ds3", "0.0.3", standardDsType,
Lists.newArrayList(os, jvm, ah));
// ds1(0.0.0)=[target1,target2], ds1(0.0.1)=[target3]
assignDistributionSet(distributionSet1.getId(), knownTarget1.getControllerId());
assignDistributionSet(distributionSet1.getId(), knownTarget2.getControllerId());
assignDistributionSet(distributionSet11.getId(), knownTarget3.getControllerId());
// ds2=[target4]
assignDistributionSet(distributionSet2.getId(), knownTarget4.getControllerId());
// ds3=[target5] --> ONLY ASSIGNED AND NOT INSTALLED
assignDistributionSet(distributionSet3.getId(), knownTarget5.getControllerId());
// set installed status
testdataFactory.sendUpdateActionStatusToTargets(
Lists.newArrayList(knownTarget1, knownTarget2, knownTarget3, knownTarget4), Status.FINISHED,
Collections.singletonList(TEST_MESSAGE));
List<InnerOuterDataReportSeries<String>> distributionUsage = reportManagement.distributionUsageInstalled(100);
for (final InnerOuterDataReportSeries<String> innerOuterDataReportSeries : distributionUsage) {
// innerseries only have one data of the name and the total count
final DataReportSeriesItem<String> dataReportSeriesItem = innerOuterDataReportSeries.getInnerSeries()
.getData()[0];
if (dataReportSeriesItem.getType().equals("ds1")) {
// total count of three because ds1 has two different versions
assertThat(dataReportSeriesItem.getData()).as("Version/Item type of DistributionSet 1 in statistics")
.isEqualTo(3L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(Arrays.stream(outerData).map(DataReportSeriesItem::getType).collect(Collectors.toList()))
.as("versio item contains wrong version").contains("0.0.0", "0.0.1");
} else if (dataReportSeriesItem.getType().equals("ds2")) {
assertThat(dataReportSeriesItem.getData()).as("Version/Item type of DistributionSet 2 in statistics")
.isEqualTo(1L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(outerData).as("Version/Item type has wrong size").hasSize(1);
assertThat(outerData[0].getType()).as("Version/Item type of DistributionSet 2 in statistics")
.isEqualTo("0.0.2");
} else if (dataReportSeriesItem.getType().equals("ds3")) {
assertThat(dataReportSeriesItem.getData()).as("Version/Item type of DistributionSet 3 in statistics")
.isEqualTo(0L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(outerData).as("Version/Item type has wrong size").hasSize(1);
assertThat(outerData[0].getType()).as("Version/Item type of DistributionSet 3 in statistics")
.isEqualTo("0.0.3");
} else {
fail("no assertion count for distribution set " + dataReportSeriesItem.getType());
}
}
// Test cache evict
final Target knownTarget6 = testdataFactory.createTarget("t6");
assignDistributionSet(distributionSet1.getId(), knownTarget6.getControllerId());
testdataFactory.sendUpdateActionStatusToTargets(Lists.newArrayList(knownTarget6), Status.FINISHED,
Collections.singletonList(TEST_MESSAGE));
distributionUsage = reportManagement.distributionUsageInstalled(100);
for (final InnerOuterDataReportSeries<String> innerOuterDataReportSeries : distributionUsage) {
final DataReportSeriesItem<String> dataReportSeriesItem = innerOuterDataReportSeries.getInnerSeries()
.getData()[0];
if (dataReportSeriesItem.getType().equals("ds1")) {
assertThat(dataReportSeriesItem.getData()).as("Data report item number").isEqualTo(4L);
}
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void targetStatusReport() {
final long knownErrorCount = 5;
final long knownSyncCount = 4;
final long knownPendingCount = 3;
final long knownRegCount = 2;
final long knownUnknownCount = 1;
createTargetsWithStatus("error", knownErrorCount, TargetUpdateStatus.ERROR);
createTargetsWithStatus("snyc", knownSyncCount, TargetUpdateStatus.IN_SYNC);
createTargetsWithStatus("pending", knownPendingCount, TargetUpdateStatus.PENDING);
createTargetsWithStatus("reg", knownRegCount, TargetUpdateStatus.REGISTERED);
createTargetsWithStatus("unknown", knownUnknownCount, TargetUpdateStatus.UNKNOWN);
DataReportSeries<TargetUpdateStatus> targetStatus = reportManagement.targetStatus();
for (final DataReportSeriesItem<TargetUpdateStatus> reportItem : targetStatus.getData()) {
switch (reportItem.getType()) {
case ERROR:
assertThat(reportItem.getData()).as("ERROR count for targets in statistics").isEqualTo(knownErrorCount);
break;
case IN_SYNC:
assertThat(reportItem.getData()).as("IN_SYNC count for targets in statistics")
.isEqualTo(knownSyncCount);
break;
case PENDING:
assertThat(reportItem.getData()).as("PENDING count for targets in statistics")
.isEqualTo(knownPendingCount);
break;
case REGISTERED:
assertThat(reportItem.getData()).as("REGISTERED count for targets in statistics")
.isEqualTo(knownRegCount);
break;
case UNKNOWN:
assertThat(reportItem.getData()).as("UNKNOWN count for targets in statistics")
.isEqualTo(knownUnknownCount);
break;
default:
fail("missing case for unknown target update status " + reportItem.getType());
}
}
// test cache evict
createTargetsWithStatus("error2", knownErrorCount, TargetUpdateStatus.ERROR);
createTargetsWithStatus("snyc2", knownSyncCount, TargetUpdateStatus.IN_SYNC);
createTargetsWithStatus("pending2", knownPendingCount, TargetUpdateStatus.PENDING);
createTargetsWithStatus("reg2", knownRegCount, TargetUpdateStatus.REGISTERED);
createTargetsWithStatus("unknown2", knownUnknownCount, TargetUpdateStatus.UNKNOWN);
targetStatus = reportManagement.targetStatus();
for (final DataReportSeriesItem<TargetUpdateStatus> reportItem : targetStatus.getData()) {
switch (reportItem.getType()) {
case ERROR:
assertThat(reportItem.getData()).as("ERROR count for targets in statistics")
.isEqualTo(knownErrorCount * 2);
break;
case IN_SYNC:
assertThat(reportItem.getData()).as("IN_SYNC count for targets in statistics")
.isEqualTo(knownSyncCount * 2);
break;
case PENDING:
assertThat(reportItem.getData()).as("PENDING count for targets in statistics")
.isEqualTo(knownPendingCount * 2);
break;
case REGISTERED:
assertThat(reportItem.getData()).as("REGISTERED count for targets in statistics")
.isEqualTo(knownRegCount * 2);
break;
case UNKNOWN:
assertThat(reportItem.getData()).as("UNKNOWN count for targets in statistics")
.isEqualTo(knownUnknownCount * 2);
break;
default:
fail("missing case for unknown target update status " + reportItem.getType());
}
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void topXDistributionUsage() {
final Target knownTarget1 = testdataFactory.createTarget("t1");
final Target knownTarget2 = testdataFactory.createTarget("t2");
final Target knownTarget3 = testdataFactory.createTarget("t3");
final Target knownTarget4 = testdataFactory.createTarget("t4");
final SoftwareModule ah = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_APP);
final SoftwareModule jvm = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_RT);
final SoftwareModule os = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_OS);
final DistributionSet distributionSet1 = testdataFactory.createDistributionSet("ds1", "0.0.0", standardDsType,
Lists.newArrayList(os, jvm, ah));
final DistributionSet distributionSet11 = testdataFactory.createDistributionSet("ds1", "0.0.1", standardDsType,
Lists.newArrayList(os, jvm, ah));
final DistributionSet distributionSet2 = testdataFactory.createDistributionSet("ds2", "0.0.2", standardDsType,
Lists.newArrayList(os, jvm, ah));
final DistributionSet distributionSet3 = testdataFactory.createDistributionSet("ds3", "0.0.3", standardDsType,
Lists.newArrayList(os, jvm, ah));
// ds1(0.0.0)=[target1,target2], ds1(0.0.1)=[target3]
assignDistributionSet(distributionSet1.getId(), knownTarget1.getControllerId());
assignDistributionSet(distributionSet1.getId(), knownTarget2.getControllerId());
assignDistributionSet(distributionSet11.getId(), knownTarget3.getControllerId());
// ds2=[target4]
assignDistributionSet(distributionSet2.getId(), knownTarget4.getControllerId());
// expect: ds1(0.0.0)=[target1,target2], ds1(0.0.1)=[target3],
// ds2=[target4], ds3=[]
List<InnerOuterDataReportSeries<String>> distributionUsage = reportManagement.distributionUsageAssigned(100);
for (final InnerOuterDataReportSeries<String> innerOuterDataReportSeries : distributionUsage) {
// innerseries only have one data of the name and the total count
final DataReportSeriesItem<String> dataReportSeriesItem = innerOuterDataReportSeries.getInnerSeries()
.getData()[0];
if (dataReportSeriesItem.getType().equals("ds1")) {
// total count of three because ds1 has two different versions
assertThat(dataReportSeriesItem.getData()).as("Total count of DistributionSet 1 in statistics")
.isEqualTo(3L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(Arrays.stream(outerData).map(DataReportSeriesItem::getType).collect(Collectors.toList()))
.as("Out series contains wrong version").contains("0.0.0", "0.0.1");
} else if (dataReportSeriesItem.getType().equals("ds2")) {
assertThat(dataReportSeriesItem.getData()).as("Total count of DistributionSet 2 in statistics")
.isEqualTo(1L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(outerData).as("out series has wrong size").hasSize(1);
assertThat(outerData[0].getType()).as("Version/Item type of DistributionSet 2 in statistics")
.isEqualTo("0.0.2");
} else if (dataReportSeriesItem.getType().equals("ds3")) {
assertThat(dataReportSeriesItem.getData()).as("Total count of DistributionSet 3 in statistics")
.isEqualTo(0L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(outerData).as("out series has wrong size").hasSize(1);
assertThat(outerData[0].getType()).as("Version/Item type of DistributionSet 3 in statistics")
.isEqualTo("0.0.3");
} else {
fail("no assertion count for distribution set " + dataReportSeriesItem.getType());
}
}
// test cache evict
final Target knownTarget5 = testdataFactory.createTarget("t5");
assignDistributionSet(distributionSet1.getId(), knownTarget5.getControllerId());
distributionUsage = reportManagement.distributionUsageAssigned(100);
for (final InnerOuterDataReportSeries<String> innerOuterDataReportSeries : distributionUsage) {
final DataReportSeriesItem<String> dataReportSeriesItem = innerOuterDataReportSeries.getInnerSeries()
.getData()[0];
if (dataReportSeriesItem.getType().equals("ds1")) {
assertThat(dataReportSeriesItem.getData()).as("Total count of DistributionSet 1 in statistics")
.isEqualTo(4L);
}
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void lastPollTargets() {
// --- prepare ---
final LocalDateTime now = LocalDateTime.now();
final int knownTargetsPollLastHour = 2;
final int knownTargetsPollLastDay = 3;
final int knownTargetsPollLastWeek = 4;
final int knownTargetsPollLastMonth = 5;
final int knownTargetsPollLastYear = 6;
final int knownTargetsNeverPoll = 7;
// never
createTargets("neverPoll", knownTargetsNeverPoll, null);
// hour
createTargets("hourPoll", knownTargetsPollLastHour, now.minusMinutes(59));
// day
createTargets("dayPoll", knownTargetsPollLastDay, now.minusHours(23));
// week
createTargets("weekPoll", knownTargetsPollLastWeek, now.minusDays(6));
// month
createTargets("monthPoll", knownTargetsPollLastMonth, now.minusWeeks(3));
// year
createTargets("yearPoll", knownTargetsPollLastYear, now.minusMonths(11));
// --- Test ---
DataReportSeries<SeriesTime> targetsNotLastPoll = reportManagement.targetsLastPoll();
DataReportSeriesItem<SeriesTime>[] data = targetsNotLastPoll.getData();
// --- Verfiy ---
// verify hour
assertThat(data[0].getType()).as("Series time").isEqualTo(SeriesTime.HOUR);
assertThat(data[0].getData()).as("Targets poll last hour").isEqualTo((long) knownTargetsPollLastHour);
// verify day
assertThat(data[1].getType()).as("Series time").isEqualTo(SeriesTime.DAY);
assertThat(data[1].getData()).as("Targets poll last day").isEqualTo((long) knownTargetsPollLastDay);
// verify week
assertThat(data[2].getType()).as("Series time").isEqualTo(SeriesTime.WEEK);
assertThat(data[2].getData()).as("Targets poll last week").isEqualTo((long) knownTargetsPollLastWeek);
// test cache evict
createTargets("hourPoll2", knownTargetsPollLastHour, now.minusMinutes(59));
targetsNotLastPoll = reportManagement.targetsLastPoll();
data = targetsNotLastPoll.getData();
assertThat(data[0].getType()).as("Series time").isEqualTo(SeriesTime.HOUR);
assertThat(data[0].getData()).as("Targets poll last hour").isEqualTo((long) knownTargetsPollLastHour * 2);
}
@Test
@WithUser(tenantId = "mytenant", allSpPermissions = true)
@Description("Ensures that targets created report is tenant aware and only creates a report for the current tenant.")
public void targetsCreatedOverPeriodMultiTenancyAware() throws Exception {
final int targetCreateAmount = 10;
// create targets for another tenant
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", "anotherTenant"), () -> {
for (int index = 0; index < targetCreateAmount; index++) {
testdataFactory.createTarget("t" + index);
}
return null;
});
// ensure targets has been created for 'anotherTenant'
final Slice<Target> targetsForAnotherTenant = securityRule.runAs(
WithSpringAuthorityRule.withUserAndTenant("user", "anotherTenant"),
() -> targetManagement.findTargetsAll(new PageRequest(0, 1000)));
assertThat(targetsForAnotherTenant).as("targets has wrong size").hasSize(targetCreateAmount);
final LocalDateTime to = LocalDateTime.now();
final LocalDateTime from = to.minusMonths(targetCreateAmount);
// now retrieve the report for the 'mytenant'
final DataReportSeries<LocalDate> targetsCreatedOverPeriod = reportManagement
.targetsCreatedOverPeriod(DateTypes.perMonth(), from, to);
assertThat(targetsCreatedOverPeriod.getData()).as("final no targets should final be created for this tenant")
.hasSize(0);
}
private void createTargets(final String prefix, final int amount, final LocalDateTime lastTargetQuery) {
for (int index = 0; index < amount; index++) {
final JpaTarget createTarget = (JpaTarget) testdataFactory.createTarget(prefix + index);
if (lastTargetQuery != null) {
createTarget
.setLastTargetQuery(lastTargetQuery.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
targetRepository.save(createTarget);
}
}
}
private void createTargetsWithStatus(final String prefix, final long amount, final TargetUpdateStatus status) {
for (int index = 0; index < amount; index++) {
final JpaTarget target = new JpaTarget(prefix + index);
target.setUpdateStatus(status);
targetRepository.save(target);
}
}
private class DynamicDateTimeProvider implements DateTimeProvider {
private Calendar datetime = Calendar.getInstance();
@Override
public Calendar getNow() {
return datetime;
}
public void now() {
datetime = Calendar.getInstance();
}
public void nowMinusMonths(final int amount) {
datetime = Calendar.getInstance();
datetime.add(Calendar.MONTH, -amount);
}
/**
* @param datetime
* the datetime to set
*/
public void setDatetime(final Calendar datetime) {
this.datetime = datetime;
}
}
}