<commit_before>/*
 * JBoss, Home of Professional Open Source
 * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 */
package org.jboss.elasticsearch.river.jira;

import java.io.IOException;
import java.util.Date;
import java.util.Map;

import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.search.SearchHit;

/**
 * Class used to run one index update process for one JIRA project. Can be used only for one run, then must be discarded
 * and new instance created!
 * 
 * @author <NAME> (velias at redhat dot com)
 */
public class JIRAProjectIndexer implements Runnable {

  private static final ESLogger logger = Loggers.getLogger(JIRAProjectIndexer.class);

  /**
   * Property value where "last indexed issue update date" is stored
   * 
   * @see IESIntegration#storeDatetimeValue(String, String, Date, BulkRequestBuilder)
   * @see IESIntegration#readDatetimeValue(String, String)
   */
  protected static final String STORE_PROPERTYNAME_LAST_INDEXED_ISSUE_UPDATE_DATE = "lastIndexedIssueUpdateDate";

  protected final IJIRAClient jiraClient;

  protected final IESIntegration esIntegrationComponent;

  /**
   * Configured JIRA issue index structure builder to be used.
   */
  protected final IJIRAIssueIndexStructureBuilder jiraIssueIndexStructureBuilder;

  /**
   * Key of JIRA project updated.
   */
  protected final String projectKey;

  /**
   * <code>true</code> if full update indexing is necessary, <code>false</code> on incremental update.
   */
  protected boolean fullUpdate = false;

  /**
   * Time when indexing started.
   */
  protected long startTime = 0;

  /**
   * Number of issues updated during this indexing.
   */
  protected int updatedCount = 0;

  /**
   * Number of issues deleted during this indexing.
   */
  protected int deleteCount = 0;

  /**
   * Number of issue comments deleted during this indexing.
   */
  protected int deleteCommentsCount = 0;

  /**
   * @param projectKey JIRA project key for project to be indexed by this indexer.
   * @param jiraClient configured JIRA client to be used to obtain informations from JIRA.
   * @param esIntegrationComponent to be used to call River component and ElasticSearch functions
   */
  public JIRAProjectIndexer(String projectKey, boolean fullUpdate, IJIRAClient jiraClient,
      IESIntegration esIntegrationComponent, IJIRAIssueIndexStructureBuilder jiraIssueIndexStructureBuilder) {
    if (projectKey == null || projectKey.trim().length() == 0)
      throw new IllegalArgumentException("projectKey must be defined");
    this.jiraClient = jiraClient;
    this.projectKey = projectKey;
    this.fullUpdate = fullUpdate;
    this.esIntegrationComponent = esIntegrationComponent;
    this.jiraIssueIndexStructureBuilder = jiraIssueIndexStructureBuilder;
  }

  @Override
  public void run() {
    startTime = System.currentTimeMillis();
    try {
      processUpdate();
      processDelete(new Date(startTime));
      long timeElapsed = (System.currentTimeMillis() - startTime);
      esIntegrationComponent.reportIndexingFinished(projectKey, true, fullUpdate, updatedCount, deleteCount, new Date(
          startTime), timeElapsed, null);
      logger.info("Finished {} update for JIRA project {}. {} updated and {} deleted issues. Time elapsed {}s.",
          fullUpdate ? "full" : "incremental", projectKey, updatedCount, deleteCount, (timeElapsed / 1000));
    } catch (Throwable e) {
      long timeElapsed = (System.currentTimeMillis() - startTime);
      esIntegrationComponent.reportIndexingFinished(projectKey, false, fullUpdate, updatedCount, deleteCount, new Date(
          startTime), timeElapsed, e.getMessage());
      logger.error("Failed {} update for JIRA project {} due: {}", e, fullUpdate ? "full" : "incremental", projectKey,
          e.getMessage());
    }
  }

  /**
   * Process update of search index for configured JIRA project. A {@link #updatedCount} field is updated inside of this
   * method. A {@link #fullUpdate} field can be updated inside of this method.
   * 
   * @throws Exception
   * 
   */<commit_msg>improved error logging not to write stacktrace for 'operational' errors as jira read timeout etc<commit_after>/*
 * JBoss, Home of Professional Open Source
 * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 */
package org.jboss.elasticsearch.river.jira;

import java.io.IOException;
import java.util.Date;
import java.util.Map;

import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.search.SearchHit;

/**
 * Class used to run one index update process for one JIRA project. Can be used only for one run, then must be discarded
 * and new instance created!
 * 
 * @author <NAME> (velias at redhat dot com)
 */
public class JIRAProjectIndexer implements Runnable {

