<commit_before>/*
*************************************************************************************
* Copyright 2013 Normation SAS
*************************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* In accordance with the terms of section 7 (7. Additional Terms.) of
* the GNU Affero GPL v3, the copyright holders add the following
* Additional permissions:
* Notwithstanding to the terms of section 5 (5. Conveying Modified Source
* Versions) and 6 (6. Conveying Non-Source Forms.) of the GNU Affero GPL v3
* licence, when you create a Related Module, this Related Module is
* not considered as a part of the work and may be distributed under the
* license agreement of your choice.
* A "Related Module" means a set of sources files including their
* documentation that, without modification of the Source Code, enables
* supplementary functions or services in addition to those offered by
* the Software.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/agpl.html>.
*
*************************************************************************************
*/

package com.normation.rudder.reports.execution

import com.normation.rudder.repository.ReportsRepository
import com.normation.rudder.domain.reports.bean._
import com.normation.utils.HashcodeCaching
import net.liftweb.common._
import com.normation.rudder.reports.status.StatusUpdateRepository
import org.joda.time.DateTime
import com.normation.rudder.batch.FindNewReportsExecution

/**
 * That service contains most of the logic to merge
 * interval of same criticity together.
 */
class ReportsExecutionService (
    reportsRepository      : ReportsRepository
  , readExecutions         : RoReportsExecutionRepository
  , writeExecutions        : WoReportsExecutionRepository
  , statusUpdateRepository : StatusUpdateRepository
  , maxDays                : Int // in days
) extends Loggable {

  val format = "yyyy/MM/dd HH:mm:ss"

  def findAndSaveExecutions(processId : Long) = {
    val startTime = DateTime.now().getMillis()
    // Get execution status
    statusUpdateRepository.getExecutionStatus match {
      // Find it, start looking for new executions
      case Full(Some((lastReportId,lastReportDate))) =>

        // Get reports of the last id and before last report date plus maxDays
        val endBatchDate = if (lastReportDate.plusDays(maxDays).isAfter(DateTime.now)) {
                              DateTime.now
                            } else {
                              lastReportDate.plusDays(maxDays)
                            }

        logger.info(s"[${FindNewReportsExecution.SERVICE_NAME}] Task #${processId}: Starting analysis for run times from ${lastReportDate.toString(format)} up to ${endBatchDate.toString(format)} (runs after SQL table ID ${lastReportId})")

        reportsRepository.getReportsfromId(lastReportId, endBatchDate) match {
          case Full((reportExec, maxReportId)) =>
            if (reportExec.size > 0) {
              val maxDate = reportExec.maxBy(_.date.getMillis()).date
              // Save new executions
              writeExecutions.updateExecutions(reportExec) match {
                case Full(result) =>
                  val executionTime = DateTime.now().getMillis() - startTime<commit_msg>Fixes #4148: Fixes reporting when a report received is older than last report treated<commit_after>/*
*************************************************************************************
* Copyright 2013 Normation SAS
*************************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* In accordance with the terms of section 7 (7. Additional Terms.) of
* the GNU Affero GPL v3, the copyright holders add the following
* Additional permissions:
* Notwithstanding to the terms of section 5 (5. Conveying Modified Source
* Versions) and 6 (6. Conveying Non-Source Forms.) of the GNU Affero GPL v3
* licence, when you create a Related Module, this Related Module is
* not considered as a part of the work and may be distributed under the
* license agreement of your choice.
* A "Related Module" means a set of sources files including their
* documentation that, without modification of the Source Code, enables
* supplementary functions or services in addition to those offered by
* the Software.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/agpl.html>.
*
*************************************************************************************
*/

package com.normation.rudder.reports.execution

import com.normation.rudder.repository.ReportsRepository
import com.normation.rudder.domain.reports.bean._
import com.normation.utils.HashcodeCaching
import net.liftweb.common._
import com.normation.rudder.reports.status.StatusUpdateRepository
import org.joda.time.DateTime
import com.normation.rudder.batch.FindNewReportsExecution

/**
 * That service contains most of the logic to merge
 * interval of same criticity together.
 */
class ReportsExecutionService (
    reportsRepository      : ReportsRepository
  , readExecutions         : RoReportsExecutionRepository
  , writeExecutions        : WoReportsExecutionRepository
  , statusUpdateRepository : StatusUpdateRepository
  , maxDays                : Int // in days
) extends Loggable {

  val format = "yyyy/MM/dd HH:mm:ss"

  def findAndSaveExecutions(processId : Long) = {
    val startTime = DateTime.now().getMillis()
    // Get execution status
    statusUpdateRepository.getExecutionStatus match {
      // Find it, start looking for new executions
      case Full(Some((lastReportId,lastReportDate))) =>

        // Get reports of the last id and before last report date plus maxDays
        val endBatchDate = if (lastReportDate.plusDays(maxDays).isAfter(DateTime.now)) {
                              DateTime.now
                            } else {
                              lastReportDate.plusDays(maxDays)
                            }

        logger.info(s"[${FindNewReportsExecution.SERVICE_NAME}] Task #${processId}: Starting analysis for run times from ${lastReportDate.toString(format)} up to ${endBatchDate.toString(format)} (runs after SQL table ID ${lastReportId})")

        reportsRepository.getReportsfromId(lastReportId, endBatchDate) match {
          case Full((reportExec, maxReportId)) =>
            if (reportExec.size > 0) {

              val maxDate = {
                // Keep the last report date is the last report treated is after all treated in this batch
                val maxReportsDate = reportExec.maxBy(_.date.getMillis()).date
                if (maxReportsDate isAfter lastReportDate) {
                  maxReportsDate
                } else {
                  lastReportDate
                }
              }
              // Save new executions
              writeExecutions.updateExecutions(reportExec) match {
                case Full(result) =>
                  val executionTime = DateTime.now().getMillis() - startTime
{'fraction_non_alphanumeric': 0.13018844685306072, 'fraction_numerical': 0.003941372090158887, 'mean_word_length': 3.3306666666666667, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1896135', 'n_tokens_mistral': 2013, 'n_tokens_neox': 1900, 'n_words': 738}