diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java deleted file mode 100644 index 6c912b6ce..000000000 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java +++ /dev/null @@ -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 - */ - public interface DateType { - /** - * @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, 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> 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> distributionUsageInstalled(int topXEntries); - - /** - * Generates report for feedback over period. - * - * @param dateType - * {@link PerMonth} - * @param from - * start date - * @param to - * end date - * @return DataReportSeries ListReportSeries list of action status - * count - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DataReportSeries feedbackReceivedOverTime(@NotNull DateType 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 DataReportSeries ListReportSeries list of target created - * count - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DataReportSeries targetsCreatedOverPeriod(@NotNull DateType 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 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 targetStatus(); - -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java deleted file mode 100644 index d9f911e01..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java +++ /dev/null @@ -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 targetStatus() { - - final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = cb.createQuery(Object[].class); - final Root targetRoot = query.from(JpaTarget.class); - final Expression countColumn = cb.count(targetRoot.get(JpaTarget_.id)); - final CriteriaQuery 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 resultList = entityManager.createQuery(multiselect).getResultList(); - - final List> 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 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> 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> distributionUsageAssigned(final int topXEntries) { - - // top X entries distribution usage - final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder(); - final CriteriaQuery queryTopX = cbTopX.createQuery(Object[].class); - final Root rootTopX = queryTopX.from(JpaDistributionSet.class); - final ListJoin joinTopX = rootTopX.join(JpaDistributionSet_.assignedToTargets, - JoinType.LEFT); - final Expression countColumn = cbTopX.count(joinTopX); - // top x usage query - final CriteriaQuery 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 resultListTop = entityManager.createQuery(groupBy).getResultList(); - // end of top X entries distribution usage - - return mapDistirbutionUsageResultToDataReport(topXEntries, resultListTop); - } - - @Override - public List> distributionUsageInstalled(final int topXEntries) { - // top X entries distribution usage - final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder(); - final CriteriaQuery queryTopX = cbTopX.createQuery(Object[].class); - final Root rootTopX = queryTopX.from(JpaDistributionSet.class); - final ListJoin joinTopX = rootTopX.join(JpaDistributionSet_.installedAtTargets, - JoinType.LEFT); - final Expression countColumn = cbTopX.count(joinTopX); - // top x usage query - final CriteriaQuery 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 resultListTop = entityManager.createQuery(groupBy).getResultList(); - // end of top X entries distribution usage - - return mapDistirbutionUsageResultToDataReport(topXEntries, resultListTop); - } - - @Override - public DataReportSeries targetsCreatedOverPeriod(final DateType dateType, - final LocalDateTime from, final LocalDateTime to) { - final Query createNativeQuery = entityManager - .createNativeQuery(getTargetsCreatedQueryTemplate(dateType, from, to)); - final List resultList = createNativeQuery.getResultList(); - - final List> 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 DataReportSeries feedbackReceivedOverTime(final DateType dateType, - final LocalDateTime from, final LocalDateTime to) { - final Query createNativeQuery = entityManager - .createNativeQuery(getFeedbackReceivedQueryTemplate(dateType, from, to)); - @SuppressWarnings("unchecked") - final List resultList = createNativeQuery.getResultList(); - - final List> 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 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 countSelect = cb.createQuery(Long.class); - final Root 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> mapDistirbutionUsageResultToDataReport( - final int topXEntries, final List resultListTop) { - final List> innerOuterReport = new ArrayList<>(); - final Map 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> 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 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 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; - } - } - -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java index 828fc1822..544371e24 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java @@ -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. * diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ReportManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ReportManagementTest.java deleted file mode 100644 index e151115b2..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ReportManagementTest.java +++ /dev/null @@ -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 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 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 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 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 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 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> distributionUsage = reportManagement.distributionUsageInstalled(100); - - for (final InnerOuterDataReportSeries innerOuterDataReportSeries : distributionUsage) { - - // innerseries only have one data of the name and the total count - final DataReportSeriesItem 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[] 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[] 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[] 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 innerOuterDataReportSeries : distributionUsage) { - final DataReportSeriesItem 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 targetStatus = reportManagement.targetStatus(); - for (final DataReportSeriesItem 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 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> distributionUsage = reportManagement.distributionUsageAssigned(100); - - for (final InnerOuterDataReportSeries innerOuterDataReportSeries : distributionUsage) { - - // innerseries only have one data of the name and the total count - final DataReportSeriesItem 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[] 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[] 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[] 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 innerOuterDataReportSeries : distributionUsage) { - final DataReportSeriesItem 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 targetsNotLastPoll = reportManagement.targetsLastPoll(); - DataReportSeriesItem[] 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 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 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; - } - } -}