  private static final ESLogger logger = Loggers.getLogger(JIRAProjectIndexer.class);

  /**
   * Property value where "last indexed issue update date" is stored
   * 
   * @see IESIntegration#storeDatetimeValue(String, String, Date, BulkRequestBuilder)
   * @see IESIntegration#readDatetimeValue(String, String)
   */
  protected static final String STORE_PROPERTYNAME_LAST_INDEXED_ISSUE_UPDATE_DATE = "lastIndexedIssueUpdateDate";

  protected final IJIRAClient jiraClient;

  protected final IESIntegration esIntegrationComponent;

  /**
   * Configured JIRA issue index structure builder to be used.
   */
  protected final IJIRAIssueIndexStructureBuilder jiraIssueIndexStructureBuilder;

  /**
   * Key of JIRA project updated.
   */
  protected final String projectKey;

  /**
   * <code>true</code> if full update indexing is necessary, <code>false</code> on incremental update.
   */
  protected boolean fullUpdate = false;

  /**
   * Time when indexing started.
   */
  protected long startTime = 0;

  /**
   * Number of issues updated during this indexing.
   */
  protected int updatedCount = 0;

  /**
   * Number of issues deleted during this indexing.
   */
  protected int deleteCount = 0;

  /**
   * Number of issue comments deleted during this indexing.
   */
  protected int deleteCommentsCount = 0;

  /**
   * @param projectKey JIRA project key for project to be indexed by this indexer.
   * @param jiraClient configured JIRA client to be used to obtain informations from JIRA.
   * @param esIntegrationComponent to be used to call River component and ElasticSearch functions
   */
  public JIRAProjectIndexer(String projectKey, boolean fullUpdate, IJIRAClient jiraClient,
      IESIntegration esIntegrationComponent, IJIRAIssueIndexStructureBuilder jiraIssueIndexStructureBuilder) {
    if (projectKey == null || projectKey.trim().length() == 0)
      throw new IllegalArgumentException("projectKey must be defined");
    this.jiraClient = jiraClient;
    this.projectKey = projectKey;
    this.fullUpdate = fullUpdate;
    this.esIntegrationComponent = esIntegrationComponent;
    this.jiraIssueIndexStructureBuilder = jiraIssueIndexStructureBuilder;
  }

  @Override
  public void run() {
    startTime = System.currentTimeMillis();
    try {
      processUpdate();
      processDelete(new Date(startTime));
      long timeElapsed = (System.currentTimeMillis() - startTime);
      esIntegrationComponent.reportIndexingFinished(projectKey, true, fullUpdate, updatedCount, deleteCount, new Date(
          startTime), timeElapsed, null);
      logger.info("Finished {} update for JIRA project {}. {} updated and {} deleted issues. Time elapsed {}s.",
          fullUpdate ? "full" : "incremental", projectKey, updatedCount, deleteCount, (timeElapsed / 1000));
    } catch (Throwable e) {
      long timeElapsed = (System.currentTimeMillis() - startTime);
      esIntegrationComponent.reportIndexingFinished(projectKey, false, fullUpdate, updatedCount, deleteCount, new Date(
          startTime), timeElapsed, e.getMessage());
      Throwable cause = e;
      // do not log stacktrace for some operational exceptions to keep log file much clear
      if (cause instanceof IOException)
        cause = null;
      logger.error("Failed {} update for JIRA project {} due: {}", cause, fullUpdate ? "full" : "incremental",
          projectKey, e.getMessage());
    }
  }

  /**
   * Process update of search index for configured JIRA project. A {@link #updatedCount} field is updated inside of this
   * method. A {@link #fullUpdate} field can be updated inside of this method.
   * 
   * @throws Exception
   */
{'fraction_non_alphanumeric': 0.08757093579615, 'fraction_numerical': 0.002893067764548793, 'mean_word_length': 3.949339207048458, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '5760240', 'n_tokens_mistral': 2525, 'n_tokens_neox': 2437, 'n_words': 793}