package gov.nysenate.openleg.dao.calendar.search;
import com.google.common.collect.Lists;
import gov.nysenate.openleg.client.view.calendar.*;
import gov.nysenate.openleg.dao.base.ElasticBaseDao;
import gov.nysenate.openleg.dao.base.LimitOffset;
import gov.nysenate.openleg.model.calendar.Calendar;
import gov.nysenate.openleg.model.calendar.CalendarId;
import gov.nysenate.openleg.model.search.SearchResults;
import gov.nysenate.openleg.util.OutputUtils;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.deletebyquery.DeleteByQueryAction;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequestBuilder;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
@Repository
public class ElasticCalendarSearchDao extends ElasticBaseDao implements CalendarSearchDao {
private static final Logger logger = LoggerFactory.getLogger(ElasticCalendarSearchDao.class);
@Autowired
CalendarViewFactory calendarViewFactory;
/** --- Index Names --- */
protected static final String calIndexName = "calendars";
/** --- Implementations --- */
/**{@inheritDoc}*/
@Override
public SearchResults<CalendarId> searchCalendars(QueryBuilder query, QueryBuilder postFilter,
List<SortBuilder> sort, LimitOffset limitOffset) {
SearchRequestBuilder searchBuilder = getSearchRequest(calIndexName, query, postFilter, sort, limitOffset);
SearchResponse response = searchBuilder.execute().actionGet();
return getSearchResults(response, limitOffset, this::getCalendarId);
}
/**{@inheritDoc}*/
@Override
public void updateCalendarIndex(Calendar calendar) {
if (calendar != null) {
BulkRequestBuilder bulkRequest = searchClient.prepareBulk();
addCalToBulkRequest(calendar, bulkRequest);
bulkRequest.execute().actionGet();
}
}
/**{@inheritDoc}*/
@Override
public void updateCalendarIndexBulk(Collection<Calendar> calendars) {
BulkRequestBuilder bulkRequest = searchClient.prepareBulk();
calendars.forEach(cal -> addCalToBulkRequest(cal, bulkRequest));
bulkRequest.execute().actionGet();
}
/**{@inheritDoc}*/
@Override
public void deleteCalendarFromIndex(CalendarId calId) {
if (calId != null) {
DeleteByQueryRequestBuilder builder = new DeleteByQueryRequestBuilder(searchClient, DeleteByQueryAction.INSTANCE);
builder.setIndices(calIndexName)
.setTypes(Integer.toString(calId.getYear()))
.setQuery(QueryBuilders.matchQuery("calendarNumber", Integer.toString(calId.getCalNo())))
.execute().actionGet();
/*searchClient.prepareDeleteByQuery(calIndexName)
.setTypes(Integer.toString(calId.getYear()))
.setQuery(QueryBuilders.matchQuery("calendarNumber", Integer.toString(calId.getCalNo())))
.execute().actionGet();*/
}
}
/**
* {@inheritDoc}
*/
@Override
protected List<String> getIndices() {
return Lists.newArrayList(calIndexName);
}
/**
* --- Internal Methods ---
*/
/**
* Adds a calendar along with all of its floor calendars and active lists to a bulk index request
*
* @param calendar
* @param bulkRequest
*/
protected void addCalToBulkRequest(Calendar calendar, BulkRequestBuilder bulkRequest) {
logger.info("Preparing to index {}", calendar);
CalendarView calendarView = calendarViewFactory.getCalendarView(calendar);
bulkRequest.add(getCalendarIndexRequest(calendarView));
}
/**
* Generates an index update request from a calendar view
*
* @param calendarView
* @return
*/
protected IndexRequestBuilder getCalendarIndexRequest(CalendarView calendarView) {
return searchClient.prepareIndex(calIndexName,
Integer.toString(calendarView.getYear()), Integer.toString(calendarView.getCalendarNumber()))
.setSource(OutputUtils.toJson(calendarView));
}
/** --- Id Mappers --- */
/**
* Retrieves a CalendarId from a search hit
*
* @param hit
* @return
*/
protected CalendarId getCalendarId(SearchHit hit) {
return new CalendarId(Integer.parseInt(hit.id()), Integer.parseInt(hit.type()));
}
}