
package gov.nih.nci.evs.api.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import gov.nih.nci.evs.api.model.Metric;

/**
 * The implementation for {@link ElasticOperationsService}.
 *
 * @author Arun
 */
@Service
public class ElasticOperationsServiceImpl implements ElasticOperationsService {

  /** The Constant logger. */
  private static final Logger logger = LoggerFactory.getLogger(ElasticOperationsServiceImpl.class);

  /** Elasticsearch operations *. */
  @Autowired
  ElasticsearchOperations operations;

  /* see superclass */
  @Override
  public boolean createIndex(String index, boolean force) throws IOException {
    boolean indexExists = operations.indexExists(index);

    if (indexExists) {
      if (!force) {
        logger.warn("Index {} already exists. Skipping index creation", index);
        return false;
      }
      operations.deleteIndex(index);
    }

    // create index
    operations.createIndex(index);
    return true;
  }

  /* see superclass */
  @SuppressWarnings("rawtypes")
  @Override
  public void bulkIndex(List objects, String index, String type, Class clazz) throws IOException {
    if (CollectionUtils.isEmpty(objects))
      return;
    List<IndexQuery> indexQueries = new ArrayList<>();

    for (Object obj : objects) {
      indexQueries.add(new IndexQueryBuilder().withObject(clazz.cast(obj)).withIndexName(index)
          .withType(type).build());
    }

    operations.bulkIndex(indexQueries);
  }

  /* see superclass */
  public void loadMetric(Metric metric, String index) throws IOException {
    if (metric == null)
      return;

    final IndexQuery query =
        new IndexQueryBuilder().withObject(metric).withIndexName(index).withType("_doc").build();
    operations.putMapping(index, ElasticOperationsService.METRIC_TYPE, Metric.class);
    operations.index(query);
  }

  /* see superclass */
  @Override
  public void index(Object object, String index, String type,
    @SuppressWarnings("rawtypes") Class clazz) throws IOException {
    IndexQuery query = new IndexQueryBuilder().withObject(clazz.cast(object)).withIndexName(index)
        .withType(type).build();

    operations.index(query);
  }

  /* see superclass */
  @Override
  public boolean deleteIndex(String index) {
    return operations.deleteIndex(index);
  }

  /* see superclass */
  public ElasticsearchOperations getElasticsearchOperations() {
    return operations;
  }
}

@@ -2095,24 +2095,16 @@
  query =
-%0A       
  new Ind
@@ -2159,16 +2159,25 @@
 e(index)
+%0A        
 .withTyp
@@ -2182,28 +2182,137 @@
 ype(
-%22_doc%22).build();%0A   
+ElasticOperationsService.METRIC_TYPE).build();%0A    // BAC: removed this, we do not need to put the mapping on each request%0A    //
  ope
@@ -2374,16 +2374,23 @@
 IC_TYPE,
+%0A    //
  Metric.
@@ -2397,16 +2397,28 @@
 class);%0A
+    try %7B%0A  
     oper
@@ -2430,32 +2430,406 @@
 s.index(query);%0A
+    %7D catch (Exception e) %7B%0A      // This happens on monthly switch-over and we need to create a new index%0A      if (e.getMessage().contains(%22index_not_found_exception%22)) %7B%0A        boolean result = operations.createIndex(index, false);%0A        if (result) %7B%0A          operations.putMapping(index, ElasticOperationsService.METRIC_TYPE, Metric.class);%0A        %7D%0A      %7D%0A    %7D%0A
   %7D%0A%0A  /* see su

Handle month turn-over and recreation of new metrics index (#83)