class PrometheusMetricsProviderImpl implements MetricsProvider {

    @Override
    public IntegrationMetricsSummary getIntegrationMetricsSummary(String integrationId) {

        // aggregate values across versions
        final Map<String, Long> totalMessagesMap = getMetricValues(integrationId, METRIC_TOTAL, deploymentVersionLabel, Long.class, PrometheusMetricsProviderImpl::sum);
        final Map<String, Long> failedMessagesMap = getMetricValues(integrationId, METRIC_FAILED, deploymentVersionLabel, Long.class, PrometheusMetricsProviderImpl::sum);

        final Map<String, Instant> startTimeMap = getMetricValues(integrationId, METRIC_START_TIMESTAMP, deploymentVersionLabel, Instant.class, PrometheusMetricsProviderImpl::max);

        // compute last processed time from lastCompleted and lastFailure times
        final Map<String, Instant> lastCompletedTimeMap = getMetricValues(integrationId, METRIC_COMPLETED_TIMESTAMP, deploymentVersionLabel, Instant.class, PrometheusMetricsProviderImpl::max);
        final Map<String, Instant> lastFailedTimeMap = getMetricValues(integrationId, METRIC_FAILURE_TIMESTAMP, deploymentVersionLabel, Instant.class, PrometheusMetricsProviderImpl::max);
        final Map<String, Instant> lastProcessedTimeMap = Stream.concat(lastCompletedTimeMap.entrySet().stream(), lastFailedTimeMap.entrySet().stream())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, PrometheusMetricsProviderImpl::max));

        final Optional<Instant> startTime = getAggregateMetricValue(integrationId, METRIC_START_TIMESTAMP, Instant.class, MIN);

        final Optional<Instant> lastCompletedTime = getAggregateMetricValue(integrationId, METRIC_COMPLETED_TIMESTAMP, Instant.class, MAX);
        final Optional<Instant> lastFailureTime = getAggregateMetricValue(integrationId, METRIC_FAILURE_TIMESTAMP, Instant.class, MAX);
        final Instant lastProcessedTime = max(lastCompletedTime.orElse(null), lastFailureTime.orElse(null));

        return createIntegrationMetricsSummary(totalMessagesMap, failedMessagesMap,
            startTimeMap, lastProcessedTimeMap, startTime, Optional.ofNullable(lastProcessedTime));
    }

    protected  PrometheusMetricsProviderImpl(PrometheusConfigurationProperties config, NamespacedOpenShiftClient openShiftClient);

}