001/* 002 * (C) Copyright 2016-2018 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Antoine Taillefer <[email protected]> 018 */ 019package org.nuxeo.drive.elasticsearch; 020 021import org.apache.commons.lang3.StringUtils; 022import org.apache.logging.log4j.LogManager; 023import org.apache.logging.log4j.Logger; 024import org.nuxeo.drive.adapter.FolderItem; 025import org.nuxeo.drive.adapter.impl.DefaultSyncRootFolderItem; 026import org.nuxeo.drive.adapter.impl.ScrollDocumentModelList; 027import org.nuxeo.ecm.core.api.CoreSession; 028import org.nuxeo.ecm.core.api.DocumentModel; 029import org.nuxeo.elasticsearch.api.ElasticSearchService; 030import org.nuxeo.elasticsearch.api.EsScrollResult; 031import org.nuxeo.elasticsearch.query.NxQueryBuilder; 032import org.nuxeo.runtime.api.Framework; 033 034/** 035 * Elasticsearch implementation of a {@link DefaultSyncRootFolderItem}. 036 * 037 * @since 8.3 038 */ 039public class ESSyncRootFolderItem extends DefaultSyncRootFolderItem { 040 041 private static final Logger log = LogManager.getLogger(ESSyncRootFolderItem.class); 042 043 public ESSyncRootFolderItem(String factoryName, FolderItem parentItem, DocumentModel doc) { 044 super(factoryName, parentItem, doc); 045 } 046 047 public ESSyncRootFolderItem(String factoryName, FolderItem parentItem, DocumentModel doc, 048 boolean relaxSyncRootConstraint) { 049 super(factoryName, parentItem, doc, relaxSyncRootConstraint); 050 } 051 052 public ESSyncRootFolderItem(String factoryName, FolderItem parentItem, DocumentModel doc, 053 boolean relaxSyncRootConstraint, boolean getLockInfo) { 054 super(factoryName, parentItem, doc, relaxSyncRootConstraint, getLockInfo); 055 } 056 057 protected ESSyncRootFolderItem() { 058 // Needed for JSON deserialization 059 } 060 061 @Override 062 protected ScrollDocumentModelList getScrollBatch(String scrollId, int batchSize, CoreSession session, 063 long keepAlive) { 064 065 ElasticSearchService ess = Framework.getService(ElasticSearchService.class); 066 067 StringBuilder sb = new StringBuilder( 068 String.format("SELECT * FROM Document WHERE ecm:ancestorId = '%s'", docId)); 069 sb.append(" AND ecm:isTrashed = 0"); 070 sb.append(" AND ecm:mixinType != 'HiddenInNavigation'"); 071 sb.append(" AND ecm:isVersion = 0"); 072 // Let's order by path to make it easier for Drive as it isn't that expensive with Elasticsearch 073 sb.append(" ORDER BY ecm:path"); 074 String query = sb.toString(); 075 NxQueryBuilder queryBuilder = new NxQueryBuilder(session).nxql(query).limit(batchSize); 076 077 EsScrollResult res; 078 if (StringUtils.isEmpty(scrollId)) { 079 log.debug( 080 "Executing Elasticsearch initial search request to scroll through the descendants of {} with batchSize = {} and keepAlive = {}: {}", 081 docPath, batchSize, keepAlive, query); 082 res = ess.scroll(queryBuilder, keepAlive); 083 } else { 084 log.debug("Scrolling through the descendants of {} with scrollId = {}, batchSize = {} and keepAlive = {}", 085 docPath, scrollId, batchSize, keepAlive); 086 res = ess.scroll(new EsScrollResult(queryBuilder, scrollId, keepAlive)); 087 } 088 return new ScrollDocumentModelList(res.getScrollId(), res.getDocuments()); 089 } 090 091}