/** * * geo-platform * Rich webgis framework * http://geo-platform.org * ==================================================================== * * Copyright (C) 2008-2017 geoSDI Group (CNR IMAA - Potenza - ITALY). * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. 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 General Public License * for more details. You should have received a copy of the GNU General * Public License along with this program. If not, see http://www.gnu.org/licenses/ * * ==================================================================== * * Linking this library statically or dynamically with other modules is * making a combined work based on this library. Thus, the terms and * conditions of the GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give you permission * to link this library with independent modules to produce an executable, regardless * of the license terms of these independent modules, and to copy and distribute * the resulting executable under terms of your choice, provided that you also meet, * for each linked independent module, the terms and conditions of the license of * that module. An independent module is a module which is not derived from or * based on this library. If you modify this library, you may extend this exception * to your version of the library, but you are not obligated to do so. If you do not * wish to do so, delete this exception statement from your version. */ package org.geosdi.geoplatform.experimental.el.dao; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.QueryBuilder; import org.geosdi.geoplatform.experimental.el.api.model.Document; import org.geosdi.geoplatform.experimental.el.condition.PredicateCondition; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; import static java.lang.Boolean.TRUE; /** * @param <D> * @author Giuseppe La Scaleia - CNR IMAA geoSDI Group * @email giuseppe.lascaleia@geosdi.org */ public abstract class AbstractElasticSearchDAO<D extends Document> extends PageableElasticSearchDAO<D> { @Override public D persist(D document) throws Exception { logger.debug("#################Try to insert {}\n\n", document); IndexResponse response; if (document.isIdSetted()) { response = this.elastichSearchClient.prepareIndex(getIndexName(), getIndexType(), document.getId()) .setSource(this.mapper.writeAsString(document)).get(); } else { response = this.elastichSearchClient.prepareIndex(getIndexName(), getIndexType()) .setSource(this.mapper.writeAsString(document)).get(); document.setId(response.getId()); update(document); } logger.debug("##############{} Created : {}\n\n", this.mapper.getDocumentClassName(), response.isCreated()); return document; } @Override public void update(D document) throws Exception { Preconditions.checkArgument( ((document != null) && ((document.getId() != null) && !(document.getId().isEmpty()))), "The {} to Update must" + " not be null or ID must not be null or Empty.", this.mapper.getDocumentClassName()); logger.debug("################Try to Update : {}\n\n", document); this.elastichSearchClient.prepareUpdate(getIndexName(), getIndexType(), document.getId()) .setDoc(this.mapper.writeAsString(document)).get(); } /** * @param ids * @return {@link List <D>} * @throws Exception */ @Override public List<D> findByIDS(Iterable<String> ids) throws Exception { return findByIDS(ids, new PredicateCondition.EmptyPredicateCondition<D>()); } /** * @param ids * @return {@link List <D>} * @throws Exception */ @Override public List<D> findByIDS(Iterable<String> ids, PredicateCondition<D> condition) throws Exception { Preconditions.checkArgument((ids != null) && (Iterables.size(ids) > 0)); MultiGetResponse multiGetResponses = this.elastichSearchClient.prepareMultiGet() .setRealtime(TRUE) .setIgnoreErrorsOnGeneratedFields(TRUE) .add(getIndexName(), getIndexType(), ids).get(); return Arrays.stream(multiGetResponses.getResponses()).filter(response -> !response.isFailed()) .map(r -> readGetResponse(r.getResponse())) .filter(d -> ((condition != null) ? ((d != null) && (condition.test(d))) : d != null)) .collect(Collectors.toList()); } @Override public BulkResponse persist(Iterable<D> documents) throws Exception { Preconditions.checkArgument(((documents != null)), "The Documents " + "to save, must not be null."); BulkRequestBuilder bulkRequest = this.elastichSearchClient.prepareBulk(); StreamSupport.stream(documents.spliterator(), Boolean.FALSE) .map(document -> this.prepareIndexRequestBuilder(document)) .filter(IndexRequestBuilder -> IndexRequestBuilder != null) .forEach(IndexRequestBuilder -> bulkRequest.add(IndexRequestBuilder)); BulkResponse bulkResponse = bulkRequest.get(); if (bulkResponse.hasFailures()) { throw new IllegalStateException(bulkResponse.buildFailureMessage()); } return bulkResponse; } /** * <p>Persist all Files json in a Directory. This method in not recursive for the Directory.</p> * * @param direrctory * @return {@link} * @throws Exception */ @Override public BulkResponse persist(Path direrctory) throws Exception { Preconditions.checkArgument((direrctory != null) && (direrctory.toFile().isDirectory()), "The Parameter Directory must not be null and must be a Directory."); return this.persist(Files.list(direrctory) .filter(path -> path.toFile().getName().endsWith(".json")) .map(path -> super.readDocument(path)) .filter(d -> d != null) .collect(Collectors.toList())); } @Override public void delete(String id) { Preconditions.checkArgument(((id != null) && !(id.isEmpty())), "The ID must not be null or an Empty String"); DeleteResponse response = elastichSearchClient.prepareDelete(getIndexName(), getIndexType(), id).execute() .actionGet(); if (response.isFound()) { logger.debug("#################Document with ID : {}, " + "was deleted.", id); } else { logger.debug("#################Document with ID : {}, " + "was not found in ElasticSearch."); } } @Override public D find(String id) throws Exception { Preconditions.checkArgument((id != null) && !(id.isEmpty()), "The ElasticSearch ID must not be null or an Empty String"); GetResponse existResponse = elastichSearchClient.prepareGet(getIndexName(), getIndexType(), id).get(); return (existResponse.isExists()) ? readGetResponse(existResponse) : null; } @Override public Long count() { return this.elastichSearchClient .prepareSearch(getIndexName()) .setTypes(getIndexType()) .get().getHits().getTotalHits(); } /** * @param queryBuilder * @return {@link Long} * @throws Exception */ @Override public Long count(QueryBuilder queryBuilder) throws Exception { return this.elastichSearchClient .prepareSearch(getIndexName()) .setQuery(queryBuilder) .setTypes(getIndexType()) .get().getHits().getTotalHits(); } @Override public void removeAll() throws Exception { SearchResponse searchResponse = this.elastichSearchClient.prepareSearch() .setIndices(getIndexName()) .setTypes(getIndexType()) .setScroll(new TimeValue(60000)) .setSize(100).execute().actionGet(); while (true) { Stream.of(searchResponse.getHits().hits()).forEach(document -> { this.elastichSearchClient.delete(new DeleteRequest(getIndexName(), getIndexType(), document.getId())).actionGet(); }); searchResponse = this.elastichSearchClient.prepareSearchScroll(searchResponse.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet(); if (searchResponse.getHits().getHits().length == 0) { break; } } } }