package sagan.search.support; import com.google.gson.Gson; import io.searchbox.action.Action; import io.searchbox.client.JestClient; import io.searchbox.client.JestResult; import io.searchbox.core.Delete; import io.searchbox.core.DeleteByQuery; import io.searchbox.core.Index; import io.searchbox.core.Search; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.elasticsearch.index.query.FilteredQueryBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import sagan.search.SearchException; import sagan.search.types.SearchEntry; import java.util.List; @Service public class SearchService { private static Log logger = LogFactory.getLog(SearchService.class); private final JestClient jestClient; private final Gson gson; private boolean useRefresh = false; private SearchResultParser searchResultParser; @Value("${elasticsearch.client.index}") private String index; @Autowired public SearchService(JestClient jestClient, SearchResultParser searchResultParser, Gson gson) { this.jestClient = jestClient; this.searchResultParser = searchResultParser; this.gson = gson; } public String getIndexName() { return index; } public void saveToIndex(SearchEntry entry) { Index.Builder indexEntryBuilder = new Index.Builder(entry).id(entry.getId()).index(index).type(entry.getType()); if (useRefresh) { indexEntryBuilder.refresh(true); } logger.debug("Indexing " + entry.getPath()); execute(indexEntryBuilder.build()); } public SearchResults search(String term, Pageable pageable, List<String> filter) { Search.Builder searchBuilder; if (StringUtils.isEmpty(term)) { searchBuilder = SaganQueryBuilders.forEmptyQuery(pageable, filter); } else { searchBuilder = SaganQueryBuilders.fullTextSearch(term, pageable, filter); } searchBuilder.addIndex(index); Search search = searchBuilder.build(); logger.debug(search.getData(this.gson)); JestResult jestResult = execute(search); return searchResultParser.parseResults(jestResult, pageable, term); } public void setUseRefresh(boolean useRefresh) { this.useRefresh = useRefresh; } public void removeFromIndex(SearchEntry entry) { Delete delete = new Delete.Builder(entry.getId()) .index(index) .type(entry.getType()) .build(); execute(delete); } public void removeOldProjectEntriesFromIndex(String projectId, List<String> supportedVersions) { FilteredQueryBuilder builder = SaganQueryBuilders.matchUnsupportedProjectEntries(projectId, supportedVersions); String query = SaganQueryBuilders.wrapQuery(builder.toString()); execute(new DeleteByQuery.Builder(query).build()); } private JestResult execute(Action action) { try { JestResult result = jestClient.execute(action); logger.debug(result.getJsonString()); if (!result.isSucceeded()) { logger.warn("Failed to execute Elastic Search action: " + result.getErrorMessage() + " " + result.getJsonString()); } return result; } catch (Exception e) { throw new SearchException(e); } } }